Commit b594868f by lmf

恢复模块文件

parent 59b81248
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
/**
* Copyright © Aitoc. All rights reserved.
*/
namespace Aitoc\Core\Api;
interface ColumnInterface
{
const AITOC_NOTIFICATION_FIELD = 'aitoc_notification';
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Block;
use Magento\Framework\Data\Form\Element\AbstractElement;
class InstalledExtensions extends \Magento\Config\Block\System\Config\Form\Fieldset
{
const AITOC_UPDATE_EXTENSION_VERSION_LINK = 'https://www.aitoc.com/customer/account/login/';
const AITOC_PRODUCT_LINK_DEFAULT = 'https://www.aitoc.com/magento-2-extensions.html';
const AITOC_SUPPROT_LINK = 'https://www.aitoc.com/get-support.html';
/**
* @var \Magento\Framework\Module\ModuleListInterface
*/
protected $_moduleList;
/**
* @var \Magento\Framework\View\LayoutFactory
*/
protected $_layoutFactory;
/**
* @var \Aitoc\Core\Helper\Extensions
*/
private $extensionsHelper;
public function __construct(
\Magento\Backend\Block\Context $context,
\Magento\Backend\Model\Auth\Session $authSession,
\Magento\Framework\View\Helper\Js $jsHelper,
\Magento\Framework\Module\ModuleListInterface $moduleList,
\Magento\Framework\View\LayoutFactory $layoutFactory,
\Aitoc\Core\Helper\Extensions $extensionsHelper,
array $data = []
) {
parent::__construct($context, $authSession, $jsHelper, $data);
$this->_moduleList = $moduleList;
$this->_layoutFactory = $layoutFactory;
$this->extensionsHelper = $extensionsHelper;
$this->_scopeConfig = $context->getScopeConfig();
}
/**
* Render fieldset html
*
* @param AbstractElement $element
* @return string
*/
public function render(AbstractElement $element)
{
$html = $this->_getHeaderHtml($element);
$modules = $this->extensionsHelper->getAitocExtensions(true);
if ($modules) {
foreach ($modules as $ext) {
$html .= $this->getRenderExtensionLine($ext);
}
}
$html .= $this->_getFooterHtml($element);
return $html;
}
/**
* Return footer html for fieldset
* Add extra tooltip comments to elements
*
* @param AbstractElement $element
* @return string
*/
protected function _getFooterHtml($element)
{
$html = '</tbody></table>';
$html .= $this->addCommentToHtml();
foreach ($element->getElements() as $field) {
if ($field->getTooltip()) {
$html .= sprintf(
'<div id="row_%s_comment" class="system-tooltip-box" style="display:none;">%s</div>',
$field->getId(),
$field->getTooltip()
);
}
}
$html .= '</fieldset>' . $this->_getExtraJs($element);
if ($element->getIsNested()) {
$html .= '</td></tr>';
} else {
$html .= '</div>';
}
return $html;
}
/**
* @param $fieldset
* @param $moduleCode
* @return string
*/
private function getRenderExtensionLine($extName)
{
$extensionsEnabled = $this->extensionsHelper->isModuleEnabled($extName);
$resultHtml = '';
$extInfo = $this->extensionsHelper->getExtInfo($extName);
$packageData = [];
$versionOld = false;
$productUrl = self::AITOC_UPDATE_EXTENSION_VERSION_LINK;
if (!is_array($extInfo) ||
!array_key_exists('version', $extInfo) ||
!array_key_exists('description', $extInfo) ||
!array_key_exists('name', $extInfo)
) {
return '';
}
$allExtensionsData = $this->extensionsHelper->getAllExtensions();
if (isset($allExtensionsData[$extInfo['name']])) {
$packageData = $allExtensionsData[$extInfo['name']];
if ($packageData && isset($packageData['version'])) {
$versionOld = $this->extensionsHelper
->compareExtensionComposerVersions($packageData['version'], $extInfo['version']);
if (isset($packageData['product_url']) && $packageData['product_url']) {
$productUrl = $packageData['product_url'];
}
}
}
$resultHtml .= '<tr id="aitoc_core_' . strtolower($extName) . '"><td class="label"><label for="aitoc_core_' .
strtolower($extName) . '"><span><a href="' . $productUrl . '" target="_blank">'
. str_replace('extension', '', str_replace('by Aitoc', '', $extInfo['description']))
. '</a> (' . ($extensionsEnabled ? __('Enabled') : __('Disabled')) . ')</span></label></td>';
$resultHtml .= '<td class="value">'
. $extInfo['version'] . ' '
. '<b>' .
($versionOld ?
__("(New version %1 is available in your account: ", $packageData['version'])
. '<a class="aitoc-button-get-new-version" href="'
. self::AITOC_UPDATE_EXTENSION_VERSION_LINK .
'" target="_blank">' . __('Get Update') . '</a> )' : '' )
. '</b></td>';
return $resultHtml . '</tr>';
}
/**
* @param $html
* @return string
*/
private function addCommentToHtml()
{
$html = '<div class="comment aitoc-support">';
$html .= 'Have any issues with <b>Aitoc extensions</b>?' .
' Please <a href="' . self::AITOC_SUPPROT_LINK
. '" class="aitoc-get-support-button" target="_blank">Contact Support</a>';
return $html . '</div>';
}
/**
* @return \Magento\Framework\View\Element\BlockInterface
*/
protected function _getFieldRenderer()
{
if (empty($this->_fieldRenderer)) {
$layout = $this->_layoutFactory->create();
$this->_fieldRenderer = $layout->createBlock(
\Magento\Config\Block\System\Config\Form\Field::class
);
}
return $this->_fieldRenderer;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Block;
/**
* Class Shopfeed
* @package Aitoc\Core\Block
*/
class Shopfeed extends \Magento\Config\Block\System\Config\Form\Fieldset
{
/**
* Render text
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
$html = $this->_getHeaderHtml($element);
$html .= $this->_getFooterHtml($element);
return $html;
}
/**
* Return element html
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
return $this->_toHtml();
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Framework\Stdlib\DateTime\DateTimeFormatterInterface;
/**
* Backend system config datetime field renderer
*/
class Notification extends \Magento\Config\Block\System\Config\Form\Field
{
/**
* @var DateTimeFormatterInterface
*/
protected $dateTimeFormatter;
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param DateTimeFormatterInterface $dateTimeFormatter
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
DateTimeFormatterInterface $dateTimeFormatter,
array $data = []
) {
parent::__construct($context, $data);
$this->dateTimeFormatter = $dateTimeFormatter;
}
/**
* @param AbstractElement $element
* @return string
*/
protected function _getElementHtml(AbstractElement $element)
{
$element->setValue($this->_cache->load(\Aitoc\Core\Model\Feed::AITOC_CACHE_NAME));
$format = $this->_localeDate->getDateTimeFormat(
\IntlDateFormatter::MEDIUM
);
return $this->dateTimeFormatter->formatObject($this->_localeDate->date(intval($element->getValue())), $format);
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Model\ResourceModel;
use Magento\Framework\Api\ExtensibleDataInterface;
use Magento\Framework\Api\Search\AggregationInterface;
use Magento\Framework\Api\Search\DocumentInterface;
use Magento\Framework\Api\SearchCriteriaInterface;
trait GridCollectionTrait
{
/**
* @var AggregationInterface
*/
private $aggregations;
/**
* Retrieve all ids for collection
* Backward compatibility with EAV collection
*
* @param int $limit
* @param int $offset
* @return array
*/
public function getAllIds($limit = null, $offset = null)
{
return $this->getConnection()->fetchCol($this->_getAllIdsSelect($limit, $offset), $this->_bindParams);
}
/**
* @return AggregationInterface
*/
public function getAggregations()
{
return $this->aggregations;
}
/**
* @param AggregationInterface $aggregations
* @return $this
*/
public function setAggregations($aggregations)
{
$this->aggregations = $aggregations;
}
/**
* Get search criteria.
*
* @return SearchCriteriaInterface|null
*/
public function getSearchCriteria()
{
return null;
}
/**
* Set search criteria.
*
* @param SearchCriteriaInterface $searchCriteria
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setSearchCriteria(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 ExtensibleDataInterface[] $items
* @return $this
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function setItems(array $items = null)
{
return $this;
}
/**
* @return DocumentInterface[]
*/
public function getItems()
{
return $this;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Model\ResourceModel;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
abstract class LinkedFieldResource extends AbstractDb
{
/**
* @var array
*/
protected $linkedFields = [];
/**
* Order is important. Key is required. For example:
* ["store_labels" => ["aitoc_shipping_carrier_labels", "label", "store_id"]
*
* @return array
*/
protected function getLinkedFields()
{
return $this->linkedFields;
}
/**
* @inheritDoc
*/
protected function _afterSave(AbstractModel $object)
{
parent::_afterSave($object);
foreach (array_keys($this->getLinkedFields()) as $linkedField) {
$this->updateLinkedField($object, $linkedField);
}
return $this;
}
/**
* @param AbstractModel $object
*/
public function loadAllLinkedData(AbstractModel $object)
{
foreach (array_keys($this->getLinkedFields()) as $linkedField) {
$this->loadLinkedValue($object, $linkedField);
}
}
/**
* @param AbstractModel $object
* @param string $linkedField
* @return array
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function loadLinkedValue(AbstractModel $object, $linkedField)
{
list($linkedTable, $valueField, $keyField) = array_values($this->linkedFields[$linkedField]);
$fetchingValues = [$valueField];
if ($keyField) {
array_unshift($fetchingValues, $keyField);
}
$select = $this->getConnection()->select()
->from($this->getTable($linkedTable), $fetchingValues)
->where($this->getIdFieldName() . ' = :id');
if ($keyField) {
$linkedData = $this->getConnection()->fetchPairs($select, [':id' => $object->getId()]);
} else {
$linkedData = $this->getConnection()->fetchCol($select, [':id' => $object->getId()]);
}
$object->setData($linkedField, $linkedData);
}
/**
* @param AbstractModel $object
* @param string $linkedField
* @return $this
* @throws \Magento\Framework\Exception\LocalizedException
*/
private function updateLinkedField(AbstractModel $object, $linkedField)
{
list($linkedTable, $valueField, $keyField) = array_values($this->linkedFields[$linkedField]);
$idField = $this->getIdFieldName();
$linkedTable = $this->getTable($linkedTable);
$connection = $this->getConnection();
if ($object->hasData($linkedField)) {
$connection->delete($linkedTable, $connection->quoteInto("$idField = ?", $object->getId()));
}
$data = [];
foreach ((array)$object->getData($linkedField) as $key => $value) {
if ($value !== null) {
$new = [
$idField => $object->getId(),
$valueField => $value,
];
if (!empty($keyField)) {
$new[$keyField] = $key;
}
$data[] = $new;
}
}
if ($data) {
$connection->insertMultiple($this->getTable($linkedTable), $data);
}
return $this;
}
}
\ No newline at end of file
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Model\Source;
use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Convert\DataObject;
class CustomerGroupsOptions implements \Magento\Framework\Data\OptionSourceInterface
{
/**
* @var GroupRepositoryInterface
*/
private $groupRepository;
/**
* @var SearchCriteriaBuilder
*/
private $criteriaBuilder;
/**
* @var DataObject
*/
private $dataObjectConverter;
public function __construct(
GroupRepositoryInterface $groupRepository,
SearchCriteriaBuilder $criteriaBuilder,
DataObject $dataObjectConverter
) {
$this->groupRepository = $groupRepository;
$this->criteriaBuilder = $criteriaBuilder;
$this->dataObjectConverter = $dataObjectConverter;
}
/**
* @return array
*/
public function toOptionArray()
{
$customerGroups = $this->groupRepository->getList($this->criteriaBuilder->create())->getItems();
return $this->dataObjectConverter->toOptionArray($customerGroups, 'id', 'code');
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Model\Source;
use Magento\Framework\Data\OptionSourceInterface;
use Magento\Store\Model\System\Store;
class StoreOptions implements OptionSourceInterface
{
/**
* @var Store
*/
private $store;
/**
* @param Store $store
*/
public function __construct(Store $store)
{
$this->store = $store;
}
/**
* @return array
*/
public function toOptionArray()
{
return $this->store->getStoreValuesForForm(false, true);
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Model\Source;
use Magento\Store\Model\System\Store;
use Magento\Framework\Data\OptionSourceInterface;
class WebsitesOptions implements OptionSourceInterface
{
/**
* @var Store
*/
protected $store;
public function __construct(Store $store)
{
$this->store = $store;
}
/**
* @inheritDoc
*/
public function toOptionArray()
{
return $this->store->getWebsiteValuesForForm();
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Model\Source;
/**
* includes "All Websites" option
*/
class WebsitesOptionsAll extends WebsitesOptions
{
/**
* @inheritDoc
*/
public function toOptionArray()
{
$options = $this->store->getWebsiteValuesForForm(false, true);
foreach ($options as &$option) {
if ($option['value'] === 0) {
$option['label'] = __('All Websites');
break;
}
}
return $options;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Model\Source;
/**
* doesn't contain "-- Please Select--" option
*/
class WebsitesOptionsMultiselect extends WebsitesOptions
{
/**
* @inheritDoc
*/
public function toOptionArray()
{
return $this->store->getWebsiteValuesForForm(true);
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Model\Source;
/**
* includes "All Websites" option
* doesn't contain "-- Please Select--" option
*/
class WebsitesOptionsMultiselectAll extends WebsitesOptions
{
/**
* @inheritDoc
*/
public function toOptionArray()
{
$options = $this->store->getWebsiteValuesForForm(true, true);
foreach ($options as &$option) {
if ($option['value'] === 0) {
$option['label'] = __('All Websites');
break;
}
}
return $options;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Ui\Component\Listing\Column;
use Magento\Customer\Api\GroupRepositoryInterface;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Convert\DataObject;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
class CustomerGroups extends Column
{
/**
* @var array
*/
private $customerGroups;
/**
* @var DataObject
*/
private $objectConverter;
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
GroupRepositoryInterface $groupRepository,
SearchCriteriaBuilder $searchCriteriaBuilder,
DataObject $objectConverter,
array $components = [],
array $data = []
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
$this->objectConverter = $objectConverter;
$this->customerGroups = $groupRepository->getList($searchCriteriaBuilder->create())->getItems();
}
/**
* @inheritDoc
*/
public function prepareDataSource(array $dataSource)
{
$groups = $this->objectConverter->toOptionHash($this->customerGroups, 'id', 'code');
if (isset($dataSource['data']['items'])) {
$fieldName = $this->getData('name');
foreach ($dataSource['data']['items'] as & $item) {
$groupNames = [];
foreach ($item[$fieldName] as $groupId) {
if (!isset($groups[$groupId])) {
continue;
}
$groupNames[] = $groups[$groupId];
}
$item[$fieldName] = implode(', ', $groupNames);
}
}
return $dataSource;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Ui\Component\Listing\Column;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Ui\Component\Listing\Columns\Column;
class Price extends Column
{
/**
* @var PriceCurrencyInterface
*/
protected $priceFormatter;
/**
* @var StoreManagerInterface
*/
private $storeManager;
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
PriceCurrencyInterface $priceFormatter,
StoreManagerInterface $storeManager,
array $components = [],
array $data = []
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
$this->priceFormatter = $priceFormatter;
$this->storeManager = $storeManager;
}
/**
* Prepare Data Source
*
* @param array $dataSource
*
* @return array
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function prepareDataSource(array $dataSource)
{
if (isset($dataSource['data']['items'])) {
$currencyCode = $this->storeManager->getStore()->getBaseCurrency()->getCurrencySymbol();
foreach ($dataSource['data']['items'] as &$item) {
if ($item[$this->getData('name')] !== null) {
$item[$this->getData('name')] = $this->priceFormatter->format(
$item[$this->getData('name')],
false,
\Magento\Framework\Pricing\PriceCurrencyInterface::DEFAULT_PRECISION,
null,
$currencyCode
);
}
}
}
return $dataSource;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Ui\Component\Listing\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Store\Model\StoreManagerInterface;
class Websites extends Column
{
/**
* @var StoreManagerInterface
*/
private $storeManager;
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
StoreManagerInterface $storeManager,
array $components = [],
array $data = []
) {
parent::__construct($context, $uiComponentFactory, $components, $data);
$this->storeManager = $storeManager;
}
/**
* @inheritDoc
*/
public function prepareDataSource(array $dataSource)
{
$websiteNames = [0 => __('All Websites')];
foreach ($this->getData('options') as $website) {
$websiteNames[$website->getWebsiteId()] = $website->getName();
}
if (isset($dataSource['data']['items'])) {
$fieldName = $this->getData('name');
foreach ($dataSource['data']['items'] as & $item) {
$websites = [];
foreach ($item[$fieldName] as $websiteId) {
if (!isset($websiteNames[$websiteId])) {
continue;
}
$websites[] = $websiteNames[$websiteId];
if ($websiteId == 0) {
break;
}
}
$item[$fieldName] = implode(', ', $websites);
}
}
return $dataSource;
}
/**
* @inheritDoc
*/
public function prepare()
{
parent::prepare();
if ($this->storeManager->isSingleStoreMode()) {
$this->_data['config']['componentDisabled'] = true;
}
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Ui\DataProvider;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Api\AttributeValueFactory;
/**
* Helping to use a Model in a Grid Collection
* @see \Magento\Framework\View\Element\UiComponent\DataProvider\Document
*/
trait DocumentTrait
{
/**
* Get an attribute value.
*
* @param string $attributeCode
* @return \Magento\Framework\Api\AttributeInterface|null
*/
public function getCustomAttribute($attributeCode)
{
$attributeValueFactory = ObjectManager::getInstance()->get(AttributeValueFactory::class);
/** @var \Magento\Framework\Api\AttributeInterface $attributeValue */
$attributeValue = $attributeValueFactory->create();
$attributeValue->setAttributeCode($attributeCode);
$attributeValue->setValue($this->getData($attributeCode));
return $attributeValue;
}
/**
* Set an attribute value for a given attribute code
*
* @param string $attributeCode
* @param mixed $attributeValue
* @return $this
*/
public function setCustomAttribute($attributeCode, $attributeValue)
{
$this->setData($attributeCode, $attributeValue);
return $this;
}
/**
* Retrieve custom attributes values.
*
* @return \Magento\Framework\Api\AttributeInterface[]|null
*/
public function getCustomAttributes()
{
$output = [];
$attributeValueFactory = ObjectManager::getInstance()->get(AttributeValueFactory::class);
foreach ($this->getData() as $key => $value) {
$attribute = $attributeValueFactory->create();
$output[] = $attribute->setAttributeCode($key)->setValue($value);
}
return $output;
}
/**
* Set array of custom attributes
*
* @param \Magento\Framework\Api\AttributeInterface[] $attributes
* @return $this
* @throws \LogicException
*/
public function setCustomAttributes(array $attributes)
{
/** @var \Magento\Framework\Api\AttributeInterface $attribute */
foreach ($attributes as $attribute) {
$this->setData(
$attribute->getAttributeCode(),
$attribute->getValue()
);
}
return $this;
}
}
\ No newline at end of file
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Ui\DataProvider\Form\Modifier;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Ui\DataProvider\Modifier\ModifierInterface;
class Price implements ModifierInterface
{
/**
* @var StoreManagerInterface
*/
private $storeManager;
/**
* @var ArrayManager
*/
private $arrayManager;
/**
* @var string
*/
private $fieldset;
/**
* @var array
*/
private $priceFields;
public function __construct(
StoreManagerInterface $storeManager,
ArrayManager $arrayManager,
$fieldset = 'general',
$priceFields = []
) {
$this->storeManager = $storeManager;
$this->arrayManager = $arrayManager;
$this->fieldset = $fieldset;
$this->priceFields = $priceFields;
}
/**
* @inheritDoc
*/
public function modifyData(array $data)
{
return $data;
}
/**
* @inheritDoc
*/
public function modifyMeta(array $meta)
{
return $this->preparePriceFields($meta);
}
/**
* @param $meta
* @return array
*/
protected function preparePriceFields($meta)
{
$symbol = $this->storeManager->getStore()->getBaseCurrency()->getCurrencySymbol();
foreach ($this->priceFields as $priceField) {
$pricePath = $this->fieldset . '/children/' . $priceField . '/arguments/data/config/';
$meta = $this->arrayManager->set($pricePath . 'addbefore', $meta, $symbol);
// $meta = $this->arrayManager->set($pricePath . 'validation', $meta, ['validate-zero-or-greater' => true]);
// $meta = $this->arrayManager->set($pricePath . 'additionalClasses', $meta, ['admin__field-small' => true]);
}
return $meta;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Components\Ui\DataProvider\Form\Modifier;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Store\Api\StoreRepositoryInterface;
use Magento\Ui\Component\Form\Element\DataType\Text;
use Magento\Ui\Component\Form\Element\Input;
use Magento\Ui\Component\Form\Field;
use Magento\Ui\DataProvider\Modifier\ModifierInterface;
class StoreViews implements ModifierInterface
{
/**
* @var StoreRepositoryInterface
*/
private $storeRepository;
/**
* @var ArrayManager
*/
private $arrayManager;
/**
* @var string
*/
private $fieldset;
/**
* @var string
*/
private $field;
public function __construct(
StoreRepositoryInterface $storeRepository,
ArrayManager $arrayManager,
$field = 'store_labels',
$fieldset = null
) {
$this->storeRepository = $storeRepository;
$this->arrayManager = $arrayManager;
$this->fieldset = $fieldset ?: $field;
$this->field = $field;
}
/**
* @inheritDoc
*/
public function modifyData(array $data)
{
if (!empty($data[$this->field])) {
foreach ($data[$this->field] as $id => $label) {
$data[$this->field . '[' . $id . ']'] = $label;
}
}
return $data;
}
/**
* @inheritDoc
*/
public function modifyMeta(array $meta)
{
$labelConfigs = [];
foreach ($this->storeRepository->getList() as $store) {
$storeId = $store->getId();
if (!$storeId) {
continue;
}
$labelConfigs[$this->field . '[' . $storeId . ']'] = $this->arrayManager->set(
'arguments/data/config',
[],
[
'formElement' => Input::NAME,
'componentType' => Field::NAME,
'label' => $store->getName(),
'dataType' => Text::NAME,
'dataScope' => $this->field . '[' . $storeId . ']',
]
);
}
$meta[$this->fieldset]['children'] = $labelConfigs;
return $meta;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\ScopeInterface;
class Config extends AbstractHelper
{
const AITOC_CORE_XML_PATH_NOTIFICATIONS = 'aitoc_core/notifications/';
const AITOC_CORE_XML_PATH_EXTENSIONS = 'aitoc_core/extensions/';
const AITOC_CORE_XML_PATH_MENU = 'aitoc_core/menu/';
/**
* @var \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress
*/
private $remoteAddress;
public function __construct(
\Magento\Framework\App\Helper\Context $context
) {
parent::__construct($context);
$this->remoteAddress = $context->getRemoteAddress();
}
/**
* @param $path
* @param int $storeId
* @return mixed
*/
public function getModuleConfig($path, $storeId = null)
{
return $this->scopeConfig->getValue(
$path,
ScopeInterface::SCOPE_STORE,
$storeId
);
}
/**
* @return string
*/
public function getCurrentIp()
{
return $this->remoteAddress->getRemoteAddress();
}
/**
* @return boolean
*/
public function getNotificationsEnable()
{
return (bool)$this->getModuleConfig(self::AITOC_CORE_XML_PATH_NOTIFICATIONS . 'notice_enable');
}
/**
* @return array
*/
public function getNotificationsType()
{
$data = $this->getModuleConfig(self::AITOC_CORE_XML_PATH_NOTIFICATIONS . 'notice_type');
return $data ? explode(',', $data) : [];
}
/**
* @return mixed
*/
public function getNotificationsFrequency()
{
return $this->getModuleConfig(self::AITOC_CORE_XML_PATH_NOTIFICATIONS . 'frequency');
}
/**
* @return mixed
*/
public function getMenuEnable()
{
return $this->getModuleConfig(self::AITOC_CORE_XML_PATH_MENU . 'menu_enable');
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use SimpleXMLElement;
use Zend\Http\Client\Adapter\Curl as CurlClient;
use Zend\Http\Response as HttpResponse;
use Zend\Uri\Http as HttpUri;
use Magento\Framework\Json\DecoderInterface;
class Extensions extends AbstractHelper
{
const EXTENSIONS_PATH = 'aitoc_extensions';
const URL_EXTENSIONS = 'http://www.aitoc.com/shopfeed/index/extensiondata';
/**
* @var CurlClient
*/
protected $curlClient;
/**
* @var \Magento\Framework\App\CacheInterface
*/
protected $cache;
/**
* @var \Magento\Framework\Module\Dir\Reader
*/
private $moduleReader;
/**
* @var \Magento\Framework\Filesystem\Driver\File
*/
private $filesystem;
/**
* @var DecoderInterface
*/
private $jsonDecoder;
/**
* @var \Magento\Framework\Module\ModuleListInterface
*/
private $moduleList;
/**
* @var array
*/
private $aitocExtensions = [];
/**
* @var \Magento\Framework\App\ProductMetadataInterface
*/
private $productMetadata;
/**
* @var \Magento\Framework\Module\Manager
*/
private $moduleManager;
/**
* @var array
*/
private $moduleIgnoreList = ['Aitoc_Core', 'Aitoc_Tips'];
/**
* @var array
*/
private $aitocPrefixList = ['Aitoc_', 'AdjustWare_'];
/**
* @var array
*/
private $moduleDirs = ['Aitoc', 'AdjustWare'];
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\App\CacheInterface $cache,
\Magento\Framework\Module\Dir\Reader $moduleReader,
\Magento\Framework\Filesystem\Driver\File $filesystem,
DecoderInterface $jsonDecoder,
\Magento\Framework\App\ProductMetadataInterface $productMetadata,
CurlClient $curl,
\Magento\Framework\Module\ModuleListInterface $moduleList
) {
parent::__construct($context);
$this->cache = $cache;
$this->curlClient = $curl;
$this->moduleReader = $moduleReader;
$this->filesystem = $filesystem;
$this->jsonDecoder = $jsonDecoder;
$this->productMetadata = $productMetadata;
$this->moduleList = $moduleList;
$this->moduleManager = $context->getModuleManager();
}
/**
* @return bool|mixed
*/
public function getAllExtensions()
{
$data = $this->cache->load(self::EXTENSIONS_PATH);
if (!$data) {
$extensionsData = $this->getExtensionsPackagesData();
$this->cache->save(json_encode($extensionsData), self::EXTENSIONS_PATH);
}
return json_decode($this->cache->load(self::EXTENSIONS_PATH), true);
}
/**
* @param $version1
* @param $version2
* @param string $operator
* @return mixed
*/
public function compareExtensionComposerVersions($version1, $version2, $operator = '>')
{
return version_compare($version1, $version2, $operator);
}
/**
* Save extensions data to magento cache
*/
protected function getExtensionsPackagesData()
{
$resultData = [];
$extensionsParsedJson = $this->getExtensionsData();
if ($extensionsParsedJson && is_array($extensionsParsedJson)) {
foreach ($extensionsParsedJson as $extName => $extData) {
if ($extName && $extData) {
$resultData[$extName] = $extData;
}
}
}
return $resultData;
}
/**
* Read data from xml file with curl
* @return bool|SimpleXMLElement
*/
protected function getExtensionsData()
{
$result = [];
try {
$extensionsData = file_get_contents(self::URL_EXTENSIONS);
if ($extensionsData && is_string($extensionsData)) {
$result = json_decode($extensionsData, true);
}
} catch (\Exception $e) {
return false;
}
return $result;
}
/**
* @param $extName
* @return array|mixed
* @throws \Magento\Framework\Exception\FileSystemException
*/
public function getExtInfo($extName)
{
$dir = $this->moduleReader->getModuleDir('', $extName);
if ($this->filesystem->isReadable($dir)) {
return $this->readExtComposerFile($dir);
}
return [];
}
/**
* @param $extDir
* @return array|mixed
* @throws \Magento\Framework\Exception\FileSystemException
*/
public function readExtComposerFile($extDir)
{
$file = $extDir . '/composer.json';
if ($this->filesystem->isExists($file)) {
$string = $this->filesystem->fileGetContents($file);
return json_decode($string, true);
}
return [];
}
/**
* @param bool $restrictedDelete
* @return array
*/
public function getAitocExtensions($restrictedDelete = false)
{
if (!$this->aitocExtensions) {
$modules = $this->moduleList->getNames();
$dispatchResult = new \Magento\Framework\DataObject($modules);
$modules = $dispatchResult->toArray();
foreach ($this->aitocPrefixList as $prefix) {
foreach ($modules as $item) {
if (strpos($item, $prefix) !== false) {
$this->aitocExtensions[] = $item;
}
}
}
}
if ($restrictedDelete) {
foreach ($this->moduleIgnoreList as $value) {
if (array_search($value, $this->aitocExtensions) !== false) {
unset($this->aitocExtensions[array_search($value, $this->aitocExtensions)]);
}
}
}
sort($this->aitocExtensions);
return $this->aitocExtensions;
}
/**
*
* @param string $moduleName Fully-qualified module name
* @return boolean
*/
public function isModuleEnabled($moduleName)
{
return $this->_moduleManager->isEnabled($moduleName);
}
/**
* @return string
*/
public function getMagentoEdition()
{
return $this->productMetadata->getEdition();
}
/**
* @return string
*/
public function getMagentoVersion()
{
return $this->productMetadata->getVersion();
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use SimpleXMLElement;
use Zend\Http\Client\Adapter\Curl as CurlClient;
use Zend\Http\Response as HttpResponse;
use Zend\Uri\Http as HttpUri;
use Magento\Framework\Json\DecoderInterface;
class Notice extends AbstractHelper
{
/**
* @var CurlClient
*/
protected $curlClient;
/**
* @var \Magento\Framework\App\CacheInterface
*/
protected $cache;
/**
* @var \Magento\Framework\Module\Dir\Reader
*/
private $moduleReader;
/**
* @var \Magento\Framework\Filesystem\Driver\File
*/
private $filesystem;
/**
* @var DecoderInterface
*/
private $jsonDecoder;
/**
* @var Config
*/
private $config;
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Framework\App\CacheInterface $cache,
\Magento\Framework\Module\Dir\Reader $moduleReader,
\Magento\Framework\Filesystem\Driver\File $filesystem,
DecoderInterface $jsonDecoder,
CurlClient $curl,
\Aitoc\Core\Helper\Config $config
) {
parent::__construct($context);
$this->cache = $cache;
$this->curlClient = $curl;
$this->moduleReader = $moduleReader;
$this->filesystem = $filesystem;
$this->jsonDecoder = $jsonDecoder;
$this->config = $config;
}
/**
* @return array
*/
public function getNotificationTypes()
{
return $this->config->getNotificationsType();
}
/**
* @return bool
*/
public function isEnable()
{
return $this->config->getNotificationsEnable();
}
/**
* @return mixed
*/
public function getFrequency()
{
return $this->config->getNotificationsFrequency();
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Model\Config\Source;
class Frequency implements \Magento\Framework\Option\ArrayInterface
{
/**
* @return array
*/
public function toOptionArray()
{
$options = [
[
'value' => 1,
'label' => __('1 Day')
],
[
'value' => 5,
'label' => __('5 Days')
],
[
'value' => 10,
'label' => __('10 Days')
]
];
return $options;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Model\Config\Source;
class NoticeType implements \Magento\Framework\Option\ArrayInterface
{
const PROMO = 'PROMO';
const EXTENSION_UPDATE_CUSTOMER = 'EXTENSION_UPDATE_CUSTOMER';
const EXTENSION_UPDATE = 'EXTENSION_UPDATE';
const NEW_EXTENSION = 'NEW_EXTENSION';
const NEWS = 'NEWS';
const TIPS_TRICKS = 'TIPS_TRICKS';
public function toOptionArray()
{
$types = [
[
'value' => self::NEWS,
'label' => __('Common News')
],
[
'value' => self::PROMO,
'label' => __('Promotions/Discounts')
],
[
'value' => self::EXTENSION_UPDATE_CUSTOMER,
'label' => __('My Extensions Updates')
],
[
'value' => self::EXTENSION_UPDATE,
'label' => __('All Extensions Updates')
],
[
'value' => self::NEW_EXTENSION,
'label' => __('New Extensions')
],
[
'value' => self::TIPS_TRICKS,
'label' => __('Magento Tricks & Tips')
]
];
return $types;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Model;
use Magento\Framework\Config\ConfigOptionsListConstants;
use Magento\Framework\Notification\MessageInterface;
/**
* AdminNotification Feed model
*/
class Feed extends \Magento\AdminNotification\Model\Feed
{
const AITOC_CACHE_NAME = 'aitoc_notifications_lastcheck';
const XML_USE_HTTPS_PATH = 'system/adminnotification/use_https';
const XML_FEED_URL_PATH = 'www.aitoc.com/feedrss';
const XML_FREQUENCY_PATH = 'system/adminnotification/frequency';
const XML_LAST_UPDATE_PATH = 'system/adminnotification/last_update';
/**
* Feed url
*
* @var string
*/
protected $_feedUrl;
/**
* @var \Magento\Backend\App\ConfigInterface
*/
protected $_backendConfig;
/**
* @var \Magento\AdminNotification\Model\InboxFactory
*/
protected $_inboxFactory;
/**
* @var \Magento\Framework\HTTP\Adapter\CurlFactory
*
*/
protected $curlFactory;
/**
* Deployment configuration
*
* @var \Magento\Framework\App\DeploymentConfig
*/
protected $_deploymentConfig;
/**
* @var \Magento\Framework\App\ProductMetadataInterface
*/
protected $productMetadata;
/**
* @var \Magento\Framework\UrlInterface
*/
protected $urlBuilder;
/**
* @var \Aitoc\Core\Helper\Notice
*/
private $noticeHelper;
/**
* @var \Aitoc\Core\Helper\Extension
*/
private $extensionHelper;
/**
* @var \Magento\Framework\App\Config\Storage\WriterInterface
*/
private $configWriter;
/**
* @var \Magento\Backend\App\ConfigInterface
*/
private $config;
/**
* @var \Magento\Framework\App\Config\ReinitableConfigInterface
*/
private $reinitableConfig;
/**
* @param \Magento\Framework\Model\Context $context
* @param \Magento\Framework\Registry $registry
* @param \Magento\Backend\App\ConfigInterface $backendConfig
* @param InboxFactory $inboxFactory
* @param \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory
* @param \Magento\Framework\App\DeploymentConfig $deploymentConfig
* @param \Magento\Framework\App\ProductMetadataInterface $productMetadata
* @param \Magento\Framework\UrlInterface $urlBuilder
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param array $data
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Backend\App\ConfigInterface $backendConfig,
\Magento\AdminNotification\Model\InboxFactory $inboxFactory,
\Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
\Magento\Framework\App\DeploymentConfig $deploymentConfig,
\Magento\Framework\App\ProductMetadataInterface $productMetadata,
\Magento\Framework\UrlInterface $urlBuilder,
\Aitoc\Core\Helper\Notice $noticeHelper,
\Aitoc\Core\Helper\Extensions $extensionHelper,
\Magento\Backend\App\ConfigInterface $config,
\Magento\Framework\App\Config\ReinitableConfigInterface $reinitableConfig,
\Magento\Framework\App\Config\Storage\WriterInterface $configWriter,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
) {
parent::__construct(
$context,
$registry,
$backendConfig,
$inboxFactory,
$curlFactory,
$deploymentConfig,
$productMetadata,
$urlBuilder,
$resource,
$resourceCollection,
$data
);
$this->noticeHelper = $noticeHelper;
$this->extensionHelper = $extensionHelper;
$this->config = $config;
$this->configWriter = $configWriter;
$this->reinitableConfig = $reinitableConfig;
}
/**
* Init model
*
* @return void
*/
protected function _construct()
{
}
/**
* Retrieve feed url
*
* @return string
*/
public function getFeedUrl()
{
$httpPath = $this->_backendConfig->isSetFlag(self::XML_USE_HTTPS_PATH) ? 'https://' : 'http://';
if ($this->_feedUrl === null) {
$this->_feedUrl = $httpPath . self::XML_FEED_URL_PATH;
}
return $this->_feedUrl;
}
/**
* Check feed for modification
*
* @return $this
*/
public function checkUpdate()
{
if ($this->getFrequency() + $this->getLastUpdate() > time()) {
return $this;
}
if (!$this->noticeHelper->isEnable()) {
return $this;
}
$feedData = [];
$feedXml = $this->getFeedData();
$installDate = $this->getFirstAitocRun();
if ($feedXml && $feedXml->channel && $feedXml->channel->item) {
foreach ($feedXml->channel->item as $item) {
$pubDate = strtotime((string)$item->pubDate);
$itemPublicationDate = strtotime((string)$item->pubDate);
if ($itemPublicationDate <= $installDate || !$this->isInteresting($item)) {
continue;
}
$feedData[] = [
'severity' => MessageInterface::SEVERITY_NOTICE,
'date_added' => date('Y-m-d H:i:s', $pubDate),
'title' => $this->escapeString($item->title),
'description' => $this->escapeString($item->description),
'url' => $this->escapeString($item->link),
'aitoc_notification' => 1
];
}
if ($feedData) {
$this->_inboxFactory->create()->parse(array_reverse($feedData));
}
}
$this->setLastUpdate();
return $this;
}
/**
* @return int|mixed
*/
private function getFirstAitocRun()
{
$coreConfigRunPath = 'aitoc_core/notifications/first_aitoc_run';
$result = $this->config->getValue($coreConfigRunPath);
if (!$result) {
$result = time();
$this->configWriter->save($coreConfigRunPath, $result);
$this->reinitableConfig->reinit();
}
return $result;
}
/**
* @param $item
* @return bool
*/
private function isInteresting($item)
{
$interests = $this->getTypes();
if (!$interests) {
return false;
}
if ($item->type != \Aitoc\Core\Model\Config\Source\NoticeType::EXTENSION_UPDATE
&& in_array((string)$item->type, $interests)
) {
return true;
}
if ($item->type == \Aitoc\Core\Model\Config\Source\NoticeType::EXTENSION_UPDATE
&& in_array(\Aitoc\Core\Model\Config\Source\NoticeType::EXTENSION_UPDATE_CUSTOMER, $interests)
&& !in_array(\Aitoc\Core\Model\Config\Source\NoticeType::EXTENSION_UPDATE, $interests)
) {
$extData = explode('-', (string)$item->extension);
if (!$extData) {
return false;
}
$extension = $extData[0];
if (array_key_exists(1, $extData)) {
$platform = $extData[1];
}
$isMagentoEE = $this->extensionHelper->getMagentoEdition() != 'Community';
if ($isMagentoEE && $platform == 'EE'
|| !$isMagentoEE && empty($platform)
) {
return $this->extensionHelper->isModuleEnabled($extension);
}
}
return false;
}
/**
* @return array
*/
private function getTypes()
{
return $this->noticeHelper->getNotificationTypes();
}
/**
* Retrieve Update Frequency
*
* @return int
*/
public function getFrequency()
{
return (int)$this->noticeHelper->getFrequency() * 60 * 60 * 24;
}
/**
* Retrieve Last update time
*
* @return int
*/
public function getLastUpdate()
{
return $this->_cacheManager->load(self::AITOC_CACHE_NAME);
}
/**
* Set last update time (now)
*
* @return $this
*/
public function setLastUpdate()
{
$this->_cacheManager->save(time(), self::AITOC_CACHE_NAME);
return $this;
}
/**
* Converts incoming data to string format and escapes special characters.
*
* @param \SimpleXMLElement $data
* @return string
*/
private function escapeString(\SimpleXMLElement $data)
{
return htmlspecialchars((string)$data);
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Model\Helpers;
class Date
{
/**
* @var \Magento\Framework\Stdlib\DateTime
*/
private $dateTime;
/**
* @var \Magento\Framework\Stdlib\DateTime\DateTime
*/
private $date;
/**
* @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
*/
private $timezone;
public function __construct(
\Magento\Framework\Stdlib\DateTime $dateTime,
\Magento\Framework\Stdlib\DateTime\DateTime $date,
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $timezone
) {
$this->dateTime = $dateTime;
$this->date = $date;
$this->timezone = $timezone;
}
/**
* @param bool $includedTime
*
* @return null|string
*/
public function getCurrentDate($includedTime = true)
{
return $this->dateTime->formatDate($this->date->gmtTimestamp(), $includedTime);
}
/**
* @param $stringTime
* @param bool $includedTime
*
* @return null|string
*/
public function getDateFromString($stringTime, $includedTime = true)
{
return $this->dateTime->formatDate($this->dateTime->strToTime($stringTime), $includedTime);
}
/**
* @param $stringTime
*
* @return int
*/
public function getTimestampFromString($stringTime)
{
return $this->dateTime->strToTime($stringTime);
}
/**
* @param $days
* @param bool $seconds
*
* @return int|null|string
*/
public function getCurrentDateAfterDays($days, $seconds = false)
{
$timestamp = $this->date->gmtTimestamp() + ($days * 24 * 3600);
return $seconds ? $timestamp : $this->dateTime->formatDate($timestamp);
}
/**
* @param $days
* @param bool $seconds
*
* @return int|null|string
*/
public function getCurrentDateBeforeDays($days, $seconds = false)
{
$timestamp = $this->date->gmtTimestamp() - ($days * 24 * 3600);
return $seconds ? $timestamp : $this->dateTime->formatDate($timestamp);
}
/**
* @return int
*/
public function getTimestamp()
{
return $this->date->gmtTimestamp();
}
/**
* @return string
*/
public function getTimezoneDate()
{
return $this->timezone->formatDate(null, \IntlDateFormatter::SHORT, true);
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Model;
class Logger extends \Magento\Framework\Logger\Monolog { }
\ No newline at end of file
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Model;
/**
* Class Platform
* @package Aitoc\Core\Model
*/
class Platform
{
const PLATFORMFILE_SUFFIX = '.platform.xml';
const CACHE_CLEAR_VERSION = '2.21.0';
const DEFAULT_VAR_PATH = 'var';
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Observer;
use Magento\Framework\Event\ObserverInterface;
/**
* AdminNotification observer
*
*/
class PredispatchAdminActionControllerObserver implements ObserverInterface
{
/**
* @var \Magento\AdminNotification\Model\FeedFactory
*/
protected $_feedFactory;
/**
* @var \Magento\Backend\Model\Auth\Session
*/
protected $_backendAuthSession;
/**
* @param \Aitoc\Core\Model\FeedFactory $feedFactory
* @param \Magento\Backend\Model\Auth\Session $backendAuthSession
*/
public function __construct(
\Aitoc\Core\Model\FeedFactory $feedFactory,
\Magento\Backend\Model\Auth\Session $backendAuthSession
) {
$this->_feedFactory = $feedFactory;
$this->_backendAuthSession = $backendAuthSession;
}
/**
* Predispatch admin action controller
*
* @param \Magento\Framework\Event\Observer $observer
* @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
if ($this->_backendAuthSession->isLoggedIn()) {
$feedModel = $this->_feedFactory->create();
/* @var $feedModel \Magento\AdminNotification\Model\Feed */
$feedModel->checkUpdate();
}
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Plugin\BackendMenu;
use Magento\Backend\Model\Menu\Config;
use Magento\Backend\Model\Menu;
use Aitoc\Core\Helper\Extensions;
use Magento\Config\Model\Config\Structure;
use Magento\Framework\App\ProductMetadataInterface;
use Magento\Backend\Model\Menu\Item;
use Magento\Backend\Model\Menu\ItemFactory;
use Magento\Backend\Model\Menu\Filter\IteratorFactory;
use Aitoc\Core\Model\Logger;
use Aitoc\Core\Helper\Config as AitocConfig;
class Builder
{
/**
* @var Config
*/
private $config;
/**
* @var AitocConfig
*/
private $aitocConfig;
/**
* @var ProductMetadataInterface
*/
private $productMetadata;
/**
* @var Extensions
*/
private $extensionHelper;
/**
* @var Structure
*/
private $configStructure;
/**
* @var ItemFactory
*/
private $itemFactory;
/**
* @var IteratorFactory
*/
private $iteratorFactory;
/**
* @var Logger
*/
private $logger;
public function __construct(
Config $config,
AitocConfig $aitocConfig,
ProductMetadataInterface $productMetadata,
Extensions $extensionHelper,
Structure $configStructure,
ItemFactory $itemFactory,
IteratorFactory $iteratorFactory,
Logger $logger
) {
$this->config = $config;
$this->aitocConfig = $aitocConfig;
$this->productMetadata = $productMetadata;
$this->extensionHelper = $extensionHelper;
$this->configStructure = $configStructure;
$this->itemFactory = $itemFactory;
$this->iteratorFactory = $iteratorFactory;
$this->logger = $logger;
}
/**
* @param $subject
* @param Menu $menu
* @return Menu
*/
public function afterGetResult($subject, Menu $menu)
{
return $menu->get('Aitoc_Core::menu') ? $this->buildMenu($menu): $menu;
}
/**
* @param Menu $menu
* @return Menu
*/
private function buildMenu(Menu $menu)
{
$menuWithoutAitoc = $this->isRemoveAitocTab($menu);
if ($menuWithoutAitoc) {
return $menuWithoutAitoc;
}
try {
$configItems = $this->getItemsFromConfig();
$extensionData = [];
$aitocExtensions = $this->extensionHelper->getAitocExtensions(true);
foreach ($aitocExtensions as $extCode) {
if (!empty($configItems[$extCode]['label']) && $configItems[$extCode]['label']) {
$label = $configItems[$extCode]['label'];
} elseif ($extInfo = $this->extensionHelper->getExtInfo($extCode) && !empty($extInfo['description'])) {
$label = $extInfo['description'];
} else {
$label = explode('_', $extCode)[1];
}
$extensionData[$label] = $extCode;
}
$this->render($extensionData, $configItems, $menu);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
return $menu;
}
/**
* @param array $extensionData
* @param array $configItems
* @param Menu $menu
* @throws \Exception
*/
private function render($extensionData, $configItems, Menu $menu)
{
$menuItems = $this->getMenuItems($this->config->getMenu());
foreach ($extensionData as $label => $extCode) {
$renderedItems = [];
if (!empty($menuItems[$extCode])) {
$renderedItems = array_merge($renderedItems, $this->getRenderedItemsByExtension($menuItems[$extCode], $menu));
}
if (!empty($configItems[$extCode]['id'])) {
$renderedItems[] = $this->renderItem(
$extCode . '_aitocMenu',
$extCode,
__('🔧 Configuration')->render(),
'Aitoc_Core::menu',
'adminhtml/system_config/edit/section/' . $configItems[$extCode]['id']
);
}
if ($renderedItems) {
$itemId = $extCode . 'aitocMenu';
/** @var Item $mainItem */
$mainItem = $this->itemFactory->create(['data' => [
'id' => $itemId,
'title' => $label,
'module' => $extCode,
'resource' => 'Aitoc_Core::menu'
]]);
$menu->add($mainItem, 'Aitoc_Core::menu', 1);
foreach ($renderedItems as $item) {
$menu->add($item, $itemId);
}
}
}
}
/**
* @param Menu $menu
* @return bool|Menu
*/
private function isRemoveAitocTab(Menu $menu)
{
if (!$this->aitocConfig->getMenuEnable()
|| version_compare($this->productMetadata->getVersion(), '2.2', '<')
) {
$menu->remove('Aitoc_Core::menu');
return $menu;
}
return false;
}
/**
* @param array $menuItems
* @param Menu $menu
* @return array
*/
private function getRenderedItemsByExtension($menuItems, Menu $menu)
{
$newItems = [];
foreach ($menuItems as $itemId) {
$item = $menu->get($itemId);
if ($item) {
$item = $item->toArray();
if (isset($item['id']) && isset($item['title']) && isset($item['resource']) && isset($item['action'])) {
$extension = empty($item['module']) ? explode('::', $item['resource'])[0] : $item['module'];
$newItems[] = $this->renderItem(
$item['id'] . '_aitocMenu',
$extension,
$item['title'],
$item['resource'],
$item['action']
);
}
}
}
return $newItems;
}
/**
* @param string $id
* @param string $extension
* @param string $title
* @param string $resource
* @param string $url
* @return Item|null
*/
private function renderItem($id, $extension, $title, $resource, $url)
{
try {
$item = $this->itemFactory->create(['data' => [
'id' => $id,
'module' => $extension,
'title' => $title,
'action' => $url,
'resource' => $resource
]]);
} catch (\Exception $e) {
$this->logger->warning($e->getMessage());
$item = null;
}
return $item;
}
/**
* @param Menu $menu
* @return array
*/
private function getMenuItems(Menu $menu)
{
$menuItems = [];
foreach ($this->generateMenuItems($menu) as $item) {
$name = explode('::', $item)[0];
if (!isset($menuItems[$name])) {
$menuItems[$name] = [];
}
$menuItems[$name][] = $item;
}
return $menuItems;
}
/**
* @param Menu $menu
* @return array
*/
private function generateMenuItems(Menu $menu)
{
$menuItems = [];
foreach ($this->iteratorFactory->create(['iterator' => $menu->getIterator()]) as $menuItem) {
/** @var Item $menuItem */
if ($this->validateMenuItem($menuItem)) {
$menuItems[] = $menuItem->getId();
}
if ($menuItem->hasChildren()) {
$menuItems = array_merge($menuItems, $this->generateMenuItems($menuItem->getChildren()));
}
}
return $menuItems;
}
/**
* @return array
*/
private function getItemsFromConfig()
{
$configItems = [];
foreach ($this->configStructure->getTabs() as $tab) {
if ($tab->getId() == 'aitoc_extensions') {
foreach ($tab->getChildren() as $item) {
$itemData = $item->getData('resource');
if (!empty($itemData['id']) && $itemData['id'] && !empty($itemData['resource'])) {
$name = explode('::', $itemData['resource'])[0];
$configItems[$name] = $itemData;
}
}
break;
}
}
return $configItems;
}
/**
* @param Item $menuItem
* @return bool
*/
private function validateMenuItem(Item $menuItem)
{
return $menuItem->getAction()
&& strpos($menuItem->getAction(), 'system_config') === false
&& strpos($menuItem->getId(), 'Aitoc') !== false
&& strpos($menuItem->getId(), 'Aitoc_Core') === false;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Plugin\BackendMenu;
use Magento\Backend\Model\Menu\Item as NativeItem;
class Item
{
/**
* @param NativeItem $subject
* @param $url
* @return string
*/
public function afterGetUrl(NativeItem $subject, $url)
{
$id = $subject->getId();
if ($id == 'Aitoc_Core::marketplace') {
return 'https://www.aitoc.com/magento-2-extensions.html?utm_source=extensions_promo&utm_medium=backend&utm_campaign=from_magento_2_menu';
} else {
return $url;
}
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Plugin\Notifications;
/**
* Class AitocNotificationLogoAdd
* @package Aitoc\Core\Plugin\Notifications
*/
class AitocNotificationLogoAdd
{
/**
* @param \Magento\AdminNotification\Block\Grid\Renderer\Notice $subject
* @param \Closure $proceed
* @param \Magento\Framework\DataObject $row
* @return mixed|string
*/
public function aroundRender(
\Magento\AdminNotification\Block\Grid\Renderer\Notice $subject,
\Closure $proceed,
\Magento\Framework\DataObject $row
) {
$result = $proceed($row);
if ($row->getData(\Aitoc\Core\Api\ColumnInterface::AITOC_NOTIFICATION_FIELD)) {
return '<div class="aitoc-grid-message"><div class="aitoc-notif-logo"></div>' . $result . '</div>';
} else {
return $result;
}
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Plugin\Notifications;
use Magento\AdminNotification\Block\ToolbarEntry as NativeToolbarEntry;
class AitocNotificationLogoAddInToolbar
{
/**
* @param NativeToolbarEntry $subject
* @param $html
* @return mixed
*/
public function afterToHtml(
NativeToolbarEntry $subject,
$html
) {
return $this->getReplacedLogoWithHtml($subject, $html);
}
/**
* @param NativeToolbarEntry $subject
* @return \Magento\AdminNotification\Model\ResourceModel\Inbox\Collection
*/
private function getAitocNotificationsCollection(NativeToolbarEntry $subject)
{
return $subject->getLatestUnreadNotifications()
->clear()
->addFieldToFilter(\Aitoc\Core\Api\ColumnInterface::AITOC_NOTIFICATION_FIELD, 1);
}
/**
* @param NativeToolbarEntry $subject
* @param $html
* @return mixed
*/
private function getReplacedLogoWithHtml(NativeToolbarEntry $subject, $html)
{
foreach ($this->getAitocNotificationsCollection($subject) as $item) {
$search = 'data-notification-id="' . $item->getId() . '"';
$html = str_replace($search, $search . ' data-aitcore-logo="1"', $html);
}
return $html;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
namespace Aitoc\Core\Plugin\Notifications;
class GridActions
{
const CONFIG_AITOC_CORE_SECTION_NAME = 'aitoc_core';
/**
* @var \Magento\Framework\UrlInterface
*/
private $urlBuilder;
/**
* GridActions constructor.
* @param \Magento\Framework\UrlInterface $urlBuilder
*/
public function __construct(
\Magento\Framework\UrlInterface $urlBuilder
) {
$this->urlBuilder = $urlBuilder;
}
/**
* @param NativeActions $subject
* @param \Closure $proceed
* @param \Magento\Framework\DataObject $row
* @return mixed|string
*/
public function aroundRender(
\Magento\AdminNotification\Block\Grid\Renderer\Actions $subject,
\Closure $proceed,
\Magento\Framework\DataObject $row
) {
$result = $proceed($row);
if ($row->getData(\Aitoc\Core\Api\ColumnInterface::AITOC_NOTIFICATION_FIELD)) {
$result .= sprintf(
'<a class="action" href="%s" title="%s">%s</a>',
$this->getDisableUrl(),
__('Disable Notifications'),
__('Disable Notifications')
);
}
return $result;
}
/**
* @return string
*/
private function getDisableUrl()
{
return $this->urlBuilder->getUrl('adminhtml/system_config/edit/'). 'section/'
. self::CONFIG_AITOC_CORE_SECTION_NAME;
}
}
<?php
namespace Aitoc\Core\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
class UpgradeSchema implements UpgradeSchemaInterface
{
const AITOC_NOTIFICATION_FIELD = 'aitoc_notification';
/**
* @param SchemaSetupInterface $setup
* @param ModuleContextInterface $context
*/
public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
if (version_compare($context->getVersion(), '1.0.1', '<')) {
$this->addAitocNotificationField($setup);
}
}
/**
* @param SchemaSetupInterface $setup
*/
private function addAitocNotificationField(SchemaSetupInterface $setup)
{
$setup->getConnection()->addColumn(
$setup->getTable('adminnotification_inbox'),
self::AITOC_NOTIFICATION_FIELD,
\Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
null,
['nullable' => false, 'default' => 0],
'Aitoc Notification'
);
}
}
{
"name": "aitoc/core",
"description": "Core extension by Aitoc",
"type": "magento2-module",
"version": "1.0.16",
"license": [
"Commercial"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Aitoc\\Core\\": ""
}
}
}
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<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="Aitoc_Core::config"
title="Aitoc - General Information"
sortOrder="100" />
</resource>
</resource>
</resource>
<resource id="Aitoc_Core::menu" title="Aitoc Extensions" translate="title" sortOrder="101">
<resource id="Aitoc_Core::marketplace" title="Aitoc Marketplace" translate="title" sortOrder="1"/>
</resource>
</resource>
</resources>
</acl>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\AdminNotification\Block\ToolbarEntry">
<plugin name="Aitoc_Core::add-aitoc-logo-in-toolbar"
type="Aitoc\Core\Plugin\Notifications\AitocNotificationLogoAddInToolbar"/>
</type>
<type name="Magento\AdminNotification\Block\Grid\Renderer\Notice">
<plugin name="Aitoc_Core::add-aitoc-logo"
type="Aitoc\Core\Plugin\Notifications\AitocNotificationLogoAdd"/>
</type>
<type name="Magento\AdminNotification\Block\Grid\Renderer\Actions">
<plugin name="Aitoc_Core::add-disable-notifications"
type="Aitoc\Core\Plugin\Notifications\GridActions"/>
</type>
<type name="Magento\Backend\Model\Menu\Item">
<plugin name="Aitoc_Core:replaceMarketplaceUrl"
type="Aitoc\Core\Plugin\BackendMenu\Item" />
</type>
<type name="Magento\Backend\Model\Menu\Builder">
<plugin name="Aitoc_Core::aitocMenuBuilder" type="Aitoc\Core\Plugin\BackendMenu\Builder" />
</type>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="controller_action_predispatch">
<observer name="aitoc_adminnotification" instance="Aitoc\Core\Observer\PredispatchAdminActionControllerObserver" />
</event>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="Aitoc_Core::menu" title="Aitoc" module="Aitoc_Core" translate="title" sortOrder="81" resource="Aitoc_Core::menu"/>
<add id="Aitoc_Core::common" title="Configuration &amp; Promo" translate="title" module="Aitoc_Core" sortOrder="1498" parent="Aitoc_Core::menu" resource="Aitoc_Core::menu"/>
</menu>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="aitcore" frontName="aitcore">
<module name="Aitoc_Core"/>
</route>
</router>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="aitoc_extensions" translate="label" sortOrder="999998" class="aitoc-tab">
<label>Aitoc Extensions</label>
</tab>
<section id="aitoc_core" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label><![CDATA[Information &amp; Marketplace]]></label>
<tab>aitoc_extensions</tab>
<resource>Aitoc_Core::config</resource>
<group id="menu" translate="label" type="text" sortOrder="15" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Aitoc Menu</label>
<field id="menu_enable" translate="label comment" type="select" sortOrder="25" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Enable Aitoc Menu</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
<group id="notifications" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Notifications</label>
<field id="notice_enable" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Enable Notifications</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>Select Yes if you want get latest information about new or updated Aitoc extensions, discounts, atricles and etc.</comment>
</field>
<field id="notice_type" translate="label comment" type="multiselect" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
<label>I'd like to be informed by Aitoc about:</label>
<source_model>Aitoc\Core\Model\Config\Source\NoticeType</source_model>
<comment>Select notice types that you want to receive notifications</comment>
<depends>
<field id="notice_enable">1</field>
</depends>
</field>
<field id="frequency" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Update Frequency</label>
<source_model>Aitoc\Core\Model\Config\Source\Frequency</source_model>
</field>
<field id="last_update" translate="label" type="label" sortOrder="40" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Last Update</label>
<frontend_model>Aitoc\Core\Block\System\Config\Form\Field\Notification</frontend_model>
</field>
</group>
</section>
</system>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<aitoc_core>
<notifications>
<notice_type>PROMO,EXTENSION_UPDATE_CUSTOMER,EXTENSION_UPDATE,NEW_EXTENSION,NEWS,TIPS_TRICKS</notice_type>
<notice_enable>1</notice_enable>
<frequency>1</frequency>
</notifications>
<menu>
<menu_enable>1</menu_enable>
</menu>
</aitoc_core>
</default>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<!--
~ Copyright © Aitoc. All rights reserved.
-->
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="adminnotification_inbox" resource="default" engine="innodb">
<column xsi:type="smallint" name="aitoc_notification" unsigned="true" nullable="false" default="0" comment="Aitoc Notification"/>
</table>
</schema>
{
"adminnotification_inbox": {
"column": {
"aitoc_notification": true
}
}
}
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<virtualType name="Aitoc\Core\Model\VirtualLoggerHandler" type="Magento\Framework\Logger\Handler\Base">
<arguments>
<argument name="fileName" xsi:type="string">/var/log/aitoc.log</argument>
</arguments>
</virtualType>
<type name="Aitoc\Core\Model\Logger">
<arguments>
<argument name="handlers" xsi:type="array">
<item name="system" xsi:type="object">Aitoc\Core\Model\VirtualLoggerHandler</item>
<item name="debug" xsi:type="object">Aitoc\Core\Model\VirtualLoggerHandler</item>
<item name="error" xsi:type="object">Aitoc\Core\Model\VirtualLoggerHandler</item>
<item name="critical" xsi:type="object">Aitoc\Core\Model\VirtualLoggerHandler</item>
</argument>
</arguments>
</type>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
<module name="Aitoc_Core" setup_version="1.0.5" />
</config>
Enabled,Enabled
Disabled,Disabled
"(New version %1 is available in your account: ","(New version %1 is available in your account: "
"Get Update","Get Update"
"1 Day","1 Day"
"5 Days","5 Days"
"10 Days","10 Days"
"Common News","Common News"
Promotions/Discounts,Promotions/Discounts
"My Extensions Updates","My Extensions Updates"
"All Extensions Updates","All Extensions Updates"
"New Extensions","New Extensions"
"Magento Tricks & Tips","Magento Tricks & Tips"
"Disable Notifications","Disable Notifications"
"<style>
.config-nav-block.aitoc-tab .title {
padding-top: 15px;
padding-bottom: 15px;
}
.config-nav-block.aitoc-tab strong:before {
background: no-repeat url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjAuNCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Cgkuc3Qwe2ZpbGw6IzBCQzdGRjt9Cgkuc3Qxe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+CjxnPgoJPGc+CgkJPHBhdGggZD0iTTI3MC4zLDMyNy44SDIxOWwyNS42LTYyLjRsLTQxLjEtMTAwbC0xMDcsMjYwLjJjLTIuNyw2LjYsMi4xLDEzLjgsOS4yLDEzLjhoNTMuOWM4LjEsMCwxNS40LTQuOSwxOC41LTEyLjRsMi44LTYuNwoJCQljNi4yLTE1LDIwLjgtMjQuOCwzNy0yNC44aDc2YzEuNCwwLDIuOCwwLjEsNC4yLDAuMkwyNzAuMywzMjcuOHoiLz4KCTwvZz4KPC9nPgo8cGF0aCBkPSJNMjI5LjgsMTM3LjdoNTMuOWM4LjEsMCwxNS40LDQuOSwxOC41LDEyLjRsMTEzLjIsMjc1LjRjMi43LDYuNi0yLjEsMTMuOC05LjIsMTMuOGgtNTMuOWMtOC4xLDAtMTUuNC00LjktMTguNS0xMi40CglMMjIwLjYsMTUxLjVDMjE3LjksMTQ1LDIyMi43LDEzNy43LDIyOS44LDEzNy43eiIvPgo8Y2lyY2xlIGN4PSIyNTYiIGN5PSI3Ny4zIiByPSIzMy4xIi8+Cjwvc3ZnPgo=');
background-size: 28px 28px;
width: 26px;
height: 30px;
content: '';
display: inline-block;
vertical-align: middle;
}
</style>
Aitoc Extensions","<style>
.config-nav-block.aitoc-tab .title {
padding-top: 15px;
padding-bottom: 15px;
}
.config-nav-block.aitoc-tab strong:before {
background: no-repeat url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjAuNCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Cgkuc3Qwe2ZpbGw6IzBCQzdGRjt9Cgkuc3Qxe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+CjxnPgoJPGc+CgkJPHBhdGggZD0iTTI3MC4zLDMyNy44SDIxOWwyNS42LTYyLjRsLTQxLjEtMTAwbC0xMDcsMjYwLjJjLTIuNyw2LjYsMi4xLDEzLjgsOS4yLDEzLjhoNTMuOWM4LjEsMCwxNS40LTQuOSwxOC41LTEyLjRsMi44LTYuNwoJCQljNi4yLTE1LDIwLjgtMjQuOCwzNy0yNC44aDc2YzEuNCwwLDIuOCwwLjEsNC4yLDAuMkwyNzAuMywzMjcuOHoiLz4KCTwvZz4KPC9nPgo8cGF0aCBkPSJNMjI5LjgsMTM3LjdoNTMuOWM4LjEsMCwxNS40LDQuOSwxOC41LDEyLjRsMTEzLjIsMjc1LjRjMi43LDYuNi0yLjEsMTMuOC05LjIsMTMuOGgtNTMuOWMtOC4xLDAtMTUuNC00LjktMTguNS0xMi40CglMMjIwLjYsMTUxLjVDMjE3LjksMTQ1LDIyMi43LDEzNy43LDIyOS44LDEzNy43eiIvPgo8Y2lyY2xlIGN4PSIyNTYiIGN5PSI3Ny4zIiByPSIzMy4xIi8+Cjwvc3ZnPgo=');
background-size: 28px 28px;
width: 26px;
height: 30px;
content: '';
display: inline-block;
vertical-align: middle;
}
</style>
Aitoc Extensions"
"Information &amp; Marketplace","Information &amp; Marketplace"
Notifications,Notifications
"Enable Notifications","Enable Notifications"
"Select Yes if you want get latest information about new or updated Aitoc extensions, discounts, atricles and etc.","Select Yes if you want get latest information about new or updated Aitoc extensions, discounts, atricles and etc."
"I'd like to be informed by Aitoc about:","I'd like to be informed by Aitoc about:"
"Select notice types that you want to receive notifications","Select notice types that you want to receive notifications"
"Update Frequency","Update Frequency"
"Last Update","Last Update"
"Installed Extensions","Installed Extensions"
"Aitoc Marketplace","Aitoc Marketplace"
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
/**
* Copyright © 2019 Aitoc. All rights reserved.
*/
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Aitoc_Core',
__DIR__
);
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="Aitoc_Core::css/config.css"/>
</head>
</page>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Core
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="Aitoc_Core::css/main.css"/>
</head>
</page>
.aitoc-button-get-new-version {
text-decoration: none;
border-bottom: 2px solid #0bc7ff;
color: #fff;
background-color: #0bc7ff;
border: 2px solid #0bc7ff;
padding: 5px;
height: 55px;
font-size: 16px;
font-weight: 600;
border-radius: 6px;
}
.aitoc-button-get-new-version:hover {
color: #fff;
text-decoration: unset;
}
.comment.aitoc-support {
font-size: 18px;
text-align: center;
margin-bottom: 2rem;
margin-top: 4rem;
}
.config-nav-block.aitoc-tab .title {
padding-top: 15px;
padding-bottom: 15px;
}
.config-nav-block.aitoc-tab strong:before {
background: no-repeat url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjAuNCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Cgkuc3Qwe2ZpbGw6IzBCQzdGRjt9Cgkuc3Qxe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+CjxnPgoJPGc+CgkJPHBhdGggZD0iTTI3MC4zLDMyNy44SDIxOWwyNS42LTYyLjRsLTQxLjEtMTAwbC0xMDcsMjYwLjJjLTIuNyw2LjYsMi4xLDEzLjgsOS4yLDEzLjhoNTMuOWM4LjEsMCwxNS40LTQuOSwxOC41LTEyLjRsMi44LTYuNwoJCQljNi4yLTE1LDIwLjgtMjQuOCwzNy0yNC44aDc2YzEuNCwwLDIuOCwwLjEsNC4yLDAuMkwyNzAuMywzMjcuOHoiLz4KCTwvZz4KPC9nPgo8cGF0aCBkPSJNMjI5LjgsMTM3LjdoNTMuOWM4LjEsMCwxNS40LDQuOSwxOC41LDEyLjRsMTEzLjIsMjc1LjRjMi43LDYuNi0yLjEsMTMuOC05LjIsMTMuOGgtNTMuOWMtOC4xLDAtMTUuNC00LjktMTguNS0xMi40CglMMjIwLjYsMTUxLjVDMjE3LjksMTQ1LDIyMi43LDEzNy43LDIyOS44LDEzNy43eiIvPgo8Y2lyY2xlIGN4PSIyNTYiIGN5PSI3Ny4zIiByPSIzMy4xIi8+Cjwvc3ZnPgo=');
background-size: 28px 28px;
width: 26px;
height: 30px;
content: '';
display: inline-block;
vertical-align: middle;
}
.aitoc-get-support-button {
width: 160px;
height: 40px;
border-radius: 16px;
background-color: #7ed321;
line-height: 38px;
font-size: 18px !important;
margin-left: 5px;
text-align: center;
display: inline-block !important;
color: #fff !important;
text-decoration: none;
vertical-align: middle;
font-weight: 600 !important;
}
.label.aitcore-legend {
margin: auto !important;
text-align: center !important;
font-size: 20px !important;
padding: 20px !important;
}
\ No newline at end of file
.aitoc-grid-message .aitoc-notif-logo {
margin-right: 15px;
height: 75px;
width: 60px;
float: left;
display: inline-block;
background: url(../images/logo-53x53.png) no-repeat;
background-position-y: 10px;
background-size: 53px;
border-right: 1px dashed gray;
}
.admin__action-dropdown-menu .notifications-entry[data-aitcore-logo="1"] {
padding-left: 37px;
background: url(../images/logo-30x30.png) no-repeat 5px 15px;
background-size: 30px;
}
div.aitoc-grid-message > div.ambase-grid-message {
padding-left: 0px;
min-height: 0px;
background: unset;
}
.config-nav-block.aitoc-tab .title {
padding-top: 15px;
padding-bottom: 15px;
}
.config-nav-block.aitoc-tab strong:before {
background: no-repeat url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIzLjAuNCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCA1MTIgNTEyOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Cgkuc3Qwe2ZpbGw6IzBCQzdGRjt9Cgkuc3Qxe2ZpbGw6I0ZGRkZGRjt9Cjwvc3R5bGU+CjxnPgoJPGc+CgkJPHBhdGggZD0iTTI3MC4zLDMyNy44SDIxOWwyNS42LTYyLjRsLTQxLjEtMTAwbC0xMDcsMjYwLjJjLTIuNyw2LjYsMi4xLDEzLjgsOS4yLDEzLjhoNTMuOWM4LjEsMCwxNS40LTQuOSwxOC41LTEyLjRsMi44LTYuNwoJCQljNi4yLTE1LDIwLjgtMjQuOCwzNy0yNC44aDc2YzEuNCwwLDIuOCwwLjEsNC4yLDAuMkwyNzAuMywzMjcuOHoiLz4KCTwvZz4KPC9nPgo8cGF0aCBkPSJNMjI5LjgsMTM3LjdoNTMuOWM4LjEsMCwxNS40LDQuOSwxOC41LDEyLjRsMTEzLjIsMjc1LjRjMi43LDYuNi0yLjEsMTMuOC05LjIsMTMuOGgtNTMuOWMtOC4xLDAtMTUuNC00LjktMTguNS0xMi40CglMMjIwLjYsMTUxLjVDMjE3LjksMTQ1LDIyMi43LDEzNy43LDIyOS44LDEzNy43eiIvPgo8Y2lyY2xlIGN4PSIyNTYiIGN5PSI3Ny4zIiByPSIzMy4xIi8+Cjwvc3ZnPgo=');
background-size: 28px 28px;
width: 26px;
height: 30px;
margin-left: -3px;
content: '';
display: inline-block;
vertical-align: middle;
}
.admin__menu [data-ui-id^="menu-aitoc-"] .submenu-group-title span:before,
.admin__menu [data-ui-id^="menu-magento-"] [data-ui-id^="menu-magento-"] [data-ui-id^="menu-aitoc-"] span:before {
background: url(../images/logo-30x30.png) no-repeat;
width: 27px;
height: 30px;
content: '';
display: inline-block;
margin-right: 6px;
vertical-align: top;
margin-top: -5px;
}
#menu-aitoc-core-menu span::before {
background: unset;
content: '';
width: 0;
height: 0;
margin-top: 0;
margin-right: 0;
}
#menu-aitoc-core-menu > a:before {
content: '' !important;
background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB3aWR0aD0iNTMiIGhlaWdodD0iNTMiPgoJPHN0eWxlPgoJCXRzcGFuIHsgd2hpdGUtc3BhY2U6cHJlIH0KCQkuc2hwMCB7IGZpbGw6ICNhYWE2YTAgfSAKCTwvc3R5bGU+Cgk8ZyA+CgkJPGcgPgoJCQk8cGF0aCBjbGFzcz0ic2hwMCIgZD0iTTI3MC4zLDMyNy44aC01MS4zbDI1LjYsLTYyLjRsLTQxLjEsLTEwMGwtMTA3LDI2MC4yYy0yLjcsNi42IDIuMSwxMy44IDkuMiwxMy44aDUzLjljOC4xLDAgMTUuNCwtNC45IDE4LjUsLTEyLjRsMi44LC02LjdjNi4yLC0xNSAyMC44LC0yNC44IDM3LC0yNC44aDc2YzEuNCwwIDIuOCwwLjEgNC4yLDAuMnoiIC8+CgkJPC9nPgoJPC9nPgoJPHBhdGggY2xhc3M9InNocDAiIGQ9Ik0yMjkuOCwxMzcuN2g1My45YzguMSwwIDE1LjQsNC45IDE4LjUsMTIuNGwxMTMuMiwyNzUuNGMyLjcsNi42IC0yLjEsMTMuOCAtOS4yLDEzLjhoLTUzLjljLTguMSwwIC0xNS40LC00LjkgLTE4LjUsLTEyLjRsLTExMy4yLC0yNzUuNGMtMi43LC02LjUgMi4xLC0xMy44IDkuMiwtMTMuOHoiIC8+Cgk8cGF0aCBjbGFzcz0ic2hwMCIgZD0iTTI4OS4xLDc3LjNjMCwtMTguMyAtMTQuOCwtMzMuMSAtMzMuMSwtMzMuMWMtMTguMywwIC0zMy4xLDE0LjggLTMzLjEsMzMuMWMwLDE4LjMgMTQuOCwzMy4xIDMzLjEsMzMuMWMxOC4zLDAgMzMuMSwtMTQuOCAzMy4xLC0zMy4xeiIgLz4KPC9zdmc+')
no-repeat center !important;;
background-size: contain !important;;
font-size: 3rem !important;;
height: 3.5rem !important;;
}
#menu-aitoc-core-menu > a:hover:before, #menu-aitoc-core-menu._show > a:before {
background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB3aWR0aD0iNTMiIGhlaWdodD0iNTMiPgoJPHN0eWxlPgoJCXRzcGFuIHsgd2hpdGUtc3BhY2U6cHJlIH0KCQkuc2hwMCB7IGZpbGw6ICNmZmZmZmYgfSAKCTwvc3R5bGU+Cgk8ZyA+CgkJPGcgPgoJCQk8cGF0aCBjbGFzcz0ic2hwMCIgZD0iTTI3MC4zLDMyNy44aC01MS4zbDI1LjYsLTYyLjRsLTQxLjEsLTEwMGwtMTA3LDI2MC4yYy0yLjcsNi42IDIuMSwxMy44IDkuMiwxMy44aDUzLjljOC4xLDAgMTUuNCwtNC45IDE4LjUsLTEyLjRsMi44LC02LjdjNi4yLC0xNSAyMC44LC0yNC44IDM3LC0yNC44aDc2YzEuNCwwIDIuOCwwLjEgNC4yLDAuMnoiIC8+CgkJPC9nPgoJPC9nPgoJPHBhdGggY2xhc3M9InNocDAiIGQ9Ik0yMjkuOCwxMzcuN2g1My45YzguMSwwIDE1LjQsNC45IDE4LjUsMTIuNGwxMTMuMiwyNzUuNGMyLjcsNi42IC0yLjEsMTMuOCAtOS4yLDEzLjhoLTUzLjljLTguMSwwIC0xNS40LC00LjkgLTE4LjUsLTEyLjRsLTExMy4yLC0yNzUuNGMtMi43LC02LjUgMi4xLC0xMy44IDkuMiwtMTMuOHoiIC8+Cgk8cGF0aCBjbGFzcz0ic2hwMCIgZD0iTTI4OS4xLDc3LjNjMCwtMTguMyAtMTQuOCwtMzMuMSAtMzMuMSwtMzMuMWMtMTguMywwIC0zMy4xLDE0LjggLTMzLjEsMzMuMWMwLDE4LjMgMTQuOCwzMy4xIDMzLjEsMzMuMWMxOC4zLDAgMzMuMSwtMTQuOCAzMy4xLC0zMy4xeiIgLz4KPC9zdmc+')
no-repeat center;
background-size: contain;
}
.admin__action-dropdown-menu .notifications-entry[data-aitcore-logo="1"]:not(.notifications-entry-last) {
padding-left: 37px;
background: url(../images/logo-30x30.png) no-repeat 5px 5px;
background-size: 30px;
}
.admin__action-dropdown-menu .notifications-entry:not(.notifications-entry-last) {
border-bottom: 1px dashed gray;
}
div.aitoc-grid-message span.grid-row-title {
font-weight: 600;
}
\ No newline at end of file
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Api\Data;
/**
* Interface LogInterface
* @package Aitoc\Smtp\Api\Data
*/
interface LogInterface
{
/**
* Constants
*/
const TABLE_NAME = 'aitoc_smtp_log';
const LOG_ID = 'log_id';
const CREATED_AT = 'created_at';
const SUBJECT = 'subject';
const EMAIL_BODY = 'email_body';
const SENDER_EMAIL = 'sender_email';
const RECIPIENT_EMAIL = 'recipient_email';
const CC = 'cc';
const BCC = 'bcc';
const STATUS = 'status';
const STATUS_MESSAGE = 'status_message';
/**
* @return int
*/
public function getLogId();
/**
* @param int $logId
* @return LogInterface
*/
public function setLogId($logId);
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Block\Adminhtml\Log;
use Aitoc\Smtp\Controller\RegistryConstants;
class Preview extends \Magento\Backend\Block\Widget
{
const LOG_PARAM_URL_KEY = 'log_id';
/**
* @var \Magento\Framework\Filter\Input\MaliciousCode
*/
protected $_maliciousCode;
/**
* @var \Aitoc\Smtp\Model\LogFactory
*/
private $logFactory;
/**
* @var \Aitoc\Smtp\Model\Config
*/
private $config;
/**
* @var string
*/
protected $profilerName = 'email_template_proccessing';
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param \Magento\Framework\Filter\Input\MaliciousCode $maliciousCode
* @param \Magento\Email\Model\TemplateFactory $emailFactory
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Magento\Framework\Filter\Input\MaliciousCode $maliciousCode,
\Aitoc\Smtp\Model\LogFactory $logFactory,
\Aitoc\Smtp\Model\Config $config,
array $data = []
) {
$this->logFactory = $logFactory;
$this->_maliciousCode = $maliciousCode;
$this->config = $config;
parent::__construct($context, $data);
}
/**
* @return mixed|string
* @throws \Exception
*/
protected function _toHtml()
{
$logModel = $this->getCurrentLog();
$string = $logModel->getEmailBody();
if ($this->config->isNewSender(RegistryConstants::VERSION_COMPARISON_NEW_MAIL)) {
$string = quoted_printable_decode($string);
}
if ($logModel->getId()) {
return '<iframe onload="resizeIframe(this)" srcdoc="'. $string . '" style="width: 100%; height: 100%"></iframe>';
} else {
throw new \Exception('Log with ID not found. Pleas try again');
}
return $logModel;
}
/**
* @return mixed
*/
public function getCurrentLog()
{
return $this->logFactory->create()->getLogById($this->getRequest()->getParam(self::LOG_PARAM_URL_KEY));
}
/**
* Get either default or any store view
*
* @return \Magento\Store\Model\Store|null
*/
protected function getAnyStoreView()
{
$store = $this->_storeManager->getDefaultStoreView();
if ($store) {
return $store;
}
foreach ($this->_storeManager->getStores() as $store) {
return $store;
}
return null;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Block\Adminhtml;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
class Provider extends Field
{
protected $_template = 'Aitoc_Smtp::config/provider.phtml';
/**
* @var \Aitoc\Smtp\Model\Providers
*/
private $providers;
/**
* @var \Magento\Framework\Json\EncoderInterface
*/
private $jsonEncoder;
public function __construct(
\Magento\Backend\Block\Template\Context $context,
\Aitoc\Smtp\Model\Providers $providers,
\Magento\Framework\Json\EncoderInterface $jsonEncoder,
array $data = []
) {
$this->providers = $providers;
$this->jsonEncoder = $jsonEncoder;
parent::__construct($context, $data);
}
/**
* @param AbstractElement $element
* @return string
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getElementHtml(AbstractElement $element)
{
/** @var \Magento\Backend\Block\Template $block */
$block = $this->_layout->createBlock(\Magento\Backend\Block\Template::class);
$block->setTemplate($this->_template)->setData('providers', $this->getProviderData());
$html = parent::_getElementHtml($element);
$html .= $block->toHtml();
return $html;
}
/**
* @return string
*/
public function getProviderData()
{
return $this->jsonEncoder->encode($this->providers->getAllProviders());
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Block\Adminhtml;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
class TestButton extends Field
{
const TEMPLATE_PATH = 'Aitoc_Smtp::config/button.phtml';
const CHECK_BUTTON_ID = 'aitoc_send_button';
/**
* @param AbstractElement $element
* @return string
* @throws \Magento\Framework\Exception\LocalizedException
*/
protected function _getElementHtml(AbstractElement $element)
{
/** @var \Magento\Backend\Block\Template $block */
$block = $this->_layout->createBlock(\Magento\Backend\Block\Template::class);
$button = $this->getLayout()->createBlock(
\Magento\Backend\Block\Widget\Button::class
)->setData([
'id' => self::CHECK_BUTTON_ID,
'label' => __('Send Test Email'),
'class' => 'primary'
]);
$block
->setTemplate(self::TEMPLATE_PATH)
->setData('send_button', $button->toHtml())
->setData('ajax_url', $this->getAjaxUrl())
->setData('button_id', self::CHECK_BUTTON_ID);
return $block->toHtml();
}
/**
* Render scope label
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
*/
protected function _renderScopeLabel(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
return '';
}
/**
* @return string
*/
private function getAjaxUrl()
{
return $this->getUrl('aitoc_smtp/smtp/test', ['_current' => true]);
}
/**
* @return string
*/
public function getCheckButtonId()
{
return self::CHECK_BUTTON_ID;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml;
use Magento\Backend\App\Action;
use Aitoc\Smtp\Controller\RegistryConstants;
abstract class Log extends Action
{
const DEFAULT_ERROR_MESSAGE = 'Something went wrong. See the error log.';
/** @var \Magento\Framework\View\Result\PageFactory */
protected $resultPageFactory;
/** @var \Magento\Framework\Registry */
protected $registry;
/** @var \Aitoc\ShippingRules\Model\RuleFactory */
protected $ruleFactory;
const ADMIN_RESOURCE = 'Aitoc_Smtp::log';
/**
* Rule constructor.
*
* @param Action\Context $context
* @param \Aitoc\ShippingRules\Model\RuleFactory $ruleFactory
* @param \Magento\Framework\Registry $registry
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
*/
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Aitoc\Smtp\Model\LogFactory $ruleFactory,
\Magento\Framework\Registry $registry,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
$this->ruleFactory = $ruleFactory;
$this->registry = $registry;
$this->resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
/**
* @return \Magento\Backend\Model\View\Result\Page
*/
protected function initPage()
{
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
$resultPage = $this->resultPageFactory->create();
$resultPage->setActiveMenu('Aitoc_Smtp::log');
$resultPage->addBreadcrumb(__('Reports'), __('Reports'));
return $resultPage;
}
/**
* @param bool $requireId
* @return \Aitoc\Smtp\Model\Log|\Magento\Framework\App\ResponseInterface
*/
protected function getRule($requireId = false)
{
$ruleId = $this->getRequest()->getParam(RegistryConstants::RULE_PARAM_URL_KEY);
if ($requireId && !$ruleId) {
$this->messageManager->addErrorMessage(__('Log doesn\'t exist.'));
return $this->redirectIndex();
}
$model = $this->ruleFactory->create();
if ($ruleId) {
$model->load($ruleId);
}
if ($ruleId && !$model->getId()) {
$this->messageManager->addErrorMessage(__('Log doesn\'t exist.'));
return $this->redirectIndex();
}
$this->registry->register(RegistryConstants::CURRENT_RULE, $model);
return $model;
}
/**
* @return \Magento\Framework\App\ResponseInterface
*/
protected function redirectIndex()
{
return $this->_redirect('*/*/');
}
/**
* @return bool
*/
protected function _isAllowed()
{
return $this->_authorization->isAllowed('Aitoc_Smtp::log');
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml\Log;
use Aitoc\Smtp\Model\ResourceModel\Log\CollectionFactory;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
class Clear extends \Magento\Backend\App\Action
{
/**
* @var CollectionFactory
*/
protected $collectionFactory;
/**
* @param Context $context
* @param CollectionFactory $collectionFactory
*/
public function __construct(
Context $context,
CollectionFactory $collectionFactory
) {
$this->collectionFactory = $collectionFactory;
parent::__construct($context);
}
/**
* @return \Magento\Backend\Model\View\Result\Redirect
*/
public function execute()
{
$collection = $this->collectionFactory->create();
$items = $collection->getItems();
$count = count($items);
if ($items) {
foreach ($items as $item) {
$item->delete();
}
}
$this->messageManager->addSuccess(__('A total of %1 email(s) have been deleted.', $count));
return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('aitoc_smtp/*/index');
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml\Log;
class Delete extends \Aitoc\Smtp\Controller\Adminhtml\Log
{
/**
* {@inheritdoc}
*/
public function execute()
{
if ($data = $this->getRequest()->getParams()) {
$rule = $this->getRule();
try {
if ($rule->getId()) {
$rule->delete();
$this->messageManager->addSuccessMessage(
__('Email Log has been successfully deleted')
);
} else {
$this->messageManager->addErrorMessage(__('Unable to find the rule'));
}
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(__(self::DEFAULT_ERROR_MESSAGE));
}
}
return $this->_redirect($this->_redirect->getRefererUrl());
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml\Log;
class Index extends \Aitoc\Smtp\Controller\Adminhtml\Log
{
/**
*
* @return \Magento\Backend\Model\View\Result\Page
*/
public function execute()
{
$resultPage = $this->initPage();
$resultPage->getConfig()->getTitle()->prepend(__('Emails Log'));
return $resultPage;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml\Log;
use Aitoc\Smtp\Model\ResourceModel\Log\CollectionFactory;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Ui\Component\MassAction\Filter;
class MassDelete extends \Magento\Backend\App\Action
{
/**
* Massactions filter
*
* @var Filter
*/
protected $filter;
/**
* @var CollectionFactory
*/
protected $collectionFactory;
/**
* @param Context $context
* @param Filter $filter
* @param CollectionFactory $collectionFactory
*/
public function __construct(
Context $context,
Filter $filter,
CollectionFactory $collectionFactory
) {
$this->filter = $filter;
$this->collectionFactory = $collectionFactory;
parent::__construct($context);
}
/**
* @return \Magento\Backend\Model\View\Result\Redirect
*/
public function execute()
{
$collection = $this->filter->getCollection($this->collectionFactory->create());
$collectionSize = $collection->getSize();
foreach ($collection as $item) {
$item->delete();
}
$this->messageManager->addSuccess(__('A total of %1 email(s) have been deleted.', $collectionSize));
return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('aitoc_smtp/*/index');
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml\Log;
use Aitoc\Smtp\Model\ResourceModel\Log\CollectionFactory;
use Magento\Backend\App\Action\Context;
use Magento\Framework\Controller\ResultFactory;
use Magento\Ui\Component\MassAction\Filter;
use Aitoc\Smtp\Model\Sender;
use Magento\Framework\Registry;
use Aitoc\Smtp\Controller\RegistryConstants;
class MassResend extends \Magento\Backend\App\Action
{
/**
* Massactions filter
*
* @var Filter
*/
protected $filter;
/**
* @var CollectionFactory
*/
protected $collectionFactory;
/**
* @var Sender
*/
private $sender;
/**
* @var Registry
*/
private $registry;
/**
* @param Context $context
* @param Filter $filter
* @param CollectionFactory $collectionFactory
*/
public function __construct(
Context $context,
Filter $filter,
Sender $sender,
Registry $registry,
CollectionFactory $collectionFactory
)
{
$this->filter = $filter;
$this->registry = $registry;
$this->sender = $sender;
$this->collectionFactory = $collectionFactory;
parent::__construct($context);
}
/**
* @return \Magento\Backend\Model\View\Result\Redirect
*/
public function execute()
{
$collection = $this->filter->getCollection($this->collectionFactory->create());
$resCount = 0;
if ($collection->getSize()) {
$this->registry->register(RegistryConstants::CURRENT_RULE, true);
}
foreach ($collection as $item) {
if ($this->sender->sendByLogId($item->getLogId())) {
$resCount += 1;
}
}
$this->messageManager->addSuccess(__('A total of %1 email(s) have been sent.', $resCount));
return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('aitoc_smtp/*/index');
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml\Log;
/**
* View a rendered template.
*/
class Preview extends \Aitoc\Smtp\Controller\Adminhtml\Log
{
/**
* Preview Newsletter template
*
* @return void|$this
*/
public function execute()
{
try {
$this->_view->loadLayout();
$this->_view->getPage()->getConfig()->getTitle()->prepend(__('Email Preview'));
$this->_view->renderLayout();
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(
__('An error occurred. The email template can not be opened for preview.')
);
$this->_redirect('*/*/');
}
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml\Log;
use Aitoc\Smtp\Controller\RegistryConstants;
class Resend extends \Aitoc\Smtp\Controller\Adminhtml\Log
{
/**
* @var \Aitoc\Smtp\Model\Sender
*/
private $sender;
public function __construct(
\Magento\Backend\App\Action\Context $context,
\Aitoc\Smtp\Model\LogFactory $ruleFactory,
\Magento\Framework\Registry $registry,
\Magento\Framework\View\Result\PageFactory $resultPageFactory,
\Aitoc\Smtp\Model\Sender $sender
) {
parent::__construct($context, $ruleFactory, $registry, $resultPageFactory);
$this->sender = $sender;
}
/**
* {@inheritdoc}
*/
public function execute()
{
$logId = $this->getRequest()->getParam(RegistryConstants::RULE_PARAM_URL_KEY);
$log = $this->getRule();
if ($logId) {
try {
if ($this->sender->sendByLogId($logId)) {
$this->messageManager->addSuccessMessage(__('Email successfully was send.'));
} else {
$this->messageManager->addErrorMessage(__('Something went wrong.'));
}
} catch (\Magento\Framework\Exception\LocalizedException $e) {
$this->messageManager->addErrorMessage($e->getMessage());
} catch (\Exception $e) {
$this->messageManager->addErrorMessage(__(self::DEFAULT_ERROR_MESSAGE));
}
} else {
$this->messageManager->addErrorMessage(__('Unable to find the rule'));
}
return $this->_redirect($this->_redirect->getRefererUrl());
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller\Adminhtml\Smtp;
use Exception;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
use Magento\Email\Model\Template\SenderResolver;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Controller\ResultInterface;
use Magento\Framework\Exception\LocalizedException;
use Psr\Log\LoggerInterface;
use Aitoc\Smtp\Controller\RegistryConstants;
class Test extends Action
{
/**
* Authorization level of a basic admin session
*
* @see _isAllowed()
*/
const ADMIN_RESOURCE = 'Aitoc_Smtp::main';
const TEST_EMAIL_TO_FIELD_NAME = 'test_email_to';
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var TransportBuilder
*/
private $_transportBuilder;
/**
* @var SenderResolver
*/
private $senderResolver;
/**
* @var \Magento\Framework\Json\EncoderInterface
*/
private $jsonEncoder;
/**
* @var Factory
*/
private $configFactory;
/**
* @var \Aitoc\Smtp\Model\Config
*/
private $config;
/**
* @var \Magento\Framework\Mail\TransportInterfaceFactory
*/
private $transportInterfaceFactory;
public function __construct(
Context $context,
LoggerInterface $logger,
SenderResolver $senderResolver,
\Magento\Framework\Json\EncoderInterface $jsonEncoder,
\Magento\Config\Model\Config\Factory $configFactory,
\Aitoc\Smtp\Model\Config $config,
\Magento\Framework\Mail\TransportInterfaceFactory $transportInterfaceFactory
) {
$this->logger = $logger;
$this->transportInterfaceFactory = $transportInterfaceFactory;
$this->senderResolver = $senderResolver;
$this->jsonEncoder = $jsonEncoder;
$this->configFactory = $configFactory;
$this->config = $config;
parent::__construct($context);
}
/**
* @return ResponseInterface|ResultInterface
* @throws LocalizedException
*/
public function execute()
{
$data = $this->getRequest()->getParams();
try {
if ($data && isset($data[self::TEST_EMAIL_TO_FIELD_NAME])) {
$config = $this->config->convertFromPostToSmtpParams($this->removeUnusedFields($data));
$config[RegistryConstants::IS_TEST_FIELD_ARRAY] = true;
unset($config[self::TEST_EMAIL_TO_FIELD_NAME]);
$transport = $this->transportInterfaceFactory->create($config);
$transport->sendMessage();
$result = [
'status' => true,
'content' => __('Message is successfully send!')
];
} else {
$result = [
'status' => false,
'content' => __('Error. Something went wrong. Please, try again.')
];
}
} catch (LocalizedException $exception) {
$result = [
'status' => false,
'content' => $exception->getMessage()
];
} catch (\Exception $exception) {
$result = [
'status' => false,
'content' => $exception->getMessage()
];
}
return $this->getResponse()->representJson($this->jsonEncoder->encode($result));
}
/**
* @param $data
* @return mixed
*/
private function removeUnusedFields($data)
{
$fields = ['key', 'section', 'isAjax', 'form_key'];
foreach ($fields as $field) {
if (isset($data[$field]) && $data[$field]) {
unset($data[$field]);
}
}
return $data;
}
/**
* @return bool
*/
protected function _isAllowed()
{
return $this->_authorization->isAllowed('Aitoc_Smtp::main');
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Controller;
class RegistryConstants
{
const RULE_PARAM_URL_KEY = 'log_id';
const CURRENT_RULE = 'aitoc_current_smtp_log';
const IS_TEST_FIELD_ARRAY = 'is_test';
const VERSION_COMPARISON_OLD_MAIL = '2.2.8';
const VERSION_COMPARISON_NEW_MAIL = '2.3.3';
const RESEND_EMAIL_TEMPLATE_ID = 'aitsmtp_resend_template';
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Cron;
use Exception;
use Aitoc\Core\Model\Helpers\Date;
use Aitoc\Smtp\Model\Config;
use Aitoc\Smtp\Model\ResourceModel\Log\CollectionFactory;
use Psr\Log\LoggerInterface;
class Clear
{
/**
* @var LoggerInterface
*/
private $logger;
/**
* @var Config
*/
private $config;
/**
* @var CollectionFactory
*/
private $collectionFactory;
/**
* @var Date
*/
private $date;
public function __construct(
LoggerInterface $logger,
CollectionFactory $collectionFactory,
Date $date,
Config $config
) {
$this->logger = $logger;
$this->date = $date;
$this->collectionFactory = $collectionFactory;
$this->config = $config;
}
/**
* @return $this
*/
public function execute()
{
if (!$this->config->enabled()) {
return $this;
}
$cleanDays = $this->config->cleanLogDays();
if ($cleanDays) {
$logCollection = $this->collectionFactory->create()
->addFieldToFilter('created_at', [
'lteq' => $this->date->getCurrentDateBeforeDays($cleanDays)
]);
foreach ($logCollection as $log) {
try {
$log->delete();
} catch (Exception $e) {
$this->logger->critical($e);
}
}
}
return $this;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Model\ScopeInterface;
use Magento\Email\Model\Template\SenderResolver;
use Magento\Framework\App\ProductMetadataInterface;
use Aitoc\Smtp\Controller\RegistryConstants;
/**
* Class Config
* @package Aitoc\Smtp\Model
*/
class Config
{
/**
* Constants
*/
const MODULE_NAME = 'aitsmtp';
const XML_PATH_TEMPLATE_ENABLED = 'aitsmtp/general/enabled';
const XML_PATH_TEMPLATE_SMTP = 'aitsmtp/smtp/';
const XML_PATH_TEMPLATE_EMAILS = 'aitsmtp/emails/';
const XML_PATH_TEMPLATE_DEBUG = 'aitsmtp/debug/';
const XML_PATH_TEMPLATE_LOG = 'aitsmtp/log/';
const ENCRYPTED_PASSWORD_VALUE = '******';
/**
* @var \Aitoc\Core\Helper\Config
*/
private $config;
/**
* @var \Magento\Framework\App\RequestInterface
*/
private $request;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;
/**
* @var Config\Options\Protocol
*/
private $protocol;
/**
* @var Config\Options\Auth
*/
private $auth;
/**
* @var \Magento\Framework\Encryption\EncryptorInterface
*/
private $encryptor;
/**
* @var SenderResolver
*/
private $senderResolver;
/**
* @var ProductMetadataInterface
*/
private $productMetadata;
/**
* @var array
*/
private $smtpFields = [
'name', 'host', 'port', 'protocol', 'login', 'password', 'auth_type'
];
public function __construct(
\Aitoc\Core\Helper\Config $config,
\Magento\Framework\App\RequestInterface $request,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Aitoc\Smtp\Model\Config\Options\Protocol $protocol,
\Aitoc\Smtp\Model\Config\Options\Auth $auth,
\Magento\Framework\Encryption\EncryptorInterface $encryptor,
SenderResolver $senderResolver,
ProductMetadataInterface $productMetadata
) {
$this->config = $config;
$this->request = $request;
$this->protocol = $protocol;
$this->storeManager = $storeManager;
$this->auth = $auth;
$this->encryptor = $encryptor;
$this->senderResolver = $senderResolver;
$this->productMetadata = $productMetadata;
}
/**
* @return bool
*/
public function enabled()
{
return (bool)$this->config->getModuleConfig(self::XML_PATH_TEMPLATE_ENABLED, $this->getCurrentStoreId());
}
/**
* @return int|mixed
*/
public function getCurrentStoreId()
{
$storeId = 0;
$requestStore = $this->request->getParam(ScopeInterface::SCOPE_STORE);
$requestWebsite = $this->request->getParam(ScopeInterface::SCOPE_WEBSITE);
try {
if ($requestStore) {
$storeId = $requestStore;
} elseif ($requestWebsite) {
$storeId = $this->storeManager->getWebsite($requestWebsite)->getDefaultStore()->getId();
} else {
$storeId = $this->storeManager->getStore()->getId();
}
} catch (LocalizedException $exception) {
} catch (NoSuchEntityException $e) {
}
return $storeId;
}
/**
* @return array
*/
public function getCcEmails()
{
$allowedEmailsString = $this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_EMAILS . 'cc',
$this->getCurrentStoreId()
);
return $this->getDataFromString($allowedEmailsString);;
}
/**
* @return array|bool
*/
public function getBccEmails()
{
$allowedEmailsString = $this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_EMAILS . 'bcc',
$this->getCurrentStoreId()
);
return $this->getDataFromString($allowedEmailsString);
}
/**
* @return array|bool
*/
protected function _getExceptionalEmails()
{
$allowedEmailsString = $this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_DEBUG . 'exeptional_email_addresses',
$this->getCurrentStoreId()
);
$arrayFromString = explode(',', $allowedEmailsString);
array_walk($arrayFromString, [$this, 'trimAllowedValues']);
return $arrayFromString;
}
/**
* @return array|bool
*/
protected function _getExceptionalDomains()
{
$allowedDomainsString = $this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_DEBUG . 'exeptional_domains',
$this->getCurrentStoreId()
);
$arrayFromString = explode(',', $allowedDomainsString);
array_walk($arrayFromString, [$this, 'trimAllowedValues']);
return $arrayFromString;
}
/**
* @param $string
* @return array|bool
*/
private function getDataFromString($string)
{
if ($string) {
$result = [];
$arrayFromString = explode(',', $string);
array_walk($arrayFromString, [$this, 'trimAllowedValues']);
foreach ($arrayFromString as $item) {
$result[] = [
'email' => $item,
'name' => null
];
}
return $result;
}
return false;
}
/**
* @param $allowedValuesArray
*/
public function trimAllowedValues(&$allowedValuesArray)
{
$allowedValuesArray = trim($allowedValuesArray);
}
/**
* @param $email
* @return bool
*/
public function needToBlockEmail($email)
{
if ($this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_DEBUG . 'delivery',
$this->getCurrentStoreId()
)) {
$domains = $this->_getExceptionalDomains();
$emails = $this->_getExceptionalEmails();
if (($emails && in_array($email, $emails)) || (is_array($domains) && $this->validDomain($email, $domains)))
{
return false;
}
return true;
}
return false;
}
/**
* @param $postParams
* @return array
*/
public function convertFromPostToSmtpParams($postParams)
{
$result = [];
foreach ($postParams as $key => $item) {
switch ($key) {
case 'protocol':
$key = 'ssl';
$item = $this->protocol->getOptionById($item);
break;
case 'auth_type':
$key = 'auth';
$item = $this->auth->getOptionById($item);
break;
case 'login':
$key = 'username';
break;
case 'password':
if ($item == self::ENCRYPTED_PASSWORD_VALUE) {
$configValue = $this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_SMTP . 'password',
$this->getCurrentStoreId()
);
$item = $this->encryptor->decrypt($configValue);
}
break;
default:
break;
}
$result[$key] = $item;
}
return $result;
}
/**
* @return bool
*/
public function isBlockedDelivery()
{
return (bool)$this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_DEBUG . 'delivery',
$this->getCurrentStoreId()
);
}
/**
* @return bool
*/
public function logEnabled()
{
return (bool)$this->config->getModuleConfig(self::XML_PATH_TEMPLATE_LOG . 'log', $this->getCurrentStoreId());
}
/**
* @return bool
*/
public function plainEnabled()
{
return (bool)$this->config->getModuleConfig(self::XML_PATH_TEMPLATE_EMAILS . 'plain', $this->getCurrentStoreId());
}
/**
* @return int
*/
public function cleanLogDays()
{
return (int)$this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_LOG . 'log_clean',
$this->getCurrentStoreId()
);
}
/**
* @param $message
* @param bool $isTest
* @return mixed
*/
public function prepareMessageToSend($message, $isTest = false)
{
$senderData = $this->getAnotherEmailSenderData();
if (!$senderData && $isTest) {
$senderData = $this->getSenderData();
}
if ($senderData) {
$message->setFrom($this->getNewAddress($senderData));
}
if (!$isTest) {
$ccEmails = $this->getCcEmails();
$bccEmails = $this->getBccEmails();
if ($ccEmails) {
$message->addCc($this->getAddressList($ccEmails));
}
if ($bccEmails) {
$message->addBcc($this->getAddressList($bccEmails));
}
}
return $message;
}
/**
* @param $emailData
* @return \Zend\Mail\Address
*/
public function getNewAddress($emailData){
return new \Zend\Mail\Address($emailData['email'], $emailData['name']);
}
/**
* @param $emailsData
* @return \Zend\Mail\AddressList
*/
public function getAddressList($emailsData) {
$addressList = new \Zend\Mail\AddressList();
foreach ($emailsData as $data) {
$addressList->add($data['email'], isset($data['name']) ? $data['name'] : null);
}
return $addressList;
}
/**
* @param string $type
* @return array|string
* @throws \Magento\Framework\Exception\MailException
*/
public function getSenderData($type = 'general')
{
return $this->senderResolver->resolve($type, $this->getCurrentStoreId());
}
/**
* @param $email
* @param $domains
* @return bool
*/
protected function validDomain($email, $domains)
{
$regExp = '/^(http:\/\/|https:\/\/){0,1}(www\.){0,1}([0-9a-z_\-\.]*[0-9a-z]*\.[a-z]{2,5})$/iu';
$emailDomain = substr(strrchr($email, "@"), 1);
foreach ($domains as $domain) {
if (preg_match($regExp, $domain, $parts) && $emailDomain == $parts[3]) {
return true;
}
}
return false;
}
/**
* @return array
*/
public function getAnotherEmailSenderData()
{
$result = [];
if ($this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_EMAILS . 'sender_enable',
$this->getCurrentStoreId()
)) {
$senderEmail = $this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_EMAILS . 'sender_email',
$this->getCurrentStoreId()
);
$senderName = $this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_EMAILS . 'sender_name',
$this->getCurrentStoreId()
);
if ($senderEmail) {
$senderName = $senderName ?: null;
$result = [
'name' => $senderName,
'email' => $senderEmail
];
}
}
return $result;
}
/**
* @return array
*/
public function getFullConfig()
{
$result = [];
foreach ($this->smtpFields as $field) {
$configValue = $this->config->getModuleConfig(
self::XML_PATH_TEMPLATE_SMTP . $field,
$this->getCurrentStoreId()
);
if ($configValue === null) {
continue;
}
if ($field == 'protocol') {
if (!$configValue) {
continue;
}
$field = 'ssl';
$configValue = $this->protocol->getOptionById($configValue);
}
if ($field == 'login') {
$field = 'username';
}
if ($field == 'password') {
$configValue = $this->encryptor->decrypt($configValue);
}
if ($field == 'auth_type') {
$field = 'auth';
$configValue = $this->auth->getOptionById($configValue);
}
$result[$field] = $configValue;
}
return $result;
}
/**
* @param $version
* @return mixed
*/
public function isNewSender($version)
{
$currentVersion = $this->productMetadata->getVersion();
return version_compare($currentVersion, $version, '>=');
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\Config\Options;
use Magento\Framework\Option\ArrayInterface;
class Auth implements ArrayInterface
{
const AUTH_NONE = 0;
const AUTH_LOGIN = 1;
const AUTH_MD = 2;
const AUTH_LOGIN_VALUE = 'login';
const AUTH_MD_VALUE = 'md';
/**
* @return array
*/
public function toOptionArray()
{
return [
[
'value' => self::AUTH_NONE,
'label' => __('Not Required')
],
[
'value' => self::AUTH_LOGIN,
'label' => __('Login/Password')
],
[
'value' => self::AUTH_MD,
'label' => __('CRAM-MD5')
]
];
}
/**
* @param $id
* @return string
*/
public function getOptionById($id)
{
$value = '';
switch ($id) {
case 1:
$value = self::AUTH_LOGIN_VALUE;
break;
case 2:
$value = self::AUTH_MD_VALUE;
break;
}
return $value;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\Config\Options;
use Magento\Framework\Option\ArrayInterface;
class Protocol implements ArrayInterface
{
const PROTOCOL_NONE = 0;
const PROTOCOL_SSL = 1;
const PROTOCOL_TLS = 2;
const PROTOCOL_SSL_VALUE = 'ssl';
const PROTOCOL_TLS_VALUE = 'tls';
/**
* @return array
*/
public function toOptionArray()
{
return [
[
'value' => self::PROTOCOL_NONE,
'label' => __('None')
],
[
'value' => self::PROTOCOL_SSL,
'label' => __('SSL')
],
[
'value' => self::PROTOCOL_TLS,
'label' => __('TLS')
]
];
}
/**
* @param $id
* @return string
*/
public function getOptionById($id)
{
$value = '';
switch ($id) {
case 1:
$value = self::PROTOCOL_SSL_VALUE;
break;
case 2:
$value = self::PROTOCOL_TLS_VALUE;
break;
}
return $value;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\Config\Options;
use Magento\Framework\Option\ArrayInterface;
class Provider implements ArrayInterface
{
/**
* @var \Aitoc\Smtp\Model\Providers
*/
private $providers;
public function __construct(
\Aitoc\Smtp\Model\Providers $providers
) {
$this->providers = $providers;
}
public function toOptionArray()
{
$result = [];
$result[] = [
'value' => 'none',
'label' => 'None'
];
foreach ($this->providers->getAllProviders() as $key => $providerData) {
$result[] = [
'value' => $key,
'label' => $providerData['label']
];
}
return $result;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\Config\Options;
use Magento\Framework\Option\ArrayInterface;
class Status implements ArrayInterface
{
const STATUS_SUCCESS = 0;
const STATUS_FAILED = 1;
const STATUS_BLOCKED = 2;
/**
* @return array
*/
public function toOptionArray()
{
return [
[
'value' => self::STATUS_SUCCESS,
'label' => __('Success')
],
[
'value' => self::STATUS_FAILED,
'label' => __('Failed')
],
[
'value' => self::STATUS_BLOCKED,
'label' => __('Blocked')
]
];
}
/**
* @param $status
* @return mixed|string
*/
public function getLabelByStatus($status) {
foreach ($this->toOptionArray() as $item) {
if ($item['value'] == $status) {
return $item['label'];
}
}
return '';
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\Framework\Mail;
use Magento\Framework\Exception\MailException;
use Magento\Framework\Phrase;
use Zend\Mail\Message as ZendMessage;
use Zend\Mail\Address;
use Zend\Mail\Transport\Smtp;
use Magento\Framework\Mail\MessageInterface;
use Magento\Email\Model\Template\SenderResolver;
use Aitoc\Smtp\Model\Config;
use Zend\Mail\Transport\SmtpOptions;
use Aitoc\Smtp\Model\Resolver\From;
use Aitoc\Smtp\Model\LogFactory;
use Aitoc\Smtp\Model\Config\Options\Status;
use Magento\Framework\Registry;
use Aitoc\Smtp\Controller\RegistryConstants;
use Zend_Mail_Transport_Smtp;
class Transport implements \Magento\Framework\Mail\TransportInterface
{
const DEFAULT_LOCAL_CLIENT_HOSTNAME = 'localhost';
const TEST_MESSAGE_SUBJECT = 'Aitoc SMTP Test';
const TEST_MESSAGE_BODY =
"Now, your store uses an Aitoc SMTP. Please, hit ‘Save Config’ to use this connection.";
/**
* @var Sendmail
*/
private $zendTransport;
/**
* @var MessageInterface
*/
private $message;
/**
* @var array
*/
private $config;
/**
* @var Config
*/
private $aitConfig;
/**
* @var SenderResolver
*/
private $senderResolver;
/**
* @var From
*/
private $fromResolver;
/**
* @var LogFactory
*/
private $logFactory;
/**
* @var Registry
*/
private $registry;
public function __construct(
$message,
SenderResolver $senderResolver,
Config $aitConfig,
From $from,
LogFactory $logFactory,
Registry $registry,
array $config = []
) {
$this->config = $config;
$this->aitConfig = $aitConfig;
$this->senderResolver = $senderResolver;
$this->fromResolver = $from;
$this->logFactory = $logFactory;
$this->registry = $registry;
if ($this->aitConfig->isNewSender(RegistryConstants::VERSION_COMPARISON_OLD_MAIL)) {
$this->zendTransport = new Smtp($this->prepareOptions($config));
} else {
$this->zendTransport = new Zend_Mail_Transport_Smtp($config['host'], $config);
}
$this->message = $message;
$this->setFrom();
}
/**
* @return $this
*/
public function setFrom()
{
$fromData = $this->fromResolver->getFrom();
$message = ZendMessage::fromString($this->message->getRawMessage());
if ($fromData) {
if (($message instanceof ZendMessage && !$message->getFrom()->count())
|| ((is_array($message->getHeaders()) && !array_key_exists("From", $message->getHeaders())))
) {
$this->message->setFrom($this->aitConfig->getNewAddress($fromData));
}
}
return $this;
}
/**
* @param $config
* @return SmtpOptions
*/
private function prepareOptions($config)
{
if (!isset($config['name']) || !$config['name']) {
$config['name'] = self::DEFAULT_LOCAL_CLIENT_HOSTNAME;
}
$options = new SmtpOptions([
'name' => isset($config['name']) ? $config['name'] : '',
'host' => isset($config['host']) ? $config['host'] : '',
'port' => isset($config['port']) ? $config['port'] : 465,
]);
$connectionConfig = [];
if (isset($config['auth']) && $config['auth'] != '') {
$options->setConnectionClass($config['auth']);
$connectionConfig = [
'username' => isset($config['username']) ? $config['username'] : '',
'password' => isset($config['password']) ? $config['password'] : ''
];
}
if (isset($config['ssl']) && $config['ssl']) {
$connectionConfig['ssl'] = $config['ssl'];
}
if (!empty($connectionConfig)) {
$options->setConnectionConfig($connectionConfig);
}
return $options;
}
/**
* @inheritdoc
*/
public function sendMessage()
{
$logDisabled = $this->registry->registry(RegistryConstants::CURRENT_RULE) ? true : false;
try {
$this->message = $this->aitConfig->prepareMessageToSend($this->getMessage());
if ($this->aitConfig->isNewSender(RegistryConstants::VERSION_COMPARISON_OLD_MAIL)) {
$message = ZendMessage::fromString($this->message->getRawMessage())->setEncoding('utf-8');
} else {
$message = $this->message;
}
if ($this->aitConfig->isBlockedDelivery()) {
$modifiedRecipient = $this->modifyTo();
if (!$modifiedRecipient) {
$errorData = [
'status' => Status::STATUS_BLOCKED,
'status_message' => 'Debug mode'
];
if (!$logDisabled) {
$this->getLoger()->log($message, $errorData);
return;
}
}
$message = $modifiedRecipient;
}
$this->zendTransport->send($message);
if (!$logDisabled) {
$this->getLoger()->log($message);
}
} catch (\Exception $e) {
$errorData = [
'status' => Status::STATUS_FAILED,
'status_message' => $e->getMessage()
];
if (!$logDisabled) {
$this->getLoger()->log($message, $errorData);
}
throw new MailException(new Phrase($e->getMessage()), $e);
}
}
/**
* @return \Aitoc\Smtp\Model\Log
*/
private function getLoger()
{
return $this->logFactory->create();
}
/**
* @return bool|ZendMessage
*/
public function modifyTo()
{
if ($this->aitConfig->isNewSender(RegistryConstants::VERSION_COMPARISON_OLD_MAIL)) {
$message = ZendMessage::fromString($this->message->getRawMessage())->setEncoding('utf-8');
} else {
$message = $this->message;
}
$toEmails = $message->getTo();
$newEmails = [];
if ($toEmails) {
foreach ($toEmails as $email) {
$name = '';
if ($email instanceof Address) {
$name = $email->getName();
$email = $email->getEmail();
}
if ($this->aitConfig->needToBlockEmail($email)) {
continue;
}
$newEmails[] = [
'email' => $email,
'name' => $name
];
}
}
if (!$newEmails) {
return false;
}
$addressList = $this->aitConfig->getAddressList($newEmails);
$message->setTo($addressList);
return $message;
}
/**
* @param $to
* @return bool
* @throws MailException
*/
public function testSend($to)
{
try {
$result = false;
$this->message = $this->aitConfig->prepareMessageToSend($this->getMessage(), true);
$this->message
->addTo($to)
->setSubject(self::TEST_MESSAGE_SUBJECT)
->setBodyText(__(self::TEST_MESSAGE_BODY));
if ($this->aitConfig->isNewSender(RegistryConstants::VERSION_COMPARISON_OLD_MAIL)) {
$message = ZendMessage::fromString($this->message->getRawMessage())->setEncoding('utf-8');
} else {
$message = $this->message;
}
$this->zendTransport->send($message);
return $result;
} catch (\Exception $e) {
throw new MailException(new Phrase($e->getMessage()), $e);
}
}
/**
* @inheritdoc
*/
public function getMessage()
{
return $this->message;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model;
/**
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://github.com/soundasleep/html2text
*/
class Html2Text {
public static function defaultOptions() {
return [
'ignore_errors' => false,
'drop_links' => false
];
}
/**
* Tries to convert the given HTML into a plain text format - best suited for
* e-mail display, etc.
*
* <p>In particular, it tries to maintain the following features:
* <ul>
* <li>Links are maintained, with the 'href' copied over
* <li>Information in the &lt;head&gt; is lost
* </ul>
*
* @param string $html the input HTML
* @param array $options Ignore xml parsing errors
* @return string the HTML converted, as best as possible, to text
* @throws \Exception if the HTML could not be loaded as a {@link \DOMDocument}
*/
public static function convert($html, $options = []) {
$options = array_merge(static::defaultOptions(), $options);
// check all options are valid
foreach ($options as $key => $value) {
if (!in_array($key, array_keys(static::defaultOptions()))) {
throw new \InvalidArgumentException("Unknown html2text option '$key'");
}
}
$is_office_document = static::isOfficeDocument($html);
if ($is_office_document) {
// remove office namespace
$html = str_replace(["<o:p>", "</o:p>"], "", $html);
}
$html = static::fixNewlines($html);
if (mb_detect_encoding($html, "UTF-8", true)) {
$html = mb_convert_encoding($html, "HTML-ENTITIES", "UTF-8");
}
$doc = static::getDocument($html, $options['ignore_errors']);
$output = static::iterateOverNode($doc, null, false, $is_office_document, $options);
// process output for whitespace/newlines
$output = static::processWhitespaceNewlines($output);
return $output;
}
/**
* Unify newlines; in particular, \r\n becomes \n, and
* then \r becomes \n. This means that all newlines (Unix, Windows, Mac)
* all become \ns.
*
* @param string $text text with any number of \r, \r\n and \n combinations
* @return string the fixed text
*/
static function fixNewlines($text) {
// replace \r\n to \n
$text = str_replace("\r\n", "\n", $text);
// remove \rs
$text = str_replace("\r", "\n", $text);
return $text;
}
static function nbspCodes() {
return [
"\xc2\xa0",
"\u00a0"
];
}
static function zwnjCodes() {
return [
"\xe2\x80\x8c",
"\u200c"
];
}
/**
* Remove leading or trailing spaces and excess empty lines from provided multiline text
*
* @param string $text multiline text any number of leading or trailing spaces or excess lines
* @return string the fixed text
*/
static function processWhitespaceNewlines($text) {
// remove excess spaces around tabs
$text = preg_replace("/ *\t */im", "\t", $text);
// remove leading whitespace
$text = ltrim($text);
// remove leading spaces on each line
$text = preg_replace("/\n[ \t]*/im", "\n", $text);
// convert non-breaking spaces to regular spaces to prevent output issues,
// do it here so they do NOT get removed with other leading spaces, as they
// are sometimes used for indentation
$text = static::renderText($text);
// remove trailing whitespace
$text = rtrim($text);
// remove trailing spaces on each line
$text = preg_replace("/[ \t]*\n/im", "\n", $text);
// unarmor pre blocks
$text = static::fixNewLines($text);
// remove unnecessary empty lines
$text = preg_replace("/\n\n\n*/im", "\n\n", $text);
return $text;
}
/**
* Parse HTML into a DOMDocument
*
* @param string $html the input HTML
* @param boolean $ignoreError Ignore xml parsing errors
* @return \DOMDocument the parsed document tree
*/
static function getDocument($html, $ignoreError = false) {
$doc = new \DOMDocument();
$html = trim($html);
if (!$html) {
// DOMDocument doesn't support empty value and throws an error
// Return empty document instead
return $doc;
}
if ($html[0] !== '<') {
// If HTML does not begin with a tag, we put a body tag around it.
// If we do not do this, PHP will insert a paragraph tag around
// the first block of text for some reason which can mess up
// the newlines. See pre.html test for an example.
$html = '<body>' . $html . '</body>';
}
if ($ignoreError) {
$doc->strictErrorChecking = false;
$doc->recover = true;
$doc->xmlStandalone = true;
$old_internal_errors = libxml_use_internal_errors(true);
$load_result = $doc->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR | LIBXML_NONET | LIBXML_PARSEHUGE);
libxml_use_internal_errors($old_internal_errors);
}
else {
$load_result = $doc->loadHTML($html);
}
if (!$load_result) {
throw new \Exception("Could not load HTML - badly formed?\n", $html);
}
return $doc;
}
/**
* Can we guess that this HTML is generated by Microsoft Office?
*/
static function isOfficeDocument($html) {
return strpos($html, "urn:schemas-microsoft-com:office") !== false;
}
/**
* Replace any special characters with simple text versions, to prevent output issues:
* - Convert non-breaking spaces to regular spaces; and
* - Convert zero-width non-joiners to '' (nothing).
*
* This is to match our goal of rendering documents as they would be rendered
* by a browser.
*/
static function renderText($text) {
$text = str_replace(static::nbspCodes(), " ", $text);
$text = str_replace(static::zwnjCodes(), "", $text);
return $text;
}
static function isWhitespace($text) {
return strlen(trim(static::renderText($text), "\n\r\t ")) === 0;
}
static function nextChildName($node) {
// get the next child
$nextNode = $node->nextSibling;
while ($nextNode != null) {
if ($nextNode instanceof \DOMText) {
if (!static::isWhitespace($nextNode->wholeText)) {
break;
}
}
if ($nextNode instanceof \DOMElement) {
break;
}
$nextNode = $nextNode->nextSibling;
}
$nextName = null;
if (($nextNode instanceof \DOMElement || $nextNode instanceof \DOMText) && $nextNode != null) {
$nextName = strtolower($nextNode->nodeName);
}
return $nextName;
}
static function iterateOverNode($node, $prevName = null, $in_pre = false, $is_office_document = false, $options = [])
{
if ($node instanceof \DOMText) {
// Replace whitespace characters with a space (equivalent to \s)
if ($in_pre) {
$text = "\n" . trim(static::renderText($node->wholeText), "\n\r\t ") . "\n";
// Remove trailing whitespace only
$text = preg_replace("/[ \t]*\n/im", "\n", $text);
// armor newlines with \r.
return str_replace("\n", "\r", $text);
} else {
$text = static::renderText($node->wholeText);
$text = preg_replace("/[\\t\\n\\f\\r ]+/im", " ", $text);
if (!static::isWhitespace($text) && ($prevName == 'p' || $prevName == 'div')) {
return "\n" . $text;
}
return $text;
}
}
if ($node instanceof \DOMDocumentType || $node instanceof \DOMProcessingInstruction) {
// ignore
return "";
}
$name = strtolower($node->nodeName);
$nextName = static::nextChildName($node);
// start whitespace
switch ($name) {
case "hr":
$prefix = '';
if ($prevName != null) {
$prefix = "\n";
}
return $prefix . "---------------------------------------------------------------\n";
case "style":
case "head":
case "title":
case "meta":
case "script":
// ignore these tags
return "";
case "h1":
case "h2":
case "h3":
case "h4":
case "h5":
case "h6":
case "ol":
case "ul":
case "pre":
// add two newlines
$output = "\n\n";
break;
case "td":
case "th":
// add tab char to separate table fields
$output = "\t";
break;
case "p":
// Microsoft exchange emails often include HTML which, when passed through
// html2text, results in lots of double line returns everywhere.
//
// To fix this, for any p element with a className of `MsoNormal` (the standard
// classname in any Microsoft export or outlook for a paragraph that behaves
// like a line return) we skip the first line returns and set the name to br.
if ($is_office_document && $node->getAttribute('class') == 'MsoNormal') {
$output = "";
$name = 'br';
break;
}
// add two lines
$output = "\n\n";
break;
case "tr":
// add one line
$output = "\n";
break;
case "div":
$output = "";
if ($prevName !== null) {
// add one line
$output .= "\n";
}
break;
case "li":
$output = "- ";
break;
default:
// print out contents of unknown tags
$output = "";
break;
}
// debug
//$output .= "[$name,$nextName]";
if (isset($node->childNodes)) {
$n = $node->childNodes->item(0);
$previousSiblingNames = [];
$previousSiblingName = null;
$parts = [];
$trailing_whitespace = 0;
while ($n != null) {
$text = static::iterateOverNode($n, $previousSiblingName, $in_pre || $name == 'pre', $is_office_document, $options);
// Pass current node name to next child, as previousSibling does not appear to get populated
if ($n instanceof \DOMDocumentType
|| $n instanceof \DOMProcessingInstruction
|| ($n instanceof \DOMText && static::isWhitespace($text))) {
// Keep current previousSiblingName, these are invisible
$trailing_whitespace++;
}
else {
$previousSiblingName = strtolower($n->nodeName);
$previousSiblingNames[] = $previousSiblingName;
$trailing_whitespace = 0;
}
$node->removeChild($n);
$n = $node->childNodes->item(0);
$parts[] = $text;
}
// Remove trailing whitespace, important for the br check below
while ($trailing_whitespace-- > 0) {
array_pop($parts);
}
// suppress last br tag inside a node list if follows text
$last_name = array_pop($previousSiblingNames);
if ($last_name === 'br') {
$last_name = array_pop($previousSiblingNames);
if ($last_name === '#text') {
array_pop($parts);
}
}
$output .= implode('', $parts);
}
// end whitespace
switch ($name) {
case "h1":
case "h2":
case "h3":
$output = mb_strtoupper($output);
case "h4":
case "h5":
case "h6":
case "pre":
case "p":
// add two lines
$output .= "\n\n";
break;
case "b":
case "strong":
$output = "*$output*";
break;
case "i":
case "em":
$output = "/$output/";
break;
case "br":
// add one line
$output .= "\n";
break;
case "div":
break;
case "a":
// links are returned in text <link> format
$href = $node->getAttribute("href");
$output = trim($output);
// if there is no link text, but a title attr
if (!$output && $node->getAttribute("title")) {
$output = $node->getAttribute("title");
}
if ($href == null) {
// it doesn't link anywhere
if ($node->getAttribute("name") != null) {
if ($options['drop_links']) {
$output = "$output";
} else {
$output = "$output";
}
}
} else {
if ($href == $output || $href == "http://$output" || $href == "https://$output") {
// link to the same address: just use link
$output = "$output";
} else {
// replace it
if ($output) {
if ($options['drop_links']) {
$output = "$output";
} else {
$output = "$output <$href>";
}
} else {
// empty string
$output = "$href";
}
}
}
// does the next node require additional whitespace?
switch ($nextName) {
case "h1": case "h2": case "h3": case "h4": case "h5": case "h6":
$output .= "\n";
break;
}
break;
case "img":
case "img":
if ($node->getAttribute("title")) {
$output = $node->getAttribute("title");
} elseif ($node->getAttribute("alt")) {
$output = $node->getAttribute("alt");
} else {
$output = "";
}
break;
case "li":
$output .= "\n";
break;
case "blockquote":
// process quoted text for whitespace/newlines
$output = static::processWhitespaceNewlines($output);
// add leading newline
$output = "\n" . $output;
// prepend '> ' at the beginning of all lines
$output = preg_replace("/\n/im", "\n> ", $output);
// replace leading '> >' with '>>'
$output = preg_replace("/\n> >/im", "\n>>", $output);
// add another leading newline and trailing newlines
$output = "\n" . $output . "\n\n";
break;
default:
// do nothing
}
return $output;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model;
use Aitoc\Smtp\Api\Data\LogInterface;
use Aitoc\Smtp\Controller\RegistryConstants;
class Log extends \Magento\Framework\Model\AbstractModel implements LogInterface
{
const LOG_ACTIVE = '1';
const LOG_INACTIVE = '0';
const LOG_ID_TYPE_FIELD = 'log_id';
/**
* @var Config
*/
private $config;
/**
* @var \Aitoc\Core\Model\Helpers\Date
*/
private $date;
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Aitoc\Smtp\Model\ResourceModel\Log $resource,
\Aitoc\Smtp\Model\ResourceModel\Log\Collection $resourceCollection,
\Aitoc\Smtp\Model\Config $config,
\Aitoc\Core\Model\Helpers\Date $date,
array $data = []
)
{
$this->config = $config;
$this->date = $date;
parent::__construct($context, $registry, $resource, $resourceCollection);
}
/**
* {@inheritdoc}
*/
public function _construct()
{
$this->_init(\Aitoc\Smtp\Model\ResourceModel\Log::class);
}
/**
* @return int|mixed
*/
public function getLogId()
{
return $this->getData(LogInterface::LOG_ID);
}
/**
* @param int $logId
* @return $this|LogInterface
*/
public function setLogId($logId)
{
$this->setData(LogInterface::LOG_ID, $logId);
return $this;
}
/**
* @param $ruleId
*
* @return $this
*/
public function getLogById($logId)
{
$resource = $this->getResource();
$resource->load($this, $logId);
return $this;
}
/**
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function beforeSave()
{
parent::beforeSave();
return $this->updateDate();
}
/**
* @return $this
*/
private function updateDate()
{
return $this;
}
/**
* @param $message
* @param array $errorData
* @return $this
* @throws \Magento\Framework\Exception\AlreadyExistsException
*/
public function log($message, $errorData = [])
{
if ($this->config->logEnabled()) {
$logData = $this->getLogData($message);
$logData[LogInterface::CREATED_AT] = $this->date->getCurrentDate();
$logData[LogInterface::STATUS] = $errorData ? $errorData[LogInterface::STATUS] : 0;
$logData[LogInterface::STATUS_MESSAGE] = $errorData ? $errorData[LogInterface::STATUS_MESSAGE] : '';
$this->setData($logData);
$this->_resource->save($this);
}
return $this;
}
/**
* @param $message
* @return array
*/
private function getLogData($message)
{
$result = [];
if ($this->config->isNewSender(RegistryConstants::VERSION_COMPARISON_OLD_MAIL)) {
$result[LogInterface::SUBJECT] = $message->getSubject() ?: '';
$result[LogInterface::SENDER_EMAIL] = $this->getEmailsFromAddressList($message->getFrom());
$result[LogInterface::RECIPIENT_EMAIL] = $this->getEmailsFromAddressList($message->getTo());
$result[LogInterface::BCC] = $this->getEmailsFromAddressList($message->getBcc());
$result[LogInterface::CC] = $this->getEmailsFromAddressList($message->getCc());
$result[LogInterface::EMAIL_BODY] = htmlspecialchars($message->getBodyText());
} else {
$headers = $message->getHeaders();
$result[LogInterface::SUBJECT] = isset($headers['Subject'][0]) ? $headers['Subject'][0] : '';
$result[LogInterface::SENDER_EMAIL] = isset($headers['From'][0]) ? $headers['From'][0] : '';
if (isset($headers['To'])) {
$recipient = $headers['To'];
if (isset($recipient['append'])) {
unset($recipient['append']);
}
$result[LogInterface::RECIPIENT_EMAIL] = $this->getEmailsFromAddressList($recipient);
}
if (isset($headers['Cc'])) {
$cc = $headers['Cc'];
if (isset($cc['append'])) {
unset($cc['append']);
}
$result[LogInterface::CC] = $this->getEmailsFromAddressList($cc);
}
if (isset($headers['Bcc'])) {
$bcc = $headers['Bcc'];
if (isset($bcc['append'])) {
unset($bcc['append']);
}
$result[LogInterface::BCC] = $this->getEmailsFromAddressList($bcc);
}
$emailBody = $message->getBodyHtml();
if (is_object($emailBody)) {
$result[LogInterface::EMAIL_BODY] = htmlspecialchars($emailBody->getRawContent());
} else {
$result[LogInterface::EMAIL_BODY] = htmlspecialchars($message->getBody()->getRawContent());
}
}
return $result;
}
/**
* @param $emails
* @return string
*/
private function getEmailsFromAddressList($emails)
{
$result = [];
if (count($emails)) {
foreach ($emails as $email) {
$name = 'Unknown';
if ($email->getName()) {
$name = $email->getName();
}
$result[] = "<" . $name . ">" . $email->getEmail();
}
}
return implode(',', $result);
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model;
/**
* Class Providers
* @package Aitoc\Smtp\Model
*/
class Providers
{
/**
* @return array
*/
public function getAllProviders()
{
return [
'gmail' => [
'label' => __('Gmail, GSuite'),
'info' => [
'host' => 'smtp.gmail.com',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'yandex' => [
'label' => __('Yandex'),
'info' => [
'host' => 'smtp.yandex.ru',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'amazon-us-east-virginia' => [
'label' => __('Amazon SES: US East (N. Virginia)'),
'info' => [
'host' => 'email-smtp.us-east-1.amazonaws.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'amazon-us-east-oregon' => [
'label' => __('Amazon SES: US West (Oregon)'),
'info' => [
'host' => 'email-smtp.us-west-2.amazonaws.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'amazon-eu-ireland' => [
'label' => __('Amazon SES: EU (Ireland)'),
'info' => [
'host' => 'email-smtp.eu-west-1.amazonaws.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'mailgun' => [
'label' => __('Mailgun'),
'info' => [
'host' => 'smtp.mailgun.org',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'mandrill' => [
'label' => __('Mandrill'),
'info' => [
'host' => 'smtp.mandrillapp.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'sendinblue' => [
'label' => __('Sendinblue'),
'info' => [
'host' => 'smtp-relay.sendinblue.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'sendgrid' => [
'label' => __('Sendgrid'),
'info' => [
'host' => 'smtp.sendgrid.net',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'elastic' => [
'label' => __('Elastic Email'),
'info' => [
'host' => 'smtp.elasticemail.com',
'port' => '2525',
'encryption' => '',
'auth_type' => 'login'
]
],
'sparkpost' => [
'label' => __('SparkPost'),
'info' => [
'host' => 'smtp.sparkpostmail.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'mailjet' => [
'label' => __('Mailjet'),
'info' => [
'host' => 'in-v3.mailjet.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'postmark' => [
'label' => __('Postmark'),
'info' => [
'host' => 'smtp.postmarkapp.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'aol' => [
'label' => __('AOL Mail'),
'info' => [
'host' => 'smtp.aol.com',
'port' => '587',
'encryption' => '',
'auth_type' => 'login'
]
],
'comcast' => [
'label' => __('Comcast'),
'info' => [
'host' => 'smtp.comcast.net',
'port' => '587',
'encryption' => '',
'auth_type' => 'login'
]
],
'gmx' => [
'label' => __('GMX'),
'info' => [
'host' => 'mail.gmx.net',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'hotmail' => [
'label' => __('Hotmail'),
'info' => [
'host' => 'smtp-mail.outlook.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'mailcom' => [
'label' => __('Mail.com'),
'info' => [
'host' => 'smtp.mail.com',
'port' => '587',
'encryption' => '',
'auth_type' => 'login'
]
],
'02mail' => [
'label' => __('O2 Mail'),
'info' => [
'host' => 'smtp.o2.ie',
'port' => '25',
'encryption' => '',
'auth_type' => 'login'
]
],
'office365' => [
'label' => __('Office365'),
'info' => [
'host' => 'smtp.office365.com',
'port' => '587',
'encryption' => '',
'auth_type' => 'login'
]
],
'orange' => [
'label' => __('Orange'),
'info' => [
'host' => 'smtp.orange.net',
'port' => '25',
'encryption' => '',
'auth_type' => 'login'
]
],
'outlook' => [
'label' => __('Outlook'),
'info' => [
'host' => 'smtp-mail.outlook.com',
'port' => '587',
'encryption' => 'tls',
'auth_type' => 'login'
]
],
'yahoo' => [
'label' => __('Yahoo Mail'),
'info' => [
'host' => 'smtp.mail.yahoo.com',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'yahooplus' => [
'label' => __('Yahoo Mail Plus'),
'info' => [
'host' => 'plus.smtp.mail.yahoo.com',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'yahooau' => [
'label' => __('Yahoo AU/NZ'),
'info' => [
'host' => 'smtp.mail.yahoo.com.au',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'at&t' => [
'label' => __('AT&T'),
'info' => [
'host' => 'smtp.att.yahoo.com',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'ntlworld' => [
'label' => __('NTL @ntlworld.com'),
'info' => [
'host' => 'smtp.ntlworld.com',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'btconnect' => [
'label' => __('BT Connect'),
'info' => [
'host' => 'pop3.btconnect.com',
'port' => '25',
'encryption' => '',
'auth_type' => 'login'
]
],
'zoho' => [
'label' => __('Zoho Mail'),
'info' => [
'host' => 'smtp.zoho.com',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'verizon' => [
'label' => __('Verizon'),
'info' => [
'host' => 'outgoing.verizon.net',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'btopenworld' => [
'label' => __('BT Openworld'),
'info' => [
'host' => 'mail.btopenworld.com',
'port' => '25',
'encryption' => '',
'auth_type' => 'login'
]
],
'o2online' => [
'label' => __('O2 Online Deutschland'),
'info' => [
'host' => 'mail.o2online.de',
'port' => '25',
'encryption' => '',
'auth_type' => 'login'
]
],
'1&1webmail' => [
'label' => __('1&1 Webmail'),
'info' => [
'host' => 'smtp.1and1.com',
'port' => '587',
'encryption' => '',
'auth_type' => 'login'
]
],
'ovh' => [
'label' => __('OVH'),
'info' => [
'host' => 'ssl0.ovh.net',
'port' => '465',
'encryption' => 'ssl',
'auth_type' => 'login'
]
],
'smtp2go' => [
'label' => __('SMTP2GO'),
'info' => [
'host' => 'mail.smtp2go.com',
'port' => '2525',
'encryption' => 'tls',
'auth_type' => 'login'
]
]
];
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\Resolver;
/**
* Class From
* @package Aitoc\Smtp\Model\Resolver
*/
class From
{
/**
* @var null
*/
protected $from = null;
/**
* @return null
*/
public function getFrom()
{
return $this->from;
}
/**
* @param $from
* @return $this
*/
public function setFrom($from)
{
$this->from = $from;
return $this;
}
/**
* @return $this
*/
public function reset()
{
$this->from = null;
return $this;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\ResourceModel;
use Magento\Framework\Model\ResourceModel\Db\VersionControl\AbstractDb;
class Log extends AbstractDb
{
/**
* Smtp Log Store Table Name
*/
const AITOC_SMTP_LOG_TABLE_NAME = 'aitoc_smtp_log';
/**
* {@inheritdoc}
*/
protected function _construct()
{
$this->_init(
self::AITOC_SMTP_LOG_TABLE_NAME,
\Aitoc\Smtp\Model\Log::LOG_ID_TYPE_FIELD
);
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\ResourceModel\Log;
use Aitoc\Smtp\Model\Log;
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
/**
* @var \Aitoc\ShippingRules\Model\Date
*/
private $date;
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,
\Aitoc\Core\Model\Helpers\Date $date,
\Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
\Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
) {
$this->date = $date;
parent::__construct(
$entityFactory,
$logger,
$fetchStrategy,
$eventManager,
$connection,
$resource
);
}
/**
* _construct
*/
protected function _construct()
{
parent::_construct();
$this->_init(\Aitoc\Smtp\Model\Log::class,
\Aitoc\Smtp\Model\ResourceModel\Log::class
);
$this->_setIdFieldName($this->getResource()->getIdFieldName());
}
/**
* @param $logId
* @return $this
*/
public function addLogIdFilter($logId)
{
$this->addFieldToFilter(Log::LOG_ID_TYPE_FIELD,
[
'eq' => $logId
]
);
return $this;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model\ResourceModel\Log\Grid;
use Magento\Framework\Api\Search\SearchResultInterface;
use Magento\Framework\Api\Search\AggregationInterface;
use Aitoc\Smtp\Model\ResourceModel\Log\Collection as LogCollection;
/**
* Class Collection
*
* @package Aitoc\ShippingRules\Model\ResourceModel\Rules\Grid
*/
class Collection extends LogCollection implements SearchResultInterface
{
/**
* @var AggregationInterface
*/
public $aggregations;
/**
* Collection constructor.
*
* @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\Framework\DB\Adapter\AdapterInterface $mainTable
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb $eventPrefix
* @param $eventObject
* @param $resourceModel
* @param string $model
* @param null $connection
* @param \Magento\Framework\Model\ResourceModel\Db\AbstractDb|null $resource
*/
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,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\EntityManager\MetadataPool $metadataPool,
\Aitoc\Core\Model\Helpers\Date $date,
$mainTable,
$eventPrefix,
$eventObject,
$resourceModel,
$model = 'Magento\Framework\View\Element\UiComponent\DataProvider\Document',
$connection = null,
\Magento\Framework\Model\ResourceModel\Db\AbstractDb $resource = null
) {
parent::__construct(
$entityFactory,
$logger,
$fetchStrategy,
$eventManager,
$date,
$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;
}
/**
* 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;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Model;
use Aitoc\Smtp\Api\Data\LogInterface;
use Aitoc\Smtp\Controller\RegistryConstants;
use Aitoc\Smtp\Model\Config\Options\Status;
use Magento\Framework\App\Area;
use Magento\Framework\Exception\MailException;
use Magento\Store\Model\Store;
class Sender
{
const ADDRESS_SCOPE_FROM = 'from';
const ADDRESS_SCOPE_TO = 'to';
/**
* @var LogFactory
*/
private $logFactory;
/**
* @var \Magento\Framework\Mail\Template\TransportBuilder
*/
private $transportBuilder;
/**
* @var Config
*/
private $config;
/**
* @param LogFactory $logFactory
* @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
* @param Config $config
*/
public function __construct(
\Aitoc\Smtp\Model\LogFactory $logFactory,
\Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
\Aitoc\Smtp\Model\Config $config
) {
$this->logFactory = $logFactory;
$this->transportBuilder = $transportBuilder;
$this->config = $config;
}
/**
* Send the Email using log Id
*
* @param int $logId
* @return bool
* @throws MailException
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function sendByLogId($logId)
{
$log = $this->getCurrentLog($logId);
if (!$log->getId()) {
return false;
}
$data = $log->getData();
$data[LogInterface::EMAIL_BODY] = htmlspecialchars_decode($data[LogInterface::EMAIL_BODY]);
$vars = [];
if (!$data[LogInterface::EMAIL_BODY]
|| !$data[LogInterface::RECIPIENT_EMAIL]
|| !$data[LogInterface::SENDER_EMAIL]
|| !$data[LogInterface::SUBJECT]
) {
return false;
}
$vars[LogInterface::EMAIL_BODY] = quoted_printable_decode($data[LogInterface::EMAIL_BODY]);
$vars[LogInterface::SUBJECT] = $data[LogInterface::SUBJECT];
$this->transportBuilder
->addTo($this->prepareEmailsData($data[LogInterface::RECIPIENT_EMAIL], self::ADDRESS_SCOPE_TO))
->setFromByScope($this->prepareEmailsData($data[LogInterface::SENDER_EMAIL], self::ADDRESS_SCOPE_FROM));
if ($data[LogInterface::BCC]) {
$this->transportBuilder->addBcc($this->prepareEmailsData($data[LogInterface::BCC]));
}
if ($data[LogInterface::CC]) {
$this->transportBuilder->addCc($this->prepareEmailsData($data[LogInterface::CC]));
}
try {
$this->transportBuilder
->setTemplateIdentifier(RegistryConstants::RESEND_EMAIL_TEMPLATE_ID)
->setTemplateOptions(['store' => Store::DEFAULT_STORE_ID, 'area' => Area::AREA_FRONTEND])
->setTemplateVars($vars);
$this->transportBuilder->getTransport()->sendMessage();
$log->setData(LogInterface::STATUS, Status::STATUS_SUCCESS)
->setData(LogInterface::STATUS_MESSAGE, '')
->save();
} catch (MailException $e) {
print_r($e->getMessage());exit;
$log->setData(LogInterface::STATUS, Status::STATUS_FAILED)
->setData(LogInterface::STATUS_MESSAGE, $e->getMessage())
->save();
return false;
}
return true;
}
/**
* Prepare the Data for Send Email
*
* @param array $emails
* @param string $scope
* @return array|mixed|string|\Zend\Mail\AddressList
*/
private function prepareEmailsData($emails, $scope = '')
{
$emailsConverted = [];
$emails = explode(',', $emails);
foreach ($emails as $email) {
$emailData = explode('>', substr($email, 1));
switch ($scope) {
case self::ADDRESS_SCOPE_TO:
return $emailData[1];
break;
case self::ADDRESS_SCOPE_FROM:
return [
'name' => ($emailData[0] == 'Unknown' ? '' : $emailData[0]),
'email' => $emailData[1],
];
break;
}
$emailsConverted[] = [
'name' => ($emailData[0] == 'Unknown' ? '' : $emailData[0]),
'email' => $emailData[1],
];
}
return $this->config->getAddressList($emailsConverted);
}
/**
* Get the Current Log Details using Log Id
*
* @param int $logId
* @return Log
*/
public function getCurrentLog($logId)
{
return $this->logFactory->create()->getLogById($logId);
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Plugin\Framework\Mail;
use Aitoc\Smtp\Model\Html2Text;
use Magento\Framework\Mail\Message as MailMessage;
class Message
{
/**
* @var \Aitoc\Smtp\Model\Config
*/
private $config;
public function __construct(
\Aitoc\Smtp\Model\Config $config
) {
$this->config = $config;
}
/**
* @param MailMessage $subject
* @return MailMessage
*/
public function afterSetBody(MailMessage $subject)
{
if (!$this->config->plainEnabled()) {
return $subject;
}
try {
$body = $subject->getBody();
if ($body instanceof \Zend\Mime\Message && !$body->isMultiPart()) {
$reflection = new \ReflectionProperty(MailMessage::class, 'zendMessage');
$reflection->setAccessible(true);
/** @var \Zend\Mail\Message $zendMessage */
$zendMessage = $reflection->getValue($subject);
$plainContent = '';
try {
$plainContent = Html2Text::convert($zendMessage->getBodyText());
} catch (\Exception $e) {
}
$textPart = new \Zend\Mime\Part($plainContent);
$textPart->setCharset($zendMessage->getEncoding());
$textPart->setType(\Zend\Mime\Mime::TYPE_TEXT);
$body->setParts(array_merge([$textPart], $body->getParts()));
$zendMessage->setBody($body);
$zendMessage->getHeaders()->get('content-type')->setType('multipart/alternative');
}
} catch (\Exception $e) {
}
return $subject;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Plugin\Framework\Mail\Template;
use Magento\Framework\Exception\MailException;
use Magento\Framework\Mail\Template\SenderResolverInterface;
use Aitoc\Smtp\Model\Resolver\From;
class TransportBuilder
{
/**
* @var From
*/
private $fromResolver;
/**
* @var SenderResolverInterface
*/
private $senderResolver;
public function __construct(
From $fromResolver,
SenderResolverInterface $SenderResolver
) {
$this->fromResolver = $fromResolver;
$this->senderResolver = $SenderResolver;
}
/**
* @param \Magento\Framework\Mail\Template\TransportBuilder $subject
* @param $from
* @return array
* @throws MailException
*/
public function beforeSetFrom(
\Magento\Framework\Mail\Template\TransportBuilder $subject,
$from
) {
$this->fromResolver->reset();
$senderData = $from;
if (is_string($from)) {
$senderData = $this->senderResolver->resolve($from);
}
if (is_array($from)) {
$senderData = $from;
}
$this->fromResolver->setFrom($senderData);
return [$from];
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Plugin\Framework\Mail\Template;
use Magento\Framework\Exception\MailException;
use Magento\Framework\Mail\Template\SenderResolverInterface;
use Magento\Framework\Mail\Template\TransportBuilderByStore as TransportBuilderByStoreOriginal;
use Aitoc\Smtp\Model\Resolver\From;
class TransportBuilderByStore
{
/**
* @var From
*/
private $fromResolver;
/**
* @var SenderResolverInterface
*/
private $senderResolver;
public function __construct(
From $fromResolver,
SenderResolverInterface $senderResolver
) {
$this->fromResolver = $fromResolver;
$this->senderResolver = $senderResolver;
}
/**
* @param TransportBuilderByStore $subject
* @param $from
* @param $store
* @return array
* @throws MailException
*/
public function beforeSetFromByStore(
TransportBuilderByStoreOriginal $subject,
$from,
$store
) {
$this->fromResolver->reset();
$this->fromResolver->setFrom($this->senderResolver->resolve($from, $store));
return [$from, $store];
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Plugin\Framework\Mail;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\Mail\TransportInterfaceFactory as TransportInterfaceFactoryCore;
use Aitoc\Smtp\Model\Config;
use Aitoc\Smtp\Controller\RegistryConstants;
/**
* TransportInterface Plugin
*/
class TransportInterfaceFactory
{
/**
* Object Manager
*
* @var \Magento\Framework\ObjectManagerInterface
*/
private $objectManager;
/**
* @var \Aitoc\Smtp\Model\Config
*/
private $config;
public function __construct(
ObjectManagerInterface $objectManager,
Config $config
) {
$this->objectManager = $objectManager;
$this->config = $config;
}
/**
* Create Class instance with Specified Parameters
*
* @param $subject TransportInterfaceFactoryCore
* @param $proceed \Callable
* @param array $data
* @return \Magento\Framework\Mail\TransportInterface
*/
public function aroundCreate($subject, $proceed, array $data = [])
{
if ($this->config->enabled()) {
if ($data && isset($data[\Aitoc\Smtp\Controller\RegistryConstants::IS_TEST_FIELD_ARRAY])) {
unset($data[RegistryConstants::IS_TEST_FIELD_ARRAY]);
$config = $data;
$data['message'] = $this->objectManager->create(\Magento\Framework\Mail\Message::class);
} else {
$config = $this->config->getFullConfig();
}
$data = array_merge($data, ['config' => $config]);
return $this->objectManager
->create(
\Aitoc\Smtp\Model\Framework\Mail\Transport::class,
$data
);
}
return $proceed($data);
}
}
<?php
namespace Aitoc\Smtp\Setup;
use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
class InstallSchema implements InstallSchemaInterface
{
const AITOC_SMTP_LOG_TABLE_NAME = 'aitoc_smtp_log';
/**
* @inheritDoc
*/
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
if (!$installer->tableExists(self::AITOC_SMTP_LOG_TABLE_NAME)) {
$table = $installer->getConnection()
->newTable($installer->getTable(self::AITOC_SMTP_LOG_TABLE_NAME))
->addColumn(
'log_id',
\Magento\Framework\DB\Ddl\Table::TYPE_INTEGER,
null,
['identity' => true, 'unsigned' => true, 'nullable' => false, 'primary' => true],
'Log Id'
)->addColumn(
'created_at',
\Magento\Framework\DB\Ddl\Table::TYPE_DATETIME,
null,
['nullable' => true, 'default' => null],
'Created At'
)
->addColumn(
'subject',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['nullable' => false]
)
->addColumn(
'email_body',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
null,
['nullable' => false]
)
->addColumn(
'sender_email',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
120,
['nullable' => false]
)
->addColumn(
'recipient_email',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
120,
['nullable' => false]
)
->addColumn(
'cc',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
120,
['nullable' => true]
)
->addColumn(
'bcc',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
120,
['nullable' => true]
)
->addColumn(
'status',
\Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
null,
['nullable' => false]
)->addColumn(
'status_message',
\Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
255,
['nullable' => true]
)->setComment('Aitoc SMTP Log');
$installer->getConnection()->createTable($table);
}
$installer->endSetup();
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Ui\Component\Listing\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use Aitoc\Smtp\Model\Config\Options\Status as StatusOptions;
/**
* Class Status
*/
class Status extends Column
{
/**
* @var StatusOptions
*/
private $statusOptions;
public function __construct(
ContextInterface $context,
UiComponentFactory $uiComponentFactory,
StatusOptions $statusOptions,
array $components = [],
array $data = []
) {
$this->statusOptions = $statusOptions;
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) {
$item[$this->getData('name')] = $this->getLabelByStatus($item[$this->getData('name')]);
}
}
return $dataSource;
}
/**
* @param $status
* @return string
*/
private function getLabelByStatus($status)
{
$html = '';
$label = $this->statusOptions->getLabelByStatus($status);
switch ($status) {
case StatusOptions::STATUS_SUCCESS:
$html = '<span class="grid-severity-notice"><span>'
. $label . '</span></span>';
break;
case StatusOptions::STATUS_FAILED:
$html = '<span class="grid-severity-major"><span>'
. $label . '</span></span>';
break;
default:
$html = '<span class="grid-severity-minor"><span>'
. $label . '</span></span>';
break;
}
return $html;
}
}
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
namespace Aitoc\Smtp\Ui\Component\Listing\Column;
use Magento\Framework\View\Element\UiComponent\ContextInterface;
use Magento\Framework\View\Element\UiComponentFactory;
use Magento\Ui\Component\Listing\Columns\Column;
use Magento\Framework\UrlInterface;
/**
* Class ViewAction
*/
class ViewAction extends Column
{
const PREVIEW_ULR_PATH = 'aitoc_smtp/log/preview';
const RESEND_URL_PATH = 'aitoc_smtp/log/resend';
const DELETE_LOG_URL_PATH = 'aitoc_smtp/log/delete';
/**
* @var UrlInterface
*/
private $urlBuilder;
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) {
if (isset($item['log_id'])) {
$urlEntityParamName = $this->getData('config/urlEntityParamName') ?: 'log_id';
$item[$this->getData('name')] = [
'preview' => [
'href' => $this->context->getUrl(
self::PREVIEW_ULR_PATH,
[
$urlEntityParamName => $item['log_id']
]
),
'target' => '_blank',
'label' => __('Preview Email'),
'popup' => true,
],
'delete' => [
'href' => $this->urlBuilder->getUrl(
self::DELETE_LOG_URL_PATH,
['log_id' => $item['log_id']]
),
'label' => __('Delete Email Log'),
'confirm' => [
'title' => __('Delete'),
'message' => __('Are you sure you want to delete?')
]
],
'resend' => [
'href' => $this->urlBuilder->getUrl(
self::RESEND_URL_PATH,
['log_id' => $item['log_id']]
),
'label' => __('Resend Email'),
'confirm' => [
'title' => __('Resend Email'),
'message' => __('Are you sure you want to resend the selected email?')
]
],
];
}
}
}
return $dataSource;
}
}
{
"name": "aitoc/smtp",
"description": "SMTP",
"require": {
"ext-dom": "*",
"aitoc/core": ">=1.0.16"
},
"type": "magento2-module",
"version": "1.0.4",
"license": [
"Commercial"
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Aitoc\\Smtp\\": ""
}
}
}
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<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_Reports::report">
<resource id="Aitoc_Smtp::main" title="Aitoc: SMTP" sortOrder="31">
<resource id="Aitoc_Smtp::log" title="SMTP Log" translate="title" sortOrder="10" />
</resource>
</resource>
<resource id="Magento_Backend::stores">
<resource id="Magento_Backend::stores_settings">
<resource id="Magento_Config::config">
<resource id="Aitoc_Smtp::config"
title="Aitoc SMTP" sortOrder="50"/>
</resource>
</resource>
</resource>
</resource>
</resources>
</acl>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Aitoc\Smtp\Model\ResourceModel\Log\Grid\Collection">
<arguments>
<argument name="mainTable" xsi:type="string">aitoc_smtp_log</argument>
<argument name="eventPrefix" xsi:type="string">aitsmtp_log_grid_collection</argument>
<argument name="eventObject" xsi:type="string">aitsmtp_log_grid_collection</argument>
<argument name="resourceModel" xsi:type="string">Aitoc\Smtp\Model\ResourceModel\Rule</argument>
</arguments>
</type>
</config>
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
<menu>
<add id="Aitoc_Smtp::main" title="SMTP" translate="title" module="Aitoc_Smtp" sortOrder="31" parent="Magento_Reports::report" resource="Aitoc_Smtp::main"/>
<add id="Aitoc_Smtp::log" action="aitoc_smtp/log/index" title="Emails Log" translate="title" module="Aitoc_Smtp" sortOrder="10" parent="Aitoc_Smtp::main" resource="Aitoc_Smtp::log"/>
</menu>
</config>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="aitoc_smtp" frontName="aitoc_smtp">
<module name="Aitoc_Smtp" />
</route>
</router>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="aitsmtp" translate="label" type="text" sortOrder="061532" showInDefault="1" showInWebsite="1" showInStore="1">
<label>SMTP</label>
<tab>aitoc_extensions</tab>
<resource>Aitoc_Smtp::config</resource>
<group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General Settings</label>
<field id="enabled" translate="label comment" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable SMTP</label>
<comment>When the option is disabled, the module will not impact on email sendings</comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
<group id="smtp" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>SMTP Settings</label>
<field id="use_default" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Use Pre-Defined SMTP Providers</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="provider" translate="label comment" type="select" sortOrder="15" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Provider</label>
<frontend_model>Aitoc\Smtp\Block\Adminhtml\Provider</frontend_model>
<source_model>Aitoc\Smtp\Model\Config\Options\Provider</source_model>
<depends>
<field id="use_default">1</field>
</depends>
</field>
<field id="name" translate="label comment" type="text" sortOrder="15" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Local Client Hostname</label>
<comment><![CDATA[Local client hostname or IP. Default: <strong>localhost</strong>]]></comment>
</field>
<field id="host" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Host</label>
<comment>Host name or IP address of SMTP Server</comment>
</field>
<field id="port" translate="label comment" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Port</label>
<comment><![CDATA[Default ports: 25, 465, or 587. (<strong>SSL</strong> - 465, <strong>TLS</strong> - 587)]]></comment>
<validate>integer</validate>
</field>
<field id="protocol" translate="label comment" type="select" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Connection Security</label>
<source_model>Aitoc\Smtp\Model\Config\Options\Protocol</source_model>
</field>
<field id="auth_type" translate="label comment" type="select" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Authentication Method</label>
<source_model>Aitoc\Smtp\Model\Config\Options\Auth</source_model>
</field>
<field id="login" translate="label comment" type="text" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Username</label>
</field>
<field id="password" translate="label comment" type="obscure" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Password</label>
<backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
</field>
<field id="test_email_to" translate="label comment" type="text" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Send Test To E-mail</label>
</field>
<field id="test_email_button" translate="label" sortOrder="90" showInDefault="1" showInWebsite="1" showInStore="1">
<label></label>
<frontend_model>Aitoc\Smtp\Block\Adminhtml\TestButton</frontend_model>
</field>
</group>
<group id="emails" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Emails Settings</label>
<field id="plain" translate="label comment" type="select" sortOrder="5" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Add Plain Text Part in Email</label>
<comment><![CDATA[Add Plain part in email recommended for <strong>increase Spam Score of email</strong>]]></comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="sender_enable" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Use Another Email Sender</label>
<comment><![CDATA[<strong>Please notice,</strong> the <strong>Sender domain</strong> must be the same as the domain where you send email. Other combinations can lead to a ban because of spam]]></comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="sender_email" translate="label comment" type="text" sortOrder="14" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sender Email</label>
<depends>
<field id="sender_enable">1</field>
</depends>
</field>
<field id="sender_name" translate="label comment" type="text" sortOrder="15" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Sender Name</label>
<depends>
<field id="sender_enable">1</field>
</depends>
</field>
<field id="cc" translate="label" type="textarea" sortOrder="20" showInDefault="1"
showInWebsite="1" showInStore="1">
<label>CC Emails</label>
<comment><![CDATA[Comma-separated. Leave empty for disable <strong>CC emails.</strong>]]></comment>
</field>
<field id="bcc" translate="label" type="textarea" sortOrder="30" showInDefault="1"
showInWebsite="1" showInStore="1">
<label>BCC Emails</label>
<comment><![CDATA[Comma-separated. Leave empty for disable <strong>BCC emails.</strong>]]></comment>
</field>
</group>
<group id="log" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Log Settings</label>
<field id="log" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable Log Outgoing Emails</label>
<comment><![CDATA[See the all emails and their contents ever <strong>sent throughout Aitoc SMTP.</strong>]]></comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="log_clean" translate="label comment" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Log Clean Every (days)</label>
<comment><![CDATA[<strong>Day(s).</strong> When empty or zero, the Email log will not be cleaned.]]></comment>
<validate>integer</validate>
<depends>
<field id="log">1</field>
</depends>
</field>
</group>
<group id="debug" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Debug</label>
<field id="delivery" translate="label comment" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Disable Actual Email Delivery (Debug Mode)</label>
<comment><![CDATA[<strong>Set the option to ‘Yes’ in order not to send emails actually.</strong> That can be used for debug or development purposes]]></comment>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="exeptional_email_addresses" translate="label" type="textarea" sortOrder="20" showInDefault="1"
showInWebsite="1" showInStore="1">
<label>Exceptional Email Addresses</label>
<comment>Comma-separated. Leave empty for disable</comment>
<depends>
<field id="delivery">1</field>
</depends>
</field>
<field id="exeptional_domains" translate="label" type="textarea" sortOrder="30" showInDefault="1"
showInWebsite="1" showInStore="1">
<label>Exceptional Email Domains</label>
<comment><![CDATA[Comma-separated. Leave empty for disable. <strong>Example:</strong> http://example.com,qwewqe.com ]]></comment>
<depends>
<field id="delivery">1</field>
</depends>
</field>
</group>
</section>
</system>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Store/etc/config.xsd">
<default>
<aitsmtp>
<general>
<enabled>1</enabled>
</general>
<smtp>
<name>localhost</name>
<use_default>0</use_default>
<provider>none</provider>
<auth_type>1</auth_type>
</smtp>
<emails>
<plain>0</plain>
<cc></cc>
<bcc></bcc>
<sender_enable>0</sender_enable>
</emails>
<log>
<log>1</log>
<log_clean>30</log_clean>
</log>
<debug>
<delivery>0</delivery>
<exeptional_email_addresses>example@example.com,unknown@unknown.com</exeptional_email_addresses>
<exeptional_domains>http://example.com, https://hello.com</exeptional_domains>
</debug>
</aitsmtp>
</default>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<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="aitoc_smtp_log_clear" instance="Aitoc\Smtp\Cron\Clear" method="execute">
<schedule>0 0 * * *</schedule>
</job>
</group>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<!--
/**
* Copyright © Aitoc. All rights reserved.
*/
-->
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="aitoc_smtp_log" resource="default" engine="innodb" comment="Aitoc SMTP Log">
<column xsi:type="int" name="log_id" unsigned="true" nullable="false" identity="true" comment="Log Id"/>
<column xsi:type="datetime" name="created_at" nullable="true" comment="Created At"/>
<column xsi:type="text" name="subject" nullable="false" />
<column xsi:type="text" name="email_body" nullable="false" />
<column xsi:type="text" name="sender_email" nullable="false" />
<column xsi:type="text" name="recipient_email" nullable="false" />
<column xsi:type="text" name="cc" nullable="true" />
<column xsi:type="text" name="bcc" nullable="true" />
<column xsi:type="smallint" name="status" nullable="false" />
<column xsi:type="text" name="status_message" nullable="true" />
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="log_id"/>
</constraint>
</table>
</schema>
{
"aitoc_smtp_log": {
"column": {
"log_id": true,
"created_at": true,
"subject": true,
"email_body": true,
"sender_email": true,
"recipient_email": true,
"cc": true,
"bcc": true,
"status": true,
"status_message": true
},
"constraint": {
"PRIMARY": true
}
}
}
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
<arguments>
<argument name="collections" xsi:type="array">
<item name="aitoc_smtp_log_listing_data_source" xsi:type="string">Aitoc\Smtp\Model\ResourceModel\Log\Grid\Collection</item>
</argument>
</arguments>
</type>
<type name="Magento\Framework\Mail\TransportInterfaceFactory">
<plugin name="Aitoc_Smtp::transportBuider" type="Aitoc\Smtp\Plugin\Framework\Mail\TransportInterfaceFactory" />
</type>
<type name="Magento\Framework\Mail\Template\TransportBuilderByStore">
<plugin name="Aitoc_Smtp::transportBuilderByStore"
type="Aitoc\Smtp\Plugin\Framework\Mail\Template\TransportBuilderByStore"/>
</type>
<type name="Magento\Framework\Mail\Template\TransportBuilder">
<plugin name="Aitoc_Smtp::TransportBuilder" type="Aitoc\Smtp\Plugin\Framework\Mail\Template\TransportBuilder"/>
</type>
<type name="Magento\Framework\Mail\Message">
<plugin name="Aitoc_Smtp::PlainPart" type="Aitoc\Smtp\Plugin\Framework\Mail\Message"/>
</type>
<type name="Magento\Framework\Mail\EmailMessage">
<arguments>
<argument name="encoding" xsi:type="string">utf-8</argument>
</arguments>
</type>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Email:etc/email_templates.xsd">
<template id="aitsmtp_resend_template" label="Aitoc SMTP Resend Template" file="resend_template.html" type="html" module="Aitoc_Smtp" area="frontend"/>
</config>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Aitoc_Smtp" setup_version="1.0.0">
<sequence>
<module name="Aitoc_Core"/>
</sequence>
</module>
</config>
"Send Test Email","Send Test Email"
Reports,Reports
"Log doesn't exist.","Log doesn't exist."
"A total of %1 email(s) have been deleted.","A total of %1 email(s) have been deleted."
"Email Log has been successfully deleted","Email Log has been successfully deleted"
"Unable to find the rule","Unable to find the rule"
"Emails Log","Emails Log"
"A total of %1 email(s) have been sent.","A total of %1 email(s) have been sent."
"Email Preview","Email Preview"
"An error occurred. The email template can not be opened for preview.","An error occurred. The email template can not be opened for preview."
"Email successfully was send.","Email successfully was send."
"Something went wrong.","Something went wrong."
"Message is successfully send!","Message is successfully send!"
"Error. Something went wrong. Please, try again.","Error. Something went wrong. Please, try again."
"Not Required","Not Required"
Login/Password,Login/Password
CRAM-MD5,CRAM-MD5
None,None
SSL,SSL
TLS,TLS
Success,Success
Failed,Failed
Blocked,Blocked
"Gmail, GSuite","Gmail, GSuite"
Yandex,Yandex
"Amazon SES: US East (N. Virginia)","Amazon SES: US East (N. Virginia)"
"Amazon SES: US West (Oregon)","Amazon SES: US West (Oregon)"
"Amazon SES: EU (Ireland)","Amazon SES: EU (Ireland)"
Mailgun,Mailgun
Mandrill,Mandrill
Sendinblue,Sendinblue
Sendgrid,Sendgrid
"Elastic Email","Elastic Email"
SparkPost,SparkPost
Mailjet,Mailjet
Postmark,Postmark
"AOL Mail","AOL Mail"
Comcast,Comcast
GMX,GMX
Hotmail,Hotmail
Mail.com,Mail.com
"O2 Mail","O2 Mail"
Office365,Office365
Orange,Orange
Outlook,Outlook
"Yahoo Mail","Yahoo Mail"
"Yahoo Mail Plus","Yahoo Mail Plus"
"Yahoo AU/NZ","Yahoo AU/NZ"
AT&T,AT&T
"NTL @ntlworld.com","NTL @ntlworld.com"
"BT Connect","BT Connect"
"Zoho Mail","Zoho Mail"
Verizon,Verizon
"BT Openworld","BT Openworld"
"O2 Online Deutschland","O2 Online Deutschland"
"1&1 Webmail","1&1 Webmail"
OVH,OVH
SMTP2GO,SMTP2GO
"Preview Email","Preview Email"
"Delete Email Log","Delete Email Log"
Delete,Delete
"Are you sure you want to delete?","Are you sure you want to delete?"
"Resend Email","Resend Email"
"Are you sure you want to resend the selected email?","Are you sure you want to resend the selected email?"
Fail,Fail
"Validation Error","Validation Error"
"Please check if the following fields are filled in: ","Please check if the following fields are filled in: "
"Send Test To E-mail","Send Test To E-mail"
"Connection Security","Connection Security"
"Authentication Method","Authentication Method"
"SMTP Log","SMTP Log"
SMTP,SMTP
"General Settings","General Settings"
"Enable SMTP","Enable SMTP"
"When the option is disabled, the module will not impact on email sendings","When the option is disabled, the module will not impact on email sendings"
"SMTP Settings","SMTP Settings"
"Use Pre-Defined SMTP Providers","Use Pre-Defined SMTP Providers"
Provider,Provider
"Local Client Hostname","Local Client Hostname"
"Local client hostname or IP. Default: <strong>localhost</strong>","Local client hostname or IP. Default: <strong>localhost</strong>"
Host,Host
"Host name or IP address of SMTP Server","Host name or IP address of SMTP Server"
Port,Port
"Default ports: 25, 465, or 587. (<strong>SSL</strong> - 465, <strong>TLS</strong> - 587)","Default ports: 25, 465, or 587. (<strong>SSL</strong> - 465, <strong>TLS</strong> - 587)"
Username,Username
Password,Password
"Emails Settings","Emails Settings"
"Add Plain Text Part in Email","Add Plain Text Part in Email"
"Add Plain part in email recommended for <strong>increase Spam Score of email</strong>","Add Plain part in email recommended for <strong>increase Spam Score of email</strong>"
"Use Another Email Sender","Use Another Email Sender"
"<strong>Please notice,</strong> the <strong>Sender domain</strong> must be the same as the domain where you send email. Other combinations can lead to a ban because of spam","<strong>Please notice,</strong> the <strong>Sender domain</strong> must be the same as the domain where you send email. Other combinations can lead to a ban because of spam"
"Sender Email","Sender Email"
"Sender Name","Sender Name"
"CC Emails","CC Emails"
"BCC Emails","BCC Emails"
"Log Settings","Log Settings"
"Enable Log Outgoing Emails","Enable Log Outgoing Emails"
"See the all emails and their contents ever <strong>sent throughout Aitoc SMTP.</strong>","See the all emails and their contents ever <strong>sent throughout Aitoc SMTP.</strong>"
"Log Clean Every (days)","Log Clean Every (days)"
"<strong>Day(s).</strong> When empty or zero, the Email log will not be cleaned.","<strong>Day(s).</strong> When empty or zero, the Email log will not be cleaned."
Debug,Debug
"Disable Actual Email Delivery (Debug Mode)","Disable Actual Email Delivery (Debug Mode)"
"<strong>Set the option to ‘Yes’ in order not to send emails actually.</strong> That can be used for debug or development purposes","<strong>Set the option to ‘Yes’ in order not to send emails actually.</strong> That can be used for debug or development purposes"
"Exceptional Email Addresses","Exceptional Email Addresses"
"Exceptional Email Domains","Exceptional Email Domains"
"Clear Emails Log","Clear Emails Log"
"Delete logs","Delete logs"
"Delete selected logs?","Delete selected logs?"
Resend,Resend
"Resend selected logs?","Resend selected logs?"
ID,ID
"Sender Data","Sender Data"
"Recipient Data","Recipient Data"
"Email Subject","Email Subject"
"Email Status","Email Status"
"Fail Message","Fail Message"
"Send Date","Send Date"
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Aitoc_Smtp',
__DIR__
);
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="styles"/>
<head>
<title>Emails Log</title>
</head>
<body>
<referenceContainer name="content">
<uiComponent name="aitoc_smtp_log_listing"/>
</referenceContainer>
</body>
</page>
<?xml version="1.0"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="empty" />
<body>
<referenceContainer name="root">
<block name="preview.page.content" class="Magento\Framework\View\Element\Template" template="Aitoc_Smtp::template/preview.phtml">
<block class="Aitoc\Smtp\Block\Adminhtml\Log\Preview" name="content" as="content"/>
</block>
</referenceContainer>
</body>
</page>
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
?>
<?php
/** @var \Aitoc\Smtp\Block\Adminhtml\TestButton $block */
?>
<?= /* @escapeNotVerified */ $block->getData('send_button') ?>
<script type="text/javascript">
require(['jquery', 'underscore', 'Magento_Ui/js/modal/alert', 'mage/translate'], function($, _, modalAlert, $t) {
var self = this,
buttonId = '<?= /* @escapeNotVerified */ $block->getData('button_id'); ?>',
params = ['name', 'host', 'port', 'protocol', 'auth_type', 'login', 'password', 'test_email_to'];
$('#' + buttonId).click(function (e) {
e.preventDefault();
showOrHideAjaxLoader('show');
call();
});
function call() {
var params = prepareSendParams(),
isValid = true,
validationFields = '';
_.each(params, function(data, key) {
if (data == '' || data === undefined) {
isValid = false;
validationFields = validationFields + '<strong>' + fieldModify(key) + '</strong>; ';
}
});
if (isValid) {
$.ajax({
url: '<?= /* @escapeNotVerified */ $block->getData('ajax_url'); ?>',
data: params,
dataType: 'json',
success: function (result) {
showOrHideAjaxLoader('hide');
modalAlert({
title: result.status ? $t('Success') : $t('Fail'),
content: result.content
});
}
});
} else {
showOrHideAjaxLoader('hide');
modalAlert({
title: $t('Validation Error'),
content: $t('Please check if the following fields are filled in: ') + validationFields
});
}
}
function fieldModify(field) {
if (field == 'test_email_to') {
field = $t('Send Test To E-mail');
return field;
}
if (field == 'protocol') {
field = $t('Connection Security');
return field;
}
if (field == 'auth_type') {
field = $t("Authentication Method");
return field;
}
if(field.length) {
field = field.charAt(0).toUpperCase() + field.slice(1);
}
return field;
}
function showOrHideAjaxLoader(action) {
$('body').loader(action);
return true;
}
/**
*
*/
function prepareSendParams() {
var selector = 'aitsmtp_smtp_',
result = {};
_.each(params, function(data){
result[data] = $('#' + selector + data).val();
});
return result;
}
})
</script>
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
?>
<?php
/** @var \Aitoc\Smtp\Block\Adminhtml\Provider $block */
?>
<script type="text/javascript">
require(['jquery', 'underscore'], function($, _) {
var self = this,
providers = $.parseJSON('<?= /* @escapeNotVerified */ $block->getData('providers'); ?>'),
params = ['host', 'port', 'protocol', 'auth_type'],
selectId = '#aitsmtp_smtp_provider';
$(selectId).change(function (e) {
var val = $(this).val();
var selector = 'aitsmtp_smtp_',
result = {};
_.each(params, function(data){
result[data] = $('#' + selector + data).val();
});
_.each(providers, function(data, key) {
if (key == val) {
_.each(params, function(param) {
var item = data.info[param];
if (param == 'protocol') {
item = data.info['encryption'];
switch (item) {
case 'ssl':
item = 1;
break;
case 'tls':
item = 2;
break;
default:
item = 0;
break;
}
}
if (param == 'auth_type') {
switch (item){
case 'login':
item = 1;
break;
default:
item = 0;
break;
}
}
$('#' + selector + param).val(item);
});
}
});
});
})
</script>
\ No newline at end of file
<?php
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
?>
<?php
/* @var $block \Aitoc\Smtp\Block\Adminhtml\Log\Preview */
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title><?= $block->escapeHtml(__('Email Preview')) ?></title>
</head>
<body>
<?= $block->getChildHtml('content') ?>
</body>
</html>
<script type="text/javascript">
function resizeIframe(obj){
obj.style.height = 0;
obj.style.height = obj.contentWindow.document.body.scrollHeight + 'px';
}
</script>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @author Aitoc Team
* @copyright Copyright (c) 2022 Aitoc (https://www.aitoc.com)
* @package Aitoc_Smtp
*/
-->
<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">aitoc_smtp_log_listing.aitoc_smtp_log_listing_data_source</item>
<item name="deps" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing_data_source</item>
</item>
<item name="spinner" xsi:type="string">aitoc_smtp_log_columns</item>
<item name="buttons" xsi:type="array">
<item name="clear_log" xsi:type="array">
<item name="name" xsi:type="string">clear</item>
<item name="class" xsi:type="string">primary</item>
<item name="label" xsi:type="string" translate="true">Clear Emails Log</item>
<item name="url" xsi:type="string">aitoc_smtp/log/clear</item>
</item>
</item>
</argument>
<dataSource name="aitoc_smtp_log_listing_data_source">
<argument name="dataProvider" xsi:type="configurableObject">
<argument name="class" xsi:type="string">Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider</argument>
<argument name="name" xsi:type="string">aitoc_smtp_log_listing_data_source</argument>
<argument name="primaryFieldName" xsi:type="string">log_id</argument>
<argument name="requestFieldName" xsi:type="string">log_id</argument>
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Magento_Ui/js/grid/provider</item>
<item name="update_url" xsi:type="url" path="mui/index/render"/>
<item name="storageConfig" xsi:type="array">
<item name="indexField" xsi:type="string">log_id</item>
</item>
</item>
</argument>
</argument>
</dataSource>
<container name="listing_top">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="template" xsi:type="string">ui/grid/toolbar</item>
</item>
</argument>
<bookmark name="bookmarks">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="namespace" xsi:type="string">aitoc_smtp_log_listing</item>
</item>
</item>
</argument>
</bookmark>
<component name="columns_controls">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsData" xsi:type="array">
<item name="provider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.aitoc_smtp_log_columns</item>
</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/controls/columns</item>
<item name="displayArea" xsi:type="string">dataGridActions</item>
</item>
</argument>
</component>
<filters name="listing_filters">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="columnsProvider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.aitoc_smtp_log_columns</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.filters</item>
</item>
<item name="childDefaults" xsi:type="array">
<item name="provider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.listing_top.listing_filters</item>
<item name="imports" xsi:type="array">
<item name="visible" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.aitoc_smtp_log_columns.${ $.index }:visible</item>
</item>
</item>
</item>
</argument>
</filters>
<massaction name="listing_massaction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="selectProvider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.aitoc_smtp_log_columns.ids</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/tree-massactions</item>
<item name="indexField" xsi:type="string">log_id</item>
</item>
</argument>
<action name="delete">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Delete logs</item>
<item name="message" xsi:type="string" translate="true">Delete selected logs?</item>
</item>
<item name="type" xsi:type="string">delete</item>
<item name="label" xsi:type="string" translate="true">Delete</item>
<item name="url" xsi:type="url" path="aitoc_smtp/log/massDelete"/>
</item>
</argument>
</action>
<action name="resend">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="confirm" xsi:type="array">
<item name="title" xsi:type="string" translate="true">Resend</item>
<item name="message" xsi:type="string" translate="true">Resend selected logs?</item>
</item>
<item name="type" xsi:type="string">resend</item>
<item name="label" xsi:type="string" translate="true">Resend</item>
<item name="url" xsi:type="url" path="aitoc_smtp/log/massResend"/>
</item>
</argument>
</action>
</massaction>
<paging name="listing_paging">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current.paging</item>
</item>
<item name="selectProvider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.aitoc_smtp_log_columns.ids</item>
</item>
</argument>
</paging>
</container>
<columns name="aitoc_smtp_log_columns">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.listing_top.bookmarks</item>
<item name="namespace" xsi:type="string">current</item>
</item>
<item name="childDefaults" xsi:type="array">
<item name="fieldAction" xsi:type="array">
<item name="provider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.aitoc_smtp_log_columns.actions</item>
<item name="target" xsi:type="string">applyAction</item>
<item name="params" xsi:type="array">
<item name="0" xsi:type="string">view</item>
<item name="1" xsi:type="string">${ $.$data.rowIndex }</item>
</item>
</item>
<item name="storageConfig" xsi:type="array">
<item name="provider" xsi:type="string">aitoc_smtp_log_listing.aitoc_smtp_log_listing.listing_top.bookmarks</item>
<item name="root" xsi:type="string">columns.${ $.index }</item>
<item name="namespace" xsi:type="string">current.${ $.storageConfig.root}</item>
</item>
</item>
</item>
</argument>
<selectionsColumn name="ids">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="indexField" xsi:type="string">log_id</item>
</item>
</argument>
</selectionsColumn>
<column name="log_id">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="sorting" xsi:type="string">desc</item>
<item name="resizeEnabled" xsi:type="boolean">true</item>
<item name="resizeDefaultWidth" xsi:type="string">40</item>
<item name="label" xsi:type="string" translate="true">ID</item>
</item>
</argument>
</column>
<column name="sender_email">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Sender Data</item>
</item>
</argument>
</column>
<column name="recipient_email">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Recipient Data</item>
</item>
</argument>
</column>
<column name="subject">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Email Subject</item>
</item>
</argument>
</column>
<column name="bcc">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">BCC Emails</item>
</item>
</argument>
</column>
<column name="cc">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">CC Emails</item>
</item>
</argument>
</column>
<column name="status" class="Aitoc\Smtp\Ui\Component\Listing\Column\Status">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="bodyTmpl" xsi:type="string">ui/grid/cells/html</item>
<item name="sortable" xsi:type="boolean">false</item>
<item name="label" xsi:type="string" translate="true">Email Status</item>
<item name="resizeEnabled" xsi:type="boolean">true</item>
<item name="resizeDefaultWidth" xsi:type="string">100</item>
</item>
</argument>
</column>
<column name="status_message">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Fail Message</item>
</item>
</argument>
</column>
<column name="created_at" class="Magento\Ui\Component\Listing\Columns\Date">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">dateRange</item>
<item name="component" xsi:type="string">Magento_Ui/js/grid/columns/date</item>
<item name="dataType" xsi:type="string">date</item>
<item name="label" xsi:type="string" translate="true">Send Date</item>
</item>
</argument>
</column>
<actionsColumn name="actions" class="Aitoc\Smtp\Ui\Component\Listing\Column\ViewAction">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="indexField" xsi:type="string">log_id</item>
<item name="viewUrlPath" xsi:type="string">aitoc_smtp/log/edit</item>
</item>
</argument>
</actionsColumn>
</columns>
</listing>
<!--@subject {{var subject}} @-->
{{var email_body|raw}}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment