diff --git a/Block/System/Config/Form/SyncButton.php b/Block/System/Config/Form/SyncButton.php
index 644a669..3598409 100644
--- a/Block/System/Config/Form/SyncButton.php
+++ b/Block/System/Config/Form/SyncButton.php
@@ -9,6 +9,7 @@
namespace Magenerds\SystemDiff\Block\System\Config\Form;
+use Magenerds\SystemDiff\Helper\Config;
use Magento\Config\Block\System\Config\Form\Field;
use Magento\Framework\Data\Form\Element\AbstractElement;
@@ -24,15 +25,41 @@ class SyncButton extends Field
*/
protected $element;
+ /**
+ * @var Config
+ */
+ public $configHelper;
+
+ /**
+ * SyncButton constructor.
+ *
+ * Additionally injects config helper.
+ *
+ * @param \Magento\Backend\Block\Template\Context $context
+ * @param array $data
+ * @param Config $configHelper
+ */
+ public function __construct(
+ \Magento\Backend\Block\Template\Context $context,
+ Config $configHelper,
+ array $data = []
+ ) {
+ $this->configHelper = $configHelper;
+
+ parent::__construct($context, $data);
+ }
+
/**
* Remove scope label
*
* @param AbstractElement $element
+ *
* @return string
*/
public function render(AbstractElement $element)
{
$element->unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
+
return parent::render($element);
}
@@ -40,6 +67,7 @@ public function render(AbstractElement $element)
* Return element html
*
* @param AbstractElement $element
+ *
* @return string
*/
protected function _getElementHtml(AbstractElement $element)
@@ -73,7 +101,7 @@ public function getButtonHtml()
);
$button->setData(
[
- 'id' => $this->element->getHtmlId(),
+ 'id' => $this->element->getHtmlId(),
'label' => __('Run'),
'class' => 'disabled' // reset when page loaded, see template script
]
@@ -82,6 +110,24 @@ public function getButtonHtml()
return $button->toHtml();
}
+ /**
+ * Returns info about last sync date time as a string for usage in "'"-JS string.
+ *
+ * @return string
+ */
+ public function getLastSyncInfo()
+ {
+ $formattedDateTime = $this->configHelper->getLastSyncDatetimeFormatted();
+
+ return (string)filter_var(
+ sprintf(
+ __('Last diff on %s'),
+ $formattedDateTime
+ ),
+ FILTER_SANITIZE_MAGIC_QUOTES
+ );
+ }
+
/**
* Returns the element defined in system.xml
*
@@ -91,4 +137,4 @@ public function getElement()
{
return $this->element;
}
-}
\ No newline at end of file
+}
diff --git a/Console/Command/ExecuteCommand.php b/Console/Command/ExecuteCommand.php
index 7409bd2..6e76734 100644
--- a/Console/Command/ExecuteCommand.php
+++ b/Console/Command/ExecuteCommand.php
@@ -9,6 +9,7 @@
namespace Magenerds\SystemDiff\Console\Command;
+use Magenerds\SystemDiff\Helper\Config;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -26,20 +27,34 @@ class ExecuteCommand extends Command
*/
const COMMAND_DESCRIPTION = 'system-diff:execute';
+ /**
+ * Exit code when exception occurred
+ */
+ const EXIT_CODE_EXCEPTION = 4;
+
/**
* @var PerformSystemDiffService
*/
private $performSystemDiffService;
+ /**
+ * @var Config
+ */
+ private $configHelper;
+
/**
* ExecuteCommand constructor.
+ *
* @param PerformSystemDiffService $performSystemDiffService
+ * @param Config $configHelper
*/
public function __construct(
- PerformSystemDiffService $performSystemDiffService
- ){
+ PerformSystemDiffService $performSystemDiffService,
+ Config $configHelper
+ ) {
parent::__construct(self::COMMAND_NAME);
$this->performSystemDiffService = $performSystemDiffService;
+ $this->configHelper = $configHelper;
}
/**
@@ -54,16 +69,28 @@ public function configure()
}
/**
- * @param InputInterface $input An InputInterface instance
+ * @param InputInterface $input An InputInterface instance
* @param OutputInterface $output An OutputInterface instance
- * @return null|int null or 0 if everything went fine, or an error code
+ *
+ * @return int 0 if everything went fine, or an error code
*/
public function execute(InputInterface $input, OutputInterface $output)
{
+ $exitStatus = 0;
try {
+ $output->write('Performing sync and diff...');
$this->performSystemDiffService->performDiff();
+ $output->writeln(
+ sprintf(
+ 'Done at %s.',
+ $this->configHelper->getLastSyncDatetimeFormatted()
+ )
+ );
} catch (\Exception $e) {
+ $exitStatus = self::EXIT_CODE_EXCEPTION;
$output->writeln(sprintf('An error occurred during diff: %s', $e->getMessage()));
}
+
+ return $exitStatus;
}
}
\ No newline at end of file
diff --git a/Controller/Adminhtml/SystemDiff/Diff.php b/Controller/Adminhtml/SystemDiff/Diff.php
index 2918ba2..971183f 100644
--- a/Controller/Adminhtml/SystemDiff/Diff.php
+++ b/Controller/Adminhtml/SystemDiff/Diff.php
@@ -9,6 +9,7 @@
namespace Magenerds\SystemDiff\Controller\Adminhtml\SystemDiff;
+use Magenerds\SystemDiff\Helper\Config;
use Magenerds\SystemDiff\Service\PerformSystemDiffService;
use Magento\Backend\App\Action;
use Magento\Backend\App\Action\Context;
@@ -31,21 +32,29 @@ class Diff extends Action
*/
private $performSystemDiffService;
+ /**
+ * @var Config
+ */
+ private $configHelper;
+
/**
* Diff action constructor.
*
- * @param Context $context
- * @param JsonFactory $jsonFactory
+ * @param Context $context
+ * @param JsonFactory $jsonFactory
* @param PerformSystemDiffService $performSystemDiffService
+ * @param Config $configHelper
*/
public function __construct(
Context $context,
JsonFactory $jsonFactory,
- PerformSystemDiffService $performSystemDiffService
+ PerformSystemDiffService $performSystemDiffService,
+ Config $configHelper
) {
$this->context = $context;
$this->jsonFactory = $jsonFactory;
$this->performSystemDiffService = $performSystemDiffService;
+ $this->configHelper = $configHelper;
parent::__construct($context);
}
@@ -60,15 +69,23 @@ public function execute()
$result = $this->jsonFactory->create();
- $message = 'OK';
+ $message = 'Diff successfully done at %s.';
try {
$this->performSystemDiffService->performDiff();
} catch (\Exception $e) {
- $message = "Error performing system diff.";
+ $message = __("Error performing system diff at %s.");
+ $result->setStatusHeader(500);
}
- $result->setData(['message' => $message]);
+ $result->setData(
+ [
+ 'message' => sprintf(
+ __($message),
+ $this->configHelper->getLastSyncDatetimeFormatted()
+ ),
+ ]
+ );
return $result;
}
diff --git a/DataWriter/StoreConfigDataWriter.php b/DataWriter/StoreConfigDataWriter.php
index 7ae8a04..2843a58 100644
--- a/DataWriter/StoreConfigDataWriter.php
+++ b/DataWriter/StoreConfigDataWriter.php
@@ -16,17 +16,6 @@
class StoreConfigDataWriter implements DataWriterInterface
{
- /**
- * Holds database field names
- */
- const LOCAL_VALUE_FIELD_NAME = 'diff_value_local';
- const REMOTE_VALUE_FIELD_NAME = 'diff_value_remote';
- const SCOPE_FIELD_NAME = 'scope';
- const SCOPE_ID_FIELD_NAME = 'scope_id';
- const PATH_FIELD_NAME = 'path';
- const SCOPE_VALUE_WEBSITES = 'websites';
- const SCOPE_VALUE_STORES = 'stores';
-
/**
* Holds further necessary consts
*/
@@ -101,8 +90,8 @@ public function write(array $diffData)
foreach ($localValues as $localPath => $localValue) {
if (array_key_exists($localPath, $remoteValues)) {
$combinedValues[$localPath] = [
- self::LOCAL_VALUE_FIELD_NAME => $localValue,
- self::REMOTE_VALUE_FIELD_NAME => $remoteValues[$localPath]
+ DiffConfigResource::LOCAL_VALUE_FIELD_NAME => $localValue,
+ DiffConfigResource::REMOTE_VALUE_FIELD_NAME => $remoteValues[$localPath]
];
unset($localValues[$localPath]);
@@ -110,8 +99,8 @@ public function write(array $diffData)
}
}
- $localModels = $this->mapDataToModels($localValues, $scope, self::LOCAL_VALUE_FIELD_NAME);
- $remoteModels = $this->mapDataToModels($remoteValues, $scope, self::REMOTE_VALUE_FIELD_NAME);
+ $localModels = $this->mapDataToModels($localValues, $scope, DiffConfigResource::LOCAL_VALUE_FIELD_NAME);
+ $remoteModels = $this->mapDataToModels($remoteValues, $scope, DiffConfigResource::REMOTE_VALUE_FIELD_NAME);
$combinedModels = $this->mapDataToModels($combinedValues, $scope);
$scopeModels = array_merge($localModels, $remoteModels, $combinedModels);
@@ -144,11 +133,11 @@ protected function mapDataToModels(array $data, $scope, $valueField = null)
foreach ($data as $path => $value) {
/** @var DiffConfigModel $diffConfigModel */
$diffConfigModel = $this->diffConfigFactory->create();
- $diffConfigModel->setData(self::SCOPE_FIELD_NAME, $scope);
+ $diffConfigModel->setScope($scope);
$scopeId = self::DEFAULT_SCOPE_ID;
- if ($scope === self::SCOPE_VALUE_WEBSITES || $scope === self::SCOPE_VALUE_STORES) {
+ if ($scope === DiffConfigResource::SCOPE_VALUE_WEBSITES || $scope === DiffConfigResource::SCOPE_VALUE_STORES) {
if (empty($path)) {
continue;
}
@@ -162,17 +151,17 @@ protected function mapDataToModels(array $data, $scope, $valueField = null)
$code = $splittedPath[0];
$path = $splittedPath[1];
- if ($scope === self::SCOPE_VALUE_WEBSITES) {
+ if ($scope === DiffConfigResource::SCOPE_VALUE_WEBSITES) {
$scopeId = $this->getWebsiteId($code);
}
- if ($scope === self::SCOPE_VALUE_STORES) {
+ if ($scope === DiffConfigResource::SCOPE_VALUE_STORES) {
$scopeId = $this->getStoreId($code);
}
}
- $diffConfigModel->setData(self::SCOPE_ID_FIELD_NAME, $scopeId);
- $diffConfigModel->setData(self::PATH_FIELD_NAME, $path);
+ $diffConfigModel->setScope($scopeId);
+ $diffConfigModel->setPath($path);
if (is_array($value) && is_null($valueField)) {
foreach ($value as $fieldName => $v) {
@@ -182,7 +171,6 @@ protected function mapDataToModels(array $data, $scope, $valueField = null)
$diffConfigModel->setData($valueField, $value);
}
-
$models[] = $diffConfigModel;
}
diff --git a/Helper/Config.php b/Helper/Config.php
index c5b8141..53f208d 100644
--- a/Helper/Config.php
+++ b/Helper/Config.php
@@ -9,7 +9,14 @@
namespace Magenerds\SystemDiff\Helper;
+use DateTimeInterface;
+use Magenerds\SystemDiff\Model\DiffConfig;
+use Magenerds\SystemDiff\Model\ResourceModel\DiffConfig as DiffConfigResource;
use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magenerds\SystemDiff\Model\ResourceModel\DiffConfig\CollectionFactory;
+use Magenerds\SystemDiff\Model\DiffConfigFactory;
+use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
+use Magento\Framework\Stdlib\DateTime\DateTime;
/**
* Class to read module-specific configuration
@@ -27,20 +34,54 @@ class Config
const XML_PATH_ACCESS_TOKEN = 'system_diff/connection/access_token';
const XML_PATH_API_TYPE = 'system_diff/connection/api_type';
const XML_PATH_DISPLAY_STORE_CONFIG = 'system_diff/display/store_config';
+ const XML_PATH_LAST_SYNC_DATETIME = 'system_diff/general/last_sync_datetime';
/**
* @var ScopeConfigInterface
*/
private $scopeConfig;
+ /**
+ * @var CollectionFactory
+ */
+ private $diffConfigCollectionFactory;
+
+ /**
+ * @var DiffConfigFactory
+ */
+ private $diffConfigFactory;
+
+ /**
+ * @var DateTime
+ */
+ private $dateTime;
+
+ /**
+ * @var TimezoneInterface
+ */
+ private $timezone;
+
/**
* Config constructor.
+ *
* @param ScopeConfigInterface $scopeConfig
+ * @param CollectionFactory $collectionFactory
+ * @param DiffConfigFactory $diffConfigFactory
+ * @param TimezoneInterface $timezone
+ * @param DateTime $dateTime
*/
public function __construct(
- ScopeConfigInterface $scopeConfig
+ ScopeConfigInterface $scopeConfig,
+ CollectionFactory $collectionFactory,
+ DiffConfigFactory $diffConfigFactory,
+ TimezoneInterface $timezone,
+ DateTime $dateTime
) {
$this->scopeConfig = $scopeConfig;
+ $this->diffConfigCollectionFactory = $collectionFactory;
+ $this->diffConfigFactory = $diffConfigFactory;
+ $this->dateTime = $dateTime;
+ $this->timezone = $timezone;
}
/**
@@ -84,4 +125,74 @@ public function isDisplayStoreConfig()
{
return $this->scopeConfig->isSetFlag(self::XML_PATH_DISPLAY_STORE_CONFIG);
}
+
+ /**
+ * Return a string with date time of last sync or n/a.
+ *
+ * @return string
+ */
+ public function getLastSyncDatetimeFormatted()
+ {
+ $dateTime = $this->getLastSyncDatetime();
+ if ($dateTime instanceof DateTimeInterface) {
+
+ return $this->timezone->formatDateTime($dateTime, \IntlDateFormatter::SHORT, true);
+ }
+
+ return (string)__('n/a');
+ }
+
+ /**
+ * The last saved sync datetime timestamp as string.
+ *
+ * Should be a gmt timestamp.
+ *
+ * @return DateTimeInterface|null;
+ */
+ public function getLastSyncDatetime()
+ {
+ $dataObject = $this->getLastSyncDiffConfig();
+ $dateTime = null;
+ if ($dataObject instanceof DiffConfig) {
+ $timeStampString = $dataObject->getDiffValueLocal();
+ $dateTime = \DateTime::createFromFormat("U", $timeStampString);
+ }
+
+ return $dateTime;
+ }
+
+ /**
+ * DiffConfig entry that holds the last sync time.
+ *
+ * @return DiffConfig|null;
+ */
+ protected function getLastSyncDiffConfig()
+ {
+ $collection = $this->diffConfigCollectionFactory->create();
+
+ /** @var DiffConfig $dataObject */
+ $dataObject = $collection->getItemByColumnValue(
+ DiffConfigResource::PATH_FIELD_NAME,
+ self::XML_PATH_LAST_SYNC_DATETIME
+ );
+
+ return $dataObject;
+ }
+
+ /**
+ * Create or update last sync entry.
+ *
+ * @return void
+ */
+ public function updateLastDiffTimestamp()
+ {
+ $diffConfig = $this->getLastSyncDiffConfig();
+ if (!($diffConfig instanceof DiffConfig)) {
+ $diffConfig = $this->diffConfigFactory->create();
+ $diffConfig->setScope('default');
+ $diffConfig->setPath(Config::XML_PATH_LAST_SYNC_DATETIME);
+ }
+ $diffConfig->setDiffValueLocal($this->dateTime->gmtTimestamp());
+ $diffConfig->save();
+ }
}
\ No newline at end of file
diff --git a/Model/DiffConfig.php b/Model/DiffConfig.php
index 2b80f6d..d746035 100644
--- a/Model/DiffConfig.php
+++ b/Model/DiffConfig.php
@@ -28,4 +28,36 @@ protected function _construct()
{
$this->_init(DiffConfigResource::class);
}
+
+ /**
+ * @param string $value
+ */
+ public function setDiffValueLocal($value)
+ {
+ $this->setData(DiffConfigResource::LOCAL_VALUE_FIELD_NAME, $value);
+ }
+
+ /**
+ * @return string
+ */
+ public function getDiffValueLocal()
+ {
+ return (string)$this->getData(DiffConfigResource::LOCAL_VALUE_FIELD_NAME);
+ }
+
+ /**
+ * @param string $path
+ */
+ public function setPath(string $path)
+ {
+ $this->setData(DiffConfigResource::PATH_FIELD_NAME, $path);
+ }
+
+ /**
+ * @param string $scope
+ */
+ public function setScope(string $scope)
+ {
+ $this->setData(DiffConfigResource::SCOPE_FIELD_NAME, $scope);
+ }
}
\ No newline at end of file
diff --git a/Model/ResourceModel/DiffConfig.php b/Model/ResourceModel/DiffConfig.php
index 290923c..35c1d76 100644
--- a/Model/ResourceModel/DiffConfig.php
+++ b/Model/ResourceModel/DiffConfig.php
@@ -17,6 +17,21 @@
*/
class DiffConfig extends AbstractDb
{
+ /**
+ * Holds database field names
+ */
+ const LOCAL_VALUE_FIELD_NAME = 'diff_value_local';
+ const REMOTE_VALUE_FIELD_NAME = 'diff_value_remote';
+ const SCOPE_FIELD_NAME = 'scope';
+ const SCOPE_ID_FIELD_NAME = 'scope_id';
+ const PATH_FIELD_NAME = 'path';
+
+ /**
+ * Values for scope
+ */
+ const SCOPE_VALUE_WEBSITES = 'websites';
+ const SCOPE_VALUE_STORES = 'stores';
+
/**
* Resource initialization
*
diff --git a/Service/SaveDiffToTableService.php b/Service/SaveDiffToTableService.php
index 8b22a0a..1648f18 100644
--- a/Service/SaveDiffToTableService.php
+++ b/Service/SaveDiffToTableService.php
@@ -12,6 +12,7 @@
use Magenerds\SystemDiff\Api\Service\SaveDiffToTableServiceInterface;
use Magenerds\SystemDiff\DataWriter\DataWriterInterface;
use Magenerds\SystemDiff\DataWriter\DataWriterPool;
+use Magenerds\SystemDiff\Helper\Config;
/**
* Class SaveDiffToTableService
@@ -24,17 +25,32 @@ class SaveDiffToTableService implements SaveDiffToTableServiceInterface
*/
private $writerPool;
+ /**
+ * @var Config
+ */
+ private $configHelper;
+
/**
* StoreConfigDataWriter constructor.
+ *
* @param DataWriterPool $writerPool
+ * @param Config $configHelper
+ *
+ * @internal param DiffConfigFactory $diffConfigFactory
+ * @internal param DateTime $dateTime
+ * @internal param StoreConfigUpdater $configUpdater
*/
- public function __construct(DataWriterPool $writerPool)
- {
+ public function __construct(
+ DataWriterPool $writerPool,
+ Config $configHelper
+ ) {
$this->writerPool = $writerPool;
+ $this->configHelper = $configHelper;
}
/**
* @param [] $diffData
+ *
* @return void
*/
public function saveData(array $diffData)
@@ -43,5 +59,7 @@ public function saveData(array $diffData)
/** @var DataWriterInterface $writer */
$writer->write($diffData);
}
+
+ $this->configHelper->updateLastDiffTimestamp();
}
}
\ No newline at end of file
diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml
index b051c9a..a5c22a3 100644
--- a/etc/adminhtml/system.xml
+++ b/etc/adminhtml/system.xml
@@ -40,7 +40,7 @@
REST: http[s]://[remotehost]/index.php/rest/all/V1/systemConfig/all
SOAP: http[s]://[remotehost]/soap?wsdl&services=magenerdsSystemDiffServiceFetchLocalDataServiceV1
- See http://devdocs.magento.com/guides/v2.2/get-started/soap/soap-web-api-calls.html
+ See http://devdocs.magento.com/guides/v2.2/get-started/soap/soap-web-api-calls.html
]]>
diff --git a/view/adminhtml/templates/system/config/sync_button.phtml b/view/adminhtml/templates/system/config/sync_button.phtml
index 72e8a42..2b3ba1a 100644
--- a/view/adminhtml/templates/system/config/sync_button.phtml
+++ b/view/adminhtml/templates/system/config/sync_button.phtml
@@ -13,26 +13,50 @@ require(
['jquery', 'prototype'],
function(jQuery){
+ var buttonId = 'getElement()->getHtmlId() ?>';
+ var buttonSelector = '#'+buttonId;
+ var infoSelector = buttonSelector+'_info';
+
+ var $info = jQuery(infoSelector);
+ var $button = jQuery(buttonSelector);
+
function enableSyncButton() {
- Form.Element.enable('getElement()->getHtmlId() ?>');
- jQuery('#getElement()->getHtmlId() ?>').removeClass('disabled');
+ Form.Element.enable(buttonId);
+ $button.removeClass('disabled');
}
function disableSyncButton() {
- Form.Element.disable('getElement()->getHtmlId() ?>');
- jQuery('#getElement()->getHtmlId() ?>').addClass('disabled');
+ Form.Element.disable(buttonId);
+ $button.addClass('disabled');
}
- Event.observe(window, 'load', function(){
+ function message(message, type) {
+ $info.html(message);
+ $info.addClass('message');
+
+ if (type === "error") {
+ $info.addClass('message-error');
+ } else {
+ $info.removeClass('message-error');
+ }
+ }
+
+ jQuery(document).ready(function(){
enableSyncButton();
});
- jQuery('#getElement()->getHtmlId() ?>').click(
+ jQuery(buttonSelector).click(
function () {
disableSyncButton();
+ message('');
jQuery.get(
'getAjaxUrl() ?>'
- ).always(function(){
+ ).done(function (data) {
+ message(data.message);
+ }).fail(function (jqXHR, textStatus, errorThrown) {
+ message(errorThrown, "error");
+
+ }).always(function(){
enableSyncButton();
})
;
@@ -42,4 +66,5 @@ require(
);
-getButtonHtml() ?>
\ No newline at end of file
+getButtonHtml() ?>
+getLastSyncInfo(); ?>
diff --git a/view/adminhtml/web/css/style.css b/view/adminhtml/web/css/style.css
index 69f35fa..6f832cf 100644
--- a/view/adminhtml/web/css/style.css
+++ b/view/adminhtml/web/css/style.css
@@ -26,4 +26,10 @@
.diff-hidden {
display: none;
+}
+
+.message.magenerds_sync_info {
+ display: block;
+ float: none;
+ margin: .5em 0;
}
\ No newline at end of file