Init Extension

Initialize the ActiveCampaign for Magento Extension
This commit is contained in:
Jordan Price committed 2021-08-11 11:17:41 -05:00
1 parent 10a72e1448
commit 189e2a67c5
110 files changed
+6849 -1

No files matched your search

Vendored
BIN
View File
Binary file not shown.
@@ -0,0 +1,159 @@
<?php
/**
* Copyright © Wagento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace ActiveCampaign\AbandonedCart\Block\System\Config;
use Magento\Backend\Block\Template\Context;
use Magento\Backend\Block\Widget\Button;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory as QuoteResourceCollectionFactory;
use ActiveCampaign\AbandonedCart\Model\Config\CronConfig;
class SyncAbandonedCartData extends Field
{
const AC_SYNC_STATUS = "ac_sync_status";
/**
* @var string
*/
protected $_template = 'ActiveCampaign_AbandonedCart::system/config/sync_abandoned_cart_data.phtml';
/**
* @param Context $context
* @param array $data
* @param QuoteResourceCollectionFactory $quoteResourceCollectionFactory
*/
public function __construct(
Context $context,
QuoteResourceCollectionFactory $quoteResourceCollectionFactory,
array $data = []
) {
parent::__construct($context, $data);
$this->quoteResourceCollectionFactory = $quoteResourceCollectionFactory;
}
/**
* Remove scope label
* @param AbstractElement $element
* @return string
*/
public function render(AbstractElement $element)
{
$element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
return parent::render($element);
}
/**
* Return element html
* @param AbstractElement $element
* @return string
*/
protected function _getElementHtml(AbstractElement $element)
{
return $this->_toHtml();
}
/**
* Return ajax url for field sync button
* @return string
*/
public function getAjaxUrl()
{
return $this->getUrl('acecommerce/index/syncaccart');
}
/**
* Generate field sync button html
* @return string
*/
public function getButtonHtml()
{
$button = $this->getLayout()->createBlock(
Button::class
)->setData([
'id' => 'ac_sync_abandoned_cart_button',
'label' => __('Sync Abandoned Cart Data'),
]);
return $button->toHtml();
}
/**
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getAbandonedCartCollection()
{
$collection = $this->quoteResourceCollectionFactory->create()
->addFieldToSelect('*')
->addFieldToFilter(
'main_table.is_active',
'1'
);
return $collection;
}
/**
* @return int|void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getSyncAbandonedCart()
{
$sync = $this->getAbandonedCartCollection()->addFieldToFilter(
self::AC_SYNC_STATUS,
[
['eq' => CronConfig::SYNCED]
]
);
return count($sync);
}
/**
* @return int|void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getTotalAbandonedCart()
{
$total = $this->getAbandonedCartCollection()->addFieldToFilter(
self::AC_SYNC_STATUS,
[
['eq' => CronConfig::SYNCED],
['eq' => CronConfig::NOT_SYNCED],
['eq' => CronConfig::FAIL_SYNCED],
]
);
return count($total);
}
/**
* @return int|void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getNotSyncAbandonedCart()
{
$notSync = $this->getAbandonedCartCollection()->addFieldToFilter(
self::AC_SYNC_STATUS,
[
['eq' => CronConfig::NOT_SYNCED],
]
)->getData();
return count($notSync);
}
/**
* @return int|void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getFailedSync()
{
$failSync = $this->getAbandonedCartCollection()->addFieldToFilter(
self::AC_SYNC_STATUS,
[
['eq' => CronConfig::FAIL_SYNCED],
]
);
return count($failSync);
}
}
@@ -0,0 +1,43 @@
<?php
/**
* Copyright © Wagento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace ActiveCampaign\AbandonedCart\Controller\Adminhtml\Index;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\View\Result\PageFactory;
class Index extends Action
{
/**
* @var PageFactory
*/
protected $resultPageFactory;
/**
* @param Context $context
* @param PageFactory $resultJsonFactory
*/
public function __construct(
Context $context,
PageFactory $resultPageFactory
) {
$this->resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
/**
* Index action
*
* @return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->prepend(__("ActiveCampaign Abandoned Carts"));
return $resultPage;
}
}
@@ -0,0 +1,101 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace ActiveCampaign\AbandonedCart\Controller\Adminhtml\Index;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Backend\App\Action\Context;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory;
use ActiveCampaign\AbandonedCart\Model\AbandonedCartSendData;
class MassSync extends \Magento\Backend\App\Action implements HttpPostActionInterface
{
/**
* Authorization level of a basic admin session
*
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'ActiveCampaign_AbandonedCart::abandonedcart_operation';
/**
* @var Filter
*/
protected $filter;
/**
* @var CollectionFactory
*/
protected $collectionFactory;
/**
* @var AbandonedCartSendData
*/
protected $abandonedCartSendData;
/**
* @param Context $context
* @param Filter $filter
* @param CollectionFactory $collectionFactory
* @param AbandonedCartSendData $abandonedCartSendData
*/
public function __construct(
Context $context,
Filter $filter,
CollectionFactory $collectionFactory,
AbandonedCartSendData $abandonedCartSendData
) {
$this->filter = $filter;
$this->collectionFactory = $collectionFactory;
$this->abandonedCartSendData = $abandonedCartSendData;
parent::__construct($context);
}
/**
* Execute action
*
* @return \Magento\Backend\Model\View\Result\Redirect
* @throws \Magento\Framework\Exception\LocalizedException|\Exception
*/
public function execute()
{
$collection = $this->filter->getCollection($this->collectionFactory->create());
$countSync = 0;
$countFailSync = 0;
$countAlreadySync = 0;
foreach ($collection as $quote) {
$ac_sync_status = $quote->getData('ac_sync_status');
if ($ac_sync_status) {
$countAlreadySync++;
} else {
$quoteId = $quote->getEntityId();
$result = $this->abandonedCartSendData->sendAbandonedCartData($quoteId);
if (array_key_exists('success', $result)) {
$countSync++;
} else if (array_key_exists('error', $result)) {
$countFailSync++;
}
}
}
if ($countSync || $countFailSync) {
$this->messageManager->addNoticeMessage(__(
'Orders synced: %1 Orders failed: %2',
$countSync,
$countFailSync
));
}
if ($countAlreadySync) {
$this->messageManager->addNoticeMessage(__('%1 order(s) had already been synced.', $countAlreadySync));
}
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
return $resultRedirect->setPath('*/*/');
}
}
@@ -0,0 +1,68 @@
<?php
/**
* Copyright © Wagento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace ActiveCampaign\AbandonedCart\Controller\Adminhtml\Index;
use Magento\Backend\App\Action;
use ActiveCampaign\AbandonedCart\Model\AbandonedCartSendData;
class Sync extends \Magento\Backend\App\Action
{
/**
* @var \Magento\Quote\Model\Quote
*/
private $quoteModel;
/**
* @var AbandonedCartSendData
*/
protected $abandonedCartSendData;
/**
* @param \Magento\Backend\App\Action $context
* @param \Magento\Quote\Model\Quote $quoteModel
* @param AbandonedCartSendData $abandonedCartSendData
*/
public function __construct(
Action\Context $context,
\Magento\Quote\Model\Quote $quoteModel,
AbandonedCartSendData $abandonedCartSendData
) {
$this->quoteModel = $quoteModel;
$this->abandonedCartSendData = $abandonedCartSendData;
parent::__construct($context);
}
/**
* Sync action
*
* @return void
*/
public function execute()
{
// check if we know what should be synced
$id = $this->getRequest()->getParam('entity_id');
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultRedirectFactory->create();
if ($id) {
$title = "";
try {
// init model and sync
$model = $this->quoteModel;
$model->load($id);
$quoteId[] = $model->getEntityId();
$this->abandonedCartSendData->sendAbandonedCartData($quoteId);
$this->messageManager->addSuccess(__('The data has been synced.'));
return $resultRedirect->setPath('*/*/');
} catch (\Exception $e) {
$this->messageManager->addError($e->getMessage());
return $resultRedirect->setPath('*/*/');
}
}
$this->messageManager->addError(__('We can\'t find a data to sync.'));
return $resultRedirect->setPath('*/*/');
}
}
@@ -0,0 +1,61 @@
<?php
/**
* Copyright © Wagento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace ActiveCampaign\AbandonedCart\Controller\Adminhtml\Index;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use ActiveCampaign\AbandonedCart\Helper\Data as AbandonedCartHelper;
use ActiveCampaign\AbandonedCart\Model\AbandonedCartSendData;
class Syncaccart extends Action
{
/**
* @var JsonFactory
*/
protected $resultJsonFactory;
/**
* @var AbandonedCartHelper
*/
protected $abandonedCartHelper;
/**
* @var AbandonedCartSendData
*/
protected $abandonedCartSendData;
/**
* @param Context $context
* @param JsonFactory $resultJsonFactory
*/
public function __construct(
Context $context,
JsonFactory $resultJsonFactory,
AbandonedCartHelper $abandonedCartHelper,
AbandonedCartSendData $abandonedCartSendData
) {
$this->resultJsonFactory = $resultJsonFactory;
$this->abandonedCartHelper = $abandonedCartHelper;
$this->abandonedCartSendData = $abandonedCartSendData;
parent::__construct($context);
}
/**
* @return Json
*/
public function execute()
{
/** @var Json $result */
$result = $this->resultJsonFactory->create();
if ($this->abandonedCartHelper->isAbandonedCartSyncingEnabled()) {
$response = $this->abandonedCartSendData->sendAbandonedCartData();
}
return $result->setData($response);
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
namespace ActiveCampaign\AbandonedCart\Cron;
use ActiveCampaign\AbandonedCart\Helper\Data as AbandonedCartHelper;
use ActiveCampaign\AbandonedCart\Model\AbandonedCartSendData;
class AbandonedCartSync
{
/**
* @var AbandonedCartHelper
*/
protected $abandonedCartHelper;
/**
* @var AbandonedCartSendData
*/
protected $abandonedCartSendData;
/**
* Abandoned cart sync constructor.
* @param AbandonedCartHelper $abandonedCartHelper
* @param AbandonedCartSendData $abandonedCartSendData
*/
public function __construct(
AbandonedCartHelper $abandonedCartHelper,
AbandonedCartSendData $abandonedCartSendData
) {
$this->abandonedCartHelper = $abandonedCartHelper;
$this->abandonedCartSendData = $abandonedCartSendData;
}
public function execute()
{
if ($this->abandonedCartHelper->isAbandonedCartSyncingEnabled()) {
$this->abandonedCartSendData->sendAbandonedCartData();
}
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
namespace ActiveCampaign\AbandonedCart\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\ScopeInterface;
use ActiveCampaign\AbandonedCart\Model\Config\CronConfig;
class Data extends AbstractHelper
{
const ACTIVE_CAMPAIGN_ABANDONED_CART_SYNC = "active_campaign/abandoned_cart/sync";
const ABANDONED_CART_NUMBER_OF_ABANDONED_CART = "active_campaign/abandoned_cart/number_of_abandoned_cart";
/**
* @param null $scopeCode
* @return bool
*/
public function isAbandonedCartSyncingEnabled($scopeCode = null)
{
return $this->scopeConfig->isSetFlag(
self::ACTIVE_CAMPAIGN_ABANDONED_CART_SYNC,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return mixed
*/
public function getCronTime($scopeCode = null)
{
return $this->scopeConfig->getValue(
CronConfig::CRON_MODEL_PATH,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return mixed
*/
public function getNumberOfAbandonedCart($scopeCode = null)
{
return $this->scopeConfig->getValue(
self::ABANDONED_CART_NUMBER_OF_ABANDONED_CART,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
}
@@ -0,0 +1,526 @@
<?php
namespace ActiveCampaign\AbandonedCart\Model;
use ActiveCampaign\Core\Helper\Curl;
use ActiveCampaign\AbandonedCart\Helper\Data as AbandonedCartHelper;
use ActiveCampaign\Core\Helper\Data as CoreHelper;
use ActiveCampaign\AbandonedCart\Model\Config\CronConfig;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\Customer as CustomerModel;
use Magento\Customer\Model\CustomerFactory;
use Magento\Customer\Model\ResourceModel\Customer as CustomerResource;
use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory as CustomerResourceCollectionFactory;
use Magento\Eav\Model\ResourceModel\Entity\Attribute;
use Psr\Log\LoggerInterface;
use Magento\Quote\Model\ResourceModel\Quote\CollectionFactory as QuoteResourceCollectionFactory;
use Magento\Quote\Api\CartRepositoryInterface;
use Magento\Quote\Model\ResourceModel\Quote\Item\CollectionFactory as QuoteItemCollectionFactory;
use Magento\Quote\Model\QuoteFactory as QuoteFactory;
use Magento\Catalog\Api\ProductRepositoryInterfaceFactory;
use Magento\Catalog\Helper\ImageFactory;
use Magento\Store\Model\App\Emulation as AppEmulation;
use Zend\Log\Writer\Stream;
use Zend\Log\Logger;
use Magento\Store\Model\StoreManagerInterface as StoreManagerInterface;
class AbandonedCartSendData extends \Magento\Framework\Model\AbstractModel
{
public const AC_SYNC_STATUS = "ac_sync_status";
public const ABANDONED_CART_URL_ENDPOINT = "ecomOrders";
public const CONTACT_ENDPOINT = "contact/sync";
public const ECOM_CUSTOMER_ENDPOINT = "ecomCustomers";
public const METHOD = "POST";
public const UPDATE_METHOD = "PUT";
public const GET_METHOD = "GET";
/**
* @var CustomerRepositoryInterface
*/
protected $customerRepository;
/**
* @var AddressRepositoryInterface
*/
protected $addressRepository;
/**
* @var CustomerResourceCollectionFactory
*/
protected $customerResourceCollectionFactory;
/**
* @var CustomerFactory
*/
protected $customerFactory;
/**
* @var CustomerResource
*/
protected $customerResource;
/**
* @var Attribute
*/
protected $eavAttribute;
/**
* @var Curl
*/
protected $curl;
/**
* @var LoggerInterface
*/
protected $logger;
/**
* @var \Magento\Catalog\Helper\ImageFactory
*/
protected $imageHelperFactory;
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterfaceFactory
*/
protected $_productRepositoryFactory;
/**
* @var AppEmulation
*/
protected $appEmulation;
/**
* @var QuoteFactory
*/
protected $quoteFactory;
/**
* @var StoreManagerInterface
*/
protected $storeManager;
/**
* CustomerSync constructor.
* @param CustomerRepositoryInterface $customerRepository
* @param AddressRepositoryInterface $addressRepository
* @param CustomerResourceCollectionFactory $customerResourceCollectionFactory
* @param CustomerFactory $customerFactory
* @param CustomerResource $customerResource
* @param Attribute $eavAttribute
* @param AbandonedCartHelper $abandonedCartHelper
* @param QuoteResourceCollectionFactory $quoteResourceCollectionFactory
* @param Curl $curl
* @param LoggerInterface $logger
* @param CartRepositoryInterface $cartRepositoryInterface
* @param CoreHelper $coreHelper
* @param QuoteItemCollectionFactory $quoteItemCollectionFactory
* @param \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory
* @param \Magento\Catalog\Helper\ImageFactory $imageHelperFactory
* @param QuoteFactory $quoteFactory
* @param AppEmulation $appEmulation
* @param StoreManagerInterface $storeManager
* @param CustomerModel $customerModel
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
AddressRepositoryInterface $addressRepository,
CustomerResourceCollectionFactory $customerResourceCollectionFactory,
CustomerFactory $customerFactory,
CustomerResource $customerResource,
Attribute $eavAttribute,
AbandonedCartHelper $abandonedCartHelper,
QuoteResourceCollectionFactory $quoteResourceCollectionFactory,
Curl $curl,
LoggerInterface $logger,
CartRepositoryInterface $cartRepositoryInterface,
CoreHelper $coreHelper,
QuoteItemCollectionFactory $quoteItemCollectionFactory,
ProductRepositoryInterfaceFactory $productRepositoryFactory,
ImageFactory $imageHelperFactory,
QuoteFactory $quoteFactory,
AppEmulation $appEmulation,
StoreManagerInterface $storeManager,
CustomerModel $customerModel
) {
$this->customerRepository = $customerRepository;
$this->addressRepository = $addressRepository;
$this->customerResourceCollectionFactory = $customerResourceCollectionFactory;
$this->customerFactory = $customerFactory;
$this->customerResource = $customerResource;
$this->eavAttribute = $eavAttribute;
$this->abandonedCartHelper = $abandonedCartHelper;
$this->quoteResourceCollectionFactory = $quoteResourceCollectionFactory;
$this->curl = $curl;
$this->logger = $logger;
$this->cartRepositoryInterface = $cartRepositoryInterface;
$this->coreHelper = $coreHelper;
$this->quoteItemCollectionFactory = $quoteItemCollectionFactory;
$this->_productRepositoryFactory = $productRepositoryFactory;
$this->imageHelperFactory = $imageHelperFactory;
$this->quoteFactory = $quoteFactory;
$this->appEmulation = $appEmulation;
$this->storeManager = $storeManager;
$this->customerModel = $customerModel;
}
/**
* @param $quoteId
* @return array
*/
public function sendAbandonedCartData($quoteId = null)
{
$quoteItemsData = [];
$contact = [];
$result = [];
$numberOfAbandonedCart = (int)$this->abandonedCartHelper->getNumberOfAbandonedCart();
$abandonedCarts = $this->quoteResourceCollectionFactory->create()
->addFieldToSelect('*')
->addFieldToFilter('main_table.' . self::AC_SYNC_STATUS, [
['neq' => CronConfig::SYNCED]
])
->addFieldToFilter(
'main_table.is_active',
'1'
);
if ($quoteId) {
$abandonedCarts->addFieldToFilter(
'main_table.entity_id',
['in' => $quoteId]
);
}
$abandonedCarts->setPageSize($numberOfAbandonedCart);
foreach ($abandonedCarts as $abandonedCart) {
$connectionId = $this->coreHelper->getConnectionId($abandonedCart->getStoreId());
$customerId = $abandonedCart->getCustomerId();
$customerAcId = 0;
$quote = $this->quoteFactory->create()->load($abandonedCart->getEntityId());
if ($customerId) {
$this->createEcomCustomer($abandonedCart->getCustomerId(), $quote);
$customerEmail = $abandonedCart->getCustomerEmail();
$customerModel = $this->customerFactory->create();
$this->customerResource->load($customerModel, $customerId);
if ($customerModel->getAcCustomerId()) {
$customerAcId = $customerModel->getAcCustomerId();
}
} else {
$customerEmail = $quote->getBillingAddress()->getEmail();
if (!$customerEmail) {
$result['error'] = true;
return $result;
}
$websiteId = $this->storeManager->getWebsite()->getWebsiteId();
$customerModel = $this->customerModel;
$customerModel->setWebsiteId($websiteId);
$customerModel->loadByEmail($customerEmail);
if ($customerModel->getId()) {
$customerId = $customerModel->getId();
} else {
$customerId = 0;
}
$this->createEcomCustomer($customerId, $quote);
$customerModel = $this->customerFactory->create();
$this->customerResource->load($customerModel, $customerId);
if ($customerModel->getAcCustomerId()) {
$customerAcId = $customerModel->getAcCustomerId();
} else {
if ($quote->getAcTempCustomerId()) {
$customerAcId = $quote->getAcTempCustomerId();
} else {
$AcCustomer = $this->curl->listAllCustomers(
self::GET_METHOD,
self::ECOM_CUSTOMER_ENDPOINT,
$customerEmail
);
foreach ($AcCustomer['data']['ecomCustomers'] as $Ac) {
if ($Ac['connectionid'] == $connectionId) {
$customerAcId = $Ac['id'];
}
}
}
}
}
$quoteItems = $this->getQuoteItems($abandonedCart->getEntityId());
foreach ($quoteItems as $quoteItem) {
$this->appEmulation->startEnvironmentEmulation(
$abandonedCart->getStoreId(),
\Magento\Framework\App\Area::AREA_FRONTEND,
true
);
$product = $this->_productRepositoryFactory->create()
->get($quoteItem->getSku());
$imageUrl = $this->imageHelperFactory->create()
->init($product, 'product_thumbnail_image')->getUrl();
$this->appEmulation->stopEnvironmentEmulation();
$quoteItemsData[] = [
"externalid" => $quoteItem->getItemId(),
"name" => $quoteItem->getName(),
"price" => $this->coreHelper->priceToCents($quoteItem->getPrice()),
"quantity" => $quoteItem->getQty(),
"sku" => $quoteItem->getSku(),
"description" => $quoteItem->getDescription(),
"imageUrl" => $imageUrl,
"productUrl" => $product->getProductUrl()
];
}
$abandonedCartData = [
"ecomOrder" => [
"externalcheckoutid" => $abandonedCart->getEntityId(),
"source" => 1,
"email" => $customerEmail,
"orderProducts" => $quoteItemsData,
"orderDiscounts" => [
"discountAmount" => $this->coreHelper->priceToCents($abandonedCart->getDiscountAmount())
],
"abandonedDate" => $abandonedCart->getCreatedAt(),
"externalCreatedDate" => $abandonedCart->getCreatedAt(),
"externalUpdatedDate" => $abandonedCart->getUpdatedAt(),
"shippingMethod" => $abandonedCart->getShippingMethod(),
"totalPrice" => $this->coreHelper->priceToCents($abandonedCart->getGrandTotal()),
"shippingAmount" => $this->coreHelper->priceToCents($abandonedCart->getShippingAmount()),
"taxAmount" => $this->coreHelper->priceToCents($abandonedCart->getTaxAmount()),
"discountAmount" => $this->coreHelper->priceToCents($abandonedCart->getDiscountAmount()),
"currency" => $abandonedCart->getGlobalCurrencyCode(),
"orderNumber" => $abandonedCart->getEntityId(),
"connectionid" => $connectionId,
"customerid" => $customerAcId
]
];
try {
if (!empty($abandonedCart->getAcOrderSyncId())) {
$abandonedCartResult = $this->curl->sendRequestAbandonedCart(
self::UPDATE_METHOD,
self::ABANDONED_CART_URL_ENDPOINT . "/" . (int)$abandonedCart->getAcOrderSyncId(),
$abandonedCartData
);
} else {
$abandonedCartResult = $this->curl->sendRequestAbandonedCart(
self::METHOD,
self::ABANDONED_CART_URL_ENDPOINT,
$abandonedCartData
);
}
if ($abandonedCartResult['success'] == 1) {
$syncStatus = CronConfig::SYNCED;
} else {
$syncStatus = CronConfig::FAIL_SYNCED;
}
$acOrderId = $abandonedCartResult['data']['ecomOrder']['id'];
$this->saveResult($abandonedCart->getEntityId(), $acOrderId, $syncStatus);
if (isset($abandonedCartResult['success'])) {
$result['success'] = __("Abandoned cart data successfully synced!!");
}
} catch (\Exception $e) {
$result['error'] = __($e->getMessage());
$this->logger->critical($e);
}
}
return $result;
}
/**
* @param $quoteId
* @return array
*/
private function getQuoteItems($quoteId)
{
$quoteItemCollection = $this->quoteItemCollectionFactory->create();
$quoteItem = $quoteItemCollection
->addFieldToSelect('*')
->addFieldToFilter('quote_id', [$quoteId]);
return $quoteItem;
}
/**
* @param $quoteId
* @param $acOrderId
* @param $syncStatus
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
private function saveResult($quoteId, $acOrderId, $syncStatus)
{
$quoteModel = $this->cartRepositoryInterface->get($quoteId);
if ($quoteModel->getEntityId()) {
$quoteModel->setAcOrderSyncId($acOrderId);
$quoteModel->setAcSyncStatus($syncStatus);
}
$quoteModel->save();
}
/**
* @param null $billingId
* @return string|null
* @throws \Magento\Framework\Exception\LocalizedException
*/
private function getTelephone($billingId = null)
{
if ($billingId) {
$address = $this->addressRepository->getById($billingId);
return $address->getTelephone();
}
return null;
}
/**
* @param $customerId
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
private function getFieldValues($customerId)
{
$fieldValues = [];
$customAttributes = $this->customerRepository->getById($customerId)->getCustomAttributes();
if (!empty($customAttributes)) {
foreach ($customAttributes as $attribute) {
$attributeId = $this->eavAttribute->getIdByCode(CustomerModel::ENTITY, $attribute->getAttributeCode());
$attributeValues['field'] = $attributeId;
$attributeValues['value'] = $attribute->getValue();
$fieldValues[] = $attributeValues;
}
}
return $fieldValues;
}
/**
* @param $customerId
* @return array
*/
private function getCustomer($customerId)
{
$customerModel = $this->customerFactory->create();
$this->customerResource->load($customerModel, $customerId);
return $customerModel;
}
/**
* @param $customerId
* @return array
*/
private function createEcomCustomer($customerId, $quote)
{
$ecomCustomerArray = [];
$ecomCustomerId = 0;
$syncStatus = CronConfig::NOT_SYNCED;
$customer = $this->getCustomer($customerId);
if ($customerId) {
$customerId = $customer->getId();
$contact['email'] = $customer->getEmail();
$customerEmail = $customer->getEmail();
$contact['firstName'] = $customer->getFirstname();
$contact['lastName'] = $customer->getLastname();
$contact['phone'] = $this->getTelephone($customer->getDefaultBilling());
$contact['fieldValues'] = $this->getFieldValues($customerId);
} else {
$customerId = 0;
$contact['email'] = $quote->getBillingAddress()->getEmail();
$customerEmail = $quote->getBillingAddress()->getEmail();
$contact['firstName'] = $quote->getBillingAddress()->getFirstname();
$contact['lastName'] = $quote->getBillingAddress()->getLastname();
$contact['phone'] = $quote->getBillingAddress()->getTelephone();
$contact['fieldValues'] = [];
}
$contactData['contact'] = $contact;
try {
$contactResult = $this->curl->createContacts(self::METHOD, self::CONTACT_ENDPOINT, $contactData);
$contactId = isset($contactResult['data']['contact']['id']) ? $contactResult['data']['contact']['id'] : null;
$connectionid = $this->coreHelper->getConnectionId($customer->getStoreId());
if (isset($contactResult['data']['contact']['id'])) {
if (!$customer->getAcCustomerId()) {
$ecomCustomer['connectionid'] = $connectionid;
$ecomCustomer['externalid'] = $customerId;
$ecomCustomer['email'] = $customerEmail;
$ecomCustomerData['ecomCustomer'] = $ecomCustomer;
$AcCustomer = $this->curl->listAllCustomers(
self::GET_METHOD,
self::ECOM_CUSTOMER_ENDPOINT,
$customerEmail
);
if (isset($AcCustomer['data']['ecomCustomers'][0])) {
foreach ($AcCustomer['data']['ecomCustomers'] as $Ac) {
if ($Ac['connectionid'] == $connectionid) {
$ecomCustomerId = $Ac['id'];
}
}
}
if (!$ecomCustomerId) {
$ecomCustomerResult = $this->curl->createContacts(
self::METHOD,
self::ECOM_CUSTOMER_ENDPOINT,
$ecomCustomerData
);
$ecomCustomerId = isset($ecomCustomerResult['data']['ecomCustomer']['id']) ? $ecomCustomerResult['data']['ecomCustomer']['id'] : null;
}
} else {
$ecomCustomerId = $customer->getAcCustomerId();
}
}
if ($ecomCustomerId != 0) {
$syncStatus = CronConfig::SYNCED;
} else {
$syncStatus = CronConfig::FAIL_SYNCED;
}
if ($customerId) {
$this->saveCustomerResult($customerId, $syncStatus, $contactId, $ecomCustomerId);
} else {
$this->saveCustomerResultQuote($quote, $ecomCustomerId);
}
} catch (\Exception $e) {
$this->logger->critical($e);
}
}
/**
* @param $customerId
* @param $syncStatus
* @param $contactId
* @param $ecomCustomerId
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
private function saveCustomerResult($customerId, $syncStatus, $contactId, $ecomCustomerId)
{
$customerModel = $this->customerFactory->create();
if ($customerId) {
$this->customerResource->load($customerModel, $customerId);
}
$customerModel->setAcSyncStatus($syncStatus);
$customerModel->setAcContactId($contactId);
$customerModel->setAcCustomerId($ecomCustomerId);
$this->customerResource->save($customerModel);
}
/**
* @param $quote
* @param $ecomCustomerId
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
private function saveCustomerResultQuote($quote, $ecomCustomerId)
{
if ($ecomCustomerId) {
$quote->setData("ac_temp_customer_id", $ecomCustomerId);
$quote->save();
}
}
}
+111
View File
@@ -0,0 +1,111 @@
<?php
namespace ActiveCampaign\AbandonedCart\Model\Config;
class CronConfig extends \Magento\Framework\App\Config\Value
{
const SYNCED = 1;
const NOT_SYNCED = 0;
const FAIL_SYNCED = 2;
/**
* Cron string path
*/
const CRON_STRING_PATH = 'crontab/default/jobs/ac_abandoned_cart_sync_cron_job/schedule/cron_expr';
/**
* Cron model path
*/
const CRON_MODEL_PATH = 'crontab/default/jobs/ac_abandoned_cart_sync_cron_job/run/model';
/**
* @var \Magento\Framework\App\Config\ValueFactory
*/
protected $_configValueFactory;
/**
* @var string
*/
protected $_runModelPath = '';
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
* @param \Magento\Framework\App\Config\ValueFactory $configValueFactory
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param string $runModelPath
* @param array $data
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Framework\App\Config\ValueFactory $configValueFactory,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
$runModelPath = '',
array $data = []
) {
$this->_runModelPath = $runModelPath;
$this->_configValueFactory = $configValueFactory;
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
}
/**
* @inheritdoc
*
* @return $this
* @throws \Exception
*/
public function afterSave()
{
$cronMinute = $this->getData('groups/abandoned_cart/fields/cron_minute/value');
$cronHour = $this->getData('groups/abandoned_cart/fields/cron_hour/value');
$cronDay = $this->getData('groups/abandoned_cart/fields/cron_day/value');
$cronMonth = $this->getData('groups/abandoned_cart/fields/cron_month/value');
$cronWeekday = $this->getData('groups/abandoned_cart/fields/cron_weekday/value');
$cronMinute = ($cronMinute == null) ? '*' : $cronMinute;
$cronHour = ($cronHour == null) ? '*' : $cronHour;
$cronDay = ($cronDay == null) ? '*' : $cronDay;
$cronMonth = ($cronMonth == null) ? '*' : $cronMonth;
$cronWeekday = ($cronWeekday == null) ? '*' : $cronWeekday;
$cronExprArray = [
$cronMinute, //Minute
$cronHour, //Hour
$cronDay, //Day of the Month
$cronMonth, //Month of the Year
$cronWeekday, //Day of the Week
];
$cronExprString = join(' ', $cronExprArray);
try {
$this->_configValueFactory->create()->load(
self::CRON_STRING_PATH,
'path'
)->setValue(
$cronExprString
)->setPath(
self::CRON_STRING_PATH
)->save();
$this->_configValueFactory->create()->load(
self::CRON_MODEL_PATH,
'path'
)->setValue(
$this->_runModelPath
)->setPath(
self::CRON_MODEL_PATH
)->save();
} catch (\Exception $e) {
throw new \Magento\Framework\Exception\LocalizedException(__('We can\'t save the cron expression.'));
}
return parent::afterSave();
}
}
@@ -0,0 +1,19 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace ActiveCampaign\AbandonedCart\Model\ResourceModel\Quote;
/**
* Quotes collection
*
* @author Magento Core Team <core@magentocommerce.com>
*/
class Collection extends \Magento\Quote\Model\ResourceModel\Quote\Collection
{
/**
* @var string
*/
protected $_idFieldName = 'entity_id';
}
@@ -0,0 +1,61 @@
<?php
namespace ActiveCampaign\AbandonedCart\Plugin\Checkout\Model;
use ActiveCampaign\AbandonedCart\Helper\Data as AbandonedCartHelper;
use ActiveCampaign\AbandonedCart\Model\AbandonedCartSendData;
class GuestPaymentInformationManagementPlugin
{
/**
* @var AbandonedCartHelper
*/
protected $abandonedCartHelper;
/**
* @var AbandonedCartSendData
*/
protected $abandonedCartSendData;
/**
* @var \Magento\Quote\Model\QuoteIdMaskFactory
*/
protected $quoteIdMaskFactory;
/**
* @param AbandonedCartHelper $abandonedCartHelper
* @param AbandonedCartSendData $abandonedCartSendData
* @param \Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory
*/
public function __construct(
AbandonedCartHelper $abandonedCartHelper,
AbandonedCartSendData $abandonedCartSendData,
\Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory
) {
$this->abandonedCartHelper = $abandonedCartHelper;
$this->abandonedCartSendData = $abandonedCartSendData;
$this->quoteIdMaskFactory = $quoteIdMaskFactory;
}
/**
* @param \Magento\Checkout\Model\ShippingInformationManagement $subject
* @param $result
* @param $cartId
* @param $email
* @param \Magento\Quote\Api\Data\PaymentInterface $paymentMethod
* @param \Magento\Quote\Api\Data\AddressInterface $billingAddress
*/
public function afterSavePaymentInformation(
\Magento\Checkout\Model\GuestPaymentInformationManagement $subject,
$result,
$cartId,
$email,
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
) {
$quoteIdMask = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id');
if ($this->abandonedCartHelper->isAbandonedCartSyncingEnabled()) {
$response = $this->abandonedCartSendData->sendAbandonedCartData($quoteIdMask->getQuoteId());
}
}
}
@@ -0,0 +1,71 @@
<?php
namespace ActiveCampaign\AbandonedCart\Plugin\Checkout\Model;
use ActiveCampaign\AbandonedCart\Helper\Data as AbandonedCartHelper;
use ActiveCampaign\AbandonedCart\Model\AbandonedCartSendData;
class PaymentInformationManagementPlugin
{
/**
* @var AbandonedCartHelper
*/
protected $abandonedCartHelper;
/**
* @var AbandonedCartSendData
*/
protected $abandonedCartSendData;
/**
* @var \Magento\Quote\Api\CartRepositoryInterface
*/
private $cartRepository;
/**
* @param AbandonedCartHelper $abandonedCartHelper
* @param AbandonedCartSendData $abandonedCartSendData
*/
public function __construct(
AbandonedCartHelper $abandonedCartHelper,
AbandonedCartSendData $abandonedCartSendData
) {
$this->abandonedCartHelper = $abandonedCartHelper;
$this->abandonedCartSendData = $abandonedCartSendData;
}
/**
* @inheritdoc
*/
public function afterSavePaymentInformation(
\Magento\Checkout\Model\PaymentInformationManagement $subject,
$result,
$cartId,
\Magento\Quote\Api\Data\PaymentInterface $paymentMethod,
\Magento\Quote\Api\Data\AddressInterface $billingAddress = null
) {
$quoteRepository = $this->getCartRepository();
/** @var \Magento\Quote\Model\Quote $quote */
$quote = $quoteRepository->getActive($cartId);
if ($this->abandonedCartHelper->isAbandonedCartSyncingEnabled()) {
$response = $this->abandonedCartSendData->sendAbandonedCartData($quote->getId());
}
}
/**
* Get Cart repository
*
* @return \Magento\Quote\Api\CartRepositoryInterface
* @deprecated 100.2.0
*/
private function getCartRepository()
{
if (!$this->cartRepository) {
$this->cartRepository = \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Quote\Api\CartRepositoryInterface::class);
}
return $this->cartRepository;
}
}
@@ -0,0 +1,25 @@
<?php
/**
* Copyright © Wagento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace ActiveCampaign\AbandonedCart\Ui\Component\Listing;
use Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult;
class AbandonedCartDataProvider extends SearchResult
{
protected function _initSelect()
{
parent::_initSelect();
$this->getSelect()
->join(
['quote_address'],
'main_table.entity_id = quote_address.quote_id',
['*']
)
->where("main_table.is_active = 1 AND quote_address.address_type = 'billing'");
return $this;
}
}
@@ -0,0 +1,42 @@
<?php
namespace ActiveCampaign\AbandonedCart\Ui\Component\Listing\Column;
use ActiveCampaign\AbandonedCart\Model\Config\CronConfig;
use Magento\Ui\Component\Listing\Columns\Column;
class AcSyncStatus extends Column
{
/**
* @inheritdoc
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as &$item) {
$item[$this->getData('name')] = $this->getFieldLabel($item);
}
}
return $dataSource;
}
/**
* Retrieve field label
*
* @param array $item
* @return string
*/
private function getFieldLabel(array $item)
{
$acSyncStatus = (int)$item['ac_sync_status'];
if ($acSyncStatus === CronConfig::SYNCED) {
return __('Synced');
} elseif ($acSyncStatus === CronConfig::NOT_SYNCED) {
return __('Not Synced');
} elseif ($acSyncStatus === CronConfig::FAIL_SYNCED) {
return __('Not Synced');
}
return __('Something Wrong');
}
}
@@ -0,0 +1,62 @@
<?php
/**
* Copyright © Wagento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace ActiveCampaign\AbandonedCart\Ui\Component\Listing\Column;
use Magento\Framework\UrlInterface;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
class Actions extends Column
{
const URL_PATH_SYNC = 'acecommerce/index/sync';
/**
* @var UrlInterface
*/
protected $urlBuilder;
/**
* @param ContextInterface $context
* @param UiComponentFactory $uiComponentFactory
* @param UrlInterface $urlBuilder
*/
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
UrlInterface $urlBuilder,
array $components = [],
array $data = []
) {
$this->urlBuilder = $urlBuilder;
parent::__construct($context, $uiComponentFactory, $components, $data);
}
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
if (isset($item['entity_id'])) {
$item[$this->getData('name')] = [
'sync' => [
'href' => $this->urlBuilder->getUrl(
static::URL_PATH_SYNC,
[
'entity_id' => $item['entity_id']
]
),
'label' => __('Sync')
]
];
}
}
}
return $dataSource;
}
}
+25
View File
@@ -0,0 +1,25 @@
{
"name": "magento/active-campaign-abandoned-cart",
"description": "N/A",
"type": "magento2-module",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"config": {
"sort-packages": true
},
"version": "104.0.2",
"require": {
"php": "~7.3.0||~7.4.0"
},
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Magento\\Catalog\\": ""
}
}
}
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Magento_Sales::sales" title="Sales" translate="title" sortOrder="20">
<resource id="ActiveCampaign_AbandonedCart::abandonedcart_operation" title="Abandoned Cart" translate="title" sortOrder="10" />
</resource>
</resource>
</resources>
</acl>
</config>
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="ActiveCampaign_AbandonedCart::abandonedcart_operation" title="Abandoned Carts" translate="title" module="ActiveCampaign_AbandonedCart" sortOrder="20" parent="ActiveCampaign_SyncLog::activecampaign" action="acecommerce/index/index" resource="ActiveCampaign_AbandonedCart::abandonedcart_operation"/>
</menu>
</config>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Wagento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="acecommerce" frontName="acecommerce">
<module name="ActiveCampaign_AbandonedCart" />
</route>
</router>
</config>
+65
View File
@@ -0,0 +1,65 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="active_campaign" translate="label" type="text" sortOrder="300" showInDefault="1" showInStore="1">
<group id="abandoned_cart" translate="label" type="text" sortOrder="20" showInDefault="1" showInStore="1">
<label>Abandoned Cart</label>
<field id="sync" translate="label" type="select" sortOrder="10" showInDefault="1">
<label>Abandoned Cart Syncing</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="cron_minute" translate="label comment" type="text" sortOrder="20" showInDefault="1">
<label>Cron Minute</label>
<comment><![CDATA[0-59 Allowed value. Set * for every minute.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
<backend_model>ActiveCampaign\AbandonedCart\Model\Config\CronConfig</backend_model>
</field>
<field id="cron_hour" translate="label comment" type="text" sortOrder="21" showInDefault="1">
<label>Cron Hour</label>
<comment><![CDATA[0-23 Allowed value. Set * for every hour.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="cron_day" translate="label comment" type="text" sortOrder="22" showInDefault="1">
<label>Cron Day</label>
<comment><![CDATA[1-31 Allowed value. Set * for every day.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="cron_month" translate="label comment" type="text" sortOrder="23" showInDefault="1">
<label>Cron Month</label>
<comment><![CDATA[1-12 Allowed value. Set * for every month.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="cron_weekday" translate="label comment" type="text" sortOrder="24" showInDefault="1">
<label>Cron Weekday</label>
<comment><![CDATA[0-6 Allowed value. Set * for every weekday.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="number_of_abandoned_cart" translate="label comment" type="text" sortOrder="30" showInDefault="1">
<label>Number of abandoned cart</label>
<validate>required-entry validate-number validate-greater-than-zero validate-integer</validate>
<comment><![CDATA[Enter here a number of abandoned cart for syncing in every X time.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="ac_abandoned_cart_syncing" translate="label comment" type="button" sortOrder="40" showInDefault="1">
<frontend_model>ActiveCampaign\AbandonedCart\Block\System\Config\SyncAbandonedCartData</frontend_model>
<label>Sync Abandoned Cart Data</label>
<depends>
<field id="active_campaign/abandoned_cart/sync">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<active_campaign>
<abandoned_cart>
<sync>0</sync>
<number_of_abandoned_cart>100</number_of_abandoned_cart>
<cron_minute>0</cron_minute>
<cron_hour>*</cron_hour>
<cron_day>*</cron_day>
<cron_month>*</cron_month>
<cron_weekday>*</cron_weekday>
</abandoned_cart>
</active_campaign>
</default>
</config>
+7
View File
@@ -0,0 +1,7 @@
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="ac_abandoned_cart_sync_cron_job" instance="ActiveCampaign\AbandonedCart\Cron\AbandonedCartSync" method="execute">
<config_path>crontab/default/jobs/ac_abandoned_cart_sync_cron_job/schedule/cron_expr</config_path>
</job>
</group>
</config>
+10
View File
@@ -0,0 +1,10 @@
<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="quote" resource="default" engine="innodb">
<column xsi:type="int" name="ac_sync_status" default="0" padding="10" unsigned="true" nullable="false"
comment="ActiveCampaign Status"/>
<column xsi:type="int" name="ac_order_sync_id" nullable="false" default="0" comment="ActiveCampaign Cart Id"/>
<column xsi:type="int" name="ac_temp_customer_id" nullable="false" default="0" comment="ActiveCampaign Customer Id"/>
</table>
</schema>
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Model\PaymentInformationManagement">
<plugin name="after_guest_payment_information" type="ActiveCampaign\AbandonedCart\Plugin\Checkout\Model\PaymentInformationManagementPlugin"/>
</type>
<type name="Magento\Checkout\Model\GuestPaymentInformationManagement">
<plugin name="after_guest_payment_information" type="ActiveCampaign\AbandonedCart\Plugin\Checkout\Model\GuestPaymentInformationManagementPlugin"/>
</type>
<preference for="Magento\Quote\Model\ResourceModel\Quote\Collection" type="ActiveCampaign\AbandonedCart\Model\ResourceModel\Quote\Collection" />
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="abandoned_cart_listing_data_source" xsi:type="string">Magento\Quote\Model\ResourceModel\Quote\Grid\Collection</item>
</argument>
</arguments>
</type>
<virtualType name="Magento\Quote\Model\ResourceModel\Quote\Grid\Collection" type="ActiveCampaign\AbandonedCart\Ui\Component\Listing\AbandonedCartDataProvider">
<arguments>
<argument name="mainTable" xsi:type="string">quote</argument>
<argument name="resourceModel" xsi:type="string">Magento\Quote\Model\ResourceModel\Quote</argument>
</arguments>
</virtualType>
</config>
@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Quote\Api\Data\CartInterface">
<attribute code="ac_temp_customer_id" type="int" />
<attribute code="ac_order_sync_id" type="int" />
<attribute code="ac_sync_status" type="int" />
</extension_attributes>
</config>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="ActiveCampaign_AbandonedCart">
<sequence>
<module name="Magento_Product"/>
<module name="Magento_Sales"/>
<module name="Magento_Customer"/>
<module name="ActiveCampaign_Core" />
</sequence>
</module>
</config>
+9
View File
@@ -0,0 +1,9 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(ComponentRegistrar::MODULE, 'ActiveCampaign_AbandonedCart', __DIR__);
@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<update handle="styles"/>
<body>
<referenceContainer name="content">
<uiComponent name="abandoned_cart_listing"/>
</referenceContainer>
</body>
</page>
@@ -0,0 +1,94 @@
<?php
/**
* Copyright © Wagento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/* @var $block \ActiveCampaign\AbandonedCart\Block\System\Config\SyncAbandonedCartData */
?>
<script>
require([
'jquery',
'prototype'
], function(jQuery){
var collectSpan = jQuery('#collect_span_field');
jQuery('#ac_sync_abandoned_cart_button').click(function () {
var params = {};
new Ajax.Request('<?= $block->escapeUrl($block->getAjaxUrl()) ?>', {
parameters: params,
asynchronous: true,
onCreate: function() {
collectSpan.find('.success-icon').hide();
collectSpan.find('.error-icon').hide();
collectSpan.find('.processing-icon').show();
collectSpan.find('.loading-mask').show();
},
onSuccess: function(response) {
var res = response.responseJSON;
collectSpan.find('.processing-icon').hide();
collectSpan.find('.loading-mask').hide();
var resultText = '';
if (res.success) {
resultText = res.success;
collectSpan.find('.success-icon').show();
} else {
resultText = res.error;
collectSpan.find('.error-icon').show();
}
jQuery('#ajax_message_field_span').text(resultText);
jQuery('#ac_sync_abandoned_cart_button').prop('disabled', false);
}
});
});
});
</script>
<?= $block->getButtonHtml() ?>
<span class="collect-indicator" id="collect_span_field">
<img class="processing-icon" hidden
alt="Processing"
src="<?= $block->escapeUrl($block->getViewFileUrl('images/process_spinner.gif')) ?>"
/>
<img class="success-icon" hidden
alt="Success"
src="<?= $block->escapeUrl($block->getViewFileUrl('images/rule_component_apply.gif')) ?>"
/>
<img class="error-icon" hidden
alt="Error"
src="<?= $block->escapeUrl($block->getViewFileUrl('images/rule_component_remove.gif')) ?>"
/>
<span id="ajax_message_field_span"></span>
</span>
<p class="note"><span>&nbsp;</span></p>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Total Abandoned Cart :")) ?>
<strong><?= $block->escapeHtml(__($block->getTotalAbandonedCart())) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Synced Abandoned Cart :")) ?>
<strong><?= $block->escapeHtml(__($block->getSyncAbandonedCart())) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Not Synced Abandoned Cart :")) ?>
<strong><?= $block->escapeHtml(__($block->getNotSyncAbandonedCart())) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Fail Synced Abandoned Cart :")) ?>
<strong><?= $block->escapeHtml(__($block->getFailedSync())) ?></strong>
</div>
</div>
</div>
@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<argument name="data" xsi:type="array">
<item name="js_config" xsi:type="array">
<item name="provider" xsi:type="string">abandoned_cart_listing.abandoned_cart_listing_data_source</item>
</item>
</argument>
<settings>
<spinner>spinner_columns</spinner>
<deps>
<dep>abandoned_cart_listing.abandoned_cart_listing_data_source</dep>
</deps>
</settings>
<dataSource name="abandoned_cart_listing_data_source" component="Magento_Ui/js/grid/provider">
<settings>
<storageConfig>
<param name="indexField" xsi:type="string">entity_id</param>
</storageConfig>
<updateUrl path="mui/index/render"/>
</settings>
<aclResource>ActiveCampaign_AbandonedCart::abandonedcart_operation</aclResource>
<dataProvider class="Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider" name="abandoned_cart_listing_data_source">
<settings>
<requestFieldName>entity_id</requestFieldName>
<primaryFieldName>entity_id</primaryFieldName>
</settings>
</dataProvider>
</dataSource>
<listingToolbar name="listing_top">
<settings>
<sticky>true</sticky>
</settings>
<bookmark name="bookmarks"/>
<columnsControls name="columns_controls"/>
<filterSearch name="fulltext"/>
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="observers" xsi:type="array">
<item name="column" xsi:type="string">column</item>
</item>
</argument>
<settings>
<templates>
<filters>
<select>
<param name="template" xsi:type="string">ui/grid/filters/elements/ui-select</param>
<param name="component" xsi:type="string">Magento_Ui/js/form/element/ui-select</param>
</select>
</filters>
</templates>
</settings>
</filters>
<massaction name="listing_massaction">
<action name="massSync">
<settings>
<url path="acecommerce/index/massSync"/>
<type>massSync</type>
<label translate="true">Sync</label>
</settings>
</action>
</massaction>
<paging name="listing_paging"/>
</listingToolbar>
<columns name="spinner_columns">
<selectionsColumn name="ids">
<settings>
<indexField>entity_id</indexField>
<resizeEnabled>false</resizeEnabled>
<resizeDefaultWidth>55</resizeDefaultWidth>
</settings>
</selectionsColumn>
<column name="entity_id">
<settings>
<filter>textRange</filter>
<label translate="true">ID</label>
<sorting>asc</sorting>
</settings>
</column>
<column name="is_active">
<settings>
<filter>text</filter>
<editor>
<editorType>text</editorType>
</editor>
<label translate="true">Is Active</label>
</settings>
</column>
<column name="items_count">
<settings>
<filter>text</filter>
<editor>
<editorType>text</editorType>
</editor>
<label translate="true">Items Count</label>
</settings>
</column>
<column name="items_qty">
<settings>
<filter>text</filter>
<editor>
<editorType>text</editorType>
</editor>
<label translate="true">Items QTY</label>
</settings>
</column>
<column name="grand_total">
<settings>
<filter>text</filter>
<editor>
<editorType>text</editorType>
</editor>
<label translate="true">Grand Total</label>
<visible>true</visible>
</settings>
</column>
<column name="customer_id">
<settings>
<filter>text</filter>
<editor>
<editorType>text</editorType>
</editor>
<label translate="true">Customer ID</label>
<visible>true</visible>
</settings>
</column>
<column name="email">
<settings>
<filter>text</filter>
<editor>
<editorType>text</editorType>
</editor>
<label translate="true">Customer Email</label>
<visible>true</visible>
</settings>
</column>
<column name="ac_sync_status" class="ActiveCampaign\AbandonedCart\Ui\Component\Listing\Column\AcSyncStatus">
<settings>
<editor>
<editorType>text</editorType>
</editor>
<label translate="true">AC Sync Status</label>
<visible>true</visible>
</settings>
</column>
<column name="ac_order_sync_id">
<settings>
<filter>text</filter>
<editor>
<editorType>text</editorType>
</editor>
<label translate="true">AC Order Sync ID</label>
<visible>true</visible>
</settings>
</column>
<column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date" component="Magento_Ui/js/grid/columns/date">
<settings>
<filter>dateRange</filter>
<dataType>date</dataType>
<label translate="true">Created</label>
</settings>
</column>
<column name="updated_at" class="Magento\Ui\Component\Listing\Columns\Date" component="Magento_Ui/js/grid/columns/date">
<settings>
<filter>dateRange</filter>
<dataType>date</dataType>
<label translate="true">Modified</label>
</settings>
</column>
<actionsColumn class="ActiveCampaign\AbandonedCart\Ui\Component\Listing\Column\Actions" name="actions">
<settings>
<indexField>entity_id</indexField>
<resizeEnabled>false</resizeEnabled>
</settings>
</actionsColumn>
</columns>
</listing>
@@ -0,0 +1,155 @@
<?php
declare(strict_types=1);
namespace ActiveCampaign\Core\Block\Adminhtml\System\Config;
use ActiveCampaign\Core\Helper\Data as ActiveCampaignHelper;
use Magento\Store\Model\ScopeInterface;
class ConnectActiveCampaign extends \Magento\Config\Block\System\Config\Form\Field
{
/**
* Set template to itself
*
* @return $this
* @since 100.1.0
*/
protected function _prepareLayout()
{
parent::_prepareLayout();
$this->setTemplate('ActiveCampaign_Core::system/config/connection.phtml');
return $this;
}
/**
* Unset some non-related element parameters
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
* @since 100.1.0
*/
public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
$element = clone $element;
$element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
return parent::render($element);
}
/**
* Get the button and scripts contents
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
* @since 100.1.0
*/
protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
$currentButton = $this->escapeHtmlAttr(__('Connect'));
$successButton = $this->escapeHtmlAttr(__('Disconnect'));
$ajaxUrl = $this->_urlBuilder->getUrl('activecampaign/system_config/connect');
$connection = true;
$isConnected = $this->isConnected();
if ($isConnected) {
$currentButton = $this->escapeHtmlAttr(__('Disconnect'));
$successButton = $this->escapeHtmlAttr(__('Connect'));
$ajaxUrl = $this->_urlBuilder->getUrl('activecampaign/system_config/disconnect');
$connection = false;
}
$this->addData(
[
'button_label' => __($currentButton),
'html_id' => $element->getHtmlId(),
'ajax_url' => $ajaxUrl,
'connection' => $connection,
'success_text' => $successButton,
'field_mapping' => str_replace('"', '\\"', json_encode($this->_getFieldMapping()))
]
);
return $this->_toHtml();
}
/**
* Returns configuration fields required to perform the ping request
*
* @return array
* @since 100.1.0
*/
protected function _getFieldMapping()
{
return [
'status' => 'active_campaign_general_status',
'api_url' => 'active_campaign_general_api_url',
'api_key' => 'active_campaign_general_api_key',
'store' => 'store_switcher'
];
}
/**
* @return array
*/
public function getConnectedStores()
{
$retuen = [];
$stores = $this->_storeManager->getStores();
foreach ($stores as $store) {
$connectionId = $this->_scopeConfig->getValue(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
ScopeInterface::SCOPE_STORES,
$store->getId()
);
$retuen[$store->getId()]['name'] = $store->getName();
$retuen[$store->getId()]['status'] = $connectionId;
}
return $retuen;
}
/**
* @return bool
*/
public function isDefaultConfig()
{
$store = $this->getRequest()->getParam('store');
return ($store) ? false : true;
}
/**
* @return bool
*/
public function isConnected()
{
$store = $this->getRequest()->getParam('store');
if ($store) {
$connectionId = $this->_scopeConfig->getValue(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
ScopeInterface::SCOPE_STORES,
$store
);
return ($connectionId) ? true : false;
} else {
$stores = $this->_storeManager->getStores();
foreach ($stores as $store) {
$connectionId = $this->_scopeConfig->getValue(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
ScopeInterface::SCOPE_STORES,
$store->getId()
);
if (!$connectionId) {
return false;
}
}
return true;
}
}
/**
* @return string
*/
public function getCacheUrl()
{
return $this->_urlBuilder->getUrl('adminhtml/cache');
}
}
@@ -0,0 +1,203 @@
<?php
namespace ActiveCampaign\Core\Controller\Adminhtml\System\Config;
use ActiveCampaign\Core\Helper\Curl;
use ActiveCampaign\Core\Helper\Data as ActiveCampaignHelper;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\Config\ConfigResource\ConfigInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Store\Api\StoreRepositoryInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
class Connect extends Action
{
const URL_ENDPOINT = "connections";
const METHOD = "POST";
const GET_METHOD = "GET";
/**
* Authorization level of a basic admin session.
*
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'ActiveCampaign_Core::config_active_campaign';
/**
* @var JsonFactory
*/
private $resultJsonFactory;
/**
* @var ConfigInterface
*/
private $configInterface;
/**
* @var StoreRepositoryInterface
*/
private $storeRepository;
/**
* @var ActiveCampaignHelper
*/
private $activeCampaignHelper;
/**
* @var StoreManagerInterface
*/
private $storeManager;
/**
* @var Curl
*/
private $curl;
/**
* Connection constructor.
* @param Context $context
* @param JsonFactory $resultJsonFactory
* @param ConfigInterface $configInterface
* @param StoreRepositoryInterface $storeRepository
* @param StoreManagerInterface $storeManager
* @param ActiveCampaignHelper $activeCampaignHelper
* @param Curl $curl
*/
public function __construct(
Context $context,
JsonFactory $resultJsonFactory,
ConfigInterface $configInterface,
StoreRepositoryInterface $storeRepository,
StoreManagerInterface $storeManager,
ActiveCampaignHelper $activeCampaignHelper,
Curl $curl
) {
parent::__construct($context);
$this->resultJsonFactory = $resultJsonFactory;
$this->configInterface = $configInterface;
$this->storeRepository = $storeRepository;
$this->storeManager = $storeManager;
$this->activeCampaignHelper = $activeCampaignHelper;
$this->curl = $curl;
}
/**
* Check for connection to server
*
* @return \Magento\Framework\Controller\Result\Json
*/
public function execute()
{
$request = $this->getRequest()->getParams();
$return = [];
if ($request['status'] && !empty($request['api_url']) && !empty($request['api_key'])) {
$isEnabled = $this->activeCampaignHelper->isEnabled($request['status']);
if (!$isEnabled) {
$this->saveConfig(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_STATUS,
$request['status'],
$request['store']
);
}
$apiUrl = $this->activeCampaignHelper->getApiUrl($request['store']);
if (empty($apiUrl)) {
$this->saveConfig(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_API_URL,
$request['api_url'],
$request['store']
);
}
$apiKey = $this->activeCampaignHelper->getApiKey($request['store']);
if (empty($apiKey)) {
$this->saveConfig(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_API_KEY,
$request['api_key'],
$request['store']
);
}
try {
if ((int)$request['store']) {
$data = $this->curlRequestData($request['store']);
$result = $this->curl->createConnection(self::METHOD, self::URL_ENDPOINT, $request, $data);
if ($result['success']) {
$connectionId = $result['data']['connection']['id'];
$this->saveConfig(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
$connectionId,
$request['store']
);
} else {
$return['success'] = false;
$return['errorMessage'] = $result['message'];
}
} elseif ($request['store'] == "0") {
$stores = $this->storeRepository->getList();
foreach ($stores as $store) {
if ($store->getId()) {
$data = $this->curlRequestData($store->getId());
$result = $this->curl->createConnection(self::METHOD, self::URL_ENDPOINT, $request, $data);
if ($result['success']) {
$return['success'] = true;
$connectionId = $result['data']['connection']['id'];
$this->saveConfig(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
$connectionId,
$store->getId()
);
} else {
$return['errorMessage'] = $result['message'];
}
}
}
}
$allConnections = $this->curl->getAllConnections(self::GET_METHOD, self::URL_ENDPOINT);
$checkConnections = $this->activeCampaignHelper->checkConnections($allConnections);
$return['success'] = $checkConnections;
} catch (\Exception $e) {
$return['success'] = false;
$return['errorMessage'] = __($e->getMessage());
}
}
$resultJson = $this->resultJsonFactory->create();
return $resultJson->setData($return);
}
/**
* @param $path
* @param $value
* @param $scopeId
*/
public function saveConfig($path, $value, $scopeId)
{
$scope = ($scopeId) ? ScopeInterface::SCOPE_STORES : ScopeConfigInterface::SCOPE_TYPE_DEFAULT;
$this->configInterface->saveConfig($path, $value, $scope, $scopeId);
}
/**
* @param $storeId
* @return array[]
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function curlRequestData($storeId)
{
$store = $this->storeManager->getStore($storeId);
return [
"connection" => [
"service" => $store->getName(),
"externalid" => $store->getCode(),
"name" => $store->getName(),
"logoUrl" => $this->activeCampaignHelper->getStoreLogo($storeId),
"linkUrl" => $store->getBaseUrl()
]
];
}
}
@@ -0,0 +1,154 @@
<?php
namespace ActiveCampaign\Core\Controller\Adminhtml\System\Config;
use ActiveCampaign\Core\Helper\Curl;
use ActiveCampaign\Core\Helper\Data as ActiveCampaignHelper;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Framework\App\Cache\Type\Config;
use Magento\Framework\App\Cache\TypeListInterface;
use Magento\Framework\App\Config\ConfigResource\ConfigInterface;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\PageCache\Model\Cache\Type;
use Magento\Store\Api\StoreRepositoryInterface;
use Magento\Store\Model\ScopeInterface;
class Disconnect extends Action
{
const URL_ENDPOINT = "connections";
const METHOD = "DELETE";
const GET_METHOD = "GET";
/**
* Authorization level of a basic admin session.
*
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'ActiveCampaign_Core::config_active_campaign';
/**
* @var JsonFactory
*/
private $resultJsonFactory;
/**
* @var TypeListInterface
*/
private $cacheTypeList;
/**
* @var ConfigInterface
*/
private $configInterface;
/**
* @var StoreRepositoryInterface
*/
private $storeRepository;
/**
* @var ActiveCampaignHelper
*/
private $activeCampaignHelper;
/**
* @var Curl
*/
private $curl;
/**
* Connection constructor.
* @param Context $context
* @param JsonFactory $resultJsonFactory
* @param TypeListInterface $cacheTypeList
* @param ConfigInterface $configInterface
* @param StoreRepositoryInterface $storeRepository
* @param ActiveCampaignHelper $activeCampaignHelper
* @param Curl $curl
*/
public function __construct(
Context $context,
JsonFactory $resultJsonFactory,
TypeListInterface $cacheTypeList,
ConfigInterface $configInterface,
StoreRepositoryInterface $storeRepository,
ActiveCampaignHelper $activeCampaignHelper,
Curl $curl
) {
parent::__construct($context);
$this->resultJsonFactory = $resultJsonFactory;
$this->cacheTypeList = $cacheTypeList;
$this->configInterface = $configInterface;
$this->storeRepository = $storeRepository;
$this->activeCampaignHelper = $activeCampaignHelper;
$this->curl = $curl;
}
/**
* Check for connection to server
*
* @return \Magento\Framework\Controller\Result\Json
*/
public function execute()
{
$request = $this->getRequest()->getParams();
$return = [];
$return['success'] = false;
if ($request['status'] && !empty($request['api_url']) && !empty($request['api_key'])) {
try {
if ((int)$request['store']) {
$connectionId = $this->activeCampaignHelper->getConnectionId($request['store']);
$urlEndpoint = self::URL_ENDPOINT . "/" . $connectionId;
$result = $this->curl->deleteConnection(self::METHOD, $urlEndpoint);
if ($result['success']) {
$this->configInterface->deleteConfig(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
ScopeInterface::SCOPE_STORES,
$request['store']
);
} else {
$return['success'] = false;
$return['errorMessage'] = $result['message'];
}
} elseif ($request['store'] == "0") {
$stores = $this->storeRepository->getList();
foreach ($stores as $store) {
if ($store->getId()) {
$connectionId = $this->activeCampaignHelper->getConnectionId($store->getId());
$urlEndpoint = self::URL_ENDPOINT . "/" . $connectionId;
$result = $this->curl->deleteConnection(self::METHOD, $urlEndpoint);
if ($result['success']) {
$this->configInterface->deleteConfig(
ActiveCampaignHelper::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
ScopeInterface::SCOPE_STORES,
$store->getId()
);
} else {
$return['success'] = false;
$return['errorMessage'] = $result['message'];
}
}
}
}
$allConnections = $this->curl->getAllConnections(self::GET_METHOD, self::URL_ENDPOINT);
$checkConnections = $this->activeCampaignHelper->checkConnections($allConnections);
$return['success'] = $checkConnections;
} catch (\Exception $e) {
$return['success'] = false;
$return['errorMessage'] = __($e->getMessage());
}
}
if ($return['success'] === true) {
$this->cacheTypeList->invalidate([
Config::TYPE_IDENTIFIER,
Type::TYPE_IDENTIFIER
]);
}
$resultJson = $this->resultJsonFactory->create();
return $resultJson->setData($return);
}
}
+331
View File
@@ -0,0 +1,331 @@
<?php
namespace ActiveCampaign\Core\Helper;
use ActiveCampaign\Core\Helper\Data as ActiveCampaignHelper;
use ActiveCampaign\Core\Logger\Logger;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\RequestOptions;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Framework\Json\Helper\Data as JsonHelper;
use ActiveCampaign\SyncLog\Model\SyncLog;
class Curl extends AbstractHelper
{
const API_VERSION = "/api/3/";
const HTTP_VERSION = "1.1";
const CONTENT_TYPE = "application/json";
/**
* @var Client|ClientInterface
*/
private $client;
/**
* @var JsonHelper
*/
private $jsonHelper;
/**
* @var Logger
*/
private $logger;
/**
* @var ActiveCampaignHelper
*/
private $activeCampaignHelper;
/**
* @var SyncLog
*/
private $syncLog;
/**
* Curl constructor.
* @param Context $context
* @param ClientInterface|null $client
* @param JsonHelper $jsonHelper
* @param Logger $logger
* @param Data $activeCampaignHelper
* @param SyncLog $syncLog
*/
public function __construct(
Context $context,
ClientInterface $client = null,
JsonHelper $jsonHelper,
Logger $logger,
ActiveCampaignHelper $activeCampaignHelper,
SyncLog $syncLog
) {
$this->client = $client ?: new Client();
$this->jsonHelper = $jsonHelper;
$this->logger = $logger;
$this->activeCampaignHelper = $activeCampaignHelper;
$this->syncLog = $syncLog;
parent::__construct($context);
}
/**
* @param $method
* @param $urlEndpoint
* @param $request
* @param array $data
* @return array
*/
public function createConnection($method, $urlEndpoint, $request, $data = [])
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiUrl = empty($apiUrl) ? $request['api_url'] : $apiUrl;
$apiKey = $this->activeCampaignHelper->getApiKey();
$apiKey = empty($apiKey) ? $request['api_key'] : $apiKey;
$url = $apiUrl . self::API_VERSION . $urlEndpoint;
$bodyData = $this->jsonHelper->jsonEncode($data);
$headers = $this->getHeaders($apiKey);
$result = $this->sendRequest($urlEndpoint, $method, $url, $headers, $bodyData);
return $result;
}
/**
* @param $method
* @param $urlEndpoint
* @param array $data
* @param $request
* @return array
*/
public function orderDataSend($method, $urlEndpoint, $data = [])
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiKey = $this->activeCampaignHelper->getApiKey();
$url = $apiUrl . self::API_VERSION . $urlEndpoint;
$bodyData = $this->jsonHelper->jsonEncode($data);
$headers = $this->getHeaders($apiKey);
$result = $this->sendRequest($urlEndpoint, $method, $url, $headers, $bodyData);
return $result;
}
/**
* @param $method
* @param $urlEndpoint
* @param array $data
* @return array
*/
public function orderDataUpdate($method, $urlEndpoint, $data = [])
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiKey = $this->activeCampaignHelper->getApiKey();
$url = $apiUrl . self::API_VERSION . $urlEndpoint;
$bodyData = $this->jsonHelper->jsonEncode($data);
$headers = $this->getHeaders($apiKey);
$result = $this->sendRequest($urlEndpoint, $method, $url, $headers, $bodyData);
return $result;
}
/**
* @param $method
* @param $urlEndpoint
* @param $orderId
* @return array
*/
public function orderDataDelete($method, $urlEndpoint, $orderId)
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiKey = $this->activeCampaignHelper->getApiKey();
$url = $apiUrl . self::API_VERSION . $urlEndpoint . $orderId;
$headers = $this->getHeaders($apiKey);
$result = $this->sendRequest($urlEndpoint, $method, $url, $headers);
return $result;
}
/**
* @param $method
* @param $urlEndpoint
* @return array
*/
public function deleteConnection($method, $urlEndpoint)
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiKey = $this->activeCampaignHelper->getApiKey();
$url = $apiUrl . self::API_VERSION . $urlEndpoint;
$headers = $this->getHeaders($apiKey);
$result = $this->sendRequest($urlEndpoint, $method, $url, $headers);
return $result;
}
public function createContacts($method, $urlEndpoint, $data = [])
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiKey = $this->activeCampaignHelper->getApiKey();
$url = $apiUrl . self::API_VERSION . $urlEndpoint;
$bodyData = $this->jsonHelper->jsonEncode($data);
$headers = $this->getHeaders($apiKey);
$result = $this->sendRequest($urlEndpoint, $method, $url, $headers, $bodyData);
return $result;
}
public function getAllConnections($method, $urlEndpoint)
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiKey = $this->activeCampaignHelper->getApiKey();
$url = $apiUrl . self::API_VERSION . $urlEndpoint;
$headers = $this->getHeaders($apiKey);
$result = $this->sendRequest($urlEndpoint, $method, $url, $headers);
return $result;
}
/**
* @param $apiKey
* @return array
*/
private function getHeaders($apiKey)
{
$headers = [];
$headers['Content-Type'] = self::CONTENT_TYPE;
$headers['Api-Token'] = $apiKey;
return $headers;
}
/**
* @param $method
* @param $url
* @param $headers
* @param $bodyData
* @return array
*/
private function sendRequest($urlEndpoint, $method, $url, $headers, $bodyData = '')
{
$result = [];
$synclog = $this->syncLog;
try {
$request = [
"METHOD"=>$method,
"URL"=>$url,
"HTTP VERSION" => self::HTTP_VERSION,
"HEADERS"=>$headers,
"BODY DATA"=>$bodyData
];
$synclog->setType($urlEndpoint);
$synclog->setEndpoint($urlEndpoint);
$synclog->setMethod($method);
$synclog->setRequest($this->jsonHelper->jsonEncode($request));
$this->logger->info("REQUEST", $request);
$options = [];
$options[RequestOptions::HEADERS] = $headers;
if ($bodyData !== null) {
$options[RequestOptions::BODY] = $bodyData;
}
$resultCurl = $this->client->request($method, $url, $options);
$body = $resultCurl->getBody()->getContents();
$response = $this->jsonHelper->jsonDecode($body);
$this->logger->info("RESPONSE", $response);
$synclog->setResponse($body);
$synclog->setStatus(1);
if (!empty($resultCurl)) {
$result['status'] = $resultCurl->getStatusCode();
if (isset($result['status']) && array_key_exists($result['status'], $this->successCodes())) {
$result['success'] = true;
$result['data'] = $response;
} elseif (isset($result['status']) && array_key_exists($result['status'], $this->failureCodes())) {
$result['success'] = false;
$result['message'] = $this->getMessage($response);
$result['data'] = $response;
} else {
$result['success'] = false;
$result['message'] = $this->getMessage($response);
}
} else {
$result['success'] = false;
$result['message'] = __('Cannot connect to active campaign server. Please try again later.');
}
} catch (\Exception $e) {
$synclog->setStatus(0);
$synclog->setErrors($e->getMessage());
$this->logger->critical($e);
$result['success'] = false;
$result['message'] = $e->getMessage();
}
$synclog->save();
$synclog->unsetData();
return $result;
}
/**
* @return string[]
*/
private function successCodes()
{
return [
200 => "OK",
201 => "Created"
];
}
/**
* @return string[]
*/
private function failureCodes()
{
return [
400 => "Bad Request",
404 => "Not Found",
422 => "Unprocessable Entity"
];
}
/**
* @param $response
* @return \Magento\Framework\Phrase
*/
private function getMessage($response)
{
if (isset($response['message'])) {
return $response['message'];
} elseif (isset($response['error']['title'])) {
return $response['error']['title'];
} elseif (isset($response['errors']['0']['title'])) {
return $response['errors']['0']['title'];
}
return __("Something was wrong Please try again later");
}
public function sendRequestAbandonedCart($method, $urlEndpoint, $data = [])
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiKey = $this->activeCampaignHelper->getApiKey();
$url = $apiUrl . self::API_VERSION . $urlEndpoint;
$bodyData = $this->jsonHelper->jsonEncode($data);
$headers = $this->getHeaders($apiKey);
$type = 'ecomAbandonedCarts';
$result = $this->sendRequest($type, $method, $url, $headers, $bodyData);
return $result;
}
public function listAllCustomers($method, $urlEndpoint, $customerEmail)
{
$apiUrl = $this->activeCampaignHelper->getApiUrl();
$apiKey = $this->activeCampaignHelper->getApiKey();
$url = $apiUrl . self::API_VERSION . $urlEndpoint . '?filters[email]=' . urlencode($customerEmail);
$headers = $this->getHeaders($apiKey);
$type = 'ecomCustomers';
$result = $this->sendRequest($type, $method, $url, $headers);
return $result;
}
}
+191
View File
@@ -0,0 +1,191 @@
<?php
namespace ActiveCampaign\Core\Helper;
use Magento\Framework\App\Config\ConfigResource\ConfigInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Api\StoreRepositoryInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Theme\Block\Html\Header\Logo;
class Data extends AbstractHelper
{
const ACTIVE_CAMPAIGN_GENERAL_STATUS = "active_campaign/general/status";
const ACTIVE_CAMPAIGN_GENERAL_API_URL = "active_campaign/general/api_url";
const ACTIVE_CAMPAIGN_GENERAL_API_KEY = "active_campaign/general/api_key";
const ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID = "active_campaign/general/connection_id";
/**
* @var StoreRepositoryInterface
*/
private $storeRepository;
/**
* @var ConfigInterface
*/
private $configInterface;
/**
* @var Logo
*/
private $logo;
/**
* Data constructor.
* @param StoreRepositoryInterface $storeRepository
* @param ConfigInterface $configInterface
* @param Context $context
* @param Logo $logo
*/
public function __construct(
StoreRepositoryInterface $storeRepository,
ConfigInterface $configInterface,
Context $context,
Logo $logo
) {
parent::__construct($context);
$this->storeRepository = $storeRepository;
$this->configInterface = $configInterface;
$this->logo = $logo;
}
/**
* @param null $scopeCode
* @return bool
*/
public function isEnabled($scopeCode = null)
{
return $this->scopeConfig->isSetFlag(
self::ACTIVE_CAMPAIGN_GENERAL_STATUS,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return mixed
*/
public function getApiUrl($scopeCode = null)
{
return $this->scopeConfig->getValue(
self::ACTIVE_CAMPAIGN_GENERAL_API_URL,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return mixed
*/
public function getApiKey($scopeCode = null)
{
return $this->scopeConfig->getValue(
self::ACTIVE_CAMPAIGN_GENERAL_API_KEY,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return mixed
*/
public function getConnectionId($scopeCode = null)
{
return $this->scopeConfig->getValue(
self::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return string
*/
public function getStoreLogo($scopeCode = null)
{
$folderName = \Magento\Config\Model\Config\Backend\Image\Logo::UPLOAD_DIR;
$storeLogoPath = $this->scopeConfig->getValue(
'design/header/logo_src',
\Magento\Store\Model\ScopeInterface::SCOPE_STORES,
$scopeCode
);
$path = $folderName . '/' . $storeLogoPath;
$logoUrl = $this->_urlBuilder->getBaseUrl(['_type' => \Magento\Framework\UrlInterface::URL_TYPE_MEDIA]) . $path;
if ($storeLogoPath !== null) {
$url = $logoUrl;
} else {
$url = $this->logo->getLogoSrc();
}
return $url;
}
/**
* Converts to cents the price amount
*
* @param float|null $price
* @return int
*/
public function priceToCents($price = 0.0)
{
return (int) round($price, 2) * 100;
}
/**
* @param $allConnections
* @return bool
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function checkConnections($allConnections)
{
if ($allConnections['success']) {
$activeConnectionIds = [];
foreach ($allConnections['data']['connections'] as $connection) {
$store = $this->storeRepository->get($connection['externalid']);
$connectionId = $this->getConnectionId($store->getId());
$activeConnectionIds[] = $connection['id'];
if ($connectionId != $connection['id']) {
$this->saveConfig(
self::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
$connection['id'],
$store->getId()
);
}
}
$stores = $this->storeRepository->getList();
foreach ($stores as $store) {
if ($store->getId()) {
$connectionId = $this->getConnectionId($store->getId());
if (($connectionId) && (!in_array($connectionId, $activeConnectionIds))) {
$this->configInterface->deleteConfig(
self::ACTIVE_CAMPAIGN_GENERAL_CONNECTION_ID,
ScopeInterface::SCOPE_STORES,
$store->getId()
);
}
}
}
return true;
}
return false;
}
/**
* @param $path
* @param $value
* @param $scopeId
*/
public function saveConfig($path, $value, $scopeId)
{
$scope = ($scopeId) ? ScopeInterface::SCOPE_STORES : ScopeConfigInterface::SCOPE_TYPE_DEFAULT;
$this->configInterface->saveConfig($path, $value, $scope, $scopeId);
}
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace ActiveCampaign\Core\Logger;
use Monolog\Logger;
class Handler extends \Magento\Framework\Logger\Handler\Base
{
/**
* Logging level
* @var int
*/
protected $loggerType = Logger::INFO;
/**
* File name
* @var string
*/
protected $fileName = '/var/log/activecampaign.log';
}
+7
View File
@@ -0,0 +1,7 @@
<?php
namespace ActiveCampaign\Core\Logger;
class Logger extends \Monolog\Logger
{
}
+20
View File
@@ -0,0 +1,20 @@
{
"name": "activecampaign/core",
"description": "ActiveCampaign Core",
"require": {
"php": "^7.1.0"
},
"type": "magento2-module",
"version": "1.0.0",
"license": [
"Commercial"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"ActiveCampaign\\Core\\": ""
}
}
}
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Magento_Backend::stores">
<resource id="Magento_Backend::stores_settings">
<resource id="Magento_Config::config">
<resource id="ActiveCampaign_Core::config_active_campaign" title="ActiveCampaign Config" translate="title" sortOrder="60" />
</resource>
</resource>
</resource>
</resource>
</resources>
</acl>
</config>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="activecampaign" frontName="activecampaign">
<module name="ActiveCampaign_Core" before="Magento_Backend" />
</route>
</router>
</config>
+38
View File
@@ -0,0 +1,38 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="active_campaign" translate="label" sortOrder="1">
<label>ActiveCampaign</label>
</tab>
<section id="active_campaign" translate="label" type="text" sortOrder="100" showInDefault="1" showInStore="1">
<class>separator-top</class>
<label>Configuration</label>
<tab>active_campaign</tab>
<resource>ActiveCampaign_Core::config_active_campaign</resource>
<group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInStore="1">
<label>General</label>
<field id="status" translate="label" type="select" sortOrder="10" showInDefault="1" showInStore="1">
<label>Status</label>
<source_model>Magento\Config\Model\Config\Source\Enabledisable</source_model>
</field>
<field id="api_url" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInStore="1">
<label>API URL</label>
<validate>required-entry validate-url validate-no-html-tags</validate>
<comment>Example: https://youraccountname.api-us1.com</comment>
</field>
<field id="api_key" translate="label" type="text" sortOrder="30" showInDefault="1" showInStore="1">
<label>API Key</label>
<validate>required-entry</validate>
</field>
<field id="connect_active_campaign" translate="button_label" sortOrder="40" showInDefault="1" showInStore="1">
<label/>
<button_label>Connect</button_label>
<frontend_model>ActiveCampaign\Core\Block\Adminhtml\System\Config\ConnectActiveCampaign</frontend_model>
<depends>
<field id="status">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="ActiveCampaign\Core\Logger\Handler">
<arguments>
<argument name="filesystem" xsi:type="object">Magento\Framework\Filesystem\Driver\File</argument>
</arguments>
</type>
<type name="ActiveCampaign\Core\Logger\Logger">
<arguments>
<argument name="name" xsi:type="string">ActiveCampaign</argument>
<argument name="handlers" xsi:type="array">
<item name="system" xsi:type="object">ActiveCampaign\Core\Logger\Handler</item>
</argument>
</arguments>
</type>
</config>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="ActiveCampaign_Core" setup_version="1.0.0"/>
</config>
+8
View File
@@ -0,0 +1,8 @@
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'ActiveCampaign_Core',
__DIR__
);
+7
View File
@@ -0,0 +1,7 @@
var config = {
map: {
'*': {
Connection: 'ActiveCampaign_Core/js/connection'
}
}
};
@@ -0,0 +1,36 @@
<?php
/** @var $block ActiveCampaign\Core\Block\Adminhtml\System\Config\ConnectActiveCampaign */
$connectedStores = $block->getConnectedStores();
?>
<button class="scalable" type="button" id="<?= $block->getHtmlId() ?>" data-mage-init='{"Connection":{
"connection": "<?= $block->escapeUrl($block->getConnection()) ?>",
"url": "<?= $block->escapeUrl($block->getAjaxUrl()) ?>",
"elementId": "<?= $block->getHtmlId() ?>",
"successText": "<?= $block->getSuccessText() ?>",
"failedText": "<?= $block->escapeHtmlAttr(__('Failed! Try again?')) ?>",
"fieldMapping": "<?= /* @noEscape */ $block->getFieldMapping() ?>"}, "validation": {}}'>
<span id="<?= $block->getHtmlId() ?>_result"><?= $block->escapeHtml($block->getButtonLabel()) ?></span>
</button>
<p class="note">
<span><?= $block->escapeHtmlAttr(__('After clicking on this button Please go to ')) ?>
<a href="<?= $block->getCacheUrl() ?>"><?= $block->escapeHtmlAttr(__('Cache Management ')) ?>
</a><?= $block->escapeHtmlAttr(__('and refresh cache types.')) ?>
</span>
</p>
<p class="note"><span>&nbsp;</span></p>
<?php if ($block->isDefaultConfig()): ?>
<?php foreach ($connectedStores as $key => $store): ?>
<div class="messages">
<div class="message message-notice">
<div>
<?= $block->escapeHtml(__($store['name'] . " :")) ?>
<?php if ($store['status']): ?>
<strong><?= $block->escapeHtml(__("Connected")) ?></strong>
<?php else: ?>
<strong class="colorRed"><?= $block->escapeHtml(__("Disconnected")) ?></strong>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
+114
View File
@@ -0,0 +1,114 @@
/**
* @api
*/
define([
'jquery',
'Magento_Ui/js/modal/alert',
'Magento_Ui/js/modal/confirm',
'jquery/ui'
], function ($, alert, confirmation) {
'use strict';
$.widget('mage.Connection', {
options: {
url: '',
elementId: '',
successText: '',
failedText: '',
fieldMapping: '',
txt:''
},
/**
* Bind handlers to events
*/
_create: function () {
this._on({
'click': $.proxy(this._connect, this)
});
},
/**
* Prepare AJAX request
* @private
*/
_connect: function () {
var result = this.options.failedText,
element = $('#' + this.options.elementId),
self = this,
params = {},
msg = '',
fieldToCheck = this.options.fieldToCheck || 'success';
element.removeClass('success').addClass('fail');
$.each($.parseJSON(this.options.fieldMapping), function (key, el) {
params[key] = $('#' + el).val();
});
if(params.store === "0"){
var content = $.mage.__('Do you want to connect all stores ?');
if(!self.options.connection){
content = $.mage.__('Do you want to disconnect all stores ?');
}
confirmation({
title: $.mage.__('Are you sure ?'),
content: content,
actions: {
confirm: function() {
self._connectAjax(self,params);
}
},
buttons: [{
text: $.mage.__('No'),
class: 'action-secondary action-dismiss',
click: function (event) {
this.closeModal(event);
}
}, {
text: $.mage.__('Yes'),
class: 'action-primary action-accept',
click: function (event) {
this.closeModal(event, true);
}
}]
});
}else{
self._connectAjax(self,params);
}
},
/**
* AJAX request to connection
* @private
*/
_connectAjax: function (self,params){
var result = self.options.failedText,
element = $('#' + self.options.elementId),
msg = '',
fieldToCheck = self.options.fieldToCheck || 'success';
$.ajax({
url: self.options.url,
showLoader: true,
data: params,
headers: self.options.headers || {}
}).done(function (response) {
if (response[fieldToCheck]) {
element.removeClass('fail').addClass('success');
result = self.options.successText;
} else {
msg = response.errorMessage;
if (msg) {
alert({
content: msg
});
}
}
}).always(function () {
$('#' + self.options.elementId + '_result').text(result);
});
}
});
return $.mage.Connection;
});
@@ -0,0 +1,79 @@
<?php
namespace ActiveCampaign\Customer\Block\Adminhtml\System\Config;
use ActiveCampaign\Customer\Model\Config\CronConfig;
use Magento\Backend\Block\Template\Context;
use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory as CustomerFactory;
class CustomerSyncStatus extends \Magento\Backend\Block\Template
{
const AC_SYNC_STATUS = "ac_sync_status";
/**
* @var string
*/
protected $_template = 'ActiveCampaign_Customer::system/config/customer_sync_status.phtml';
/**
* @var CustomerFactory
*/
protected $customerFactory;
/**
* @var int
*/
public $totalCustomer = 0;
/**
* @var int
*/
public $syncedCustomer = 0;
/**
* @var int
*/
public $notSyncedCustomer = 0;
/**
* @var int
*/
public $failSyncedCustomer = 0;
/**
*
* @param Context $context
* @param array $data
*/
public function __construct(
Context $context,
CustomerFactory $customerFactory,
array $data = []
) {
$this->customerFactory = $customerFactory;
parent::__construct($context, $data);
$this->setSyncStatusData();
}
/**
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function setSyncStatusData()
{
$customersData = $this->customerFactory->create()
->addAttributeToFilter([
['attribute' => self::AC_SYNC_STATUS,'null' => true ],
['attribute' => self::AC_SYNC_STATUS,'eq' => CronConfig::SYNCED ],
['attribute' => self::AC_SYNC_STATUS,'eq' => CronConfig::NOT_SYNCED ],
['attribute' => self::AC_SYNC_STATUS,'eq' => CronConfig::FAIL_SYNCED ]
])->getData();
$this->totalCustomer = count($customersData);
$this->syncedCustomer = count(array_keys(array_column($customersData, self::AC_SYNC_STATUS), CronConfig::SYNCED));
$this->notSyncedCustomer = count(array_keys(array_column($customersData, self::AC_SYNC_STATUS), CronConfig::NOT_SYNCED));
$this->failSyncedCustomer = count(array_keys(array_column($customersData, self::AC_SYNC_STATUS), CronConfig::FAIL_SYNCED));
return $this;
}
}
@@ -0,0 +1,27 @@
<?php
namespace ActiveCampaign\Customer\Block\Adminhtml\System\Config;
class Widget extends \Magento\Config\Block\System\Config\Form\Fieldset
{
/**
* {@inheritdoc}
*/
protected function _prepareLayout()
{
$this->addChild('customer_sync_status', CustomerSyncStatus::class);
return parent::_prepareLayout();
}
/**
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
*
* @return string
*/
public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
return $this->getChildHtml('customer_sync_status');
}
}
@@ -0,0 +1,121 @@
<?php
namespace ActiveCampaign\Customer\Controller\Adminhtml\Customer;
use ActiveCampaign\Core\Helper\Curl;
use ActiveCampaign\Customer\Model\Config\CronConfig;
use ActiveCampaign\Customer\Model\Customer;
use Magento\Backend\App\Action\Context;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Controller\Adminhtml\Index\AbstractMassAction;
use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Ui\Component\MassAction\Filter;
use Psr\Log\LoggerInterface;
class MassSync extends AbstractMassAction implements HttpPostActionInterface
{
const CONTACT_ENDPOINT = "contact/sync";
const METHOD = "POST";
const ECOM_CUSTOMER_ENDPOINT = "ecomCustomers";
/**
* @var CustomerRepositoryInterface
*/
protected $customerRepository;
/**
* @var Customer
*/
private $customer;
/**
* @var Curl
*/
protected $curl;
/**
* MassSync constructor.
* @param Context $context
* @param Filter $filter
* @param CollectionFactory $collectionFactory
* @param Customer $customer
* @param Curl $curl
* @param LoggerInterface $logger
* @param CustomerRepositoryInterface $customerRepository
*/
public function __construct(
Context $context,
Filter $filter,
CollectionFactory $collectionFactory,
Customer $customer,
Curl $curl,
LoggerInterface $logger,
CustomerRepositoryInterface $customerRepository
) {
parent::__construct($context, $filter, $collectionFactory);
$this->customer = $customer;
$this->curl = $curl;
$this->logger = $logger;
$this->customerRepository = $customerRepository;
}
/**
* @param AbstractCollection $collection
* @return \Magento\Backend\Model\View\Result\Redirect
*/
public function massAction(AbstractCollection $collection)
{
$customersSynced = 0;
$contactId = 0;
$ecomCustomerId = 0;
$syncStatus = CronConfig::NOT_SYNCED;
foreach ($collection->getAllIds() as $customerId) {
if (!empty($customerId)) {
try {
$contactData = $this->customer->getContactData($customerId);
$isEcomCustomer = $contactData['contact']['isEcomCustomer'];
unset($contactData['contact']['isEcomCustomer']);
$contactResult = $this->curl->createContacts(
self::METHOD,
self::CONTACT_ENDPOINT,
$contactData
);
$contactId = isset($contactResult['data']['contact']['id']) ? $contactResult['data']['contact']['id'] : null;
$syncStatus = ($contactResult['success']) ? CronConfig::SYNCED : CronConfig::FAIL_SYNCED;
if ($contactResult['success'] && !$isEcomCustomer) {
$ecomCustomerData = $this->customer->getEcomCustomerData($customerId);
$ecomCustomerResult = $this->curl->createContacts(
self::METHOD,
self::ECOM_CUSTOMER_ENDPOINT,
$ecomCustomerData
);
$ecomCustomerId = isset($ecomCustomerResult['data']['ecomCustomer']['id']) ? $ecomCustomerResult['data']['ecomCustomer']['id'] : null;
}
$this->customer->saveResult($customerId, $syncStatus, $contactId, $ecomCustomerId);
} catch (\Exception $exception) {
$this->logger->critical($exception);
}
}
$customersSynced++;
}
if ($customersSynced) {
$this->messageManager->addSuccessMessage(__('A total of %1 record(s) were synced in the ActiveCampaign.', $customersSynced));
}
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
$resultRedirect->setPath('customer/index');
return $resultRedirect;
}
}
+225
View File
@@ -0,0 +1,225 @@
<?php
namespace ActiveCampaign\Customer\Cron;
use ActiveCampaign\Core\Helper\Curl;
use ActiveCampaign\Customer\Helper\Data as CustomerHelper;
use ActiveCampaign\Core\Helper\Data as CoreHelper;
use ActiveCampaign\Customer\Model\Config\CronConfig;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\Customer;
use Magento\Customer\Model\CustomerFactory;
use Magento\Customer\Model\ResourceModel\Customer as CustomerResource;
use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory as CustomerResourceCollectionFactory;
use Magento\Eav\Model\ResourceModel\Entity\Attribute;
use Psr\Log\LoggerInterface;
class CustomerSync
{
const AC_SYNC_STATUS = "ac_sync_status";
const CONTACT_ENDPOINT = "contacts";
const ECOM_CUSTOMER_ENDPOINT = "ecomCustomers";
const METHOD = "POST";
/**
* @var CustomerRepositoryInterface
*/
protected $customerRepository;
/**
* @var AddressRepositoryInterface
*/
protected $addressRepository;
/**
* @var CustomerResourceCollectionFactory
*/
protected $customerResourceCollectionFactory;
/**
* @var CustomerFactory
*/
protected $customerFactory;
/**
* @var CustomerResource
*/
protected $customerResource;
/**
* @var Attribute
*/
protected $eavAttribute;
/**
* @var CustomerHelper
*/
protected $customerHelper;
/**
* @var CoreHelper
*/
private $coreHelper;
/**
* @var Curl
*/
protected $curl;
/**
* @var LoggerInterface
*/
protected $logger;
/**
* CustomerSync constructor.
* @param CustomerRepositoryInterface $customerRepository
* @param AddressRepositoryInterface $addressRepository
* @param CustomerResourceCollectionFactory $customerResourceCollectionFactory
* @param CustomerFactory $customerFactory
* @param CustomerResource $customerResource
* @param Attribute $eavAttribute
* @param CustomerHelper $customerHelper
* @param CoreHelper $coreHelper
* @param Curl $curl
* @param LoggerInterface $logger
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
AddressRepositoryInterface $addressRepository,
CustomerResourceCollectionFactory $customerResourceCollectionFactory,
CustomerFactory $customerFactory,
CustomerResource $customerResource,
Attribute $eavAttribute,
CustomerHelper $customerHelper,
CoreHelper $coreHelper,
Curl $curl,
LoggerInterface $logger
) {
$this->customerRepository = $customerRepository;
$this->addressRepository = $addressRepository;
$this->customerResourceCollectionFactory = $customerResourceCollectionFactory;
$this->customerFactory = $customerFactory;
$this->customerResource = $customerResource;
$this->eavAttribute = $eavAttribute;
$this->customerHelper = $customerHelper;
$this->coreHelper = $coreHelper;
$this->curl = $curl;
$this->logger = $logger;
}
public function execute()
{
if ($this->customerHelper->isCustomerSyncingEnabled()) {
$contact = [];
$ecomCustomer = [];
$numberOfCustomers = (int)$this->customerHelper->getNumberOfCustomers();
$customers = $this->customerResourceCollectionFactory->create()
->addAttributeToFilter([
['attribute' => self::AC_SYNC_STATUS,'null' => true ],
['attribute' => self::AC_SYNC_STATUS,'neq' => CronConfig::SYNCED ]
])
->setPageSize($numberOfCustomers);
foreach ($customers as $customer) {
$contactId = 0;
$ecomCustomerId = 0;
$syncStatus = CronConfig::NOT_SYNCED;
$customerId = $customer->getId();
$contact['email'] = $customer->getEmail();
$contact['firstName'] = $customer->getFirstname();
$contact['lastName'] = $customer->getLastname();
$contact['phone'] = $this->getTelephone($customer->getDefaultBilling());
$contact['fieldValues'] = $this->getFieldValues($customerId);
$contactData['contact'] = $contact;
try {
$contactResult = $this->curl->createContacts(self::METHOD, self::CONTACT_ENDPOINT, $contactData);
$contactId = isset($contactResult['data']['contact']['id']) ? $contactResult['data']['contact']['id'] : null;
if ($contactResult['success']) {
$ecomCustomer['connectionid'] = $this->coreHelper->getConnectionId($customer->getStoreId());
$ecomCustomer['externalid'] = $customerId;
$ecomCustomer['email'] = $customer->getEmail();
$ecomCustomerData['ecomCustomer'] = $ecomCustomer;
$ecomCustomerResult = $this->curl->createContacts(
self::METHOD,
self::ECOM_CUSTOMER_ENDPOINT,
$ecomCustomerData
);
$ecomCustomerId = isset($ecomCustomerResult['data']['ecomCustomer']['id']) ? $ecomCustomerResult['data']['ecomCustomer']['id'] : null;
$syncStatus = CronConfig::SYNCED;
} else {
$syncStatus = CronConfig::FAIL_SYNCED;
}
$this->saveResult($customerId, $syncStatus, $contactId, $ecomCustomerId);
} catch (\Exception $e) {
$this->logger->critical($e);
}
}
}
}
/**
* @param $customerId
* @param $syncStatus
* @param $contactId
* @param $ecomCustomerId
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
private function saveResult($customerId, $syncStatus, $contactId, $ecomCustomerId)
{
$customerModel = $this->customerFactory->create();
if ($customerId) {
$this->customerResource->load($customerModel, $customerId);
}
$customerModel->setAcSyncStatus($syncStatus);
$customerModel->setAcContactId($contactId);
$customerModel->setAcCustomerId($ecomCustomerId);
$this->customerResource->save($customerModel);
}
/**
* @param null $billingId
* @return string|null
* @throws \Magento\Framework\Exception\LocalizedException
*/
private function getTelephone($billingId = null)
{
if ($billingId) {
$address = $this->addressRepository->getById($billingId);
return $address->getTelephone();
}
return null;
}
/**
* @param $customerId
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
private function getFieldValues($customerId)
{
$fieldValues = [];
$customAttributes = $this->customerRepository->getById($customerId)->getCustomAttributes();
if (!empty($customAttributes)) {
foreach ($customAttributes as $attribute) {
$attributeId = $this->eavAttribute->getIdByCode(Customer::ENTITY, $attribute->getAttributeCode());
$attributeValues['field'] = $attributeId;
$attributeValues['value'] = $attribute->getValue();
$fieldValues[] = $attributeValues;
}
}
return $fieldValues;
}
}
+62
View File
@@ -0,0 +1,62 @@
<?php
namespace ActiveCampaign\Customer\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\ScopeInterface;
use ActiveCampaign\Customer\Model\Config\CronConfig;
class Data extends AbstractHelper
{
const ACTIVE_CAMPAIGN_CUSTOMER_SYNC = "active_campaign/customer/sync";
const ACTIVE_CAMPAIGN_CUSTOMER_NUMBER_OF_CUSTOMERS = "active_campaign/customer/number_of_customers";
/**
* Data constructor.
* @param Context $context
*/
public function __construct(
Context $context
) {
parent::__construct($context);
}
/**
* @param null $scopeCode
* @return bool
*/
public function isCustomerSyncingEnabled($scopeCode = null)
{
return $this->scopeConfig->isSetFlag(
self::ACTIVE_CAMPAIGN_CUSTOMER_SYNC,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return mixed
*/
public function getCronTime($scopeCode = null)
{
return $this->scopeConfig->getValue(
CronConfig::CRON_MODEL_PATH,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return mixed
*/
public function getNumberOfCustomers($scopeCode = null)
{
return $this->scopeConfig->getValue(
self::ACTIVE_CAMPAIGN_CUSTOMER_NUMBER_OF_CUSTOMERS,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
}
+111
View File
@@ -0,0 +1,111 @@
<?php
namespace ActiveCampaign\Customer\Model\Config;
class CronConfig extends \Magento\Framework\App\Config\Value
{
const SYNCED = 1;
const NOT_SYNCED = 0;
const FAIL_SYNCED = 2;
/**
* Cron string path
*/
const CRON_STRING_PATH = 'crontab/default/jobs/ac_customer_sync_cron_job/schedule/cron_expr';
/**
* Cron model path
*/
const CRON_MODEL_PATH = 'crontab/default/jobs/ac_customer_sync_cron_job/run/model';
/**
* @var \Magento\Framework\App\Config\ValueFactory
*/
protected $_configValueFactory;
/**
* @var string
*/
protected $_runModelPath = '';
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
* @param \Magento\Framework\App\Config\ValueFactory $configValueFactory
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param string $runModelPath
* @param array $data
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Framework\App\Config\ValueFactory $configValueFactory,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
$runModelPath = '',
array $data = []
) {
$this->_runModelPath = $runModelPath;
$this->_configValueFactory = $configValueFactory;
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
}
/**
* @inheritdoc
*
* @return $this
* @throws \Exception
*/
public function afterSave()
{
$cronMinute = $this->getData('groups/customer/fields/cron_minute/value');
$cronHour = $this->getData('groups/customer/fields/cron_hour/value');
$cronDay = $this->getData('groups/customer/fields/cron_day/value');
$cronMonth = $this->getData('groups/customer/fields/cron_month/value');
$cronWeekday = $this->getData('groups/customer/fields/cron_weekday/value');
$cronMinute = ($cronMinute == null) ? '*' : $cronMinute;
$cronHour = ($cronHour == null) ? '*' : $cronHour;
$cronDay = ($cronDay == null) ? '*' : $cronDay;
$cronMonth = ($cronMonth == null) ? '*' : $cronMonth;
$cronWeekday = ($cronWeekday == null) ? '*' : $cronWeekday;
$cronExprArray = [
$cronMinute, //Minute
$cronHour, //Hour
$cronDay, //Day of the Month
$cronMonth, //Month of the Year
$cronWeekday, //Day of the Week
];
$cronExprString = join(' ', $cronExprArray);
try {
$this->_configValueFactory->create()->load(
self::CRON_STRING_PATH,
'path'
)->setValue(
$cronExprString
)->setPath(
self::CRON_STRING_PATH
)->save();
$this->_configValueFactory->create()->load(
self::CRON_MODEL_PATH,
'path'
)->setValue(
$this->_runModelPath
)->setPath(
self::CRON_MODEL_PATH
)->save();
} catch (\Exception $e) {
throw new \Exception(__('We can\'t save the cron expression.'));
}
return parent::afterSave();
}
}
+179
View File
@@ -0,0 +1,179 @@
<?php
namespace ActiveCampaign\Customer\Model;
use ActiveCampaign\Core\Helper\Data as CoreHelper;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Model\CustomerFactory;
use Magento\Customer\Model\ResourceModel\Customer as CustomerResource;
use Magento\Eav\Model\ResourceModel\Entity\Attribute;
class Customer
{
const AC_CUSTOMER_ID = 'ac_customer_id';
/**
* @var bool
*/
private $isEcomCustomer = false;
/**
* @var CustomerRepositoryInterface
*/
protected $customerRepository;
/**
* @var AddressRepositoryInterface
*/
protected $addressRepository;
/**
* @var Attribute
*/
protected $eavAttribute;
/**
* @var CoreHelper
*/
private $coreHelper;
/**
* @var CustomerFactory
*/
protected $customerFactory;
/**
* @var CustomerResource
*/
protected $customerResource;
/**
* Customer constructor.
* @param CustomerRepositoryInterface $customerRepository
* @param AddressRepositoryInterface $addressRepository
* @param Attribute $eavAttribute
* @param CoreHelper $coreHelper
* @param CustomerFactory $customerFactory
* @param CustomerResource $customerResource
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
AddressRepositoryInterface $addressRepository,
Attribute $eavAttribute,
CoreHelper $coreHelper,
CustomerFactory $customerFactory,
CustomerResource $customerResource
) {
$this->customerRepository = $customerRepository;
$this->addressRepository = $addressRepository;
$this->eavAttribute = $eavAttribute;
$this->coreHelper = $coreHelper;
$this->customerFactory = $customerFactory;
$this->customerResource = $customerResource;
}
/**
* @param $customerId
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getContactData($customerId)
{
$contact = [];
$customer = $this->customerRepository->getById($customerId);
$contact['email'] = $customer->getEmail();
$contact['firstName'] = $customer->getFirstname();
$contact['lastName'] = $customer->getLastname();
$contact['phone'] = $this->getTelephone($customer->getDefaultBilling());
$contact['fieldValues'] = $this->getFieldValues($customer->getCustomAttributes());
$contact['isEcomCustomer'] = $this->isEcomCustomer;
$contactData['contact'] = $contact;
return $contactData;
}
/**
* @param $customerId
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function getEcomCustomerData($customerId)
{
$ecomCustomer = [];
$customer = $this->customerRepository->getById($customerId);
$ecomCustomer['connectionid'] = $this->coreHelper->getConnectionId($customer->getStoreId());
$ecomCustomer['externalid'] = $customer->getId();
$ecomCustomer['email'] = $customer->getEmail();
$ecomCustomerData['ecomCustomer'] = $ecomCustomer;
return $ecomCustomerData;
}
/**
* @param null $billingId
* @return string|null
* @throws \Magento\Framework\Exception\LocalizedException
*/
private function getTelephone($billingId = null)
{
if ($billingId) {
$address = $this->addressRepository->getById($billingId);
return $address->getTelephone();
}
return null;
}
/**
* @param $customAttributes
* @return array
*/
private function getFieldValues($customAttributes)
{
$fieldValues = [];
if (!empty($customAttributes)) {
foreach ($customAttributes as $attribute) {
$attributeId = $this->eavAttribute->getIdByCode(
\Magento\Customer\Model\Customer::ENTITY,
$attribute->getAttributeCode()
);
if ($attribute->getAttributeCode() === self::AC_CUSTOMER_ID) {
$this->isEcomCustomer = ($attribute->getValue()) ? true : false;
}
$attributeValues['field'] = $attributeId;
$attributeValues['value'] = $attribute->getValue();
$fieldValues[] = $attributeValues;
}
}
return $fieldValues;
}
/**
* @param $customerId
* @param $syncStatus
* @param $contactId
* @param $ecomCustomerId
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
public function saveResult($customerId, $syncStatus, $contactId, $ecomCustomerId)
{
$customerModel = $this->customerFactory->create();
if ($customerId) {
$this->customerResource->load($customerModel, $customerId);
}
$customerModel->setAcSyncStatus($syncStatus);
if ($contactId) {
$customerModel->setAcContactId($contactId);
}
if ($ecomCustomerId) {
$customerModel->setAcCustomerId($ecomCustomerId);
}
$this->customerResource->save($customerModel);
}
}
+92
View File
@@ -0,0 +1,92 @@
<?php
namespace ActiveCampaign\Customer\Observer;
use ActiveCampaign\Core\Helper\Curl;
use ActiveCampaign\Customer\Model\Config\CronConfig;
use ActiveCampaign\Customer\Model\Customer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Psr\Log\LoggerInterface;
class CustomerSaveAfter implements ObserverInterface
{
const CONTACT_ENDPOINT = "contact/sync";
const METHOD = "POST";
const ECOM_CUSTOMER_ENDPOINT = "ecomCustomers";
/**
* @var Customer
*/
private $customer;
/**
* @var Curl
*/
protected $curl;
/**
* CustomerSaveAfter constructor.
* @param Customer $customer
* @param Curl $curl
* @param LoggerInterface $logger
*/
public function __construct(
Customer $customer,
Curl $curl,
LoggerInterface $logger
) {
$this->customer = $customer;
$this->curl = $curl;
$this->logger = $logger;
}
/**
* Upgrade order customer email when customer has changed email
*
* @param Observer $observer
* @return void
*/
public function execute(Observer $observer): void
{
/** @var Customer $originalCustomer */
$originalCustomer = $observer->getEvent()->getOrigCustomerDataObject();
if (!$originalCustomer) {
return;
}
/** @var Customer $customer */
$customer = $observer->getEvent()->getCustomerDataObject();
$contactId = 0;
$ecomCustomerId = 0;
$syncStatus = CronConfig::NOT_SYNCED;
$customerId = $customer->getId();
try {
$contactData = $this->customer->getContactData($customerId);
$isEcomCustomer = $contactData['contact']['isEcomCustomer'];
unset($contactData['contact']['isEcomCustomer']);
$contactResult = $this->curl->createContacts(self::METHOD, self::CONTACT_ENDPOINT, $contactData);
$contactId = isset($contactResult['data']['contact']['id']) ? $contactResult['data']['contact']['id'] : null;
$syncStatus = ($contactResult['success']) ? CronConfig::SYNCED : CronConfig::FAIL_SYNCED;
if ($contactResult['success'] && !$isEcomCustomer) {
$ecomCustomerData = $this->customer->getEcomCustomerData($customerId);
$ecomCustomerResult = $this->curl->createContacts(
self::METHOD,
self::ECOM_CUSTOMER_ENDPOINT,
$ecomCustomerData
);
$ecomCustomerId = isset($ecomCustomerResult['data']['ecomCustomer']['id']) ? $ecomCustomerResult['data']['ecomCustomer']['id'] : null;
}
$this->customer->saveResult($customerId, $syncStatus, $contactId, $ecomCustomerId);
} catch (\Exception $e) {
$this->logger->critical($e);
}
}
}
@@ -0,0 +1,120 @@
<?php
namespace ActiveCampaign\Customer\Setup\Patch\Data;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Model\Entity\Attribute\Set;
use Magento\Eav\Model\Entity\Attribute\SetFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
class AddCustomerAttributeAcContactId implements DataPatchInterface, PatchRevertableInterface
{
/**
* @var ModuleDataSetupInterface
*/
protected $moduleDataSetup;
/**
* @var CustomerSetup
*/
protected $customerSetupFactory;
/**
* @var SetFactory
*/
protected $attributeSetFactory;
/**
* Constructor
*
* @param ModuleDataSetupInterface $moduleDataSetup
* @param CustomerSetupFactory $customerSetupFactory
* @param SetFactory $attributeSetFactory
*/
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
CustomerSetupFactory $customerSetupFactory,
SetFactory $attributeSetFactory
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->customerSetupFactory = $customerSetupFactory;
$this->attributeSetFactory = $attributeSetFactory;
}
/**
* {@inheritdoc}
*/
public function apply()
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
$customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
$attributeSetId = $customerEntity->getDefaultAttributeSetId();
/** @var $attributeSet Set */
$attributeSet = $this->attributeSetFactory->create();
$attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
if (!$customerSetup->getAttributeId(Customer::ENTITY, 'ac_contact_id')) {
$customerSetup->addAttribute(
Customer::ENTITY,
'ac_contact_id',
[
'type' => 'int',
'input' => 'hidden',
'label' => 'ActiveCampaign Contact Id',
'default' => 0,
'required' => false,
'visible' => false,
'system' => false,
'user_defined' => false,
'is_visible_in_grid' => true,
'is_used_in_grid' => true,
'is_filterable_in_grid' => true,
'is_searchable_in_grid' => true,
'position' => 999
]
);
$attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'ac_contact_id');
$attribute->addData([
'attribute_set_id' => $attributeSetId,
'attribute_group_id' => $attributeGroupId
]);
$attribute->save();
}
$this->moduleDataSetup->getConnection()->endSetup();
}
public function revert()
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
$customerSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY, 'ac_contact_id');
$this->moduleDataSetup->getConnection()->endSetup();
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
return [];
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
return [
];
}
}
@@ -0,0 +1,120 @@
<?php
namespace ActiveCampaign\Customer\Setup\Patch\Data;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Model\Entity\Attribute\Set;
use Magento\Eav\Model\Entity\Attribute\SetFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
class AddCustomerAttributeAcCustomerId implements DataPatchInterface, PatchRevertableInterface
{
/**
* @var ModuleDataSetupInterface
*/
protected $moduleDataSetup;
/**
* @var CustomerSetup
*/
protected $customerSetupFactory;
/**
* @var SetFactory
*/
protected $attributeSetFactory;
/**
* Constructor
*
* @param ModuleDataSetupInterface $moduleDataSetup
* @param CustomerSetupFactory $customerSetupFactory
* @param SetFactory $attributeSetFactory
*/
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
CustomerSetupFactory $customerSetupFactory,
SetFactory $attributeSetFactory
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->customerSetupFactory = $customerSetupFactory;
$this->attributeSetFactory = $attributeSetFactory;
}
/**
* {@inheritdoc}
*/
public function apply()
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
$customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
$attributeSetId = $customerEntity->getDefaultAttributeSetId();
/** @var $attributeSet Set */
$attributeSet = $this->attributeSetFactory->create();
$attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
if (!$customerSetup->getAttributeId(Customer::ENTITY, 'ac_customer_id')) {
$customerSetup->addAttribute(
Customer::ENTITY,
'ac_customer_id',
[
'type' => 'int',
'input' => 'hidden',
'label' => 'ActiveCampaign Customer Id',
'default' => 0,
'required' => false,
'visible' => false,
'system' => false,
'user_defined' => false,
'is_visible_in_grid' => true,
'is_used_in_grid' => true,
'is_filterable_in_grid' => true,
'is_searchable_in_grid' => true,
'position' => 999
]
);
$attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'ac_customer_id');
$attribute->addData([
'attribute_set_id' => $attributeSetId,
'attribute_group_id' => $attributeGroupId
]);
$attribute->save();
}
$this->moduleDataSetup->getConnection()->endSetup();
}
public function revert()
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
$customerSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY, 'ac_customer_id');
$this->moduleDataSetup->getConnection()->endSetup();
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
return [];
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
return [
];
}
}
@@ -0,0 +1,120 @@
<?php
namespace ActiveCampaign\Customer\Setup\Patch\Data;
use Magento\Customer\Model\Customer;
use Magento\Customer\Setup\CustomerSetup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Eav\Model\Entity\Attribute\Set;
use Magento\Eav\Model\Entity\Attribute\SetFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\PatchRevertableInterface;
class AddCustomerAttributeAcSyncStatus implements DataPatchInterface, PatchRevertableInterface
{
/**
* @var ModuleDataSetupInterface
*/
protected $moduleDataSetup;
/**
* @var CustomerSetup
*/
protected $customerSetupFactory;
/**
* @var SetFactory
*/
protected $attributeSetFactory;
/**
* Constructor
*
* @param ModuleDataSetupInterface $moduleDataSetup
* @param CustomerSetupFactory $customerSetupFactory
* @param SetFactory $attributeSetFactory
*/
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
CustomerSetupFactory $customerSetupFactory,
SetFactory $attributeSetFactory
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->customerSetupFactory = $customerSetupFactory;
$this->attributeSetFactory = $attributeSetFactory;
}
/**
* {@inheritdoc}
*/
public function apply()
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
$customerEntity = $customerSetup->getEavConfig()->getEntityType(Customer::ENTITY);
$attributeSetId = $customerEntity->getDefaultAttributeSetId();
/** @var $attributeSet Set */
$attributeSet = $this->attributeSetFactory->create();
$attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
if (!$customerSetup->getAttributeId(Customer::ENTITY, 'ac_sync_status')) {
$customerSetup->addAttribute(
Customer::ENTITY,
'ac_sync_status',
[
'type' => 'int',
'input' => 'hidden',
'label' => 'ActiveCampaign Status',
'default' => 0,
'required' => false,
'visible' => false,
'system' => false,
'user_defined' => false,
'is_visible_in_grid' => true,
'is_used_in_grid' => true,
'is_filterable_in_grid' => true,
'is_searchable_in_grid' => true,
'position' => 998
]
);
$attribute = $customerSetup->getEavConfig()->getAttribute(Customer::ENTITY, 'ac_sync_status');
$attribute->addData([
'attribute_set_id' => $attributeSetId,
'attribute_group_id' => $attributeGroupId
]);
$attribute->save();
}
$this->moduleDataSetup->getConnection()->endSetup();
}
public function revert()
{
$this->moduleDataSetup->getConnection()->startSetup();
/** @var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
$customerSetup->removeAttribute(\Magento\Customer\Model\Customer::ENTITY, 'ac_sync_status');
$this->moduleDataSetup->getConnection()->endSetup();
}
/**
* {@inheritdoc}
*/
public function getAliases()
{
return [];
}
/**
* {@inheritdoc}
*/
public static function getDependencies()
{
return [
];
}
}
@@ -0,0 +1,42 @@
<?php
namespace ActiveCampaign\Customer\Ui\Component\Listing\Column;
use ActiveCampaign\Customer\Model\Config\CronConfig;
use Magento\Ui\Component\Listing\Columns\Column;
class AcSyncStatus extends Column
{
/**
* @inheritdoc
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as &$item) {
$item[$this->getData('name')] = $this->getFieldLabel($item);
}
}
return $dataSource;
}
/**
* Retrieve field label
*
* @param array $item
* @return string
*/
private function getFieldLabel(array $item)
{
$acSyncStatus = (int)$item['ac_sync_status'];
if ($acSyncStatus === CronConfig::SYNCED) {
return __('Synced');
} elseif ($acSyncStatus === CronConfig::NOT_SYNCED) {
return __('Not Synced');
} elseif ($acSyncStatus === CronConfig::FAIL_SYNCED) {
return __('Not Synced');
}
return __('Something Wrong');
}
}
+21
View File
@@ -0,0 +1,21 @@
{
"name": "activecampaign/customer",
"description": "ActiveCampaign Customer",
"require": {
"php": "^7.1.0",
"amasty/base": ">=1.0.0"
},
"type": "magento2-module",
"version": "1.0.0",
"license": [
"Commercial"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"ActiveCampaign\\Customer\\": ""
}
}
}
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="activecampaign_customer" frontName="activecampaign_customer">
<module name="ActiveCampaign_Customer" before="Magento_Backend" />
</route>
</router>
</config>
+66
View File
@@ -0,0 +1,66 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="active_campaign" translate="label" type="text" sortOrder="100" showInDefault="1" showInStore="1">
<group id="customer" translate="label" type="text" sortOrder="20" showInDefault="1" showInStore="1">
<label>Customer</label>
<field id="sync" translate="label" type="select" sortOrder="10" showInDefault="1">
<label>Customer Syncing</label>
<comment><![CDATA[Choosing yes will start syncing your all existing customer.]]></comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="cron_minute" translate="label comment" type="text" sortOrder="20" showInDefault="1">
<label>Cron Minute</label>
<comment><![CDATA[0-59 Allowed value. Set * for every minute.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
<backend_model>ActiveCampaign\Customer\Model\Config\CronConfig</backend_model>
</field>
<field id="cron_hour" translate="label comment" type="text" sortOrder="21" showInDefault="1">
<label>Cron Hour</label>
<comment><![CDATA[0-23 Allowed value. Set * for every hour.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="cron_day" translate="label comment" type="text" sortOrder="22" showInDefault="1">
<label>Cron Day</label>
<comment><![CDATA[1-31 Allowed value. Set * for every day.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="cron_month" translate="label comment" type="text" sortOrder="23" showInDefault="1">
<label>Cron Month</label>
<comment><![CDATA[1-12 Allowed value. Set * for every month.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="cron_weekday" translate="label comment" type="text" sortOrder="24" showInDefault="1">
<label>Cron Weekday</label>
<comment><![CDATA[0-6 Allowed value. Set * for every weekday.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="number_of_customers" translate="label comment" type="text" sortOrder="30" showInDefault="1">
<label>Number of customers</label>
<validate>required-entry validate-number validate-greater-than-zero validate-integer</validate>
<comment><![CDATA[Enter here a number of customer for syncing in every X time.]]></comment>
<depends>
<field id="sync">1</field>
</depends>
</field>
<field id="customer_sync_status" translate="label" sortOrder="40" showInDefault="1" >
<label>Number of customers test</label>
<frontend_model>ActiveCampaign\Customer\Block\Adminhtml\System\Config\Widget</frontend_model>
<depends>
<field id="sync">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<active_campaign>
<customer>
<sync>0</sync>
<number_of_customers>100</number_of_customers>
<cron_minute>10</cron_minute>
<cron_hour>*</cron_hour>
<cron_day>*</cron_day>
<cron_month>*</cron_month>
<cron_weekday>*</cron_weekday>
</customer>
</active_campaign>
</default>
</config>
+7
View File
@@ -0,0 +1,7 @@
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="ac_customer_sync_cron_job" instance="ActiveCampaign\Customer\Cron\CustomerSync" method="execute">
<config_path>crontab/default/jobs/ac_customer_sync_cron_job/schedule/cron_expr</config_path>
</job>
</group>
</config>
+5
View File
@@ -0,0 +1,5 @@
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="customer_save_after_data_object">
<observer name="activecampaign_customer" instance="ActiveCampaign\Customer\Observer\CustomerSaveAfter" />
</event>
</config>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="ActiveCampaign_Customer" setup_version="1.0.0">
<sequence>
<module name="ActiveCampaign_Core"/>
</sequence>
</module>
</config>
+8
View File
@@ -0,0 +1,8 @@
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'ActiveCampaign_Customer',
__DIR__
);
@@ -0,0 +1,49 @@
<?php
use ActiveCampaign\Customer\Block\Adminhtml\System\Config\CustomerSyncStatus;
/**
* @var CustomerSyncStatus $block
*/
?>
<table cellspacing="0" class="form-list">
<tbody>
<tr>
<td class="label"></td>
<td class="value">
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Total Customer :")) ?>
<strong><?= $block->escapeHtml(__($block->totalCustomer)) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Synced Customer :")) ?>
<strong><?= $block->escapeHtml(__($block->syncedCustomer)) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Not Synced Customer :")) ?>
<strong><?= $block->escapeHtml(__($block->notSyncedCustomer)) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Fail Synced Customer :")) ?>
<strong><?= $block->escapeHtml(__($block->failSyncedCustomer)) ?></strong>
</div>
</div>
</div>
</td>
<td class></td>
</tr>
</tbody>
</table>
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<listingToolbar name="listing_top">
<massaction name="listing_massaction" component="Magento_Ui/js/grid/tree-massactions">
<action name="ac_sync">
<settings>
<confirm>
<message translate="true">Are you sure you want to sync the selected customers in the ActiveCampaign?</message>
<title translate="true">Sync</title>
</confirm>
<url path="activecampaign_customer/Customer/MassSync"/>
<type>sync</type>
<label translate="true">Sync to ActiveCampaign</label>
</settings>
</action>
</massaction>
</listingToolbar>
<columns name="customer_columns" class="Magento\Customer\Ui\Component\Listing\Columns">
<column name="ac_sync_status" class="ActiveCampaign\Customer\Ui\Component\Listing\Column\AcSyncStatus" sortOrder="300">
<settings>
<dataType>select</dataType>
<label translate="true">ActiveCampaign Sync Status</label>
<visible>true</visible>
</settings>
</column>
</columns>
</listing>
@@ -0,0 +1,111 @@
<?php
namespace ActiveCampaign\Order\Block\Adminhtml\System\Config;
use ActiveCampaign\Order\Model\Config\CronConfig;
use Magento\Backend\Block\Template\Context;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
class OrderSyncStatus extends \Magento\Backend\Block\Template
{
const AC_SYNC_STATUS = "ac_order_sync_status";
/**
* @var string
*/
protected $_template = 'ActiveCampaign_Order::system/config/order_sync_status.phtml';
/**
* @var OrderFactory|CollectionFactory
*/
protected $orderFactory;
/**
* OrderSyncStatus constructor.
* @param Context $context
* @param OrderFactory $orderFactory
* @param array $data
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function __construct(
Context $context,
CollectionFactory $orderFactory,
array $data = []
) {
$this->orderFactory = $orderFactory;
parent::__construct($context, $data);
$this->setSyncStatusData();
}
/**
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getOrderCollection()
{
$collection = $this->orderFactory->create()->addAttributeToSelect('*');
return $collection;
}
/**
* @return int|void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getSyncOrder()
{
$sync = $this->getOrderCollection()->addFieldToFilter(
self::AC_SYNC_STATUS,
[
['eq' => CronConfig::SYNCED],
]
);
return count($sync);
}
/**
* @return int|void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getTotalOrder()
{
$total = $this->getOrderCollection()->addFieldToFilter(
self::AC_SYNC_STATUS,
[
['eq' => CronConfig::SYNCED],
['eq' => CronConfig::NOT_SYNCED],
['eq' => CronConfig::FAIL_SYNCED],
]
);
return count($total);
}
/**
* @return int|void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getNotSyncOrder()
{
$notSync = $this->getOrderCollection()->addFieldToFilter(
self::AC_SYNC_STATUS,
[
['eq' => CronConfig::NOT_SYNCED],
]
)->getData();
return count($notSync);
}
/**
* @return int|void
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function getFailedSync()
{
$failSync = $this->getOrderCollection()->addFieldToFilter(
self::AC_SYNC_STATUS,
[
['eq' => CronConfig::FAIL_SYNCED],
]
);
return count($failSync);
}
}
@@ -0,0 +1,26 @@
<?php
namespace ActiveCampaign\Order\Block\Adminhtml\System\Config;
class Widget extends \Magento\Config\Block\System\Config\Form\Fieldset
{
/**
* @return Widget
*/
protected function _prepareLayout()
{
$this->addChild('order_sync_status', OrderSyncStatus::class);
return parent::_prepareLayout();
}
/**
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
*/
public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
return $this->getChildHtml('order_sync_status');
}
}
@@ -0,0 +1,101 @@
<?php
namespace ActiveCampaign\Order\Controller\Adminhtml\Order;
use ActiveCampaign\Order\Model\OrderData\OrderDataSend;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Magento\Sales\Api\OrderManagementInterface;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
use Magento\Ui\Component\MassAction\Filter;
use Magento\Quote\Api\CartRepositoryInterface;
use ActiveCampaign\Core\Helper\Curl;
class Masssync extends \Magento\Sales\Controller\Adminhtml\Order\AbstractMassAction
{
public const DELETE_METHOD = "DELETE";
public const URL_ENDPOINT = "ecomOrders/";
/**
* @var OrderDataSend
*/
protected $orderdataSend;
/**
* @var OrderManagementInterface
*/
protected $orderManagement;
/**
* @var CartRepositoryInterface
*/
protected $quoteRepository;
/**
* @var Curl
*/
protected $curl;
/**
* MassSync constructor.
* @param Context $context
* @param Filter $filter
* @param OrderDataSend $orderdataSend
* @param CollectionFactory $collectionFactory
* @param OrderManagementInterface $orderManagement
*/
public function __construct(
Context $context,
Filter $filter,
OrderDataSend $orderdataSend,
CollectionFactory $collectionFactory,
OrderManagementInterface $orderManagement,
Curl $curl,
CartRepositoryInterface $quoteRepository
) {
parent::__construct($context, $filter);
$this->orderdataSend = $orderdataSend;
$this->collectionFactory = $collectionFactory;
$this->orderManagement = $orderManagement;
$this->curl = $curl;
$this->quoteRepository = $quoteRepository;
}
protected function massAction(AbstractCollection $collection)
{
$countUpdateOrder = 0;
$countAlreadySync = 0;
foreach ($collection->getItems() as $order) {
if (!$order->getEntityId()) {
continue;
}
$ac_order_sync_status = $order->getData('ac_order_sync_status');
if (!$ac_order_sync_status) {
$result = $this->orderdataSend->orderDataSend($order);
if (array_key_exists('success', $result) && $result['success'] != false) {
$countUpdateOrder++;
}
$quote = $this->quoteRepository->get($order->getQuoteId());
if ($quote->getAcOrderSyncId() != 0) {
$this->curl->orderDataDelete(self::DELETE_METHOD, self::URL_ENDPOINT, $quote->getAcOrderSyncId());
}
} else {
$countAlreadySync++;
}
}
$countNonUpdateOrder = $collection->count() - $countUpdateOrder - $countAlreadySync;
if ($countUpdateOrder || $countNonUpdateOrder) {
$this->messageManager->addNoticeMessage(__(
'Orders synced: %1 Orders failed: %2',
$countUpdateOrder,
$countNonUpdateOrder
));
}
if ($countAlreadySync) {
$this->messageManager->addNoticeMessage(__('%1 order(s) had already been synced.', $countAlreadySync));
}
$resultRedirect = $this->resultRedirectFactory->create();
$resultRedirect->setPath($this->getComponentRefererUrl());
return $resultRedirect;
}
}
+100
View File
@@ -0,0 +1,100 @@
<?php
namespace ActiveCampaign\Order\Cron;
use ActiveCampaign\Order\Helper\Data as ActiveCampaignOrderHelper;
use ActiveCampaign\Order\Model\OrderData\OrderDataSend;
use Magento\Sales\Model\ResourceModel\Order\CollectionFactory;
use Magento\Framework\App\State;
use Magento\Quote\Api\CartRepositoryInterface;
use ActiveCampaign\Core\Helper\Curl;
class OrderSyncCron
{
const DELETE_METHOD = "DELETE";
const URL_ENDPOINT = "ecomOrders/";
/**
* @var ActiveCampaignOrderHelper
*/
private $activeCampaignHelper;
/**
* @var OrderDataSend
*/
protected $orderdataSend;
/**
* @var CollectionFactory
*/
protected $_orderCollectionFactory;
/**
* @var State
*/
private $state;
/**
* @var CartRepositoryInterface
*/
protected $quoteRepository;
/**
* @var Curl
*/
protected $curl;
/**
* OrderSyncCron constructor.
* @param OrderDataSend $orderdataSend
* @param CollectionFactory $orderCollectionFactory
* @param ActiveCampaignOrderHelper $activeCampaignHelper
* @param State $state
* @param Curl $curl
*/
public function __construct(
OrderDataSend $orderdataSend,
CollectionFactory $orderCollectionFactory,
ActiveCampaignOrderHelper $activeCampaignHelper,
State $state,
Curl $curl,
CartRepositoryInterface $quoteRepository
) {
$this->orderdataSend = $orderdataSend;
$this->_orderCollectionFactory = $orderCollectionFactory;
$this->activeCampaignHelper = $activeCampaignHelper;
$this->state = $state;
$this->curl = $curl;
$this->quoteRepository = $quoteRepository;
}
/**
* @return $this
*/
public function execute()
{
$isEnabled = $this->activeCampaignHelper->isOrderSyncEnabled();
if ($isEnabled) {
$OrderSyncNum = $this->activeCampaignHelper->getOrderSyncNum();
$orderCollection = $collection = $this->_orderCollectionFactory->create()
->addAttributeToSelect('*')
->addAttributeToSelect('*')
->addFilter(
'ac_order_sync_status',
'0',
'eq'
)
->setPageSize($OrderSyncNum);
foreach ($orderCollection as $order) {
$this->orderdataSend->orderDataSend($order);
$quote = $this->quoteRepository->get($order->getQuoteId());
if ($quote->getAcOrderSyncId() != 0) {
$this->curl->orderDataDelete(self::DELETE_METHOD, self::URL_ENDPOINT, $quote->getAcOrderSyncId());
}
}
return $this;
} else {
return $this;
}
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php
namespace ActiveCampaign\Order\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Magento\Store\Model\ScopeInterface;
class Data extends AbstractHelper
{
const ACTIVE_CAMPAIGN_ORDER_STATUS = "active_campaign/order_sync/order_sync_enable";
const ACTIVE_CAMPAIGN_ORDER_SYNC_NUM = "active_campaign/order_sync/order_sync_num";
/**
* @var \Magento\Framework\App\State *
*/
private $state;
/**
* Data constructor.
* @param Context $context
*/
public function __construct(
Context $context,
\Magento\Framework\App\State $state
) {
parent::__construct($context);
$this->state = $state;
}
/**
* @param null $scopeCode
* @return bool
*/
public function isOrderSyncEnabled($scopeCode = null)
{
return $this->scopeConfig->isSetFlag(
self::ACTIVE_CAMPAIGN_ORDER_STATUS,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
/**
* @param null $scopeCode
* @return mixed
*/
public function getOrderSyncNum($scopeCode = null)
{
return $this->scopeConfig->getValue(
self::ACTIVE_CAMPAIGN_ORDER_SYNC_NUM,
ScopeInterface::SCOPE_STORES,
$scopeCode
);
}
}
+111
View File
@@ -0,0 +1,111 @@
<?php
namespace ActiveCampaign\Order\Model\Config;
use function PHPUnit\Framework\isNull;
class CronConfig extends \Magento\Framework\App\Config\Value
{
const SYNCED = 1;
const NOT_SYNCED = 0;
const FAIL_SYNCED = 2;
/**
* Cron string path
*/
const CRON_STRING_PATH = 'crontab/default/jobs/ac_order_sync_cron_job/schedule/cron_expr';
/**
* Cron model path
*/
const CRON_MODEL_PATH = 'crontab/default/jobs/ac_order_sync_cron_job/run/model';
/**
* @var \Magento\Framework\App\Config\ValueFactory
*/
protected $_configValueFactory;
/**
* @var string
*/
protected $_runModelPath = '';
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\App\Config\ScopeConfigInterface $config
* @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypeList
* @param \Magento\Framework\App\Config\ValueFactory $configValueFactory
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param string $runModelPath
* @param array $data
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
\Magento\Framework\App\Cache\TypeListInterface $cacheTypeList,
\Magento\Framework\App\Config\ValueFactory $configValueFactory,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
$runModelPath = '',
array $data = []
) {
$this->_runModelPath = $runModelPath;
$this->_configValueFactory = $configValueFactory;
parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
}
/**
* {@inheritdoc}
*
* @return $this
* @throws \Exception
*/
public function afterSave()
{
$cronMinute = $this->getData('groups/order_sync/fields/cron_minute/value');
$cronHour = $this->getData('groups/order_sync/fields/cron_hour/value');
$cronDay = $this->getData('groups/order_sync/fields/cron_day/value');
$cronMonth = $this->getData('groups/order_sync/fields/cron_month/value');
$cronWeekday = $this->getData('groups/order_sync/fields/cron_weekday/value');
$cronMinute = ($cronMinute == null) ? '*' : $cronMinute;
$cronHour = ($cronHour == null) ? '*' : $cronHour;
$cronDay = ($cronDay == null) ? '*' : $cronDay;
$cronMonth = ($cronMonth == null) ? '*' : $cronMonth;
$cronWeekday = ($cronWeekday == null) ? '*' : $cronWeekday;
$cronExprArray = [
$cronMinute, //Minute
$cronHour, //Hour
$cronDay, //Day of the Month
$cronMonth, //Month of the Year
$cronWeekday, //Day of the Week
];
$cronExprString = join(' ', $cronExprArray);
try {
$this->_configValueFactory->create()->load(
self::CRON_STRING_PATH,
'path'
)->setValue(
$cronExprString
)->setPath(
self::CRON_STRING_PATH
)->save();
$this->_configValueFactory->create()->load(
self::CRON_MODEL_PATH,
'path'
)->setValue(
$this->_runModelPath
)->setPath(
self::CRON_MODEL_PATH
)->save();
} catch (\Exception $e) {
throw new \Exception(__('We can\'t save the cron expression.'));
}
return parent::afterSave();
}
}
+468
View File
@@ -0,0 +1,468 @@
<?php
namespace ActiveCampaign\Order\Model\OrderData;
use ActiveCampaign\Core\Helper\Curl;
use ActiveCampaign\Core\Helper\Data as ActiveCampaignHelper;
use ActiveCampaign\Order\Helper\Data as ActiveCampaignOrderHelper;
use Magento\Catalog\Api\ProductRepositoryInterfaceFactory;
use Magento\Catalog\Helper\ImageFactory;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\App\Config\ConfigResource\ConfigInterface;
use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Store\Api\StoreRepositoryInterface;
use Magento\Customer\Model\CustomerFactory;
use Magento\Store\Model\StoreManagerInterface as StoreManagerInterface;
use Magento\Customer\Model\Customer as CustomerModel;
use Magento\Customer\Api\AddressRepositoryInterface;
use Magento\Eav\Model\ResourceModel\Entity\Attribute;
use ActiveCampaign\Core\Helper\Data as CoreHelper;
use Magento\Customer\Model\ResourceModel\Customer as CustomerResource;
use ActiveCampaign\AbandonedCart\Model\Config\CronConfig;
class OrderDataSend extends \Magento\Framework\Model\AbstractModel
{
const URL_ENDPOINT = "ecomOrders";
const METHOD = "POST";
const UPDATE_METHOD = "PUT";
const GET_METHOD = "GET";
const AC_SYNC_STATUS = "ac_sync_status";
const CONTACT_ENDPOINT = "contact/sync";
const ECOM_CUSTOMER_ENDPOINT = "ecomOrders";
const ECOM_CUSTOMERLIST_ENDPOINT = "ecomCustomers";
/**
* @var ActiveCampaignOrderHelper
*/
private $activeCampaignOrderHelper;
/**
* @var ActiveCampaignHelper
*/
private $activeCampaignHelper;
/**
* @var ConfigInterface
*/
private $configInterface;
/**
* @var StoreRepositoryInterface
*/
private $storeRepository;
/**
* @var Curl
*/
protected $curl;
/**
* @var \Magento\Catalog\Api\ProductRepositoryInterfaceFactory
*/
protected $_productRepositoryFactory;
/**
* @var \Magento\Customer\Api\CustomerRepositoryInterface
*/
protected $_customerRepositoryInterface;
/**
* @var \Magento\Catalog\Helper\ImageFactory
*/
protected $imageHelperFactory;
/**
* @var CustomerFactory
*/
protected $customerFactory;
/**
* @var StoreManagerInterface
*/
protected $storeManager;
/**
* @var AddressRepositoryInterface
*/
protected $addressRepository;
/**
* @var Attribute
*/
protected $eavAttribute;
/**
* @var CustomerResource
*/
protected $customerResource;
/**
* OrderDataSend constructor.
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
* @param \Magento\Sales\Model\ResourceModel\Order\CollectionFactory $orderCollectionFactory
* @param \Magento\Catalog\Api\ProductRepositoryInterfaceFactory $productRepositoryFactory
* @param \Magento\Catalog\Helper\ImageFactory $imageHelperFactory
* @param ActiveCampaignOrderHelper $activeCampaignOrderHelper
* @param ActiveCampaignHelper $activeCampaignHelper
* @param ConfigInterface $configInterface
* @param Curl $curl
* @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface
* @param StoreRepositoryInterface $storeRepository
* @param CustomerFactory $customerFactory
* @param StoreManagerInterface $storeManager
* @param CustomerModel $customerModel
* @param AddressRepositoryInterface $addressRepository
* @param Attribute $eavAttribute
* @param CoreHelper $coreHelper
* @param CustomerResource $customerResource
* @param array $data
*/
public function __construct(
Context $context,
\Magento\Framework\Registry $registry,
AbstractResource $resource = null,
AbstractDb $resourceCollection = null,
ProductRepositoryInterfaceFactory $productRepositoryFactory,
ImageFactory $imageHelperFactory,
ActiveCampaignOrderHelper $activeCampaignOrderHelper,
ActiveCampaignHelper $activeCampaignHelper,
ConfigInterface $configInterface,
Curl $curl,
CustomerRepositoryInterface $customerRepositoryInterface,
StoreRepositoryInterface $storeRepository,
CustomerFactory $customerFactory,
StoreManagerInterface $storeManager,
CustomerModel $customerModel,
AddressRepositoryInterface $addressRepository,
Attribute $eavAttribute,
CoreHelper $coreHelper,
CustomerResource $customerResource,
array $data = []
) {
$this->_productRepositoryFactory = $productRepositoryFactory;
$this->imageHelperFactory = $imageHelperFactory;
$this->activeCampaignOrderHelper = $activeCampaignOrderHelper;
$this->activeCampaignHelper = $activeCampaignHelper;
$this->configInterface = $configInterface;
$this->curl = $curl;
$this->_customerRepositoryInterface = $customerRepositoryInterface;
$this->storeRepository = $storeRepository;
$this->customerFactory = $customerFactory;
$this->storeManager = $storeManager;
$this->customerModel = $customerModel;
$this->addressRepository = $addressRepository;
$this->eavAttribute = $eavAttribute;
$this->coreHelper = $coreHelper;
$this->customerResource = $customerResource;
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
}
/**
* @param $OrderSyncNum
* @return array
*/
public function orderDataSend($order)
{
$return = [];
$acOrderId = 0;
$isEnabled = $this->activeCampaignOrderHelper->isOrderSyncEnabled();
if ($isEnabled) {
try {
$connectionId = $this->activeCampaignHelper->getConnectionId($order->getStoreId());
$customerId = $order->getCustomerId();
$customerAcId = 0;
if ($customerId) {
$this->createEcomCustomer($order->getCustomerId(), $order);
$customerEmail = $order->getCustomerEmail();
$customerModel = $this->customerFactory->create();
$this->customerResource->load($customerModel, $customerId);
if ($customerModel->getAcCustomerId()) {
$customerAcId = $customerModel->getAcCustomerId();
}
} else {
$customerEmail = $order->getBillingAddress()->getEmail();
$websiteId = $this->storeManager->getWebsite()->getWebsiteId();
$customerModel = $this->customerModel;
$customerModel->setWebsiteId($websiteId);
$customerModel->loadByEmail($customerEmail);
if ($customerModel->getId()) {
$customerId = $customerModel->getId();
} else {
$customerId = 0;
}
$this->createEcomCustomer($customerId, $order);
$customerModel = $this->customerFactory->create();
$this->customerResource->load($customerModel, $customerId);
if ($customerModel->getAcCustomerId()) {
$customerAcId = $customerModel->getAcCustomerId();
} else {
if ($order->getAcTempCustomerId()) {
$customerAcId = $order->getAcTempCustomerId();
} else {
$AcCustomer = $this->curl->listAllCustomers(
self::GET_METHOD,
self::ECOM_CUSTOMER_ENDPOINT,
$customerEmail
);
foreach ($AcCustomer['data']['ecomCustomers'] as $Ac) {
if ($Ac['connectionid'] == $connectionId) {
$customerAcId = $Ac['id'];
}
}
}
}
}
foreach ($order->getAllVisibleItems() as $item) {
$product = $this->_productRepositoryFactory->create()
->get($item->getSku());
$imageUrl = $this->imageHelperFactory->create()
->init($product, 'product_thumbnail_image')->getUrl();
$items[] = [
"externalid" => $item->getProductId(),
"name" => $item->getName(),
"price" => $this->activeCampaignHelper->priceToCents($item->getPrice()),
"quantity" => $item->getQtyOrdered(),
"category" => implode(', ', $product->getCategoryIds()),
"sku" => $item->getSku(),
"description" => $item->getDescription(),
"imageUrl" => $imageUrl,
"productUrl" => $product->getProductUrl()
];
}
$data = [
"ecomOrder" => [
"externalid" => $order->getId(),
"source" => 1,
"email" => $customerEmail,
"orderProducts" => $items,
"orderDiscounts" => [
"discountAmount" => $this->activeCampaignHelper->priceToCents($order->getDiscountAmount())
],
"externalCreatedDate" => $order->getCreatedAt(),
"externalUpdatedDate" => $order->getUpdatedAt(),
"shippingMethod" => $order->getShippingMethod(),
"totalPrice" => $this->activeCampaignHelper->priceToCents($order->getGrandTotal()),
"shippingAmount" => $this->activeCampaignHelper->priceToCents($order->getShippingAmount()),
"taxAmount" => $this->activeCampaignHelper->priceToCents($order->getTaxAmount()),
"discountAmount" => $this->activeCampaignHelper->priceToCents($order->getDiscountAmount()),
"currency" => $order->getOrderCurrencyCode(),
"orderNumber" => $order->getIncrementId(),
"connectionid" => $connectionId,
"customerid" => $customerAcId
]
];
if (!$order->getAcOrderSyncId()) {
$result = $this->curl->orderDataSend(
self::METHOD,
self::URL_ENDPOINT,
$data
);
if ($result['status'] == '422' || $result['status'] == '400') {
$ecomAlreadyExistOrderData = [];
$ecomAlreadyExistOrderResult = $this->curl->createContacts(
self::GET_METHOD,
self::URL_ENDPOINT,
$ecomAlreadyExistOrderData
);
$ecomOrders = $ecomAlreadyExistOrderResult['data']['ecomOrders'];
foreach ($ecomOrders as $ecomKey => $customers) {
$ecomOrderArray[$ecomOrders[$ecomKey]['email']] = $ecomOrders[$ecomKey]['id'];
}
$acOrderId = $ecomOrderArray[$customerEmail];
} else {
$acOrderId = isset($result['data']['ecomOrders']['id']) ? $result['data']['ecomOrders']['id'] : null;
}
} else {
$acOrderId = $order->getAcOrderSyncId();
}
if ($acOrderId != 0) {
$syncStatus = CronConfig::SYNCED;
} else {
$syncStatus = CronConfig::FAIL_SYNCED;
}
$order->setData("ac_order_sync_status", $syncStatus)
->setData("ac_order_sync_id", $acOrderId)
->save();
if (isset($result['success'])) {
$return['success'] = __("Order data successfully synced!!");
}
} catch (\Exception $e) {
$return['success'] = false;
$return['errorMessage'] = __($e->getMessage());
}
}
return $return;
}
/**
* @param null $billingId
* @return string|null
* @throws \Magento\Framework\Exception\LocalizedException
*/
private function getTelephone($billingId = null)
{
if ($billingId) {
$address = $this->addressRepository->getById($billingId);
return $address->getTelephone();
}
return null;
}
/**
* @param $customerId
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
private function getFieldValues($customerId)
{
$fieldValues = [];
$customAttributes = $this->_customerRepositoryInterface->getById($customerId);
$customAttributes->getCustomAttributes();
if (!empty($customAttributes)) {
foreach ($customAttributes as $attribute) {
$attributeId = $this->eavAttribute->getIdByCode(CustomerModel::ENTITY, $attribute->getAttributeCode());
$attributeValues['field'] = $attributeId;
$attributeValues['value'] = $attribute->getValue();
$fieldValues[] = $attributeValues;
}
}
return $fieldValues;
}
/**
* @param $customerId
* @return array
*/
private function getCustomer($customerId)
{
$customerModel = $this->customerFactory->create();
$this->customerResource->load($customerModel, $customerId);
return $customerModel;
}
/**
* @param $customerId
* @return array
*/
private function createEcomCustomer($customerId, $quote)
{
$ecomOrderArray = [];
$ecomCustomerId = 0;
$syncStatus = CronConfig::NOT_SYNCED;
$customer = $this->getCustomer($customerId);
if ($customerId) {
$customerId = $customer->getId();
$contact['email'] = $customer->getEmail();
$customerEmail = $customer->getEmail();
$contact['firstName'] = $customer->getFirstname();
$contact['lastName'] = $customer->getLastname();
$contact['phone'] = $this->getTelephone($customer->getDefaultBilling());
$contact['fieldValues'] = $this->getFieldValues($customerId);
} else {
$customerId = 0;
$contact['email'] = $quote->getBillingAddress()->getEmail();
$customerEmail = $quote->getBillingAddress()->getEmail();
$contact['firstName'] = $quote->getBillingAddress()->getFirstname();
$contact['lastName'] = $quote->getBillingAddress()->getLastname();
$contact['phone'] = $quote->getBillingAddress()->getTelephone();
$contact['fieldValues'] = [];
}
$contactData['contact'] = $contact;
try {
$contactResult = $this->curl->createContacts(self::METHOD, self::CONTACT_ENDPOINT, $contactData);
$contactId = isset($contactResult['data']['contact']['id']) ? $contactResult['data']['contact']['id'] : null;
$connectionid = $this->coreHelper->getConnectionId($customer->getStoreId());
if (isset($contactResult['data']['contact']['id'])) {
if (!$customer->getAcCustomerId()) {
$ecomCustomer['connectionid'] = $connectionid;
$ecomCustomer['externalid'] = $customerId;
$ecomCustomer['email'] = $customerEmail;
$ecomCustomerData['ecomCustomer'] = $ecomCustomer;
$AcCustomer = $this->curl->listAllCustomers(
self::GET_METHOD,
self::ECOM_CUSTOMERLIST_ENDPOINT,
$customerEmail
);
if (ISSET($AcCustomer['data']['ecomCustomers'][0])) {
foreach ($AcCustomer['data']['ecomCustomers'] as $Ac) {
if ($Ac['connectionid'] == $connectionid) {
$ecomCustomerId = $Ac['id'];
}
}
}
if (!$ecomCustomerId) {
$ecomCustomerResult = $this->curl->createContacts(
self::METHOD,
self::ECOM_CUSTOMERLIST_ENDPOINT,
$ecomCustomerData
);
$ecomCustomerId = isset($ecomCustomerResult['data']['ecomCustomer']['id']) ? $ecomCustomerResult['data']['ecomCustomer']['id'] : null;
}
} else {
$ecomCustomerId = $customer->getAcCustomerId();
}
}
if ($ecomCustomerId != 0) {
$syncStatus = CronConfig::SYNCED;
} else {
$syncStatus = CronConfig::FAIL_SYNCED;
}
if ($customerId) {
$this->saveCustomerResult($customerId, $syncStatus, $contactId, $ecomCustomerId);
} else {
$this->saveCustomerResultQuote($quote, $ecomCustomerId);
}
} catch (\Exception $e) {
$this->logger->critical($e);
}
}
/**
* @param $customerId
* @param $syncStatus
* @param $contactId
* @param $ecomCustomerId
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
private function saveCustomerResult($customerId, $syncStatus, $contactId, $ecomCustomerId)
{
$customerModel = $this->customerFactory->create();
if ($customerId) {
$this->customerResource->load($customerModel, $customerId);
}
$customerModel->setAcSyncStatus($syncStatus);
$customerModel->setAcContactId($contactId);
$customerModel->setAcCustomerId($ecomCustomerId);
$this->customerResource->save($customerModel);
}
/**
* @param $quote
* @param $ecomCustomerId
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
private function saveCustomerResultQuote($quote, $ecomCustomerId)
{
if ($ecomCustomerId) {
$quote->setData("ac_temp_customer_id", $ecomCustomerId);
$quote->save();
}
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
namespace ActiveCampaign\Order\Observer;
use ActiveCampaign\Core\Helper\Curl;
use ActiveCampaign\Order\Helper\Data as ActiveCampaignOrderHelper;
use ActiveCampaign\Order\Model\OrderData\OrderDataSend;
use Magento\Framework\Event\ObserverInterface;
use Magento\Sales\Model\Order as OrderModel;
use Magento\Quote\Api\CartRepositoryInterface;
class OrderSync implements ObserverInterface
{
const DELETE_METHOD = "DELETE";
const URL_ENDPOINT = "ecomOrders/";
/**
* @var ActiveCampaignOrderHelper
*/
private $activeCampaignHelper;
/**
* @var OrderDataSend
*/
protected $orderdataSend;
/**
* @var Curl
*/
protected $curl;
/**
* @var CartRepositoryInterface
*/
protected $quoteRepository;
/**
* OrderSync constructor.
* @param OrderDataSend $orderdataSend
* @param ActiveCampaignOrderHelper $activeCampaignHelper
*/
public function __construct(
OrderDataSend $orderdataSend,
Curl $curl,
ActiveCampaignOrderHelper $activeCampaignHelper,
OrderModel $orderModel,
CartRepositoryInterface $quoteRepository
) {
$this->orderdataSend = $orderdataSend;
$this->curl = $curl;
$this->activeCampaignHelper = $activeCampaignHelper;
$this->orderModel = $orderModel;
$this->quoteRepository = $quoteRepository;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$isEnabled = $this->activeCampaignHelper->isOrderSyncEnabled();
$orderIds = $observer->getEvent()->getOrderIds();
if ($isEnabled) {
foreach ($orderIds as $orderId) {
$orderData = $this->orderModel->load($orderId);
$acOrderStatus = $orderData->getAcOrderSyncStatus();
if ($acOrderStatus == 0) {
$this->orderdataSend->orderDataSend($orderData);
}
$quote = $this->quoteRepository->get($orderData->getQuoteId());
$this->curl->orderDataDelete(self::DELETE_METHOD, self::URL_ENDPOINT, $quote->getAcOrderSyncId());
if ($orderData->getStatus() == 'canceled') {
$orderSyncId = $orderData->getAcOrderSyncId();
$this->curl->orderDataDelete(self::DELETE_METHOD, self::URL_ENDPOINT, $orderSyncId);
}
}
}
}
}
@@ -0,0 +1,51 @@
<?php
namespace ActiveCampaign\Order\Ui\Component\Listing\Column;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Ui\Component\Listing\Columns\Column;
class OrderStatus extends Column
{
protected $_orderRepository;
protected $_searchCriteria;
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
OrderRepositoryInterface $orderRepository,
SearchCriteriaBuilder $criteria,
array $components = [],
array $data = []
) {
$this->_orderRepository = $orderRepository;
$this->_searchCriteria = $criteria;
parent::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* @param array $dataSource
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as & $item) {
$order = $this->_orderRepository->get($item["entity_id"]);
$status = $order->getData("ac_order_sync_status");
if ($status) {
$message = 'Synced';
} else {
$message = 'Not Synced';
}
$item[$this->getData('name')] = $message;
}
}
return $dataSource;
}
}
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="ordermass" frontName="ordermass">
<module name="ActiveCampaign_Order" />
</route>
</router>
</config>
+65
View File
@@ -0,0 +1,65 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="active_campaign" translate="label" type="text" sortOrder="100" showInDefault="1" showInStore="1">
<class>separator-top</class>
<label>Configuration</label>
<tab>active_campaign</tab>
<resource>ActiveCampaign_Core::config_active_campaign</resource>
<group id="order_sync" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Order Sync Configuration</label>
<field id="order_sync_enable" translate="Order Sync Enable" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Order Sync Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="cron_minute" translate="label comment" type="text" sortOrder="20" showInDefault="1">
<label>Cron Minute</label>
<comment><![CDATA[0-59 Allowed value. Set * for every minute.]]></comment>
<depends>
<field id="order_sync_enable">1</field>
</depends>
<backend_model>ActiveCampaign\Order\Model\Config\CronConfig</backend_model>
</field>
<field id="cron_hour" translate="label comment" type="text" sortOrder="21" showInDefault="1">
<label>Cron Hour</label>
<comment><![CDATA[0-23 Allowed value. Set * for every hour.]]></comment>
<depends>
<field id="order_sync_enable">1</field>
</depends>
</field>
<field id="cron_day" translate="label comment" type="text" sortOrder="22" showInDefault="1">
<label>Cron Day</label>
<comment><![CDATA[1-31 Allowed value. Set * for every day.]]></comment>
<depends>
<field id="order_sync_enable">1</field>
</depends>
</field>
<field id="cron_month" translate="label comment" type="text" sortOrder="23" showInDefault="1">
<label>Cron Month</label>
<comment><![CDATA[1-12 Allowed value. Set * for every month.]]></comment>
<depends>
<field id="order_sync_enable">1</field>
</depends>
</field>
<field id="cron_weekday" translate="label comment" type="text" sortOrder="24" showInDefault="1">
<label>Cron Weekday</label>
<comment><![CDATA[0-6 Allowed value. Set * for every weekday.]]></comment>
<depends>
<field id="order_sync_enable">1</field>
</depends>
</field>
<field id="order_sync_num" translate="Order Sync Numbers" type="text" sortOrder="30" showInDefault="1" showInStore="1">
<label>Order Sync Numbers</label>
<comment>Number of orders sync at a time</comment>
</field>
<field id="order_sync_status" translate="label" sortOrder="40" showInDefault="1" >
<label>Number of orders test</label>
<frontend_model>ActiveCampaign\Order\Block\Adminhtml\System\Config\Widget</frontend_model>
<depends>
<field id="sync">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<active_campaign>
<order_sync>
<order_sync_enable>0</order_sync_enable>
<order_sync_num>100</order_sync_num>
<cron_minute>5</cron_minute>
<cron_hour>*</cron_hour>
<cron_day>*</cron_day>
<cron_month>*</cron_month>
<cron_weekday>*</cron_weekday>
</order_sync>
</active_campaign>
</default>
</config>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Cron:etc/crontab.xsd">
<group id="default">
<job name="ac_order_sync_cron_job" instance="ActiveCampaign\Order\Cron\OrderSyncCron" method="execute">
<config_path>crontab/default/jobs/ac_order_sync_cron_job/schedule/cron_expr</config_path>
</job>
</group>
</config>
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="sales_order" resource="sales" comment="Sales Flat Order Address">
<column xsi:type="int" name="ac_order_sync_id" nullable="false" default="0" comment="ActiveCampaign Order Id"/>
<column xsi:type="int" name="ac_order_sync_status" nullable="false" default="0" comment="ActiveCampaign Status"/>
</table>
<table name="sales_order_grid" resource="sales" engine="innodb" comment="Sales Flat Order Grid">
<column xsi:type="int" name="ac_order_sync_id" nullable="false" default="0" comment="ActiveCampaign Order Id"/>
<column xsi:type="int" name="ac_order_sync_status" nullable="false" default="0" comment="ActiveCampaign Status"/>
</table>
</schema>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="checkout_onepage_controller_success_action">
<observer instance="ActiveCampaign\Order\Observer\OrderSync" name="ac_order_sync_sales_order_save_after"/>
</event>
</config>
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
<extension_attributes for="Magento\Sales\Api\Data\OrderInterface">
<attribute code="ac_temp_customer_id" type="int" />
<attribute code="ac_order_sync_id" type="int" />
<attribute code="ac_order_sync_status" type="int" />
</extension_attributes>
</config>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="ActiveCampaign_Order" setup_version="1.0.0">
<sequence>
<module name="ActiveCampaign_Core" />
</sequence>
</module>
</config>
+8
View File
@@ -0,0 +1,8 @@
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'ActiveCampaign_Order',
__DIR__
);
@@ -0,0 +1,49 @@
<?php
use ActiveCampaign\Order\Block\Adminhtml\System\Config\OrderSyncStatus;
/**
* @var OrderSyncStatus $block
*/
?>
<table cellspacing="0" class="form-list">
<tbody>
<tr>
<td class="label"></td>
<td class="value">
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Total Orders :")) ?>
<strong><?= $block->escapeHtml(__($block->getTotalOrder())) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Synced Orders :")) ?>
<strong><?= $block->escapeHtml(__($block->getSyncOrder())) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Not Synced Orders :")) ?>
<strong><?= $block->escapeHtml(__($block->getNotSyncOrder())) ?></strong>
</div>
</div>
</div>
<div class="messages">
<div class="message message-notice" >
<div>
<?= $block->escapeHtml(__("Fail Synced Orders :")) ?>
<strong><?= $block->escapeHtml(__($block->getFailedSync())) ?></strong>
</div>
</div>
</div>
</td>
<td class></td>
</tr>
</tbody>
</table>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<listingToolbar name="listing_top">
<massaction name="listing_massaction">
<action name="order_sync">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="type" xsi:type="string">order_sync</item>
<item name="label" xsi:type="string" translate="true">Sync to ActiveCampaign</item>
<item name="url" xsi:type="url" path="ordermass/order/masssync"/>
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Sync Order(s)</item>
<item name="message" xsi:type="string" translate="true">Are you sure you wan\'t to sync selected items?</item>
</item>
</item>
</argument>
</action>
</massaction>
</listingToolbar>
<columns name="sales_order_columns">
<column name="ac_order_sync_status" class="ActiveCampaign\Order\Ui\Component\Listing\Column\OrderStatus">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="visible" xsi:type="boolean">true</item>
<item name="label" xsi:type="string" translate="true">ActiveCampaign Sync Status</item>
</item>
</argument>
</column>
</columns>
</listing>
+45 -1
View File
@@ -1 +1,45 @@
# module-integration
<p align="center">
<a href="https://www.wagento.com/">
<img src="https://www.wagento.com/static/version1607417403/frontend/Wagento/default/en_US/images/wagento-logo-black.png" width="180px" alt="Wagento" />
</a>
</p>
ACTIVECAMPAIGN extension for Magento 2.3 and 2.4
<!--Name of the project -->
ACTIVECAMPAIGN extension for Magento 2.3 and 2.4
Compatible with Community Edition, Commerce and Cloud
ActiveCampaign gives you the email marketing, marketing automation,
and CRM tools you need to create incredible customer experiences.
<!-- Write description here -->
## System Requirements
* PHP 7.4
* Magento 2.3/2.4
* Elastic Search 7
* RabbitMQ
<!-- mention all the system requirements -->
## Project Setup
<a href="https://wagento.atlassian.net/wiki/spaces/ActiveCampaign/pages/2124939269/Local+Setup">Link to confluence project setup page</a>
<!-- mention confluence link about local project setup -->
## Branching Flow
<a href="https://wagento.atlassian.net/wiki/spaces/ActiveCampaign/pages/2124939282/Deployment+Process">Link to confluence branching flow page</a>
<!-- mention confluence link about branching flow -->
## Deployment Process
<a href="https://wagento.atlassian.net/wiki/spaces/ActiveCampaign/pages/2124939282/Deployment+Process">Link to confluence page</a>
<!-- mention confluence link about deployment process -->
## Known Issues
*
## Contributor (Developers)
* Rohit Dave
* Yair Garcia
<!-- mention all developers name who is working or had worked on this project. -->
## Contact
* Rohit - [rohit@wagento.com]
* Yair - [yair.garcia@wagento.com]
+32
View File
@@ -0,0 +1,32 @@
<?php
namespace ActiveCampaign\SyncLog\Block\Adminhtml\View;
use ActiveCampaign\SyncLog\Model\SyncLog;
use Magento\Framework\App\RequestInterface;
class Log extends \Magento\Framework\View\Element\Template
{
protected $syncLogModelFactory;
protected $request;
public function __construct(
\Magento\Catalog\Block\Product\Context $context,
SyncLog $syncLogModelFactory,
RequestInterface $request,
array $data = []
) {
parent::__construct($context, $data);
$this->syncLogModelFactory = $syncLogModelFactory;
$this->_request = $request;
}
public function getLogCollection()
{
$param = $this->getRequest()->getParams();
$collection = $this->syncLogModelFactory->getCollection()
->addFieldToFilter('id', $param['id'])->getData();
//echo "<pre>";print_r($collection);exit;
return $collection;
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace ActiveCampaign\SyncLog\Controller\Adminhtml\Index;
class Index extends \Magento\Backend\App\Action
{
/**
* @var \Magento\Framework\View\Result\PageFactory
*/
protected $resultPageFactory;
/**
* @param \Magento\Backend\App\Action\Context $context
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
/**
* Grid List page.
*
* @return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
$resultPage->setActiveMenu('ActiveCampaign_SyncLog::logs');
$resultPage->getConfig()->getTitle()->prepend(__('ActiveCampaign Sync Logs'));
return $resultPage;
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace ActiveCampaign\SyncLog\Controller\Adminhtml\Index;
class View extends \Magento\Backend\App\Action
{
/**
* @var \Magento\Framework\View\Result\PageFactory
*/
protected $resultPageFactory;
/**
* @param \Magento\Backend\App\Action\Context $context
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
parent::__construct($context);
$this->resultPageFactory = $resultPageFactory;
}
/**
* Grid List page.
*
* @return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->prepend(__('ActiveCampaign Log Information'));
return $resultPage;
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace ActiveCampaign\SyncLog\Model\ResourceModel;
class SyncLog extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
public function __construct(
\Magento\Framework\Model\ResourceModel\Db\Context $context
) {
parent::__construct($context);
}
protected function _construct()
{
$this->_init('sync_log', 'id');
}
}
+20
View File
@@ -0,0 +1,20 @@
<?php
namespace ActiveCampaign\SyncLog\Model\ResourceModel\SyncLog;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
protected $idFieldName = 'id';
protected $eventPrefix = 'sync_log';
protected $eventObject = 'sync_log';
/**
* Define resource model
*
* @return void
*/
protected function _construct()
{
$this->_init('ActiveCampaign\SyncLog\Model\SyncLog', 'ActiveCampaign\SyncLog\Model\ResourceModel\SyncLog');
}
}
+133
View File
@@ -0,0 +1,133 @@
<?php
namespace ActiveCampaign\SyncLog\Model\ResourceModel\SyncLog\Grid;
use Magento\Framework\Api\Search\SearchResultInterface;
use Magento\Framework\Api\Search\AggregationInterface;
use ActiveCampaign\SyncLog\Model\ResourceModel\SyncLog\Collection as SyncLogCollection;
class Collection extends SyncLogCollection implements SearchResultInterface
{
/**
* @var AggregationInterface
*/
protected $aggregations;
/**
* @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Framework\EntityManager\MetadataPool $metadataPool
* @param mixed|null $mainTable
* @param string $eventPrefix
* @param mixed $eventObject
* @param mixed $resourceModel
* @param string $model
* @param null $connection
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource
*
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
\Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory,
\Psr\Log\LoggerInterface $logger,
\Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
\Magento\Framework\Event\ManagerInterface $eventManager,
$mainTable,
$eventPrefix,
$eventObject,
$resourceModel,
$model = \Magento\Framework\View\Element\UiComponent\DataProvider\Document::class,
$connection = null,
\Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
) {
parent::__construct(
$entityFactory,
$logger,
$fetchStrategy,
$eventManager,
$connection,
$resource
);
$this->_eventPrefix = $eventPrefix;
$this->_eventObject = $eventObject;
$this->_init($model, $resourceModel);
$this->setMainTable($mainTable);
}
/**
* @return AggregationInterface
*/
public function getAggregations()
{
return $this->aggregations;
}
/**
* @param AggregationInterface $aggregations
* @return $this
*/
public function setAggregations($aggregations)
{
$this->aggregations = $aggregations;
return $this;
}
/**
* Get search criteria.
*
* @return \Magento\Framework\Api\SearchCriteriaInterface|null
*/
public function getSearchCriteria()
{
return null;
}
/**
* Set search criteria.
*
* @param \Magento\Framework\Api\SearchCriteriaInterface $searchCriteria
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setSearchCriteria(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria = null)
{
return $this;
}
/**
* Get total count.
*
* @return int
*/
public function getTotalCount()
{
return $this->getSize();
}
/**
* Set total count.
*
* @param int $totalCount
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setTotalCount($totalCount)
{
return $this;
}
/**
* Set items list.
*
* @param \Magento\Framework\Api\ExtensibleDataInterface[] $items
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setItems(array $items = null)
{
return $this;
}
}
+51
View File
@@ -0,0 +1,51 @@
<?php
namespace ActiveCampaign\SyncLog\Model;
use Magento\Framework\Data\OptionSourceInterface;
class Status implements OptionSourceInterface
{
/**
* Get Grid row status type labels array.
* @return array
*/
public function getOptionArray()
{
$options = ['1' => __('Success'),'0' => __('Unsuccess')];
return $options;
}
/**
* Get Grid row status labels array with empty value for option element.
*
* @return array
*/
public function getAllOptions()
{
$res = $this->getOptions();
array_unshift($res, ['value' => '', 'label' => '']);
return $res;
}
/**
* Get Grid row type array for option element.
* @return array
*/
public function getOptions()
{
$res = [];
foreach ($this->getOptionArray() as $index => $value) {
$res[] = ['value' => $index, 'label' => $value];
}
return $res;
}
/**
* {@inheritdoc}
*/
public function toOptionArray()
{
return $this->getOptions();
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace ActiveCampaign\SyncLog\Model;
class SyncLog extends \Magento\Framework\Model\AbstractModel implements \Magento\Framework\DataObject\IdentityInterface
{
public const CACHE_TAG = 'sync_log';
protected $cacheTag = 'sync_log';
protected $eventPrefix = 'sync_log';
protected function _construct()
{
$this->_init('ActiveCampaign\SyncLog\Model\ResourceModel\SyncLog');
}
public function getIdentities()
{
return [self::CACHE_TAG . '_' . $this->getId()];
}
public function getDefaultValues()
{
$values = [];
return $values;
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
namespace ActiveCampaign\SyncLog\Ui\Component\Listing\Grid\Column;
use Magento\Framework\UrlInterface;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
class Action extends Column
{
/** Url path */
public const ROW_VIEW_URL = 'synclog/index/view';
/**
* @var UrlInterface
*/
protected $urlBuilder;
/**
* @param ContextInterface $context
* @param UiComponentFactory $uiComponentFactory
* @param UrlInterface $urlBuilder
* @param array $components
* @param array $data
* @param string $editUrl
*/
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
UrlInterface $urlBuilder,
array $components = [],
array $data = []
) {
$this->urlBuilder = $urlBuilder;
parent::__construct($context, $uiComponentFactory, $components, $data);
}
/**
* Prepare Data Source.
*
* @param array $dataSource
*
* @return array
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
foreach ($dataSource['data']['items'] as &$item) {
$name = $this->getData('name');
if (isset($item['id'])) {
$item[$name]['delete'] = [
'href' => $this->urlBuilder->getUrl(self::ROW_VIEW_URL, ['id' => $item['id']]),
'label' => __('View')
];
}
}
}
return $dataSource;
}
}
Loaded 100 of 110 files, more files were not shown because too many files have changed in this diff. Show more