Your IP : 127.0.0.1
<?php
/**
* @author Glace Team
* @copyright Copyright (c) 2019 Glace (https://www.glace.com)
* @package Glace_Lib01
*/
namespace Glace\Lib01\Model;
use Glace\Lib01\Model\AdminNotification\Model\ResourceModel\Inbox\Collection\ExistsFactory;
use Glace\Lib01\Model\Source\NotificationType;
use Magento\Framework\HTTP\Adapter\Curl;
use Magento\Framework\Notification\MessageInterface;
use Magento\Store\Model\ScopeInterface;
use Glace\Lib01\Model\AdminNotification\Model\ResourceModel\Inbox\Collection\Expired;
use Glace\Lib01\Model\AdminNotification\Model\ResourceModel\Inbox\Collection\ExpiredFactory;
use Glace\Lib01\Helper\Module;
class Feed
{
const HOUR_MIN_SEC_VALUE = 60 * 60 * 24;
const REMOVE_EXPIRED_FREQUENCY = 60 * 60 * 6;//4 times per day
const XML_LAST_UPDATE = 'glace_lib01/system_value/last_update';
const XML_FREQUENCY_PATH = 'glace_lib01/notifications/frequency';
const XML_FIRST_MODULE_RUN = 'glace_lib01/system_value/first_module_run';
const XML_LAST_REMOVMENT = 'glace_lib01/system_value/remove_date';
const URL_NEWS = 'glace.com/feed-news-segments.xml';//do not use https:// or http
/**
* @var array
*/
private $glaceModules = [];
/**
* @var \Magento\Backend\App\ConfigInterface
*/
private $config;
/**
* @var \Magento\Framework\App\Config\ReinitableConfigInterface
*/
private $reinitableConfig;
/**
* @var \Magento\Framework\App\Config\Storage\WriterInterface
*/
private $configWriter;
/**
* @var \Magento\Framework\HTTP\Adapter\CurlFactory
*/
private $curlFactory;
/**
* @var \Magento\Framework\App\ProductMetadataInterface
*/
private $productMetadata;
/**
* @var \Magento\AdminNotification\Model\InboxFactory
*/
private $inboxFactory;
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
private $scopeConfig;
/**
* @var ExpiredFactory
*/
private $expiredFactory;
/**
* @var \Magento\Framework\Module\ModuleListInterface
*/
private $moduleList;
/**
* @var AdminNotification\Model\ResourceModel\Inbox\Collection\ExistsFactory
*/
private $inboxExistsFactory;
/**
* @var \Magento\Store\Model\StoreManagerInterface
*/
private $storeManager;
/**
* @var Module
*/
private $moduleHelper;
public function __construct(
\Magento\Backend\App\ConfigInterface $config,
\Magento\Framework\App\Config\ReinitableConfigInterface $reinitableConfig,
\Magento\Framework\App\Config\Storage\WriterInterface $configWriter,
\Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
\Magento\AdminNotification\Model\InboxFactory $inboxFactory,
\Magento\Framework\App\ProductMetadataInterface $productMetadata,
\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
ExpiredFactory $expiredFactory,
\Magento\Framework\Module\ModuleListInterface $moduleList,
ExistsFactory $inboxExistsFactory,
\Magento\Store\Model\StoreManagerInterface $storeManager,
Module $moduleHelper
) {
$this->config = $config;
$this->reinitableConfig = $reinitableConfig;
$this->configWriter = $configWriter;
$this->curlFactory = $curlFactory;
$this->productMetadata = $productMetadata;
$this->inboxFactory = $inboxFactory;
$this->scopeConfig = $scopeConfig;
$this->expiredFactory = $expiredFactory;
$this->moduleList = $moduleList;
$this->inboxExistsFactory = $inboxExistsFactory;
$this->storeManager = $storeManager;
$this->moduleHelper = $moduleHelper;
}
/**
* @return $this
*/
public function checkUpdate()
{
if ($this->getFrequency() + $this->getLastUpdate() > time()) {
return $this;
}
$allowedNotifications = $this->getAllowedTypes();
if (empty($allowedNotifications) || in_array(NotificationType::UNSUBSCRIBE_ALL, $allowedNotifications)) {
return $this;
}
$feedData = null;
$maxPriority = 0;
$feedXml = $this->getFeedData();
if ($feedXml && $feedXml->channel && $feedXml->channel->item) {
$installDate = $this->getFirstModuleRun();
foreach ($feedXml->channel->item as $item) {
if (!array_intersect($this->convertToArray($item->type), $allowedNotifications)
|| (int)$item->version == 1 // for magento One
|| ((string)$item->edition && (string)$item->edition != $this->getCurrentEdition())
) {
continue;
}
$priority =(int)$item->priority ?: 1;
if ($priority <= $maxPriority) {
continue; //add only one with the highest priority
}
if (!$this->validateByExtension((string)$item->extension)) {
continue;
}
if (!$this->validateByGlaceCount($item->glace_module_qty)) {
continue;
}
if (!$this->validateByNotInstalled((string)$item->glace_module_not)) {
continue;
}
if (!$this->validateByExtension((string)$item->third_party_modules, true)) {
continue;
}
if (!$this->validateByDomainZone((string)$item->domain_zone)) {
continue;
}
if ($this->isItemExists($item)) {
continue;
}
$date = strtotime((string)$item->pubDate);
$expired =(string)$item->expirationDate ? strtotime((string)$item->expirationDate) : null;
if ($installDate <= $date
&& (!$expired || $expired > gmdate('U'))
) {
$maxPriority = $priority;
$expired = $expired ? date('Y-m-d H:i:s', $expired) : null;
$feedData = [
'severity' => MessageInterface::SEVERITY_NOTICE,
'date_added' => date('Y-m-d H:i:s', $date),
'expiration_date' => $expired,
'title' => $this->convertString($item->title),
'description' => $this->convertString($item->description),
'url' => $this->convertString($item->link),
'is_glace' => 1
];
}
}
if ($feedData) {
/** @var \Magento\AdminNotification\Model\Inbox $inbox */
$inbox = $this->inboxFactory->create();
$inbox->parse([$feedData]);
}
}
$this->setLastUpdate();
return $this;
}
/**
* @param $value
*
* @return array
*/
private function convertToArray($value)
{
return explode(',', (string)$value);
}
/**
* @param \SimpleXMLElement $item
* @return bool
*/
private function isItemExists(\SimpleXMLElement $item)
{
return $this->inboxExistsFactory->create()->execute($item);
}
/**
* @return string
*/
protected function getCurrentEdition()
{
return $this->productMetadata->getEdition() == 'Community' ? 'ce' : 'ee';
}
/**
* @return $this
*/
public function removeExpiredItems()
{
if ($this->getLastRemovement() + self::REMOVE_EXPIRED_FREQUENCY > time()) {
return $this;
}
/** @var Expired $collection */
$collection = $this->expiredFactory->create();
foreach ($collection as $model) {
$model->setIsRemove(1)->save();
}
$this->setLastRemovement();
return $this;
}
/**
* @return \SimpleXMLElement|false
*/
public function getFeedData()
{
/** @var Curl $curlObject */
$curlObject = $this->curlFactory->create();
$curlObject->setConfig(
[
'timeout' => 2,
'useragent' => $this->productMetadata->getName()
. '/' . $this->productMetadata->getVersion()
. ' (' . $this->productMetadata->getEdition() . ')'
]
);
$curlObject->write(\Zend_Http_Client::GET, $this->getFeedUrl(), '1.0');
$result = $curlObject->read();
if ($result === false || $result === '') {
return false;
}
$result = preg_split('/^\r?$/m', $result, 2);
$result = trim($result[1]);
$curlObject->close();
try {
$xml = new \SimpleXMLElement($result);
} catch (\Exception $e) {
return false;
}
return $xml;
}
/**
* @return array
*/
private function getAllowedTypes()
{
$allowedNotifications = $this->getModuleConfig('notifications/type');
$allowedNotifications = explode(',', $allowedNotifications);
return $allowedNotifications;
}
/**
* @param \SimpleXMLElement $data
* @return string
*/
private function convertString(\SimpleXMLElement $data)
{
$data = htmlspecialchars((string)$data);
return $data;
}
/**
* @return int
*/
private function getFrequency()
{
return $this->config->getValue(self::XML_FREQUENCY_PATH) * self::HOUR_MIN_SEC_VALUE;
}
/**
* @return string
*/
private function getFeedUrl()
{
$scheme = $this->getCurrentScheme();
$url = $scheme ?: 'http://';
return $url . self::URL_NEWS;
}
/**
* @return int
*/
private function getLastUpdate()
{
return $this->config->getValue(self::XML_LAST_UPDATE);
}
/**
* @return $this
*/
private function setLastUpdate()
{
$this->configWriter->save(self::XML_LAST_UPDATE, time());
$this->reinitableConfig->reinit();
return $this;
}
/**
* @return int|mixed
*/
private function getFirstModuleRun()
{
$result = $this->config->getValue(self::XML_FIRST_MODULE_RUN);
if (!$result) {
$result = time();
$this->configWriter->save(self::XML_FIRST_MODULE_RUN, $result);
$this->reinitableConfig->reinit();
}
return $result;
}
/**
* @param $path
* @param int $storeId
* @return mixed
*/
private function getModuleConfig($path, $storeId = null)
{
return $this->scopeConfig->getValue(
'glace_lib01/' . $path,
ScopeInterface::SCOPE_STORE,
$storeId
);
}
/**
* @return int
*/
private function getLastRemovement()
{
return $this->config->getValue(self::XML_LAST_REMOVMENT);
}
/**
* @return $this
*/
private function setLastRemovement()
{
$this->configWriter->save(self::XML_LAST_REMOVMENT, time());
$this->reinitableConfig->reinit();
return $this;
}
/**
* @return array|string[]
*/
private function getInstalledGlaceExtensions()
{
if (!$this->glaceModules) {
$modules = $this->moduleList->getNames();
$dispatchResult = new \Magento\Framework\DataObject($modules);
$modules = $dispatchResult->toArray();
$modules = array_filter(
$modules,
function ($item) {
return strpos($item, 'Glace_') !== false;
}
);
$this->glaceModules = $modules;
}
return $this->glaceModules;
}
/**
* @return array|string[]
*/
private function getAllExtensions()
{
$modules = $this->moduleList->getNames();
$dispatchResult = new \Magento\Framework\DataObject($modules);
$modules = $dispatchResult->toArray();
return $modules;
}
/**
* @param string $extensions
* @return bool
*/
private function validateByExtension($extensions, $allModules = false)
{
if ($extensions) {
$result = false;
$extensions = $this->validateExtensionValue($extensions);
if ($extensions) {
$installedModules = $allModules ? $this->getAllExtensions() : $this->getInstalledGlaceExtensions();
$intersect = array_intersect($extensions, $installedModules);
if ($intersect) {
$result = true;
}
}
} else {
$result = true;
}
return $result;
}
/**
* @param string $extensions
* @return bool
*/
private function validateByNotInstalled($extensions)
{
if ($extensions) {
$result = false;
$extensions = $this->validateExtensionValue($extensions);
if ($extensions) {
$installedModules = $this->getInstalledGlaceExtensions();
$diff = array_diff($extensions, $installedModules);
if ($diff) {
$result = true;
}
}
} else {
$result = true;
}
return $result;
}
/**
* @param string $extensions
*
* @return array
*/
private function validateExtensionValue($extensions)
{
$extensions = explode(',', $extensions);
$extensions = array_filter($extensions, function ($item) {
return strpos($item, '_1') === false;
});
$extensions = array_map(function ($item) {
return str_replace('_2', '', $item);
}, $extensions);
return $extensions;
}
/**
* @param $counts
* @return bool
*/
private function validateByGlaceCount($counts)
{
$result = true;
$countString = (string)$counts;
if ($countString) {
$moreThan = null;
$result = false;
$position = strpos($countString, '>');
if ($position !== false) {
$moreThan = substr($countString, $position + 1);
$moreThan = explode(',', $moreThan);
$moreThan = array_shift($moreThan);
}
$counts = $this->convertToArray($counts);
$glaceModules = $this->getInstalledGlaceExtensions();
$dependModules = $this->getDependModules($glaceModules);
$glaceModules = array_diff($glaceModules, $dependModules);
$glaceCount = count($glaceModules);
if ($glaceCount
&& (in_array($glaceCount, $counts)
|| ($moreThan && $glaceCount >= $moreThan)
)
) {
$result = true;
}
}
return $result;
}
/**
* @param $zones
*
* @return bool
*/
private function validateByDomainZone($zones)
{
$result = true;
if ($zones) {
$zones = $this->convertToArray($zones);
$currentZone = $this->getDomainZone();
if (!in_array($currentZone, $zones)) {
$result = false;
}
}
return $result;
}
/**
* @return string
*/
private function getDomainZone()
{
$domain = '';
$url = $this->storeManager->getStore()->getBaseUrl();
$components = parse_url($url);
if (isset($components['host'])) {
$host = explode('.', $components['host']);
$domain = end($host);
}
return $domain;
}
/**
* @return string
*/
private function getCurrentScheme()
{
$scheme = '';
$url = $this->storeManager->getStore()->getBaseUrl();
$components = parse_url($url);
if (isset($components['scheme'])) {
$scheme = $components['scheme'] . '://';
}
return $scheme;
}
/**
* @param $glaceModules
*
* @return array
*/
private function getDependModules($glaceModules)
{
$depend = [];
$result = [];
$dataName = [];
foreach ($glaceModules as $module) {
$data = $this->moduleHelper->getModuleInfo($module);
if (isset($data['name'])) {
$dataName[$data['name']] = $module;
}
if (isset($data['require']) and is_array($data['require'])) {
foreach ($data['require'] as $requireItem => $version) {
if (strpos($requireItem, 'glace') !== false) {
$depend[] = $requireItem;
}
}
}
}
$depend = array_unique($depend);
foreach ($depend as $item) {
if (isset($dataName[$item])) {
$result[] = $dataName[$item];
}
}
return $result;
}
}