first commit

This commit is contained in:
2024-11-11 18:46:54 +01:00
commit a630d17338
25634 changed files with 4923715 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
<?php
namespace FreshMail\Sender;
use Freshmail\Entity\AbandonedCartSettings;
use FreshMail\Entity\Cart;
use Freshmail\Entity\FreshmailSetting;
use FreshMail\Repository\FreshmailAbandonCartSettings;
use FreshMail\Sender\Service\CartDataCollector;
class AbstractSender{
protected $fmSettings = null;
protected $cartSettings = null;
public function __construct(FreshmailSetting $fmSettings, FreshmailAbandonCartSettings $cartSettings)
{
$this->fmSettings = $fmSettings;
$this->cartSettings = $cartSettings;
}
public static function getProductsLegacy(\Context $context, $products)
{
$context->smarty->assign('list', $products);
return $context->smarty->fetch(_PS_MODULE_DIR_ . 'freshmail/views/templates/email/order_conf_product_list.tpl');
}
public static function getProductsFM($html, $products){
$output = '';
foreach ($products as $product){
$output .= str_replace(
['{product_cover}', '{product_cover_big}' , '{product_name}', '{product_quantity}', '{unit_price_tax_incl}'],
[ $product['img'], $product['img_big'], $product['name'], $product['quantity'], $product['price_wt'] ],
$html
);
}
return $output;
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace FreshMail\Sender;
use FreshMail\Freshmail;
use FreshMail\FreshmailApiV3;
use FreshMail\Repository\Birthdays;
use FreshMail\TransactionalEmail;
class Birthday
{
private $bearer_token;
public function __construct($bearer_token)
{
$this->bearer_token = $bearer_token;
}
private function getMailHtml(\FreshMail\Entity\Birthday $birthday) : string
{
if(!empty($birthday->tpl)){
$fm = new Freshmail($this->bearer_token);
$html = $fm->getTemplateHtml($birthday->tpl);
if(!empty($html)){
return $html;
}
}
return '';
}
public function send(\Customer $customer, \FreshMail\Entity\Birthday $birthday) : bool
{
$shop = new \Shop($birthday->id_shop);
$html = str_replace(
['{firstname}', '{lastname}', '{content}', '{shop_url}'],
[$customer->firstname, $customer->lastname, $birthday->content[$customer->id_lang]],
$this->getMailHtml($birthday)
);
$recipient = new Email($customer->email, $customer->firstname);
$sender = new Email(\Configuration::get('PS_SHOP_EMAIL'), $shop->name);
$fmApi = new FreshmailApiV3($this->bearer_token);
return $fmApi->sendTransactionalEmail(
new TransactionalEmail($recipient, $sender, $birthday->email_subject[$customer->id_lang], $html)
);
}
}

View File

@@ -0,0 +1,18 @@
<?php
namespace FreshMail\Sender;
class Email{
public $email;
public $name;
public $lastname;
public function __construct($email, $name = '', $lastname = '')
{
$this->email = $email;
$this->name = $name;
$this->lastname = $lastname;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace FreshMail\Sender;
use FreshMail\Discount\Percent;
use Freshmail\Entity\AbandonedCartSettings;
use Freshmail\Entity\FreshmailSetting;
use FreshMail\Interfaces\Sender;
use FreshMail\Repository\FreshmailAbandonCartSettings;
class Factory {
public static function getSender(FreshmailSetting $fmSetting, FreshmailAbandonCartSettings $cartSettings) : Sender
{
if(empty($fmSetting->api_token)) {
return new Legacy($fmSetting, $cartSettings);
} else {
return new FmSender($fmSetting, $cartSettings);
}
}
}

View File

@@ -0,0 +1,115 @@
<?php
namespace FreshMail\Sender;
use FreshMail\Entity\Cart;
use Freshmail\Entity\FreshmailSetting;
use FreshMail\Freshmail;
use FreshMail\FreshmailApiV3;
use FreshMail\Interfaces\Sender;
use FreshMail\Repository\FreshmailAbandonCartSettings;
use FreshMail\Repository\FreshmailSettings;
use FreshMail\Sender\Service\CartDataCollector;
use FreshMail\TransactionalEmail;
class FmSender extends AbstractSender implements Sender{
private $freshmailApi = null;
public function __construct(FreshmailSetting $fmSettings, FreshmailAbandonCartSettings $cartSettings)
{
parent::__construct($fmSettings, $cartSettings);
$this->freshmailApi = new Freshmail($this->fmSettings->api_token);
}
public function send(\Cart $cart, Cart $fmCart, Email $email, CartDataCollector $cartDataCollector) : bool
{
$shop = new \Shop($cart->id_shop);
$fmApi = new FreshmailApiV3($this->fmSettings->api_token);
$cs = $this->cartSettings->findForShop($cart->id_shop);
$context = \Context::getContext();
$context->cart = $cart;
$context->shop = new \Shop($cart->id_shop);
$customer = $cartDataCollector::getCustomer($cart);
if (\Configuration::get('PS_LOGO_MAIL') !== false && file_exists(_PS_IMG_DIR_.\Configuration::get('PS_LOGO_MAIL', null, null, $cart->id_shop))) {
$logo = _PS_IMG_DIR_.\Configuration::get('PS_LOGO_MAIL', null, null, $cart->id_shop);
} else {
if (file_exists(_PS_IMG_DIR_.\Configuration::get('PS_LOGO', null, null, $cart->id_shop))) {
$logo = _PS_IMG_DIR_.\Configuration::get('PS_LOGO', null, null, $cart->id_shop);
}
}
$logo_url = '';
if(file_exists($logo)){
$logo_url = $context->shop->getBaseURL() . _PS_IMG_ . \Configuration::get('PS_LOGO', null, null, $cart->id_shop);
}
$replaceFrom = [
'{products_list}',
'{discount_code}',
'{shop_name}',
'{shop_url}',
'{shop_logo}',
'{cart_url}',
'{company_name}',
'{company_address}',
'{firstname}',
'{lastname}',
'{cartrule_validto}',
'{preheader}'
];
$productsHtml = AbstractSender::getProductsFM($this->getProductHtml($cart, $fmCart), $cartDataCollector::getProductList($cart, $context));
if(empty($productsHtml)){
$productsHtml = AbstractSender::getProductsLegacy($context, $cartDataCollector::getProductList($cart, $context));
}
$replaceTo = [
$productsHtml,
$cartDataCollector::getDiscountCode($fmCart),
$shop->name, //\Configuration::get('PS_SHOP_NAME'),
$context->shop->getBaseURL(), //$context->link->getPageLink('index', true, $cart->id_lang, null, false, $cart->id_shop),
$logo_url,
$cartDataCollector::getCartUrl($fmCart),
\Configuration::get('PS_SHOP_NAME', $cart->id_lang, null, $cart->id_shop),
$cartDataCollector::getShopAddress(),
$customer->firstname,
$customer->lastname,
$cartDataCollector::getDiscountValidTo($fmCart),
$cs->email_preheader[$cart->id_lang],
];
$html = str_replace(
$replaceFrom,
$replaceTo,
$this->getMailHtml($cart, $fmCart)
);
$sender = new Email(\Configuration::get('PS_SHOP_EMAIL'), $shop->name);
return $fmApi->sendTransactionalEmail(
new TransactionalEmail($email, $sender, $cs->email_subject[$cart->id_lang], $html)
);
}
private function getMailHtml(\Cart $cart, Cart $fmCart) : string
{
$cs = $this->cartSettings->findForShop($cart->id_shop);
if(!empty($cs->template_id_hash)){
return $this->freshmailApi->getTemplateHtml($cs->template_id_hash);
}
$lang = new \Language($cart->id_lang);
return file_get_contents(_PS_MODULE_DIR_.'freshmail/mails/'.$lang->iso_code.'/abandoned-cart.html');
}
private function getProductHtml(\Cart $cart, Cart $fmCart) : string
{
$cs = $this->cartSettings->findForShop($cart->id_shop);
if(!empty($cs->template_id_hash)){
return $this->freshmailApi->getProductHtml($cs->template_id_hash);
}
return '';
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace FreshMail\Sender;
use FreshMail\Entity\Cart;
use FreshMail\Repository\Carts;
use FreshMail\Sender\Service\CartDataCollector;
class Legacy extends AbstractSender implements \FreshMail\Interfaces\Sender{
public function send(\Cart $cart, Cart $fmCart, Email $email, CartDataCollector $cartDataCollector) : bool
{
$context = \Context::getContext();
$context->cart = $cart;
$context->shop = new \Shop($cart->id_shop);
$customer = new \Customer($cart->id_customer);
$vars = [
'{products_list}' => AbstractSender::getProductsLegacy($context, $cartDataCollector::getProductList($cart, $context)),
'{discount_code}' => $cartDataCollector::getDiscountCode($fmCart),
'{cart_url}' => $cartDataCollector::getCartUrl($fmCart),
'{company_name}' => \Configuration::get('PS_SHOP_NAME'),
'{company_address}' => $cartDataCollector::getShopAddress(),
'{firstname}' => $customer->firstname,
'{lastname}' => $customer->lastname,
'{cartrule_validto}' => $cartDataCollector::getDiscountValidTo($fmCart),
];
$cs = $this->cartSettings->findForShop($cart->id_shop);
return \Mail::send(
$cart->id_lang,
'abandoned-cart',
$cs->email_subject[$cart->id_lang],
$vars,
$email->email,
$email->name,
null,
null,
null,
null,
_PS_MODULE_DIR_.'freshmail/mails/'
);
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace FreshMail\Sender\Service;
use FreshMail\Entity\Cart;
use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter;
class CartData implements CartDataCollector
{
public static function getProductList(\Cart $cart, \Context $context)
{
$priceFormatter = new PriceFormatter();
$productList = $cart->getProducts();
foreach ($productList as &$prod) {
$prod['img'] = $context->link->getImageLink($prod['name'], \Product::getCover($prod['id_product'], $context)['id_image'], 'cart_default');
$prod['img_big'] = $context->link->getImageLink($prod['name'], \Product::getCover($prod['id_product'], $context)['id_image'], 'home_default');
$prod['price_wt'] = $priceFormatter->format($prod['price_wt'], new \Currency($cart->id_currency));
}
return $productList;
}
public static function getDiscountCode(Cart $fmCart)
{
$discountCode = '';
if (!empty($fmCart->id_cart_rule)) {
$discountCode = (new \CartRule($fmCart->id_cart_rule))->code;
} elseif (!empty($fmCart->discount_code)) {
$discountCode = $fmCart->discount_code;
}
return $discountCode;
}
public static function getDiscountValidTo(Cart $fmCart)
{
if (!empty($fmCart->id_cart_rule)) {
$id = $fmCart->id_cart_rule;
} elseif (!empty($fmCart->discount_code)) {
$id = \CartRule::getIdByCode($fmCart->discount_code);
}
if (empty($id)) {
return '';
}
$cr = new \CartRule($id);
if (!\Validate::isLoadedObject($cr)) {
return '';
}
return $cr->date_to;
}
public static function getCartUrl(Cart $fmCart)
{
return \Context::getContext()->link->getModuleLink('freshmail', 'restore', ['hash' => $fmCart->cart_token]);
}
public static function getShopAddress()
{
$city = \Configuration::get('PS_SHOP_CITY');
$postal = \Configuration::get('PS_SHOP_CODE');
$addr1 = \Configuration::get('PS_SHOP_ADDR1');
$addr2 = \Configuration::get('PS_SHOP_ADDR2');
return $city . ' ' . $postal . ' ' . $addr1 . ' ' . $addr2;
}
public static function getCustomer(\Cart $cart) : \Customer
{
return new \Customer($cart->id_customer);
}
}

View File

@@ -0,0 +1,15 @@
<?php
namespace FreshMail\Sender\Service;
use FreshMail\Entity\Cart;
interface CartDataCollector
{
public static function getProductList(\Cart $cart, \Context $context);
public static function getDiscountCode(Cart $fmCart);
public static function getDiscountValidTo(Cart $fmCart);
public static function getCartUrl(Cart $fmCart);
public static function getShopAddress();
public static function getCustomer(\Cart $cart) : \Customer;
}

View File

@@ -0,0 +1,80 @@
<?php
namespace FreshMail\Sender\Service;
use FreshMail\Entity\Cart;
use PrestaShop\PrestaShop\Adapter\Product\PriceFormatter;
class MockCartData implements CartDataCollector
{
public static function getProductList(\Cart $cart, \Context $context)
{
$query = new \DbQuery();
$query->select('p.*, pl.*')
->from('product', 'p')
->leftJoin('product_lang', 'pl', 'p.id_product = pl.id_product AND pl.id_lang = '.(int)$context->language->id)
->leftJoin('product_sale', 'ps', 'p.id_product = ps.id_product')
->where('p.active = 1')
->where('p.available_for_order = 1')
->orderBy('ps.quantity desc')
->limit(1)
;
$productList = \Db::getInstance()->executeS($query);
$priceFormatter = new PriceFormatter();
foreach ($productList as &$prod) {
$prod['name'] = \Product::getProductName($prod['id_product']);
$prod['quantity'] = 1;
$prod['price_wt'] = $priceFormatter->format(
\Product::getPriceStatic((int)$prod['id_product'], true),
new \Currency($cart->id_currency)
);
$prod['img'] = $context->link->getImageLink($prod['name'], \Product::getCover($prod['id_product'], $context)['id_image'], 'cart_default');
$prod['img_big'] = $context->link->getImageLink($prod['name'], \Product::getCover($prod['id_product'], $context)['id_image'], 'home_default');
}
return $productList;
}
public static function getDiscountCode(Cart $fmCart)
{
return 'PROMO_CODE';
}
public static function getDiscountValidTo(Cart $fmCart)
{
return 'YYYY-MM-DD';
}
public static function getCartUrl(Cart $fmCart)
{
return \Context::getContext()->link->getModuleLink('freshmail', 'restore', ['hash' => $fmCart->cart_token]);
}
public static function getShopAddress()
{
$city = \Configuration::get('PS_SHOP_CITY');
$postal = \Configuration::get('PS_SHOP_CODE');
$addr1 = \Configuration::get('PS_SHOP_ADDR1');
$addr2 = \Configuration::get('PS_SHOP_ADDR2');
return $city . ' ' . $postal . ' ' . $addr1 . ' ' . $addr2;
}
public static function getCustomer(\Cart $cart) : \Customer
{
$query = new \DbQuery();
$query->select('DISTINCT(firstname)')->from('customer')->limit(100);
$firstame = \Db::getInstance()->executeS($query);
$query = new \DbQuery();
$query->select('DISTINCT(lastname)')->from('customer')->limit(100);
$lastname = \Db::getInstance()->executeS($query);
$customer = new \Customer();
$customer->firstname = $firstame[array_rand($firstame)]['firstname'];
$customer->lastname = $lastname[array_rand($lastname)]['lastname'];
return $customer;
}
}