Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 41 additions & 3 deletions Block/Adminhtml/System/Config/Form/Info.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Magefan\Community\Api\GetModuleVersionInterface;
use Magefan\Community\Api\SecureHtmlRendererInterface;
use Magefan\Community\Api\GetModuleInfoInterface;
use Magefan\Community\Model\SectionFactory;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Framework\Module\ModuleListInterface;
Expand Down Expand Up @@ -40,21 +41,28 @@ class Info extends \Magento\Config\Block\System\Config\Form\Field
*/
protected $getModuleInfo;

/**
* @var SectionFactory
*/
protected $sectionFactory;

/**
* @param ModuleListInterface $moduleList
* @param Context $context
* @param array $data
* @param GetModuleVersionInterface|null $getModuleVersion
* @param SecureHtmlRendererInterface|null $mfSecureRenderer
* @param ModuleInfoInterface|null $getModuleInfo
* @param SectionFactory|null $sectionFactory
*/
public function __construct(
ModuleListInterface $moduleList,
Context $context,
array $data = [],
?GetModuleVersionInterface $getModuleVersion = null,
?SecureHtmlRendererInterface $mfSecureRenderer = null,
?GetModuleInfoInterface $getModuleInfo = null
?GetModuleInfoInterface $getModuleInfo = null,
?SectionFactory $sectionFactory = null
) {
parent::__construct($context, $data);
$this->moduleList = $moduleList;
Expand All @@ -65,6 +73,8 @@ public function __construct(
->get(SecureHtmlRendererInterface::class);
$this->getModuleInfo = $getModuleInfo ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(GetModuleInfoInterface::class);
$this->sectionFactory = $sectionFactory ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(SectionFactory::class);
}

/**
Expand Down Expand Up @@ -206,12 +216,20 @@ public function render(AbstractElement $element)
<div class="col-actions">
<div class="actions">';
if ($canUpgradeToMaxPlan) {
$escapedUrl = $this->escapeHtml($moduleUrl . '/pricing' . $utmParam);
$productKey = $this->getProductKey($element);

if ($productKey) {
$upgradeUrl = 'https://magefan.com/mfplanupgrade/upgrade/index?product_key=' . urlencode($productKey);
} else {
$upgradeUrl = $moduleUrl . '/pricing' . $utmParam . '&utm_campaign=upgrade-plan';
}

$escapedUrl = $this->escapeHtml($upgradeUrl);
$html .= '<button
id="upgrade"
title="Upgrade Plan"
class="action-upgrade"
onclick="window.open(\'' . $escapedUrl . '&utm_campaign=upgrade-plan\', \'_blank\'); return false;"
onclick="window.open(\'' . $escapedUrl . '\', \'_blank\'); return false;"
>
<span>Upgrade Plan</span>
</button>';
Expand Down Expand Up @@ -351,6 +369,26 @@ class="action-update"
return $html;
}

/**
* Get configured product key for the current section, if any
*
* @param AbstractElement $element
* @return string|null
*/
protected function getProductKey(AbstractElement $element)
{
$fieldConfig = $element->getFieldConfig();
$sectionName = !empty($fieldConfig['path']) ? explode('/', $fieldConfig['path'])[0] : '';

if (!$sectionName) {
return null;
}

$productKey = $this->sectionFactory->create(['name' => $sectionName])->getKey();

return $productKey ?: null;
}

/**
* Return extension url
*
Expand Down
166 changes: 140 additions & 26 deletions Plugin/Magento/Backend/Model/Menu/BuilderPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
namespace Magefan\Community\Plugin\Magento\Backend\Model\Menu;

use Magefan\Community\Api\GetModuleInfoInterface;
use Magefan\Community\Api\GetModuleVersionInterface;
use Magento\Backend\Model\Menu\Builder;
use Magento\Backend\Model\Menu;
use Magento\Backend\Model\Menu\ItemFactory;
use Magefan\Community\Model\Config;
use Magefan\Community\Model\SectionFactory;
use Magento\Config\Model\Config\Structure;
use Magento\Framework\Module\Manager;
use Magento\Framework\Module\ModuleListInterface;
Expand Down Expand Up @@ -49,6 +51,11 @@ class BuilderPlugin
*/
private $configSections;

/**
* @var array
*/
private $allConfigSections;

/**
* @var array
*/
Expand All @@ -59,6 +66,16 @@ class BuilderPlugin
*/
private $getModuleInfo;

/**
* @var GetModuleVersionInterface
*/
private $getModuleVersion;

/**
* @var SectionFactory
*/
private $sectionFactory;

/**
* BuilderPlugin constructor.
* @param ItemFactory $menuItemFactory
Expand All @@ -67,14 +84,18 @@ class BuilderPlugin
* @param ModuleListInterface $moduleList
* @param Manager $moduleManager
* @param GetModuleInfoInterface $getModuleInfo
* @param GetModuleVersionInterface|null $getModuleVersion
* @param SectionFactory|null $sectionFactory
*/
public function __construct(
ItemFactory $menuItemFactory,
Config $config,
Structure $structure,
ModuleListInterface $moduleList,
Manager $moduleManager,
GetModuleInfoInterface $getModuleInfo
GetModuleInfoInterface $getModuleInfo,
?GetModuleVersionInterface $getModuleVersion = null,
?SectionFactory $sectionFactory = null
) {
$this->menuItemFactory = $menuItemFactory;
$this->config = $config;
Expand All @@ -83,6 +104,12 @@ public function __construct(
$this->moduleManager = $moduleManager;
$this->magefanModules = $this->getMagefanModules();
$this->getModuleInfo = $getModuleInfo;
$this->getModuleVersion = $getModuleVersion ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
GetModuleVersionInterface::class
);
$this->sectionFactory = $sectionFactory ?: \Magento\Framework\App\ObjectManager::getInstance()->get(
SectionFactory::class
);
}

/**
Expand Down Expand Up @@ -236,32 +263,12 @@ private function addUserGuideLinks(Menu $menu): void
$added[] = $id;

// extract module name from id e.g. Magefan_Blog::elements -> Magefan_Blog
$module = explode('::', $id)[0];
$module = explode('_', $module)[1];
$url = !empty($modulesInfo[$module]) ? $modulesInfo[$module]->getDocumentationUrl() : '';
// unique id per module to avoid conflicts
$newItemId = $id . '_user_guides';
if (!$url) {
continue;
}

try {
$encodedUrl = 'mf-ug-url-start' . rtrim(strtr(base64_encode($url), '+/', '-_'), '=') . 'mf-ug-url-end';

$userGuideItem = $this->menuItemFactory->create([
'data' => [
'id' => $newItemId,
'title' => 'User Guides',
'module' => 'Magefan_Community',
'resource' => 'Magefan_Community::elements',
'action' => $encodedUrl,
]
]);

$menu->add($userGuideItem, $id, 6000);
$moduleFullName = explode('::', $id)[0];
$module = explode('_', $moduleFullName)[1];
$moduleInfo = !empty($modulesInfo[$module]) ? $modulesInfo[$module] : null;

} catch (\Exception $e) {
}
$this->addUserGuideLink($menu, $id, $moduleInfo);
$this->addUpgradePlanLink($menu, $id, $moduleFullName, $moduleInfo);
}
}
}
Expand All @@ -270,6 +277,90 @@ private function addUserGuideLinks(Menu $menu): void
}
}

/**
* Add "User Guides" sub menu item for a module
*
* @param Menu $menu
* @param string $id
* @param \Magento\Framework\DataObject|null $moduleInfo
* @return void
*/
private function addUserGuideLink(Menu $menu, string $id, $moduleInfo): void
{
$url = $moduleInfo ? $moduleInfo->getDocumentationUrl() : '';
if (!$url) {
return;
}

try {
$encodedUrl = 'mf-ug-url-start' . rtrim(strtr(base64_encode($url), '+/', '-_'), '=') . 'mf-ug-url-end';

$userGuideItem = $this->menuItemFactory->create([
'data' => [
'id' => $id . '_user_guides',
'title' => 'User Guides',
'module' => 'Magefan_Community',
'resource' => 'Magefan_Community::elements',
'action' => $encodedUrl,
]
]);

$menu->add($userGuideItem, $id, 6000);
} catch (\Exception $e) {
}
}

/**
* Add "Upgrade Plan" sub menu item for a module, if a higher paid plan is available for it
*
* @param Menu $menu
* @param string $id
* @param string $moduleFullName
* @param \Magento\Framework\DataObject|null $moduleInfo
* @return void
*/
private function addUpgradePlanLink(Menu $menu, string $id, string $moduleFullName, $moduleInfo): void
{
if (!$moduleInfo || !$moduleInfo->getMaxPlan()) {
return;
}

$canUpgradeToMaxPlan = !$this->getModuleVersion->execute(
$moduleFullName . ucfirst($moduleInfo->getMaxPlan())
);

if (!$canUpgradeToMaxPlan) {
return;
}

$productKey = $this->getProductKeyForModule($moduleFullName);

if ($productKey) {
$url = 'https://magefan.com/mfplanupgrade/upgrade/index?product_key=' . urlencode($productKey);
} else {
$moduleUrl = $moduleInfo->getProductUrl() ?: 'https://magefan.com/';
$url = rtrim($moduleUrl, '/') . '/pricing'
. '?utm_source=admin&utm_medium=menu&utm_campaign=upgrade-plan';
}

try {
$encodedUrl = 'mf-upg-url-start' . rtrim(strtr(base64_encode($url), '+/', '-_'), '=') . 'mf-upg-url-end';

$upgradePlanItem = $this->menuItemFactory->create([
'data' => [
'id' => $id . '_upgrade_plan',
'title' => 'Upgrade Plan',
'module' => 'Magefan_Community',
'resource' => 'Magefan_Community::elements',
'action' => $encodedUrl,
]
]);

$menu->add($upgradePlanItem, $id, 6001);
} catch (\Exception $e) {
}
}

/**
* Ge config by module name
*
Expand Down Expand Up @@ -304,11 +395,34 @@ private function getConfigSections($moduleName)
$mName = $this->getModuleNameByResource($section['resource']);
$this->configSections[$mName] = $section;
}

$this->allConfigSections = $this->configSections;
}

return isset($this->configSections[$moduleName]) ? $this->configSections[$moduleName] : null;
}

/**
* Get configured product key for a Magefan module, if any
*
* @param string $moduleFullName
* @return string|null
*/
private function getProductKeyForModule(string $moduleFullName): ?string
{
// ensure sections are loaded, regardless of whether createMenuItem() already consumed them
$this->getConfigSections($moduleFullName);

$sectionKey = $this->allConfigSections[$moduleFullName]['key'] ?? null;
if (!$sectionKey) {
return null;
}

$productKey = $this->sectionFactory->create(['name' => $sectionKey])->getKey();

return $productKey ?: null;
}

/**
* Get module by resource
*
Expand Down
Loading