Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#94738 add customer groups to nodes #298

Merged
merged 23 commits into from
Aug 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9f2a1ff
#94738 add serialized customer groups field to nodes
adamwaclawczyk Oct 17, 2023
ca6c474
#94738 remove types from properties
adamwaclawczyk Oct 17, 2023
8d19112
#94738 add fixes for github pipeline
adamwaclawczyk Oct 17, 2023
042e795
Merge branch 'develop' into feature/94738
ofrankowska Jan 8, 2024
8dc9468
#94738 - add customer groups multiselect
ofrankowska Jan 8, 2024
c085557
#94738 add http context variable, system config for handling it
adamwaclawczyk Jan 12, 2024
6bf5a2d
Merge branch 'develop' into feature/94738
ofrankowska Apr 5, 2024
fd00669
#94738 - add id to input elements
ofrankowska Apr 5, 2024
068102d
#94738 - return only customer_group.value
ofrankowska Apr 5, 2024
0c29a29
#94738 - remove redundant set customer group in http context
adamwaclawczyk Jul 5, 2024
3e6c7d8
#94738 - add customer group id to menu cache key
adamwaclawczyk Jul 5, 2024
057d545
#94738 generate declarative schema
adamwaclawczyk Jul 5, 2024
523fe62
#94738 generate db_schema_whitelist.json
adamwaclawczyk Jul 5, 2024
c6867e4
#94738 remove unnecessary setup scripts
adamwaclawczyk Jul 5, 2024
cd2db76
#94738 wip adjust loading customer group assignments
adamwaclawczyk Jul 5, 2024
a34f01f
#94738 adjust Block/Menu
adamwaclawczyk Jul 8, 2024
b578a0c
#94738 add node_id index
adamwaclawczyk Jul 8, 2024
4d6f87b
#94738 cleanup Node.php
adamwaclawczyk Jul 8, 2024
d30d2ac
#94738 regenerate db_schema_whitelist.json
adamwaclawczyk Jul 8, 2024
c89c331
#94738 fix errors
adamwaclawczyk Jul 8, 2024
2bf3811
#94738 use HttpContext to obtain customer group id
adamwaclawczyk Jul 8, 2024
3f5c7eb
#94738 use serializer, catch thrown exception when image is missing
adamwaclawczyk Jul 9, 2024
606e1cb
Merge branch 'develop' into feature/94738
adamwaclawczyk Aug 1, 2024
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
18 changes: 18 additions & 0 deletions Api/Data/NodeInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface NodeInterface
const IS_ACTIVE = 'is_active';
const ADDITIONAL_DATA = 'additional_data';
const SELECTED_ITEM_ID = 'selected_item_id';
const CUSTOMER_GROUPS = 'customer_groups';

/**
* Get node id
Expand Down Expand Up @@ -298,4 +299,21 @@ public function getSelectedItemId();
* @return $this
*/
public function setSelectedItemId($selectedItemId);

/**
* Get customer groups
*
*/
public function getCustomerGroups();

/**
* @return $this
*/
public function setCustomerGroups($customerGroups);

/**
* @param int $customerGroupId
* @return bool
*/
public function isVisible($customerGroupId);
}
16 changes: 15 additions & 1 deletion Block/Adminhtml/Edit/Tab/Nodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Magento\Framework\Registry;
use Snowdog\Menu\Api\NodeRepositoryInterface;
use Snowdog\Menu\Controller\Adminhtml\Menu\Edit;
use Snowdog\Menu\Model\CustomerGroupsProvider;
use Snowdog\Menu\Model\Menu\Node\Image\File as ImageFile;
use Snowdog\Menu\Model\NodeTypeProvider;
use Snowdog\Menu\Model\VueProvider;
Expand Down Expand Up @@ -45,13 +46,19 @@ class Nodes extends Template implements TabInterface
*/
private $vueProvider;

/**
* @var CustomerGroupsProvider
*/
private $customerGroupsProvider;

public function __construct(
Template\Context $context,
NodeRepositoryInterface $nodeRepository,
ImageFile $imageFile,
NodeTypeProvider $nodeTypeProvider,
Registry $registry,
VueProvider $vueProvider,
CustomerGroupsProvider $customerGroupsProvider,
array $data = []
) {
parent::__construct($context, $data);
Expand All @@ -60,6 +67,7 @@ public function __construct(
$this->nodeTypeProvider = $nodeTypeProvider;
$this->imageFile = $imageFile;
$this->vueProvider = $vueProvider;
$this->customerGroupsProvider = $customerGroupsProvider;
}

public function renderNodes()
Expand Down Expand Up @@ -185,7 +193,8 @@ private function renderNodeList($level, $parent, $data)
'image_width' => $node->getImageWidth(),
'image_height' => $node->getImageHeight(),
'columns' => $this->renderNodeList($level + 1, $node->getId(), $data) ?: [],
'selected_item_id' => $node->getSelectedItemId()
'selected_item_id' => $node->getSelectedItemId(),
'customer_groups' => $node->getCustomerGroups()
];
}
return $menu;
Expand All @@ -208,4 +217,9 @@ public function getVueComponents(): array
{
return $this->vueProvider->getComponents();
}

public function getCustomerGroups()
{
return $this->customerGroupsProvider->getAll();
}
}
43 changes: 27 additions & 16 deletions Block/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

namespace Snowdog\Menu\Block;

use Magento\Framework\Api\Search\FilterGroupBuilder;
use Magento\Framework\Api\Search\SearchCriteriaFactory;
use Magento\Framework\App\Cache\Type\Block;
use Magento\Framework\App\Http\Context;
use Magento\Framework\DataObject;
use Magento\Framework\View\Element\Template;
use Magento\Framework\Event\Manager as EventManager;
Expand All @@ -19,9 +18,13 @@

/**
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
*/
class Menu extends Template implements DataObject\IdentityInterface
{
const XML_SNOWMENU_GENERAL_CUSTOMER_GROUPS = 'snowmenu/general/customer_groups';

/**
* @var MenuRepositoryInterface
*/
Expand All @@ -41,15 +44,6 @@ class Menu extends Template implements DataObject\IdentityInterface

private $menu = null;

/**
* @var SearchCriteriaFactory
*/
private $searchCriteriaFactory;

/**
* @var FilterGroupBuilder
*/
private $filterGroupBuilder;
/**
* @var EventManager
*/
Expand Down Expand Up @@ -85,6 +79,11 @@ class Menu extends Template implements DataObject\IdentityInterface
*/
private $escaper;

/**
* @var Context
*/
private $httpContext;

/**
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
Expand All @@ -94,25 +93,23 @@ public function __construct(
MenuRepositoryInterface $menuRepository,
NodeRepositoryInterface $nodeRepository,
NodeTypeProvider $nodeTypeProvider,
SearchCriteriaFactory $searchCriteriaFactory,
FilterGroupBuilder $filterGroupBuilder,
TemplateResolver $templateResolver,
ImageFile $imageFile,
Escaper $escaper,
Context $httpContext,
array $data = []
) {
parent::__construct($context, $data);
$this->menuRepository = $menuRepository;
$this->nodeRepository = $nodeRepository;
$this->nodeTypeProvider = $nodeTypeProvider;
$this->searchCriteriaFactory = $searchCriteriaFactory;
$this->filterGroupBuilder = $filterGroupBuilder;
$this->eventManager = $eventManager;
$this->templateResolver = $templateResolver;
$this->imageFile = $imageFile;
$this->escaper = $escaper;
$this->setTemplate($this->getMenuTemplate($this->_template));
$this->submenuTemplate = $this->getSubmenuTemplate();
$this->httpContext = $httpContext;
}

/**
Expand Down Expand Up @@ -178,6 +175,9 @@ public function getCacheKeyInfo()
if ($nodeCacheKeyInfo) {
$info = array_merge($info, $nodeCacheKeyInfo);
}
if ($this->_scopeConfig->isSetFlag(self::XML_SNOWMENU_GENERAL_CUSTOMER_GROUPS)) {
$info[] = 'cust_group_' . $this->getCustomerGroupId();
}

return $info;
}
Expand Down Expand Up @@ -410,7 +410,8 @@ private function getMenuNodeBlock($node)
->setImageAltText($node->getImageAltText())
->setCustomTemplate($node->getNodeTemplate())
->setAdditionalData($node->getAdditionalData())
->setSelectedItemId($node->getSelectedItemId());
->setSelectedItemId($node->getSelectedItemId())
->setCustomerGroups($node->getCustomerGroups());

return $nodeBlock;
}
Expand Down Expand Up @@ -442,12 +443,17 @@ private function getSubmenuBlock($nodes, $parentNode, $level = 0)
private function fetchData()
{
$nodes = $this->nodeRepository->getByMenu($this->loadMenu()->getId());
$currentCustomerGroup = $this->getCustomerGroupId();
$customerGroupEnabled = $this->_scopeConfig->getValue(self::XML_SNOWMENU_GENERAL_CUSTOMER_GROUPS);
$result = [];
$types = [];
foreach ($nodes as $node) {
if (!$node->getIsActive()) {
continue;
}
if ($customerGroupEnabled && !$node->isVisible($currentCustomerGroup)) {
continue;
}

$level = $node->getLevel();
$parent = $node->getParentId() ?: 0;
Expand Down Expand Up @@ -502,4 +508,9 @@ private function getSubmenuTemplate()

return $this->getMenuTemplate($baseSubmenuTemplate);
}

public function getCustomerGroupId()
{
return $this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_GROUP);
}
}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
### Added
- `width` and `height` attributes to menu node images (DEV-102271)
- Option to specify customer groups for each node (DEV-94738)
- Snowdog branding in admin panel (DEV-105762)
- Automatically open collapsed menu node when dragging another node inside (DEV-101986)
- Duplicate node functionality (DEV-104364)
Expand Down
35 changes: 35 additions & 0 deletions Model/CustomerGroupsProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Snowdog\Menu\Model;

use Magento\Customer\Model\Group;
use Magento\Customer\Model\ResourceModel\Group\CollectionFactory as GroupCollectionFactory;

class CustomerGroupsProvider
{
/**
* @var GroupCollectionFactory
*/
private $groupCollectionFactory;

public function __construct(
GroupCollectionFactory $groupCollectionFactory
) {
$this->groupCollectionFactory = $groupCollectionFactory;
}

public function getAll()
{
$customerGroups = [];

/** @var Group $customerGroup */
foreach ($this->groupCollectionFactory->create() as $customerGroup) {
$customerGroups[] = [
'label' => $customerGroup->getCode(),
'value' => $customerGroup->getId()
];
}

return $customerGroups;
}
}
4 changes: 3 additions & 1 deletion Model/GraphQl/Resolver/DataProvider/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ private function convertData(NodeInterface $node): array
self::SUBMENU_TEMPLATE_FIELD => $node->getSubmenuTemplate(),
NodeInterface::CREATION_TIME => $node->getCreationTime(),
NodeInterface::UPDATE_TIME => $node->getUpdateTime(),
NodeInterface::ADDITIONAL_DATA => $node->getAdditionalData()
NodeInterface::ADDITIONAL_DATA => $node->getAdditionalData(),
NodeInterface::SELECTED_ITEM_ID => $node->getSelectedItemId(),
NodeInterface::CUSTOMER_GROUPS => $node->getCustomerGroups()
];
}

Expand Down
66 changes: 66 additions & 0 deletions Model/Menu/Node.php
Original file line number Diff line number Diff line change
@@ -1,14 +1,36 @@
<?php
namespace Snowdog\Menu\Model\Menu;

use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\Model\AbstractModel;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\ResourceModel\AbstractResource as AbstractResource;
use Magento\Framework\Registry;
use Magento\Framework\Serialize\SerializerInterface;
use Snowdog\Menu\Api\Data\NodeInterface;

class Node extends AbstractModel implements NodeInterface, IdentityInterface
{
const CACHE_TAG = 'snowdog_menu_node';

/**
* @var SerializerInterface
*/
private $serializer;

public function __construct(
Context $context,
Registry $registry,
SerializerInterface $serializer,
AbstractResource $resource = null,
AbstractDb $resourceCollection = null,
array $data = []
) {
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
$this->serializer = $serializer;
}

protected function _construct()
{
$this->_init(\Snowdog\Menu\Model\ResourceModel\Menu\Node::class);
Expand Down Expand Up @@ -325,4 +347,48 @@ public function setSelectedItemId($selectedItemId)
{
return $this->setData(NodeInterface::SELECTED_ITEM_ID, $selectedItemId);
}

public function getCustomerGroups()
{
$customerGroups = $this->_getData(NodeInterface::CUSTOMER_GROUPS);
if ($customerGroups == null) {
return [];
}
$customerGroups = explode(',', $customerGroups);
if (is_array($customerGroups) && !empty($customerGroups)) {
return $customerGroups;
}

return [];
}

public function setCustomerGroups($customerGroups)
{
if (empty($customerGroups)) {
$this->setData(NodeInterface::CUSTOMER_GROUPS);
return $this;
}

if (is_string($customerGroups) && $this->serializer->unserialize($customerGroups)) {
return $this->setData(NodeInterface::CUSTOMER_GROUPS, $customerGroups);
}

return $this->setData(NodeInterface::CUSTOMER_GROUPS, $this->serializer->serialize($customerGroups));
}

public function isVisible($customerGroupId)
{
$customerGroups = $this->getCustomerGroups();
if (empty($customerGroups)) {
return true;
}

foreach ($customerGroups as $customerGroup) {
if ((int) $customerGroup === (int) $customerGroupId) {
return true;
}
}

return false;
}
}
2 changes: 1 addition & 1 deletion Model/Menu/Node/Image/Node.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function updateNodeImage(int $nodeId, ?string $image): void
public function getNodeListImages(array $nodeIds): array
{
$searchCriteria = $this->searchCriteriaBuilder
->addFilter(NodeInterface::NODE_ID, $nodeIds, 'in')
->addFilter('main_table.' . NodeInterface::NODE_ID, $nodeIds, 'in')
->addFilter(NodeInterface::IMAGE, true, 'notnull')
->addFilter(NodeInterface::IMAGE, '', 'neq')
->create();
Expand Down
1 change: 1 addition & 0 deletions Model/Menu/NodeRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Snowdog\Menu\Model\Menu\NodeFactory;
use Snowdog\Menu\Model\ResourceModel\Menu\Node\CollectionFactory;
use Magento\Framework\Api\SortOrder;
use Magento\Framework\DB\Sql\Expression;

class NodeRepository implements NodeRepositoryInterface
{
Expand Down
Loading
Loading