first commit

This commit is contained in:
2024-11-05 12:22:50 +01:00
commit e5682a3912
19641 changed files with 2948548 additions and 0 deletions

View File

@@ -0,0 +1,60 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Adapter;
use Configuration;
use Shop;
class ConfigurationAdapter
{
/**
* @var Shop
*/
private $shopId;
public function __construct($shopId)
{
$this->shopId = $shopId;
}
public function get($key, $idLang = null, $idShopGroup = null, $idShop = null, $default = false)
{
if ($idShop === null) {
$idShop = $this->shopId;
}
return Configuration::get($key, $idLang, $idShopGroup, $idShop, $default);
}
public function updateValue($key, $values, $html = false, $idShopGroup = null, $idShop = null)
{
if ($idShop === null) {
$idShop = $this->shopId;
}
return Configuration::updateValue($key, $values, $html, $idShopGroup, $idShop);
}
public function deleteByName($key)
{
return Configuration::deleteByName($key);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,80 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Buffer;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockFileSessionStorage;
class TemplateBuffer
{
/**
* @var Session
*/
private $session;
/**
* @param string $userId
*/
public function init($userId)
{
$this->session = new Session(
new MockFileSessionStorage(
\_PS_CACHE_DIR_ . '/psxmarketingwithgoogle_sessions',
'conversionaction'
)
);
$this->session->setId($userId);
$this->session->start();
register_shutdown_function([$this, 'save']);
}
/**
* add data to the buffer
*
* @param string $data
*
* @return void
*/
public function add($data)
{
$this->session->getFlashBag()->add('gtag_events', $data);
}
/**
* return buffer content and reset it
*
* @return string
*/
public function flush(): string
{
$data = '';
foreach ($this->session->getFlashBag()->get('gtag_events', []) as $message) {
$data .= $message;
}
return $data;
}
public function save(): void
{
$this->session->save();
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,232 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Builder;
use Carrier;
use Currency;
use Language;
use PrestaShop\Module\PsxMarketingWithGoogle\Adapter\ConfigurationAdapter;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\Carrier as DTOCarrier;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\CarrierDetail;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\CarrierTax;
use PrestaShop\Module\PsxMarketingWithGoogle\Repository\CarrierRepository;
use PrestaShop\Module\PsxMarketingWithGoogle\Repository\CountryRepository;
use PrestaShop\Module\PsxMarketingWithGoogle\Repository\StateRepository;
use PrestaShop\Module\PsxMarketingWithGoogle\Repository\TaxRepository;
use RangePrice;
use RangeWeight;
class CarrierBuilder
{
/**
* @var CarrierRepository
*/
private $carrierRepository;
/**
* @var CountryRepository
*/
private $countryRepository;
/**
* @var StateRepository
*/
private $stateRepository;
/**
* @var TaxRepository
*/
private $taxRepository;
/**
* @var ConfigurationAdapter
*/
private $configurationAdapter;
public function __construct(
CarrierRepository $carrierRepository,
CountryRepository $countryRepository,
StateRepository $stateRepository,
TaxRepository $taxRepository,
ConfigurationAdapter $configurationAdapter
) {
$this->carrierRepository = $carrierRepository;
$this->countryRepository = $countryRepository;
$this->stateRepository = $stateRepository;
$this->taxRepository = $taxRepository;
$this->configurationAdapter = $configurationAdapter;
}
public function buildCarriers(array $carriers, Language $lang, Currency $currency, string $weightUnit): array
{
$carrierLines = [];
foreach ($carriers as $carrier) {
$carrierLines[] = self::buildCarrier(
new Carrier($carrier['id_carrier'], $lang->id),
$currency->iso_code,
$weightUnit
);
}
$formattedCarriers = [];
/** @var DTOCarrier $carrierLine */
foreach ($carrierLines as $carrierLine) {
$formattedCarriers = array_merge($formattedCarriers, $carrierLine->jsonSerialize());
}
return $formattedCarriers;
}
public function buildCarrier(Carrier $carrier, string $currencyIsoCode, string $weightUnit): DTOCarrier
{
$carrierLine = new DTOCarrier();
$freeShippingStartsAtPrice = (float) $this->configurationAdapter->get('PS_SHIPPING_FREE_PRICE');
$freeShippingStartsAtWeight = (float) $this->configurationAdapter->get('PS_SHIPPING_FREE_WEIGHT');
$carrierLine->setFreeShippingStartsAtPrice($freeShippingStartsAtPrice);
$carrierLine->setFreeShippingStartsAtWeight($freeShippingStartsAtWeight);
$carrierLine->setShippingHandling($this->getShippingHandlePrice((bool) $carrier->shipping_handling));
$countryIsoCodes = [];
foreach ($carrier->getZones() as $zone) {
$countryIsoCodes = array_merge($countryIsoCodes, $this->countryRepository->getCountryIsoCodesByZoneId($zone['id_zone']));
}
$carrierLine
->setIdCarrier((int) $carrier->id)
->setIdReference((int) $carrier->id_reference)
->setName($carrier->name)
->setTaxesRatesGroupId((int) $carrier->getIdTaxRulesGroup())
->setUrl((string) $carrier->url)
->setActive($carrier->active)
->setDeleted($carrier->deleted)
->setDisableCarrierWhenOutOfRange((bool) $carrier->range_behavior)
->setIsModule($carrier->is_module)
->setIsFree($carrier->is_free)
->setShippingExternal($carrier->shipping_external)
->setNeedRange($carrier->need_range)
->setExternalModuleName((string) $carrier->external_module_name)
->setMaxWidth($carrier->max_width)
->setMaxHeight($carrier->max_height)
->setMaxDepth($carrier->max_depth)
->setMaxWeight($carrier->max_weight)
->setGrade($carrier->grade)
->setDelay($carrier->delay)
->setCurrency($currencyIsoCode)
->setWeightUnit($weightUnit)
->setCountryIsoCodes($countryIsoCodes);
$deliveryPriceByRanges = $this->carrierRepository->getDeliveryPriceByRange($carrier);
$carrierLine->setCarrierTaxes($this->buildCarrierTaxes($carrier));
if (!$deliveryPriceByRanges) {
return $carrierLine;
}
$carrierDetails = [];
foreach ($deliveryPriceByRanges as $deliveryPriceByRange) {
$range = $this->carrierRepository->getCarrierRange($deliveryPriceByRange);
if (!$range) {
continue;
}
foreach ($deliveryPriceByRange['zones'] as $zone) {
$carrierDetail = $this->buildCarrierDetails($carrier, $range, $zone, $deliveryPriceByRange);
if ($carrierDetail) {
$carrierDetails[] = $carrierDetail;
}
}
}
$carrierLine->setCarrierDetails($carrierDetails);
return $carrierLine;
}
/**
* @param Carrier $carrier
* @param RangeWeight|RangePrice $range
* @param array $zone
* @param array $deliveryPriceByRange
*
* @return ?CarrierDetail
*/
private function buildCarrierDetails(Carrier $carrier, $range, array $zone, array $deliveryPriceByRange)
{
$rangeTable = $carrier->getRangeTable();
$carrierDetailId = isset($deliveryPriceByRange['id_range_weight']) ? $deliveryPriceByRange['id_range_weight'] : $deliveryPriceByRange['id_range_price'];
$carrierDetail = new CarrierDetail();
$carrierDetail->setShippingMethod($rangeTable);
$carrierDetail->setCarrierDetailId($carrierDetailId);
$carrierDetail->setDelimiter1($range->delimiter1);
$carrierDetail->setDelimiter2($range->delimiter2);
$carrierDetail->setPrice($zone['price']);
$carrierDetail->setCarrierReference($carrier->id_reference);
$carrierDetail->setZoneId($zone['id_zone']);
$carrierDetail->setRangeId($range->id);
$countryIsoCodes = $this->countryRepository->getCountryIsoCodesByZoneId($zone['id_zone']);
if (!$countryIsoCodes) {
return null;
}
$carrierDetail->setCountryIsoCodes($countryIsoCodes);
$stateIsoCodes = $this->stateRepository->getStateIsoCodesByZoneId($zone['id_zone']);
$carrierDetail->setStateIsoCodes($stateIsoCodes);
return $carrierDetail;
}
/**
* @return array<CarrierTax>
*/
private function buildCarrierTaxes(Carrier $carrier): array
{
$taxRulesGroupId = (int) $carrier->getIdTaxRulesGroup();
$carrierTaxesByZone = $this->taxRepository->getCarrierTaxesByTaxRulesGroupId($taxRulesGroupId);
if (!$carrierTaxesByZone[0]['country_iso_code']) {
return [];
}
$carrierTaxesByZone = $carrierTaxesByZone[0];
$carrierTax = new CarrierTax();
$carrierTax->setCarrierReference($carrier->id_reference);
$carrierTax->setTaxRulesGroupId($taxRulesGroupId);
$carrierTax->setCountryIsoCode((string) $carrierTaxesByZone['country_iso_code']);
$carrierTax->setStateIsoCodes((string) $carrierTaxesByZone['state_iso_code']);
$carrierTax->setTaxRate($carrierTaxesByZone['rate']);
return [
$carrierTax,
];
}
private function getShippingHandlePrice(bool $shippingHandling): float
{
if ($shippingHandling) {
return (float) $this->configurationAdapter->get('PS_SHIPPING_HANDLING');
}
return 0.0;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,551 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\DTO;
use JsonSerializable;
class Carrier implements JsonSerializable
{
/**
* @var string
*/
private $collection = 'carriers';
/**
* @var int
*/
private $idCarrier;
/**
* @var int
*/
private $idReference;
/**
* @var int
*/
private $taxesRatesGroupId;
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $url;
/**
* @var bool
*/
private $active;
/**
* @var bool
*/
private $deleted;
/**
* @var float
*/
private $shippingHandling = 0;
/**
* @var float
*/
private $freeShippingStartsAtPrice;
/**
* @var float
*/
private $freeShippingStartsAtWeight;
/**
* @var bool
*/
private $disableCarrierWhenOutOfRange;
/**
* @var bool
*/
private $isModule;
/**
* @var bool
*/
private $isFree;
/**
* @var bool
*/
private $shippingExternal;
/**
* @var bool
*/
private $needRange;
/**
* @var string
*/
private $externalModuleName;
/**
* @var float
*/
private $maxWidth;
/**
* @var float
*/
private $maxHeight;
/**
* @var float
*/
private $maxDepth;
/**
* @var float
*/
private $maxWeight;
/**
* @var int
*/
private $grade;
/**
* @var string
*/
private $delay;
/**
* @var string
*/
private $currency;
/**
* @var string
*/
private $weightUnit;
/**
* @var array
*/
private $countryIsoCodes;
/**
* @var CarrierDetail[]
*/
private $carrierDetails = [];
/**
* @var CarrierTax[]
*/
private $carrierTaxes = [];
public function getCollection(): string
{
return $this->collection;
}
public function setCollection(string $collection): Carrier
{
$this->collection = $collection;
return $this;
}
public function getIdCarrier(): int
{
return $this->idCarrier;
}
public function setIdCarrier(int $idCarrier): Carrier
{
$this->idCarrier = $idCarrier;
return $this;
}
public function getIdReference(): int
{
return $this->idReference;
}
public function setIdReference(int $idReference): Carrier
{
$this->idReference = $idReference;
return $this;
}
public function getTaxesRatesGroupId(): int
{
return $this->taxesRatesGroupId;
}
public function setTaxesRatesGroupId(int $taxesRatesGroupId): Carrier
{
$this->taxesRatesGroupId = $taxesRatesGroupId;
return $this;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): Carrier
{
$this->name = $name;
return $this;
}
public function getUrl(): string
{
return $this->url;
}
public function setUrl(string $url): Carrier
{
$this->url = $url;
return $this;
}
public function isActive(): bool
{
return $this->active;
}
public function setActive(bool $active): Carrier
{
$this->active = $active;
return $this;
}
public function isDeleted(): bool
{
return $this->deleted;
}
public function setDeleted(bool $deleted): Carrier
{
$this->deleted = $deleted;
return $this;
}
public function getShippingHandling(): float
{
return $this->shippingHandling;
}
public function setShippingHandling(float $shippingHandling): Carrier
{
$this->shippingHandling = $shippingHandling;
return $this;
}
public function getFreeShippingStartsAtPrice(): float
{
return $this->freeShippingStartsAtPrice;
}
public function setFreeShippingStartsAtPrice(float $freeShippingStartsAtPrice): Carrier
{
$this->freeShippingStartsAtPrice = $freeShippingStartsAtPrice;
return $this;
}
public function getFreeShippingStartsAtWeight(): float
{
return $this->freeShippingStartsAtWeight;
}
public function setFreeShippingStartsAtWeight(float $freeShippingStartsAtWeight): Carrier
{
$this->freeShippingStartsAtWeight = $freeShippingStartsAtWeight;
return $this;
}
public function isDisableCarrierWhenOutOfRange(): bool
{
return $this->disableCarrierWhenOutOfRange;
}
public function setDisableCarrierWhenOutOfRange(bool $disableCarrierWhenOutOfRange): Carrier
{
$this->disableCarrierWhenOutOfRange = $disableCarrierWhenOutOfRange;
return $this;
}
public function isModule(): bool
{
return $this->isModule;
}
public function setIsModule(bool $isModule): Carrier
{
$this->isModule = $isModule;
return $this;
}
public function isFree(): bool
{
return $this->isFree;
}
public function setIsFree(bool $isFree): Carrier
{
$this->isFree = $isFree;
return $this;
}
public function isShippingExternal(): bool
{
return $this->shippingExternal;
}
public function setShippingExternal(bool $shippingExternal): Carrier
{
$this->shippingExternal = $shippingExternal;
return $this;
}
public function isNeedRange(): bool
{
return $this->needRange;
}
public function setNeedRange(bool $needRange): Carrier
{
$this->needRange = $needRange;
return $this;
}
public function getExternalModuleName(): string
{
return $this->externalModuleName;
}
public function setExternalModuleName(string $externalModuleName): Carrier
{
$this->externalModuleName = $externalModuleName;
return $this;
}
public function getMaxWidth(): float
{
return $this->maxWidth;
}
public function setMaxWidth(float $maxWidth): Carrier
{
$this->maxWidth = $maxWidth;
return $this;
}
public function getMaxHeight(): float
{
return $this->maxHeight;
}
public function setMaxHeight(float $maxHeight): Carrier
{
$this->maxHeight = $maxHeight;
return $this;
}
public function getMaxDepth(): float
{
return $this->maxDepth;
}
public function setMaxDepth(float $maxDepth): Carrier
{
$this->maxDepth = $maxDepth;
return $this;
}
public function getMaxWeight(): float
{
return $this->maxWeight;
}
public function setMaxWeight(float $maxWeight): Carrier
{
$this->maxWeight = $maxWeight;
return $this;
}
public function getGrade(): int
{
return $this->grade;
}
public function setGrade(int $grade): Carrier
{
$this->grade = $grade;
return $this;
}
public function getDelay(): string
{
return $this->delay;
}
public function setDelay(string $delay): Carrier
{
$this->delay = $delay;
return $this;
}
public function getCurrency(): string
{
return $this->currency;
}
public function setCurrency(string $currency): Carrier
{
$this->currency = $currency;
return $this;
}
public function getWeightUnit(): string
{
return $this->weightUnit;
}
public function setWeightUnit(string $weightUnit): Carrier
{
$this->weightUnit = $weightUnit;
return $this;
}
public function getCountryIsoCodes(): array
{
return $this->countryIsoCodes;
}
public function setCountryIsoCodes(array $countryIsoCodes): Carrier
{
$this->countryIsoCodes = $countryIsoCodes;
return $this;
}
public function getCarrierDetails(): array
{
return $this->carrierDetails;
}
public function setCarrierDetails(array $carrierDetails): Carrier
{
$this->carrierDetails = $carrierDetails;
return $this;
}
public function getCarrierTaxes(): array
{
return $this->carrierTaxes;
}
public function setCarrierTaxes(array $carrierTaxes): Carrier
{
$this->carrierTaxes = $carrierTaxes;
return $this;
}
public function jsonSerialize()
{
$return = [];
$return[] = [
'collection' => $this->getCollection(),
'id' => (string) $this->getIdReference(),
'properties' => [
'id_carrier' => (string) $this->getIdCarrier(),
'id_reference' => (string) $this->getIdReference(),
'name' => (string) $this->getName(),
'carrier_taxes_rates_group_id' => (string) $this->getTaxesRatesGroupId(),
'url' => (string) $this->getUrl(),
'active' => (bool) $this->isActive(),
'deleted' => (bool) $this->isDeleted(),
'shipping_handling' => (float) $this->getShippingHandling(),
'free_shipping_starts_at_price' => (float) $this->getFreeShippingStartsAtPrice(),
'free_shipping_starts_at_weight' => (float) $this->getFreeShippingStartsAtWeight(),
'disable_carrier_when_out_of_range' => (bool) $this->isDisableCarrierWhenOutOfRange(),
'is_module' => (bool) $this->isModule(),
'is_free' => (bool) $this->isFree(),
'shipping_external' => (bool) $this->isShippingExternal(),
'need_range' => (bool) $this->isNeedRange(),
'external_module_name' => (string) $this->getExternalModuleName(),
'max_width' => (float) $this->getMaxWidth(),
'max_height' => (float) $this->getMaxHeight(),
'max_depth' => (float) $this->getMaxDepth(),
'max_weight' => (float) $this->getMaxWeight(),
'grade' => (int) $this->getGrade(),
'delay' => (string) $this->getDelay(),
'currency' => (string) $this->getCurrency(),
'weight_unit' => (string) $this->getWeightUnit(),
'country_ids' => (string) implode(',', $this->getCountryIsoCodes()),
],
];
$carrierDetails = [];
foreach ($this->getCarrierDetails() as $carrierDetail) {
$carrierDetails[] = $carrierDetail->jsonSerialize();
}
$carrierTaxRates = [];
foreach ($this->getCarrierTaxes() as $carrierTax) {
$carrierTaxRates[] = $carrierTax->jsonSerialize();
}
return array_merge($return, $carrierDetails, $carrierTaxRates);
}
}

View File

@@ -0,0 +1,239 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\DTO;
use JsonSerializable;
class CarrierDetail implements JsonSerializable
{
public const RANGE_BY_WEIGHT = 0;
public const RANGE_BY_PRICE = 1;
/**
* @var string
*/
private $collection = 'carrier_details';
/**
* @var string
*/
private $shippingMethod;
/**
* @var int
*/
private $carrierReference;
/**
* @var int
*/
private $carrierDetailId;
/**
* @var int
*/
private $zoneId;
/**
* @var int
*/
private $rangeId;
/**
* @var float
*/
private $delimiter1;
/**
* @var float
*/
private $delimiter2;
/**
* @var array
*/
private $countryIsoCodes;
/**
* @var array
*/
private $stateIsoCodes;
/**
* @var float
*/
private $price;
public function getCollection(): string
{
return $this->collection;
}
public function setCollection(string $collection): CarrierDetail
{
$this->collection = $collection;
return $this;
}
public function getShippingMethod(): string
{
return $this->shippingMethod;
}
public function setShippingMethod(string $shippingMethod): CarrierDetail
{
$this->shippingMethod = $shippingMethod;
return $this;
}
public function getCarrierReference(): int
{
return $this->carrierReference;
}
public function setCarrierReference(int $carrierReference): CarrierDetail
{
$this->carrierReference = $carrierReference;
return $this;
}
public function getCarrierDetailId(): int
{
return $this->carrierDetailId;
}
public function setCarrierDetailId(int $carrierDetailId): CarrierDetail
{
$this->carrierDetailId = $carrierDetailId;
return $this;
}
public function getZoneId(): int
{
return $this->zoneId;
}
public function setZoneId(int $zoneId): CarrierDetail
{
$this->zoneId = $zoneId;
return $this;
}
public function getRangeId(): int
{
return $this->rangeId;
}
public function setRangeId(int $rangeId): CarrierDetail
{
$this->rangeId = $rangeId;
return $this;
}
public function getDelimiter1(): float
{
return $this->delimiter1;
}
public function setDelimiter1(float $delimiter1): CarrierDetail
{
$this->delimiter1 = $delimiter1;
return $this;
}
public function getDelimiter2(): float
{
return $this->delimiter2;
}
public function setDelimiter2(float $delimiter2): CarrierDetail
{
$this->delimiter2 = $delimiter2;
return $this;
}
public function getCountryIsoCodes(): array
{
return $this->countryIsoCodes;
}
public function setCountryIsoCodes(array $countryIsoCodes): CarrierDetail
{
$this->countryIsoCodes = $countryIsoCodes;
return $this;
}
public function getStateIsoCodes(): array
{
return $this->stateIsoCodes;
}
public function setStateIsoCodes(array $stateIsoCodes): CarrierDetail
{
$this->stateIsoCodes = $stateIsoCodes;
return $this;
}
public function getPrice(): float
{
return $this->price;
}
public function setPrice(float $price): CarrierDetail
{
$this->price = $price;
return $this;
}
public function jsonSerialize()
{
$countryIds = implode(',', $this->getCountryIsoCodes());
$stateIds = implode(',', $this->getStateIsoCodes());
$shippingMethod = $this->getShippingMethod() === 'range_weight' ? self::RANGE_BY_WEIGHT : self::RANGE_BY_PRICE;
return [
'collection' => $this->getCollection(),
'id' => $this->getCarrierReference() . '-' . $this->getZoneId() . '-' . $shippingMethod . '-' . $this->getRangeId(),
'properties' => [
'id_reference' => (string) $this->getCarrierReference(),
'id_carrier_detail' => (string) $this->getCarrierDetailId(),
'shipping_method' => (string) $this->getShippingMethod(),
'delimiter1' => (float) $this->getDelimiter1(),
'delimiter2' => (float) $this->getDelimiter2(),
'country_ids' => (string) $countryIds,
'state_ids' => (string) $stateIds,
'price' => (float) $this->getPrice(),
],
];
}
}

View File

@@ -0,0 +1,142 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\DTO;
use JsonSerializable;
class CarrierTax implements JsonSerializable
{
/**
* @var string
*/
private $collection = 'carrier_taxes';
/**
* @var int
*/
private $carrierReference;
/**
* @var int
*/
private $taxRulesGroupId;
/**
* @var string
*/
private $countryIsoCode;
/**
* @var string
*/
private $stateIsoCodes;
/**
* @var float
*/
private $taxRate;
public function getCollection(): string
{
return $this->collection;
}
public function setCollection(string $collection): CarrierTax
{
$this->collection = $collection;
return $this;
}
public function getCarrierReference(): int
{
return $this->carrierReference;
}
public function setCarrierReference(int $carrierReference): CarrierTax
{
$this->carrierReference = $carrierReference;
return $this;
}
public function getTaxRulesGroupId(): int
{
return $this->taxRulesGroupId;
}
public function setTaxRulesGroupId(int $taxRulesGroupId): CarrierTax
{
$this->taxRulesGroupId = $taxRulesGroupId;
return $this;
}
public function getCountryIsoCode(): string
{
return $this->countryIsoCode;
}
public function setCountryIsoCode(string $countryIsoCode): CarrierTax
{
$this->countryIsoCode = $countryIsoCode;
return $this;
}
public function getStateIsoCodes(): string
{
return $this->stateIsoCodes;
}
public function setStateIsoCodes(string $stateIsoCodes): CarrierTax
{
$this->stateIsoCodes = $stateIsoCodes;
return $this;
}
public function getTaxRate(): float
{
return $this->taxRate;
}
public function setTaxRate(float $taxRate): CarrierTax
{
$this->taxRate = $taxRate;
return $this;
}
public function jsonSerialize()
{
return [
'collection' => $this->getCollection(),
'id' => $this->getCarrierReference(),
'properties' => [
'id_reference' => (string) $this->getCarrierReference(),
'id_carrier_tax' => (string) $this->getTaxRulesGroupId(),
'country_id' => (string) $this->getCountryIsoCode(),
'state_ids' => (string) $this->getStateIsoCodes(),
'tax_rate' => (float) $this->getTaxRate(),
],
];
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\DTO;
use JsonSerializable;
/**
* @see https://developers.google.com/analytics/devguides/collection/gtagjs/enhanced-ecommerce#action-data
*/
class ConversionEventData implements JsonSerializable
{
/**
* Value (i.e. revenue) associated with the event.
*
* @var string
*/
protected $value;
/**
* @var string
*/
protected $currency;
/**
* @var string
*/
protected $sendTo;
/**
* The transaction ID (e.g. T1234).
*
* @var string|null
*/
protected $transactionId;
public function jsonSerialize(): array
{
$eventData = [
'send_to' => $this->sendTo,
'value' => $this->value,
'currency' => $this->currency,
];
if ($this->transactionId) {
$eventData['transaction_id'] = $this->transactionId;
}
return $eventData;
}
public function setTransactionId(string $transactionId)
{
$this->transactionId = $transactionId;
return $this;
}
/**
* Set value (i.e. revenue) associated with the event.
*
* @param string|null $value Value (i.e. revenue) associated with the event.
*
* @return self
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* @param string|null $currency
*
* @return self
*/
public function setCurrency($currency)
{
$this->currency = $currency;
return $this;
}
/**
* @param string|null $sendTo
*
* @return self
*/
public function setSendTo($sendTo)
{
$this->sendTo = $sendTo;
return $this;
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\DTO\Remarketing;
use JsonSerializable;
class ProductData implements JsonSerializable
{
/**
* The product ID or SKU (e.g. P67890).
*
* @var string
*/
protected $id;
/**
* The price of a product (e.g. 29.20).
* Kept as a float
*
* @var float|null
*/
protected $price;
/**
* The quantity of a product (e.g. 2).
*
* @var int|null
*/
protected $quantity;
public function jsonSerialize(): array
{
return [
'id' => $this->id,
'quantity' => $this->quantity,
'price' => $this->price,
];
}
/**
* Set the product ID or SKU (e.g. P67890).
*
* @param string $id The product ID or SKU (e.g. P67890).
*
* @return self
*/
public function setId(string $id)
{
$this->id = $id;
return $this;
}
/**
* Set kept as a string to avoid float issues
*
* @param float|null $price Kept as a string to avoid float issues
*
* @return self
*/
public function setPrice($price)
{
$this->price = $price;
return $this;
}
/**
* Set the quantity of a product (e.g. 2).
*
* @param int|null $quantity The quantity of a product (e.g. 2).
*
* @return self
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
}

View File

@@ -0,0 +1,135 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\DTO\Remarketing;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\ConversionEventData;
class PurchaseEventData extends ConversionEventData
{
/**
* @var ProductData[]
*/
protected $items;
/**
* @var int
*/
protected $awMerchandId;
/**
* @var string
*/
protected $awFeedCountry;
/**
* @var string
*/
protected $awFeedLanguage;
/**
* @var float
*/
protected $discount;
public function jsonSerialize(): array
{
return array_merge(
parent::jsonSerialize(),
[
'items' => $this->items,
'discount' => $this->discount,
'aw_merchant_id' => $this->awMerchandId,
'aw_feed_country' => $this->awFeedCountry,
'aw_feed_language' => $this->awFeedLanguage,
]
);
}
/**
* Set the value of awFeedLanguage
*
* @param string $awFeedLanguage
*
* @return self
*/
public function setAwFeedLanguage(string $awFeedLanguage)
{
$this->awFeedLanguage = $awFeedLanguage;
return $this;
}
/**
* Set the value of awMerchandId
*
* @param int $awMerchandId
*
* @return self
*/
public function setAwMerchandId(int $awMerchandId)
{
$this->awMerchandId = $awMerchandId;
return $this;
}
/**
* Set the value of awFeedCountry
*
* @param string $awFeedCountry
*
* @return self
*/
public function setAwFeedCountry(string $awFeedCountry)
{
$this->awFeedCountry = $awFeedCountry;
return $this;
}
/**
* Set the value of items
*
* @param array $items
*
* @return self
*/
public function setItems(array $items)
{
$this->items = $items;
return $this;
}
/**
* Set the value of discount
*
* @param float $discount
*
* @return self
*/
public function setDiscount(float $discount)
{
$this->discount = $discount;
return $this;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,223 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Database;
use Exception;
use Language;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Config;
use PrestaShop\Module\PsxMarketingWithGoogle\Exception\MktgWithGoogleInstallerException;
use PrestaShop\Module\PsxMarketingWithGoogle\Handler\ErrorHandler;
use PrestaShop\Module\PsxMarketingWithGoogle\Tracker\Segment;
use PsxMarketingWithGoogle;
use Tab;
class Installer
{
public const CLASS_NAME = 'Installer';
private $module;
/**
* @var array
*/
private $errors = [];
/**
* @var Segment
*/
private $segment;
/**
* @var ErrorHandler
*/
private $errorHandler;
public function __construct(PsxMarketingWithGoogle $module, Segment $segment, ErrorHandler $errorHandler)
{
$this->module = $module;
$this->segment = $segment;
$this->errorHandler = $errorHandler;
}
/**
* @return bool
*/
public function install()
{
$this->segment->setMessage('PSX Marketing With Google installed');
$this->segment->track();
return $this->installConfiguration() &&
$this->installTabs() &&
$this->installTables();
}
/**
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* Install configuration for each shop
*
* @return bool
*/
public function installConfiguration()
{
$result = true;
foreach (\Shop::getShops(false, null, true) as $shopId) {
/* todo: remove ignore when first configuration is added to the list */
/* @phpstan-ignore-next-line */
foreach (Config::CONFIGURATION_LIST as $name => $value) {
if (false === \Configuration::hasKey((string) $name, null, null, (int) $shopId)) {
$result = $result && \Configuration::updateValue(
(string) $name,
$value,
false,
null,
(int) $shopId
);
}
}
}
return $result;
}
/**
* This method is often use to create an ajax controller
*
* @return bool
*/
public function installTabs()
{
$installTabCompleted = true;
foreach ($this->getTabs() as $tab) {
try {
$installTabCompleted = $installTabCompleted && $this->installTab(
$tab['className'],
$tab['parent'],
$tab['name'],
$tab['module'],
$tab['active'],
$tab['icon']
);
} catch (Exception $e) {
$this->errorHandler->handle(
new MktgWithGoogleInstallerException(
'Failed to install module tabs',
MktgWithGoogleInstallerException::MKTG_WITH_GOOGLE_INSTALL_EXCEPTION,
$e
),
MktgWithGoogleInstallerException::MKTG_WITH_GOOGLE_INSTALL_EXCEPTION,
false
);
$this->errors[] = sprintf($this->module->l('Failed to install %1s tab', self::CLASS_NAME), $tab['className']);
return false;
}
}
return $installTabCompleted;
}
public function installTab($className, $parent, $name, $module, $active, $icon)
{
if (Tab::getIdFromClassName($className)) {
return true;
}
$idParent = is_int($parent) ? $parent : Tab::getIdFromClassName($parent);
$moduleTab = new Tab();
$moduleTab->class_name = $className;
$moduleTab->id_parent = $idParent;
$moduleTab->module = $module;
$moduleTab->active = $active;
if (property_exists($moduleTab, 'icon')) {
$moduleTab->icon = $icon;
}
$languages = Language::getLanguages(true);
foreach ($languages as $language) {
$moduleTab->name[$language['id_lang']] = $name;
}
return $moduleTab->add();
}
public function installTables()
{
try {
include dirname(__FILE__) . '/../../sql/install.php';
} catch (\Exception $e) {
$this->errorHandler->handle(
new MktgWithGoogleInstallerException(
'Failed to install database tables',
MktgWithGoogleInstallerException::MKTG_WITH_GOOGLE_UNINSTALL_EXCEPTION,
$e
),
$e->getCode(),
false
);
$this->errors[] = $this->module->l('Failed to install database tables', self::CLASS_NAME);
return false;
}
return true;
}
private function getTabs()
{
return [
[
'className' => 'Marketing',
'parent' => 'IMPROVE',
'name' => 'Marketing',
'module' => '',
'active' => true,
'icon' => 'campaign',
],
[
'className' => 'AdminPsxMktgWithGoogleModule',
'parent' => 'Marketing',
'name' => 'Google',
'module' => $this->module->name,
'active' => true,
'icon' => '',
],
[
'className' => 'AdminAjaxPsxMktgWithGoogle',
'parent' => -1,
'name' => $this->module->name,
'module' => $this->module->name,
'active' => true,
'icon' => '',
],
];
}
}

View File

@@ -0,0 +1,165 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Database;
use Exception;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Config;
use PrestaShop\Module\PsxMarketingWithGoogle\Exception\MktgWithGoogleInstallerException;
use PrestaShop\Module\PsxMarketingWithGoogle\Handler\ErrorHandler;
use PrestaShop\Module\PsxMarketingWithGoogle\Repository\TabRepository;
use PrestaShop\Module\PsxMarketingWithGoogle\Tracker\Segment;
class Uninstaller
{
public const CLASS_NAME = 'Uninstaller';
/**
* @var array
*/
private $errors = [];
private $module;
/**
* @var TabRepository
*/
private $tabRepository;
/**
* @var Segment
*/
private $segment;
/**
* @var ErrorHandler
*/
private $errorHandler;
public function __construct(
\PsxMarketingWithGoogle $module,
TabRepository $tabRepository,
Segment $segment,
ErrorHandler $errorHandler
) {
$this->module = $module;
$this->tabRepository = $tabRepository;
$this->segment = $segment;
$this->errorHandler = $errorHandler;
}
/**
* @return bool
*
* @throws Exception
*/
public function uninstall()
{
$this->segment->setMessage('PS Google shopping uninstalled');
$this->segment->track();
/* todo: remove ignore when first configuration is added to the list */
/* @phpstan-ignore-next-line */
foreach (array_keys(Config::CONFIGURATION_LIST) as $name) {
\Configuration::deleteByName((string) $name);
}
return $this->uninstallTabs() && $this->uninstallTables();
}
/**
* @return bool
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException|Exception
*/
private function uninstallTabs()
{
$uninstallTabCompleted = true;
try {
foreach (Config::MODULE_ADMIN_CONTROLLERS as $controllerName) {
$id_tab = (int) \Tab::getIdFromClassName($controllerName);
$tab = new \Tab($id_tab);
if (\Validate::isLoadedObject($tab)) {
$uninstallTabCompleted = $uninstallTabCompleted && $tab->delete();
}
}
$uninstallTabCompleted = $uninstallTabCompleted && $this->uninstallMarketingTab();
} catch (Exception $e) {
$this->errorHandler->handle(
new MktgWithGoogleInstallerException(
'Failed to uninstall module tabs',
MktgWithGoogleInstallerException::MKTG_WITH_GOOGLE_UNINSTALL_EXCEPTION,
$e
),
$e->getCode(),
false
);
$this->errors[] = $this->module->l('Failed to uninstall database tables', self::CLASS_NAME);
return false;
}
return $uninstallTabCompleted;
}
/**
* @return bool
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
private function uninstallMarketingTab()
{
$id_tab = (int) \Tab::getIdFromClassName('Marketing');
$tab = new \Tab($id_tab);
if (!\Validate::isLoadedObject($tab)) {
return true;
}
if ($this->tabRepository->hasChildren($id_tab)) {
return true;
}
return $tab->delete();
}
public function uninstallTables()
{
try {
include dirname(__FILE__) . '/../../sql/uninstall.php';
} catch (\Exception $e) {
$this->errorHandler->handle(
new MktgWithGoogleInstallerException(
'Failed to uninstall database tables',
MktgWithGoogleInstallerException::MKTG_WITH_GOOGLE_UNINSTALL_EXCEPTION,
$e
),
$e->getCode(),
false
);
$this->errors[] = $this->module->l('Failed to uninstall database tables', self::CLASS_NAME);
return false;
}
return true;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,34 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Exception;
use Exception;
class ApiClientException extends Exception
{
public const REQUEST_EXCEPTION = 501;
public const GET_EXCEPTION = 502;
public const POST_EXCEPTION = 503;
public const DELETE_EXCEPTION = 504;
}

View File

@@ -0,0 +1,30 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Exception;
use Exception;
class MktgWithGoogleInstallerException extends Exception
{
public const MKTG_WITH_GOOGLE_INSTALL_EXCEPTION = 1;
public const MKTG_WITH_GOOGLE_UNINSTALL_EXCEPTION = 2;
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,42 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Factory;
use GuzzleHttp\Client;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Env;
class ApiClientFactory implements ApiClientFactoryInterface
{
/**
* @var string
*/
private $apiUrl;
public function __construct(Env $env)
{
$this->apiUrl = $env->get('PSX_MKTG_WITH_GOOGLE_API_URL');
}
public function createClient()
{
return new Client(['base_url' => $this->apiUrl]);
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Factory;
use GuzzleHttp\Client;
interface ApiClientFactoryInterface
{
/**
* @return Client
*/
public function createClient();
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Factory;
use Configuration;
use Context;
use Currency;
class ContextFactory
{
public static function getContext()
{
return Context::getContext();
}
public static function getLanguage()
{
return Context::getContext()->language;
}
/**
* Return the currency present in the context, or the default one
* when the context doesn't have a currency yet (i.e when user session is empty).
*
* @return Currency
*/
public static function getCurrency()
{
if (Context::getContext()->currency !== null) {
return Context::getContext()->currency;
}
return new Currency((int) Configuration::get('PS_CURRENCY_DEFAULT'));
}
public static function getSmarty()
{
return Context::getContext()->smarty;
}
public static function getShop()
{
return Context::getContext()->shop;
}
public static function getController()
{
return Context::getContext()->controller;
}
public static function getCookie()
{
return Context::getContext()->cookie;
}
public static function getLink()
{
return Context::getContext()->link;
}
public static function getCountry()
{
return Context::getContext()->country;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,126 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Handler;
use Exception;
use Module;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Config;
use PrestaShop\PsAccountsInstaller\Installer\Facade\PsAccounts;
use PsxMarketingWithGoogle;
/**
* Handle Error.
*/
class ErrorHandler
{
/**
* @var ModuleFilteredRavenClient
*/
protected $client;
/**
* @var ErrorHandler
*/
private static $instance;
public function __construct()
{
/** @var PsxMarketingWithGoogle */
$module = Module::getInstanceByName('psxmarketingwithgoogle');
$this->client = new ModuleFilteredRavenClient(
Config::PSX_MKTG_WITH_GOOGLE_SENTRY_CREDENTIALS_PHP,
[
'level' => 'warning',
'tags' => [
'php_version' => phpversion(),
'psxmarketingwithgoogle_version' => $module->version,
'prestashop_version' => _PS_VERSION_,
'psxmarketingwithgoogle_is_enabled' => \Module::isEnabled('psxmarketingwithgoogle'),
'psxmarketingwithgoogle_is_installed' => \Module::isInstalled('psxmarketingwithgoogle'),
],
'release' => "v{$module->version}",
]
);
try {
$psAccountsService = $module->getService(PsAccounts::class)->getPsAccountsService();
$this->client->user_context([
'id' => $psAccountsService->getShopUuidV4(),
]);
} catch (Exception $e) {
// Do nothing
}
// We use realpath to get errors even if module is behind a symbolic link
$this->client->setAppPath(realpath(_PS_MODULE_DIR_ . $module->name . '/'));
// - Do no not add the shop root folder, it will exclude everything even if specified in the app path.
// - Excluding vendor/ avoids errors comming from one of your libraries library when called by another module.
$this->client->setExcludedAppPaths([
realpath(_PS_MODULE_DIR_ . $module->name . '/vendor/'),
]);
$this->client->setExcludedDomains(['127.0.0.1', 'localhost', '.local']);
if (version_compare(phpversion(), '7.4.0', '>=') && version_compare(_PS_VERSION_, '1.7.8.0', '<')) {
return;
}
$this->client->install();
}
/**
* @param \Exception $error
* @param mixed $code
* @param bool|null $throw
* @param array|null $data
*
* @return void
*
* @throws \Exception
*/
public function handle($error, $code = null, $throw = true, $data = null)
{
$this->client->captureException($error, $data);
if ($code && true === $throw) {
http_response_code($code);
throw $error;
}
}
/**
* @return ErrorHandler
*/
public static function getInstance()
{
if (self::$instance === null) {
self::$instance = new ErrorHandler();
}
return self::$instance;
}
/**
* @return void
*/
private function __clone()
{
}
}

View File

@@ -0,0 +1,126 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Handler;
use Raven_Client;
/**
* Inheritance allow us to check data generated by Raven and filter errors
* that are not related to the module.
* Raven does not filter errors by itself depending on the appPath and any
* excludedAppPaths, but declares what phase of the stack trace is outside the app.
* We use this data to allow each module filtering their own errors.
*
* IMPORTANT NOTE: This class is present is this module during the
* stabilisation phase, and will be moved later in a library.
*/
class ModuleFilteredRavenClient extends Raven_Client
{
/**
* @var string[]|null
*/
protected $excluded_domains;
public function capture($data, $stack = null, $vars = null)
{
/*
Content of $data:
array:2 [▼
"exception" => array:1 [▼
"values" => array:1 [▼
0 => array:3 [▼
"value" => "Class 'DogeInPsFacebook' not found"
"type" => "Error"
"stacktrace" => array:1 [▼
"frames" => array:4 [▼
0 => array:7 [▼
"filename" => "index.php"
"lineno" => 93
"function" => null
"pre_context" => array:5 [▶]
"context_line" => " Dispatcher::getInstance()->dispatch();"
"post_context" => array:2 [▶]
"in_app" => false
1 => array:3 [▼
[Can be defined when a subexception is set]
*/
if (!isset($data['exception']['values'][0]['stacktrace']['frames'])) {
return null;
}
if ($this->isErrorFilteredByContext()) {
return null;
}
$allowCapture = false;
foreach ($data['exception']['values'] as $errorValues) {
$allowCapture = $allowCapture || $this->isErrorInApp($errorValues);
}
if (!$allowCapture) {
return null;
}
return parent::capture($data, $stack, $vars);
}
/**
* @return self
*/
public function setExcludedDomains(array $domains)
{
$this->excluded_domains = $domains;
return $this;
}
/**
* @return bool
*/
private function isErrorInApp(array $data)
{
$atLeastOneFileIsInApp = false;
foreach ($data['stacktrace']['frames'] as $frame) {
$atLeastOneFileIsInApp = $atLeastOneFileIsInApp || ((isset($frame['in_app']) && $frame['in_app']));
}
return $atLeastOneFileIsInApp;
}
/**
* Check the conditions in which the error is thrown, so we can apply filters
*
* @return bool
*/
private function isErrorFilteredByContext()
{
if ($this->excluded_domains && !empty($_SERVER['REMOTE_ADDR'])) {
foreach ($this->excluded_domains as $domain) {
if (strpos($_SERVER['REMOTE_ADDR'], $domain) !== false) {
return true;
}
}
}
return false;
}
}

View File

@@ -0,0 +1,198 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Handler;
use Context;
use PrestaShop\Module\PsxMarketingWithGoogle\Adapter\ConfigurationAdapter;
use PrestaShop\Module\PsxMarketingWithGoogle\Buffer\TemplateBuffer;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Config;
use PrestaShop\Module\PsxMarketingWithGoogle\Provider\CartEventDataProvider;
use PrestaShop\Module\PsxMarketingWithGoogle\Provider\PageViewEventDataProvider;
use PrestaShop\Module\PsxMarketingWithGoogle\Provider\PurchaseEventDataProvider;
use PsxMarketingWithGoogle;
class RemarketingHookHandler
{
/**
* @var ConfigurationAdapter
*/
protected $configurationAdapter;
/**
* @var TemplateBuffer
*/
protected $templateBuffer;
/**
* @var Context
*/
protected $context;
/**
* @var PsxMarketingWithGoogle
*/
protected $module;
/**
* @var bool
*/
protected $active;
/**
* @var array
*/
protected $conversionLabels;
public function __construct(ConfigurationAdapter $configurationAdapter, TemplateBuffer $templateBuffer, Context $context, $module)
{
$this->configurationAdapter = $configurationAdapter;
$this->templateBuffer = $templateBuffer;
$this->context = $context;
$this->module = $module;
$this->active = (bool) $this->configurationAdapter->get(Config::PSX_MKTG_WITH_GOOGLE_REMARKETING_STATUS)
&& (bool) $this->configurationAdapter->get(Config::PSX_MKTG_WITH_GOOGLE_REMARKETING_TAG)
&& in_array($this->context->controller->controller_type, ['front', 'modulefront']);
$this->conversionLabels = json_decode($this->configurationAdapter->get(Config::PSX_MKTG_WITH_GOOGLE_REMARKETING_CONVERSION_LABELS), true)
?: [];
if ($this->active) {
$this->templateBuffer->init($this->findIdentifierFromContext($context));
}
}
public function handleHook(string $hookName, array $data = []): string
{
if (!$this->active) {
return '';
}
switch ($hookName) {
case 'hookDisplayTop':
if (($sendTo = $this->getSendTo(Config::REMARKETING_CONVERSION_LABEL_PAGE_VIEW)) === null) {
break;
}
$eventData = $this->module->getService(PageViewEventDataProvider::class)->getEventData($sendTo);
if ($eventData === null) {
break;
}
$this->context->smarty->assign([
'eventData' => $eventData,
]);
$this->templateBuffer->add(
$this->module->display($this->module->getfilePath(), '/views/templates/hook/gtagEvent.tpl')
);
break;
case 'hookDisplayOrderConfirmation':
if (($sendTo = $this->getSendTo(Config::REMARKETING_CONVERSION_LABEL_PURCHASE)) === null) {
break;
}
$this->context->smarty->assign([
'eventData' => $this->module->getService(PurchaseEventDataProvider::class)->getEventData($sendTo, $data['order']),
]);
$this->templateBuffer->add(
$this->module->display($this->module->getfilePath(), '/views/templates/hook/gtagEvent.tpl')
);
break;
case 'hookActionCartUpdateQuantityBefore':
if ($data['operator'] !== 'up') {
break;
}
if (($sendTo = $this->getSendTo(Config::REMARKETING_CONVERSION_LABEL_ADD_TO_CART)) === null) {
break;
}
$this->context->smarty->assign([
'eventData' => $this->module->getService(CartEventDataProvider::class)->getEventData($sendTo, $data),
]);
$this->templateBuffer->add(
$this->module->display($this->module->getfilePath(), '/views/templates/hook/gtagEvent.tpl')
);
break;
}
if ($hookName === 'hookDisplayHeader') {
return base64_decode($this->configurationAdapter->get(Config::PSX_MKTG_WITH_GOOGLE_REMARKETING_TAG));
}
// Return the existing content in case we have a display hook
if (strpos($hookName, 'Display') === 4 && !$this->isCurrentRequestAnAjax()) {
return $this->templateBuffer->flush();
}
return '';
}
private function getSendTo($eventName)
{
if (!empty($this->conversionLabels[$eventName])) {
return $this->conversionLabels[$eventName];
}
return null;
}
/**
* @return bool
*/
private function isCurrentRequestAnAjax()
{
/*
* An ajax property is available in controllers
* when the whole page template should not be generated.
*/
if ($this->context->controller->ajax) {
return true;
}
/*
* In case the ajax property is not properly set, there is
* another check available.
*/
if ($this->context->controller->isXmlHttpRequest()) {
return true;
}
return false;
}
/**
* @return string
*/
private function findIdentifierFromContext(Context $context)
{
if (!empty($context->customer->id_guest)) {
return 'guest_' . $context->customer->id_guest;
}
if (!empty($context->cart->id)) {
return 'cart_' . $context->cart->id;
}
return '';
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,97 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Provider;
use Carrier;
use Currency;
use Language;
use PrestaShop\Module\PsxMarketingWithGoogle\Adapter\ConfigurationAdapter;
use PrestaShop\Module\PsxMarketingWithGoogle\Builder\CarrierBuilder;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\Carrier as DTOCarrier;
use PrestaShop\Module\PsxMarketingWithGoogle\Repository\CarrierRepository;
use RangePrice;
use RangeWeight;
class CarrierDataProvider
{
/**
* @var ConfigurationAdapter
*/
private $configurationAdapter;
/**
* @var CarrierBuilder
*/
private $carrierBuilder;
/**
* @var CarrierRepository
*/
private $carrierRepository;
public function __construct(
ConfigurationAdapter $configurationAdapter,
CarrierBuilder $carrierBuilder,
CarrierRepository $carrierRepository
) {
$this->configurationAdapter = $configurationAdapter;
$this->carrierBuilder = $carrierBuilder;
$this->carrierRepository = $carrierRepository;
}
public function getFormattedData(): array
{
$language = new Language($this->configurationAdapter->get('PS_LANG_DEFAULT'));
$currency = new Currency($this->configurationAdapter->get('PS_CURRENCY_DEFAULT'));
$carriers = Carrier::getCarriers($language->id, false, false, false, null, Carrier::ALL_CARRIERS);
/** @var DTOCarrier[] $carrierLines */
$carrierLines = $this->carrierBuilder->buildCarriers(
$carriers,
$language,
$currency,
$this->configurationAdapter->get('PS_WEIGHT_UNIT')
);
return $carrierLines;
}
/**
* @param array $deliveryPriceByRange
*
* @return false|RangeWeight|RangePrice
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
public function getCarrierRange(array $deliveryPriceByRange)
{
if (isset($deliveryPriceByRange['id_range_weight'])) {
return new RangeWeight($deliveryPriceByRange['id_range_weight']);
}
if (isset($deliveryPriceByRange['id_range_price'])) {
return new RangePrice($deliveryPriceByRange['id_range_price']);
}
return false;
}
}

View File

@@ -0,0 +1,52 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Provider;
use Context;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\ConversionEventData;
class CartEventDataProvider
{
/**
* @var Context
*/
protected $context;
public function __construct(Context $context)
{
$this->context = $context;
}
/**
* Return the items concerned by the transaction
* https://developers.google.com/analytics/devguides/collection/gtagjs/enhanced-ecommerce#action-data
*/
public function getEventData($sendTo, $data): ConversionEventData
{
$product = $data['product'];
$idProductAttribute = isset($data['id_product_attribute']) ? $data['id_product_attribute'] : 0;
return (new ConversionEventData())
->setSendTo($sendTo)
->setCurrency($this->context->currency->iso_code)
->setValue((string) \Product::getPriceStatic($product->id, true, $idProductAttribute, 2));
}
}

View File

@@ -0,0 +1,47 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Provider;
use Context;
use Currency;
use Order;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\ConversionEventData;
class ConversionEventDataProvider
{
/**
* @var Context
*/
protected $context;
public function __construct(Context $context)
{
$this->context = $context;
}
public function getActionDataByOrderObject(Order $order): ConversionEventData
{
return (new ConversionEventData())
->setTransactionId((string) $order->id)
->setValue((string) $order->total_products_wt)
->setCurrency((new Currency($order->id_currency))->iso_code);
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Provider;
class GoogleTagProvider
{
/**
* html contents (front office)
*
* @var string|bool
*/
private $contents;
/**
* Check if the given tag already exist on the shop
*
* @param string $googleTag eg: AW-253749562
*
* @return bool
*/
public function checkGoogleTagAlreadyExists(string $googleTag, int $shopId): bool
{
$this->crawlFront($shopId);
if (empty($this->contents)) {
return false;
}
return str_contains($this->contents, $googleTag);
}
/**
* Crawl front office
*
* @param int $shopId
*
* @return void
*/
private function crawlFront(int $shopId): void
{
$shop = \Shop::getShop($shopId);
$url = \Tools::getShopProtocol() . $shop[$this->getDomainType()] . $shop['uri'];
$contents = \Tools::file_get_contents($url);
$this->contents = $contents;
}
/**
* Retrieve the domain type to use depending on ssl
*
* @return string domain type can be domain_ssl || domain
*/
private function getDomainType(): string
{
return \Tools::usingSecureMode() ? 'domain_ssl' : 'domain';
}
}

View File

@@ -0,0 +1,59 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Provider;
use Context;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\ConversionEventData;
class PageViewEventDataProvider
{
/**
* @var Context
*/
protected $context;
public function __construct(Context $context)
{
$this->context = $context;
}
/**
* Return the items concerned by the transaction
* https://developers.google.com/analytics/devguides/collection/gtagjs/enhanced-ecommerce#action-data
*
* @return ConversionEventData|null
*/
public function getEventData($sendTo)
{
if ($this->context->controller instanceof \ProductControllerCore) {
/** @var \ProductControllerCore $controller */
$controller = $this->context->controller;
$product = $controller->getTemplateVarProduct();
return (new ConversionEventData())
->setSendTo($sendTo)
->setCurrency($this->context->currency->iso_code)
->setValue((string) $product['price_amount']);
}
return null;
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Provider;
use Context;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\Remarketing\ProductData;
class ProductDataProvider
{
/**
* @var Context
*/
protected $context;
public function __construct(Context $context)
{
$this->context = $context;
}
public function getProductDataByProductArray(array $product): ProductData
{
$productData = new ProductData();
$productData->setId(implode(
'-',
[
(int) $product['id_product'],
(int) $product['id_product_attribute'],
]
));
$productData->setPrice((float) $product['product_price_wt']);
$productData->setQuantity((int) $product['product_quantity']);
return $productData;
}
public function getProductDataByProductObject(array $params): ProductData
{
$product = $params['product'];
$productData = new ProductData();
$productData->setId(implode(
'-',
[
(int) $product->id,
(int) $params['id_product_attribute'],
]
));
$productData->setPrice($product->price);
$productData->setQuantity($params['quantity']);
return $productData;
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Provider;
use Context;
use Order;
use PrestaShop\Module\PsxMarketingWithGoogle\Adapter\ConfigurationAdapter;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Config;
use PrestaShop\Module\PsxMarketingWithGoogle\DTO\Remarketing\PurchaseEventData;
use PrestaShop\Module\PsxMarketingWithGoogle\Repository\CountryRepository;
use PrestaShop\Module\PsxMarketingWithGoogle\Repository\LanguageRepository;
class PurchaseEventDataProvider
{
/**
* @var ProductDataProvider
*/
protected $productDataProvider;
/**
* @var Context
*/
protected $context;
/**
* @var ConfigurationAdapter
*/
private $configurationAdapter;
/**
* @var LanguageRepository
*/
private $languageRepository;
/**
* @var CountryRepository
*/
private $countryRepository;
public function __construct(
ProductDataProvider $productDataProvider,
Context $context,
ConfigurationAdapter $configurationAdapter,
LanguageRepository $languageRepository,
CountryRepository $countryRepository
) {
$this->productDataProvider = $productDataProvider;
$this->context = $context;
$this->configurationAdapter = $configurationAdapter;
$this->languageRepository = $languageRepository;
$this->countryRepository = $countryRepository;
}
/**
* Return the items concerned by the transaction
*
* @see https://support.google.com/google-ads/answer/9028614
*/
public function getEventData($sendTo, Order $order): PurchaseEventData
{
$purchaseData = new PurchaseEventData();
// Common details
$purchaseData->setSendTo($sendTo);
$purchaseData->setCurrency($this->context->currency->iso_code);
$purchaseData->setValue((string) $order->total_products_wt);
$purchaseData->setTransactionId($order->reference);
// CwCD Parameters
$purchaseData->setDiscount((float) $order->total_discounts_tax_incl);
$purchaseData->setAwMerchandId((int) $this->configurationAdapter->get(Config::REMARKETING_CONVERSION_MERCHANT_GMC_ID));
$purchaseData->setAwFeedCountry(
$this->countryRepository->getIsoById(
$this->context->country->id
)
);
$purchaseData->setAwFeedLanguage(
$this->languageRepository->getIsoById(
$this->context->language->id
)
);
$items = [];
foreach ($order->getCartProducts() as $product) {
$items[] = $this->productDataProvider->getProductDataByProductArray($product);
}
$purchaseData->setItems($items);
return $purchaseData;
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,66 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Context;
class AttributesRepository
{
/**
* @var Context
*/
private $context;
public function __construct(Context $context)
{
$this->context = $context;
}
/**
* Get all custom and product attributes.
*
* @return array
*/
public function getAllAttributes(): array
{
$attributes = [];
$customAttributes = \AttributeGroupCore::getAttributesGroups($this->context->language->id);
$features = \FeatureCore::getFeatures($this->context->language->id);
foreach ($customAttributes as $attr) {
$attributes[] = [
// Not the best way in terms of permances, but avoid being responsible of a whole SQL query.
'name' => array_values(array_unique((array) (new \AttributeGroupCore($attr['id_attribute_group']))->name)),
'type' => 'custom',
];
}
foreach ($features as $feature) {
$attributes[] = [
// Not the best way in terms of permances, but avoid being responsible of a whole SQL query.
'name' => array_values(array_unique((array) (new \FeatureCore($feature['id_feature']))->name)),
'type' => 'feature',
];
}
return $attributes;
}
}

View File

@@ -0,0 +1,132 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Carrier;
use Context;
use Db;
use RangePrice;
use RangeWeight;
class CarrierRepository
{
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
public function getCarriers(int $langId): array
{
$carriers = Carrier::getCarriers($langId, false, false, false, null, Carrier::ALL_CARRIERS);
$data = [];
foreach ($carriers as $key => $carrier) {
$carrierObj = new Carrier($carrier['id_carrier']);
$data[$key]['collection'] = 'carriers';
$data[$key]['id'] = $carrierObj->id;
$data[$key]['properties'] = $carrier;
$deliveryPriceByRanges = self::getDeliveryPriceByRange($carrierObj);
foreach ($deliveryPriceByRanges as $deliveryPriceByRange) {
$data[$key]['collection'] = 'carriers_details';
$data[$key]['id'] = $deliveryPriceByRange['id_range_weight'];
$data[$key]['properties'] = $deliveryPriceByRange;
}
}
return $data;
}
public function getDeliveryPriceByRange(Carrier $carrierObj): array
{
$rangeTable = $carrierObj->getRangeTable();
switch ($rangeTable) {
case 'range_weight':
return self::getCarrierByWeightRange($carrierObj);
case 'range_price':
return self::getCarrierByPriceRange($carrierObj);
default:
return [];
}
}
private function getCarrierByPriceRange(Carrier $carrierObj): array
{
$deliveryPriceByRange = Carrier::getDeliveryPriceByRanges('range_price', (int) $carrierObj->id);
$filteredRanges = [];
foreach ($deliveryPriceByRange as $range) {
$filteredRanges[$range['id_range_price']]['id_range_price'] = $range['id_range_price'];
$filteredRanges[$range['id_range_price']]['id_carrier'] = $range['id_carrier'];
$filteredRanges[$range['id_range_price']]['zones'][$range['id_zone']]['id_zone'] = $range['id_zone'];
$filteredRanges[$range['id_range_price']]['zones'][$range['id_zone']]['price'] = $range['price'];
}
return $filteredRanges;
}
private function getCarrierByWeightRange(Carrier $carrierObj): array
{
$deliveryPriceByRange = Carrier::getDeliveryPriceByRanges('range_weight', (int) $carrierObj->id);
$filteredRanges = [];
foreach ($deliveryPriceByRange as $range) {
$filteredRanges[$range['id_range_weight']]['id_range_weight'] = $range['id_range_weight'];
$filteredRanges[$range['id_range_weight']]['id_carrier'] = $range['id_carrier'];
$filteredRanges[$range['id_range_weight']]['zones'][$range['id_zone']]['id_zone'] = $range['id_zone'];
$filteredRanges[$range['id_range_weight']]['zones'][$range['id_zone']]['price'] = $range['price'];
}
return $filteredRanges;
}
/**
* @param array $deliveryPriceByRange
*
* @return false|RangeWeight|RangePrice
*
* @throws \PrestaShopDatabaseException
* @throws \PrestaShopException
*/
public function getCarrierRange(array $deliveryPriceByRange)
{
if (isset($deliveryPriceByRange['id_range_weight'])) {
return new RangeWeight($deliveryPriceByRange['id_range_weight']);
}
if (isset($deliveryPriceByRange['id_range_price'])) {
return new RangePrice($deliveryPriceByRange['id_range_price']);
}
return false;
}
}

View File

@@ -0,0 +1,183 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Context;
use Country;
use Db;
use DbQuery;
use PrestaShop\Module\PsxMarketingWithGoogle\Adapter\ConfigurationAdapter;
class CountryRepository
{
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
private $countryIsoCodeCache = [];
/**
* @var ConfigurationAdapter
*/
private $configurationAdapter;
private $country;
public function __construct(Db $db, Context $context, Country $country, ConfigurationAdapter $configAdapter)
{
$this->db = $db;
$this->context = $context;
$this->country = $country;
$this->configurationAdapter = $configAdapter;
}
private function getBaseQuery(): DbQuery
{
$query = new DbQuery();
$query->from('country', 'c')
->innerJoin('country_shop', 'cs', 'cs.id_country = c.id_country')
->innerJoin('country_lang', 'cl', 'cl.id_country = c.id_country')
->where('cs.id_shop = ' . (int) $this->context->shop->id)
->where('cl.id_lang = ' . (int) $this->context->language->id);
return $query;
}
public function getCountryIsoCodesByZoneId(int $zoneId, bool $active = true): array
{
$cacheKey = $zoneId . '-' . (int) $active;
if (!isset($this->countryIsoCodeCache[$cacheKey])) {
$query = $this->getBaseQuery();
$query->select('iso_code');
$query->where('id_zone = ' . (int) $zoneId);
$query->where('active = ' . (bool) $active);
$isoCodes = [];
foreach ($this->db->executeS($query) as $country) {
$isoCodes[] = $country['iso_code'];
}
$this->countryIsoCodeCache[$cacheKey] = $isoCodes;
}
return $this->countryIsoCodeCache[$cacheKey];
}
public function getActiveCountries(): array
{
$query = $this->getBaseQuery();
$query->select('iso_code');
$query->where('active = ' . true);
$isoCodes = [];
foreach ($this->db->executeS($query) as $country) {
$isoCodes[] = $country['iso_code'];
}
return $isoCodes;
}
public function getShopDefaultCountry(): array
{
return [
'name' => Country::getNameById($this->context->language->id, $this->configurationAdapter->get('PS_COUNTRY_DEFAULT')),
'iso_code' => Country::getIsoById($this->configurationAdapter->get('PS_COUNTRY_DEFAULT')),
];
}
public function getIsoById(int $countryId)
{
return Country::getIsoById($countryId);
}
public function getShopContactCountry(): array
{
if (empty($this->configurationAdapter->get('PS_SHOP_COUNTRY_ID'))) {
return [
'name' => null,
'iso_code' => null,
];
}
return [
'name' => Country::getNameById($this->context->language->id, $this->configurationAdapter->get('PS_SHOP_COUNTRY_ID')),
'iso_code' => Country::getIsoById($this->configurationAdapter->get('PS_SHOP_COUNTRY_ID')),
];
}
public function countryNeedState(int $countryId): bool
{
return Country::containsStates($this->configurationAdapter->get($countryId));
}
/**
* isCompatibleForCSS
*
* @return bool
*/
public function isCompatibleForCSS()
{
$availableCountries = [
'BG',
'BE',
'CZ',
'DK',
'CY',
'LV',
'LT',
'LU',
'ES',
'FR',
'HR',
'IT',
'PL',
'PT',
'RO',
'SI',
'HU',
'MT',
'NL',
'AT',
'IS',
'LI',
'NO',
'SK',
'FI',
'SE',
'DE',
'IE',
'EL',
'CH',
'GB',
];
return in_array($this->country->iso_code, $availableCountries);
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Currency;
class CurrencyRepository
{
/**
* @var Currency
*/
private $currency;
public function __construct(Currency $currency)
{
$this->currency = $currency;
}
/**
* Get details about the currency associated to the shop context.
* Don't return all the details about the currency, as they should be
* available from another source (i.e CLDR json).
*
* @return array
*/
public function getShopCurrency(): array
{
return [
'isoCode' => $this->currency->iso_code,
];
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Language;
class LanguageRepository
{
public function __construct()
{
}
public function getIsoById(int $id)
{
return Language::getIsoById($id);
}
}

View File

@@ -0,0 +1,121 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Context;
use Module;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Config;
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
class ModuleRepository
{
/**
* @var string
*/
private $moduleName;
public function __construct(string $moduleName)
{
$this->moduleName = $moduleName;
}
/**
* @return string|null
*/
public function getModuleVersion()
{
/** @var Module $module */
$module = Module::getInstanceByName($this->moduleName);
if (!empty($module)) {
return $module->version;
}
return null;
}
/**
* @return string
*/
public function getUpgradeLink()
{
$router = SymfonyContainer::getInstance()->get('router');
return \Tools::getHttpHost(true) . $router->generate('admin_module_manage_action', [
'action' => 'upgrade',
'module_name' => $this->moduleName,
]);
}
/**
* @return string
*/
public function getEnableLink()
{
$router = SymfonyContainer::getInstance()->get('router');
return \Tools::getHttpHost(true) . $router->generate('admin_module_manage_action', [
'action' => 'enable',
'module_name' => $this->moduleName,
]);
}
/**
* @return array
*/
public function getInformationsAboutModule(): array
{
return [
'version' => $this->getModuleVersion(),
'upgradeLink' => $this->getUpgradeLink(),
'hooks' => $this->getActiveHooks(),
];
}
/**
* @return bool
*/
public function moduleIsEnabled(): bool
{
return Module::isEnabled($this->moduleName);
}
/**
* @return array
*/
public function getActiveHooks(): array
{
$context = Context::getContext();
$hooks = [];
/** @var Module $moduleInstance */
$moduleInstance = Module::getInstanceByName($this->moduleName);
if (empty($moduleInstance)) {
return $hooks;
}
foreach (Config::HOOK_LIST as $hook) {
$hooks[$hook] = \Hook::isModuleRegisteredOnHook($moduleInstance, $hook, $context->shop->id);
}
return $hooks;
}
}

View File

@@ -0,0 +1,50 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Db;
use DbQuery;
class ProductRepository
{
public function getProductsTotal($shopId, array $options = [])
{
$sql = new DbQuery();
$sql->select('COUNT(1) as total');
$sql->from('product', 'p');
$sql->innerJoin('product_shop', 'ps', 'ps.id_product = p.id_product');
if (isset($options['splitPerLangAndCombination'])) {
$sql->innerJoin('product_lang', 'pl', 'pl.id_product = ps.id_product AND pl.id_shop = ps.id_shop');
$sql->leftJoin('product_attribute_shop', 'pas', 'pas.id_product = ps.id_product AND pas.id_shop = ps.id_shop');
}
$sql->where('ps.id_shop = ' . (int) $shopId);
if (isset($options['onlyActive'])) {
$sql->where('ps.active = 1');
}
$res = Db::getInstance()->executeS($sql);
return $res[0]['total'];
}
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Db;
use DbQuery;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Config;
class ShopRepository
{
public function getShopDomainsAndConfiguration()
{
$sql = new DbQuery();
$sql->select('su.`id_shop`, `domain`, `domain_ssl`, c.`value` as acces_token_value');
$sql->from('shop_url', 'su');
$sql->leftJoin('configuration', 'c', 'su.id_shop = c.id_shop');
$sql->where('c.name LIKE "' . Config::PSX_MKTG_WITH_GOOGLE_ACCOUNT_IS_LINKED . '"');
return Db::getInstance()->executeS($sql);
}
}

View File

@@ -0,0 +1,78 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Context;
use Db;
use DbQuery;
class StateRepository
{
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
private $stateIsoCodeCache = [];
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
private function getBaseQuery(): DbQuery
{
$query = new DbQuery();
$query->from('state', 's');
return $query;
}
public function getStateIsoCodesByZoneId(int $zoneId, bool $active = true): array
{
$cacheKey = $zoneId . '-' . (int) $active;
if (!isset($this->stateIsoCodeCache[$cacheKey])) {
$query = $this->getBaseQuery();
$query->select('s.iso_code');
$query->innerJoin('country', 'c', 'c.id_country = s.id_country');
$query->where('s.id_zone = ' . (int) $zoneId);
$query->where('s.active = ' . (bool) $active);
$query->where('c.active = ' . (bool) $active);
$isoCodes = [];
foreach ($this->db->executeS($query) as $state) {
$isoCodes[] = $state['iso_code'];
}
$this->stateIsoCodeCache[$cacheKey] = $isoCodes;
}
return $this->stateIsoCodeCache[$cacheKey];
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Db;
use DbQuery;
class TabRepository
{
public function hasChildren(int $tabId): bool
{
$sql = new DbQuery();
$sql->select('id_tab');
$sql->from('tab');
$sql->where('`id_parent` = "' . (int) $tabId . '"');
return (bool) Db::getInstance()->getValue($sql);
}
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Repository;
use Context;
use Db;
use DbQuery;
class TaxRepository
{
/**
* @var Db
*/
private $db;
/**
* @var Context
*/
private $context;
private $countryIsoCodeCache = [];
public function __construct(Db $db, Context $context)
{
$this->db = $db;
$this->context = $context;
}
private function getBaseQuery(): DbQuery
{
$query = new DbQuery();
$query->from('tax', 't')
->innerJoin('tax_rule', 'tr', 'tr.id_tax = t.id_tax')
->innerJoin('tax_rules_group', 'trg', 'trg.id_tax_rules_group = tr.id_tax_rules_group')
->innerJoin('tax_rules_group_shop', 'trgs', 'trgs.id_tax_rules_group = tr.id_tax_rules_group')
->innerJoin('tax_lang', 'tl', 'tl.id_tax = t.id_tax')
->where('trgs.id_shop = ' . (int) $this->context->shop->id)
->where('tl.id_lang = ' . (int) $this->context->language->id);
return $query;
}
public function getCarrierTaxesByTaxRulesGroupId(int $taxRulesGroupId, bool $active = true): array
{
$cacheKey = (int) $taxRulesGroupId . '-' . (int) $active;
if (!isset($this->countryIsoCodeCache[$cacheKey])) {
$query = $this->getBaseQuery();
$query->select('rate, c.iso_code as country_iso_code, GROUP_CONCAT(s.iso_code SEPARATOR ",") as state_iso_code');
$query->leftJoin('country', 'c', 'c.id_country = tr.id_country');
$query->leftJoin('state', 's', 's.id_state = tr.id_state');
$query->where('tr.id_tax_rules_group = ' . (int) $taxRulesGroupId);
$query->where('c.active = ' . (bool) $active);
$query->where('s.active = ' . (bool) $active . ' OR s.active IS NULL');
$query->where('t.active = ' . (bool) $active);
$query->where('c.iso_code IS NOT NULL');
$this->countryIsoCodeCache[$cacheKey] = $this->db->executeS($query);
}
return $this->countryIsoCodeCache[$cacheKey];
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,192 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Tracker;
use Context;
use PrestaShop\Module\PsxMarketingWithGoogle\Config\Config;
class Segment implements TrackerInterface
{
/**
* @var string
*/
private $message = '';
/**
* @var array
*/
private $options = [];
/**
* @var Context
*/
private $context;
/**
* Segment constructor.
*/
public function __construct(Context $context)
{
$this->context = $context;
$this->init();
}
/**
* Init segment client with the api key
*/
private function init()
{
\Segment::init(Config::PSX_MKTG_WITH_GOOGLE_SEGMENT_API_KEY);
}
/**
* Track event on segment
*
* @return bool
*
* @throws \PrestaShopException
*/
public function track()
{
if (empty($this->message)) {
throw new \PrestaShopException('Message cannot be empty. Need to set it with setMessage() method.');
}
// Dispatch track depending on context shop
$this->dispatchTrack();
return true;
}
private function segmentTrack($userId)
{
$userAgent = array_key_exists('HTTP_USER_AGENT', $_SERVER) === true ? $_SERVER['HTTP_USER_AGENT'] : '';
$ip = array_key_exists('REMOTE_ADDR', $_SERVER) === true ? $_SERVER['REMOTE_ADDR'] : '';
$referer = array_key_exists('HTTP_REFERER', $_SERVER) === true ? $_SERVER['HTTP_REFERER'] : '';
$url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
\Segment::track([
'userId' => $userId,
'event' => $this->message,
'channel' => 'browser',
'context' => [
'ip' => $ip,
'userAgent' => $userAgent,
'locale' => $this->context->language->iso_code,
'page' => [
'referrer' => $referer,
'url' => $url,
],
],
'properties' => array_merge([
'module' => 'psxmarketingwithgoogle',
], $this->options),
]);
\Segment::flush();
}
/**
* Handle tracking differently depending on the shop context
*
* @return mixed
*/
private function dispatchTrack()
{
$dictionary = [
\Shop::CONTEXT_SHOP => function () {
return $this->trackShop();
},
\Shop::CONTEXT_GROUP => function () {
return $this->trackShopGroup();
},
\Shop::CONTEXT_ALL => function () {
return $this->trackAllShops();
},
];
return call_user_func($dictionary[$this->context->shop->getContext()]);
}
/**
* Send track segment only for the current shop
*/
private function trackShop()
{
$userId = $this->context->shop->domain;
$this->segmentTrack($userId);
}
/**
* Send track segment for each shop in the current shop group
*/
private function trackShopGroup()
{
$shops = $this->context->shop->getShops(true, $this->context->shop->getContextShopGroupID());
foreach ($shops as $shop) {
$this->segmentTrack($shop['domain']);
}
}
/**
* Send track segment for all shops
*/
private function trackAllShops()
{
$shops = $this->context->shop->getShops();
foreach ($shops as $shop) {
$this->segmentTrack($shop['domain']);
}
}
/**
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* @param string $message
*/
public function setMessage($message)
{
$this->message = $message;
}
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @param array $options
*/
public function setOptions($options)
{
$this->options = $options;
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Tracker;
interface TrackerInterface
{
/**
* @return void
*/
public function track();
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,65 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Config;
class Config
{
public const PSX_MKTG_WITH_GOOGLE_API_URL = 'https://googleshopping-api.psessentials.net';
public const PSX_MKTG_WITH_GOOGLE_CDN_URL = 'https://storage.googleapis.com/psxmarketing-cdn/v1.x.x/js/';
public const HOOK_LIST = [
'displayBackOfficeHeader',
'displayHeader',
'displayOrderConfirmation',
'displayTop',
'actionCartUpdateQuantityBefore',
];
public const CONFIGURATION_LIST = [];
public const MODULE_ADMIN_CONTROLLERS = [
'AdminAjaxPsgoogleshipping',
'AdminPsgoogleshippingModule',
];
public const PSX_MKTG_WITH_GOOGLE_SENTRY_CREDENTIALS_PHP = 'https://446479f8bca645fa8838c1a5f99dceba@o298402.ingest.sentry.io/5949536';
public const PSX_MKTG_WITH_GOOGLE_SENTRY_CREDENTIALS_VUE = 'https://6504c60594bd490eab93afa78f274e35@o298402.ingest.sentry.io/5984715';
public const USE_LOCAL_VUE_APP = false;
public const PSX_MKTG_WITH_GOOGLE_SEGMENT_API_KEY = 'RqYiLJKyoWv13t9aKxBvza6vsCsRpPpC';
public const PSX_MKTG_WITH_GOOGLE_WEBSITE_VERIFICATION_META = 'PSX_MKTG_WITH_GOOGLE_WEBSITE_VERIFICATION_META';
public const PSX_MKTG_WITH_GOOGLE_WEBSITE_REQUIREMENTS_STATUS = 'PSX_MKTG_WITH_GOOGLE_WEBSITE_REQUIREMENTS_STATUS';
public const PSX_MKTG_WITH_GOOGLE_REMARKETING_STATUS = 'PSX_MKTG_WITH_GOOGLE_REMARKETING_STATUS';
public const PSX_MKTG_WITH_GOOGLE_REMARKETING_TAG = 'PSX_MKTG_WITH_GOOGLE_REMARKETING_TAG';
public const PSX_MKTG_WITH_GOOGLE_REMARKETING_CONVERSION_LABELS = 'PSX_MKTG_WITH_GOOGLE_REMARKETING_CONVERSION_LABELS';
public const REMARKETING_CONVERSION_LABEL_PURCHASE = 'PURCHASE';
public const REMARKETING_CONVERSION_LABEL_ADD_TO_CART = 'ADD_TO_CART';
public const REMARKETING_CONVERSION_LABEL_PAGE_VIEW = 'PAGE_VIEW';
public const REMARKETING_CONVERSION_LABELS = [
self::REMARKETING_CONVERSION_LABEL_PURCHASE,
self::REMARKETING_CONVERSION_LABEL_ADD_TO_CART,
self::REMARKETING_CONVERSION_LABEL_PAGE_VIEW,
];
public const REMARKETING_CONVERSION_MERCHANT_GMC_ID = 'REMARKETING_CONVERSION_MERCHANT_GMC_ID';
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* Copyright since 2007 PrestaShop SA and Contributors
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License version 3.0
* that is bundled with this package in the file LICENSE.md.
* It is also available through the world-wide-web at this URL:
* https://opensource.org/licenses/AFL-3.0
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* @author PrestaShop SA and Contributors <contact@prestashop.com>
* @copyright Since 2007 PrestaShop SA and Contributors
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
*/
namespace PrestaShop\Module\PsxMarketingWithGoogle\Config;
/**
* This class allows to retrieve config data that can be overwritten by a .env file.
* Otherwise it returns by default from the Config class.
*/
class Env
{
/**
* @param string $key
*
* @return string
*/
public function get($key)
{
if (!empty($_ENV[$key])) {
return $_ENV[$key];
}
return constant(Config::class . '::' . $key);
}
}

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;

View File

@@ -0,0 +1,11 @@
<?php
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
header('Location: ../');
exit;