├── composer.json
├── registration.php
├── etc
├── adminhtml
│ ├── routes.xml
│ ├── menu.xml
│ ├── events.xml
│ └── system.xml
├── config.xml
├── frontend
│ └── events.xml
├── module.xml
├── acl.xml
├── db_schema_whitelist.json
├── di.xml
└── db_schema.xml
├── Model
├── Condition
│ └── Sql
│ │ ├── Expression.php
│ │ └── Builder.php
├── ImageField.php
├── Source
│ └── Config
│ │ ├── Position.php
│ │ ├── Store.php
│ │ ├── LabelType.php
│ │ ├── Type.php
│ │ ├── Status.php
│ │ └── CustomerGroup.php
├── Config.php
├── Rule
│ ├── Condition
│ │ ├── Combine.php
│ │ └── Product.php
│ └── DataProvider.php
├── ResourceModel
│ ├── Rule
│ │ └── Collection.php
│ └── Rule.php
├── Indexer
│ ├── Full.php
│ └── Row.php
└── Rule.php
├── view
├── adminhtml
│ ├── layout
│ │ ├── product_label_rule_edit.xml
│ │ └── product_label_rule_index.xml
│ ├── templates
│ │ └── rule
│ │ │ └── fieldset.phtml
│ └── ui_component
│ │ └── boolfly_label_rule_listing.xml
└── frontend
│ ├── layout
│ └── catalog_product_view.xml
│ ├── templates
│ ├── label.phtml
│ └── product
│ │ └── label.phtml
│ └── web
│ └── css
│ └── source
│ └── _module.less
├── Controller
└── Adminhtml
│ ├── Image
│ └── Upload.php
│ ├── Rule
│ ├── NewAction.php
│ ├── Index.php
│ ├── Delete.php
│ ├── NewConditionHtml.php
│ ├── Edit.php
│ ├── MassDelete.php
│ ├── MassStatus.php
│ └── Save.php
│ └── AbstractRule.php
├── Observer
├── AfterLoadProductCollection.php
├── AddLabelRuleData.php
├── AfterSaveRule.php
├── UpdateRuleAfterProductSave.php
└── ProcessingImageUpload.php
├── Plugin
└── Catalog
│ └── Block
│ ├── ProductPlugin.php
│ └── Product
│ └── ImagePlugin.php
├── Block
├── Label.php
├── Product
│ └── Label.php
└── Adminhtml
│ └── Rule
│ └── Conditions.php
├── Ui
└── Component
│ └── Listing
│ └── Columns
│ └── EditActions.php
├── README.md
├── Api
└── Data
│ └── RuleInterface.php
├── LICENSE.txt
└── Helper
└── Rule.php
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "boolfly/module-product-label",
3 | "description": "Product Label Module",
4 | "require": {
5 | "php": ">=7.3 || >=8.0",
6 | "boolfly/module-base": "^1.0.0"
7 | },
8 | "type": "magento2-module",
9 | "license": [
10 | "OSL-3.0",
11 | "AFL-3.0"
12 | ],
13 | "autoload": {
14 | "files": [
15 | "registration.php"
16 | ],
17 | "psr-4": {
18 | "Boolfly\\ProductLabel\\": ""
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/registration.php:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Model/Condition/Sql/Expression.php:
--------------------------------------------------------------------------------
1 | _expression !== '' ? '(' . $this->_expression . ')' : '';
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 | 1
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/view/adminhtml/layout/product_label_rule_edit.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/view/adminhtml/layout/product_label_rule_index.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Model/ImageField.php:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Image/Upload.php:
--------------------------------------------------------------------------------
1 | _forward('edit');
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/etc/frontend/events.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Rule/Index.php:
--------------------------------------------------------------------------------
1 | initAction()->_addBreadcrumb(__('Catalog'), __('Catalog'));
27 | $this->_view->getPage()->getConfig()->getTitle()->prepend(__('Manage Rules'));
28 | $this->_view->renderLayout();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/etc/adminhtml/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/etc/adminhtml/events.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/etc/acl.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 | separator-top
16 | boolfly
17 | Product Label
18 | Boolfly_ProductLabel::config
19 |
20 | Settings
21 |
22 | Enable
23 | Magento\Config\Model\Config\Source\Yesno
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Observer/AfterLoadProductCollection.php:
--------------------------------------------------------------------------------
1 | helperRule = $helperRule;
38 | }
39 |
40 | /**
41 | * @param Observer $observer
42 | * @throws \Exception
43 | */
44 | public function execute(Observer $observer)
45 | {
46 | /** @var Collection $collection */
47 | $collection = $observer->getEvent()->getData('collection');
48 | $this->helperRule->addRuleIdsToCollection($collection);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Observer/AddLabelRuleData.php:
--------------------------------------------------------------------------------
1 | helperRule = $helperRule;
39 | }
40 |
41 | /**
42 | * @param Observer $observer
43 | * @throws \Exception
44 | */
45 | public function execute(Observer $observer)
46 | {
47 | /** @var Product $product */
48 | $product = $observer->getEvent()->getData('product');
49 | if ($product instanceof Product) {
50 | $this->helperRule->addRuleIds($product);
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Model/Source/Config/Position.php:
--------------------------------------------------------------------------------
1 | 'top-left', 'label' => __('Top-Left')],
31 | ['value' => 'top-right', 'label' => __('Top-Right')],
32 | ['value' => 'bot-left', 'label' => __('Bottom-Left')],
33 | ['value' => 'bot-right', 'label' => __('Bottom-Right')]
34 | ];
35 |
36 | return $options;
37 | }
38 |
39 | /**
40 | * Get options in "key-value" format
41 | *
42 | * @return array
43 | */
44 | public function toArray()
45 | {
46 | return [
47 | 'top-left' => __('Top-Left'),
48 | 'top-right' => __('Top-Right'),
49 | 'bottom-left' => __('Bottom-Left'),
50 | 'bottom-right' => __('Bottom-Right')
51 | ];
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Observer/AfterSaveRule.php:
--------------------------------------------------------------------------------
1 | indexerFull = $indexerFull;
40 | }
41 |
42 | /**
43 | * Execute event
44 | *
45 | * @param Observer $observer
46 | * @throws \Exception
47 | */
48 | public function execute(Observer $observer)
49 | {
50 | $rule = $observer->getEvent()->getData('label_rule');
51 | if ($rule instanceof RuleInterface) {
52 | $this->indexerFull->setRule($rule);
53 | $this->indexerFull->execute();
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/view/frontend/templates/label.phtml:
--------------------------------------------------------------------------------
1 | getGroupRule();
12 | ?>
13 |
14 | $rules) :?>
15 |
16 |
18 |
20 | isUseImageInList()) :?>
21 |
24 |
25 |
26 | = /* @escapeNotVerified */ $rule->getCategoryText()?>
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/view/frontend/templates/product/label.phtml:
--------------------------------------------------------------------------------
1 | getGroupRule();
12 | ?>
13 |
14 | $rules) :?>
15 |
16 |
18 |
20 | isUseImageInProduct()) :?>
21 |
24 |
25 |
26 | = /* @escapeNotVerified */ $rule->getProductText()?>
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Model/Config.php:
--------------------------------------------------------------------------------
1 | scopeConfig = $scopeConfig;
41 | }
42 |
43 | /**
44 | * Get Configuration
45 | *
46 | * @param $path
47 | * @return mixed
48 | */
49 | public function getConfig($path)
50 | {
51 | return $this->scopeConfig->getValue($path, ScopeInterface::SCOPE_STORES);
52 | }
53 |
54 | /**
55 | * Enable Mega menu
56 | *
57 | * @return boolean
58 | */
59 | public function isEnable()
60 | {
61 | return $this->scopeConfig->isSetFlag(self::XML_PATH_PRODUCT_LABEL_ENABLE, ScopeInterface::SCOPE_STORES);
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/Model/Source/Config/Store.php:
--------------------------------------------------------------------------------
1 | systemStore = $systemStore;
44 | }
45 |
46 | /**
47 | * Retrieve option array with empty value
48 | *
49 | * @return string[]
50 | */
51 | public function getAllOptions()
52 | {
53 | if ($this->_options === null) {
54 | $this->_options = $this->systemStore->getStoreValuesForForm(false, false);
55 | }
56 | return $this->_options;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Model/Source/Config/LabelType.php:
--------------------------------------------------------------------------------
1 | __('Image'),
41 | self::TEXT_TYPE => __('Text')
42 | ];
43 | }
44 |
45 | /**
46 | * Retrieve option array with empty value
47 | *
48 | * @return string[]
49 | */
50 | public function getAllOptions()
51 | {
52 | $result = [];
53 |
54 | foreach (self::getOptionArray() as $index => $value) {
55 | $result[] = ['value' => $index, 'label' => $value];
56 | }
57 |
58 | return $result;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/Plugin/Catalog/Block/ProductPlugin.php:
--------------------------------------------------------------------------------
1 | config = $config;
39 | }
40 |
41 | /**
42 | * Set Product
43 | *
44 | * @param $subject
45 | * @param $result
46 | * @param Image $product
47 | * @param $imageId
48 | * @param array $attribute
49 | * @return mixed
50 | */
51 | public function afterGetImage(
52 | AbstractProduct $subject,
53 | $result,
54 | $product,
55 | $imageId,
56 | $attribute = []
57 | ) {
58 | if ($result instanceof Image && $this->config->isEnable()) {
59 | $result->setData('product', $product);
60 | }
61 |
62 | return $result;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/view/adminhtml/templates/rule/fieldset.phtml:
--------------------------------------------------------------------------------
1 |
13 | getElement() ?>
14 | getFieldSetId() != null ? $block->getFieldSetId() : $element->getHtmlId() ?>
15 |
16 |
serialize(['class']) ?> class="fieldset">
17 | = $block->escapeHtml($element->getLegend()) ?>
18 |
19 | getComment()) : ?>
20 |
21 |
= $block->escapeHtml($element->getComment()) ?>
22 |
23 |
24 |
25 | = $element->getChildrenHtml() ?>
26 |
27 |
28 |
29 |
42 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Rule/Delete.php:
--------------------------------------------------------------------------------
1 | getRequest()->getParam('id');
27 | /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
28 | $resultRedirect = $this->resultRedirectFactory->create();
29 | if ($id) {
30 | /** @var \Boolfly\ProductLabel\Model\Rule $model */
31 | $model = $this->ruleFactory->create();
32 | try {
33 | $model->load($id);
34 | $model->delete();
35 | $this->messageManager->addSuccessMessage(__('The rule has been deleted.'));
36 | return $resultRedirect->setPath('*/*/');
37 | } catch (\Exception $e) {
38 | $this->messageManager->addErrorMessage(__('Something went wrong while deleted the rule.'));
39 | $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e->getMessage());
40 | }
41 | }
42 |
43 | return $resultRedirect->setPath('*/*/');
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Rule/NewConditionHtml.php:
--------------------------------------------------------------------------------
1 | getRequest()->getParam('id');
28 | $formName = $this->getRequest()->getParam('form_namespace');
29 | $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
30 | $type = $typeArr[0];
31 |
32 | $model = $this->_objectManager->create($type)
33 | ->setId($id)
34 | ->setType($type)
35 | ->setRule($this->ruleFactory->create())
36 | ->setPrefix('conditions');
37 |
38 | if (!empty($typeArr[1])) {
39 | $model->setAttribute($typeArr[1]);
40 | }
41 |
42 | if ($model instanceof AbstractCondition) {
43 | $model->setJsFormObject($this->getRequest()->getParam('form'));
44 | $model->setFormName($formName);
45 | $html = $model->asHtmlRecursive();
46 | } else {
47 | $html = '';
48 | }
49 | $this->getResponse()->setBody($html);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Model/Source/Config/Type.php:
--------------------------------------------------------------------------------
1 | __('New'),
46 | self::SALE_LABEL => __('Sale'),
47 | self::BEST_SELLER_LABEL => __('Best Seller'),
48 | self::CUSTOM_LABEL => __('Custom')
49 | ];
50 | }
51 |
52 | /**
53 | * Retrieve option array with empty value
54 | *
55 | * @return string[]
56 | */
57 | public function getAllOptions()
58 | {
59 | $result = [];
60 |
61 | foreach (self::getOptionArray() as $index => $value) {
62 | $result[] = ['value' => $index, 'label' => $value];
63 | }
64 |
65 | return $result;
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/Model/Source/Config/Status.php:
--------------------------------------------------------------------------------
1 | __('Enabled'), self::STATUS_DISABLED => __('Disabled')];
39 | }
40 |
41 | /**
42 | * Retrieve option array with empty value
43 | *
44 | * @return string[]
45 | */
46 | public function getAllOptions()
47 | {
48 | $result = [];
49 |
50 | foreach (self::getOptionArray() as $index => $value) {
51 | $result[] = ['value' => $index, 'label' => $value];
52 | }
53 |
54 | return $result;
55 | }
56 |
57 | /**
58 | * Retrieve option text by option value
59 | *
60 | * @param string $optionId
61 | * @return string
62 | */
63 | public function getOptionText($optionId)
64 | {
65 | $options = self::getOptionArray();
66 |
67 | return isset($options[$optionId]) ? $options[$optionId] : null;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/Block/Label.php:
--------------------------------------------------------------------------------
1 | helperRule = $helperRule;
52 | }
53 |
54 | /**
55 | * Set Product
56 | *
57 | * @param $product
58 | * @return $this
59 | */
60 | public function setProduct($product)
61 | {
62 | $this->product = $product;
63 | return $this;
64 | }
65 |
66 | /**
67 | * Get Group Rule
68 | *
69 | * @return array
70 | */
71 | public function getGroupRule()
72 | {
73 | try {
74 | return $this->helperRule->getAppliedCategoryRule($this->product);
75 | } catch (\Exception $e) {
76 | return [];
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/Observer/UpdateRuleAfterProductSave.php:
--------------------------------------------------------------------------------
1 | indexerRow = $indexerRow;
47 | $this->messageManager = $messageManager;
48 | }
49 |
50 | /**
51 | * @param Observer $observer
52 | */
53 | public function execute(Observer $observer)
54 | {
55 | try {
56 | $product = $observer->getEvent()->getData('product');
57 | if ($product instanceof Product && $product->getId()) {
58 | $this->indexerRow->execute($product->getId());
59 | }
60 | } catch (\Exception $e) {
61 | $this->messageManager->addWarningMessage('Something went wrong while updating product label.');
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/AbstractRule.php:
--------------------------------------------------------------------------------
1 | coreRegistry = $coreRegistry;
57 | $this->ruleFactory = $ruleFactory;
58 | }
59 |
60 | /**
61 | * Init action
62 | *
63 | * @return $this
64 | */
65 | protected function initAction()
66 | {
67 | $this->_view->loadLayout();
68 | $this->_setActiveMenu(
69 | 'Boolfly_ProductLabel::rule'
70 | )->_addBreadcrumb(
71 | __('Manage Rule'),
72 | __('Manage Rule')
73 | );
74 | return $this;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Rule/Edit.php:
--------------------------------------------------------------------------------
1 | getRequest()->getParam('id');
28 | /** @var \Boolfly\ProductLabel\Model\Rule $model */
29 | $model = $this->ruleFactory->create();
30 | $this->coreRegistry->register('current_label_rule', $model);
31 | if ($id) {
32 | $model->load($id);
33 | if (!$model->getId()) {
34 | $this->messageManager->addErrorMessage(__('This rule no longer exists.'));
35 | $this->_redirect('*/rule/*');
36 | return;
37 | }
38 | $model->getConditions()->setFormName('label_rule_form');
39 | $model->getConditions()->setJsFormObject(
40 | $model->getConditionsFieldSetId($model->getConditions()->getFormName())
41 | );
42 | $model->getActions()->setFormName('label_rule_form');
43 | $model->getActions()->setJsFormObject(
44 | $model->getActionsFieldSetId($model->getActions()->getFormName())
45 | );
46 | }
47 | $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getPageData(true);
48 | if (!empty($data)) {
49 | $model->addData($data);
50 | }
51 |
52 | $this->initAction();
53 | $this->_addBreadcrumb(
54 | $id ? __('Edit Rule') : __('New Rule'),
55 | $id ? __('Edit Rule') : __('New Rule')
56 | );
57 | $this->_view->getPage()->getConfig()->getTitle()->prepend(
58 | $model->getId() ? $model->getTitle() : __('New Rule')
59 | );
60 | $this->_view->renderLayout();
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Plugin/Catalog/Block/Product/ImagePlugin.php:
--------------------------------------------------------------------------------
1 | layout = $layout;
46 | $this->config = $config;
47 | }
48 |
49 | /**
50 | * Add Label Html after Product Image
51 | *
52 | * @param Image $image
53 | * @param string $result
54 | * @return string
55 | */
56 | public function afterToHtml(
57 | Image $image,
58 | $result
59 | ) {
60 | if ($image->getData('product') && $result && $this->config->isEnable()) {
61 | /** @var Label $labelBlock */
62 | $labelBlock = $this->layout->createBlock(Label::class);
63 | $labelBlock->setProduct($image->getData('product'));
64 | $labelHtml = $labelBlock->toHtml();
65 | if ($labelHtml) {
66 | return $this->wrapper($result, $labelHtml);
67 | }
68 | }
69 | return $result;
70 | }
71 |
72 | /**
73 | * Wrapper Html
74 | *
75 | * @param $result
76 | * @param $labelHtml
77 | * @return string
78 | */
79 | protected function wrapper($result, $labelHtml)
80 | {
81 | return rtrim(trim($result), '') . $labelHtml . '';
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Block/Product/Label.php:
--------------------------------------------------------------------------------
1 | helperRule = $helperRule;
63 | $this->registry = $registry;
64 | $this->config = $config;
65 | }
66 |
67 | /**
68 | * @return string
69 | */
70 | protected function _toHtml()
71 | {
72 | return $this->config->isEnable() ? parent::_toHtml() : '';
73 | }
74 |
75 | /**
76 | * Get Product
77 | *
78 | * @return mixed
79 | */
80 | public function getProduct()
81 | {
82 | return $this->registry->registry('current_product');
83 | }
84 |
85 | /**
86 | * Get Group Rule
87 | *
88 | * @return array
89 | */
90 | public function getGroupRule()
91 | {
92 | try {
93 | return $this->helperRule->getAppliedProductRule($this->getProduct());
94 | } catch (\Exception $e) {
95 | return [];
96 | }
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/Model/Source/Config/CustomerGroup.php:
--------------------------------------------------------------------------------
1 | moduleManager = $moduleManager;
51 | $this->groupRepository = $groupRepository;
52 | $this->searchCriteriaBuilder = $searchCriteriaBuilder;
53 | }
54 |
55 | /**
56 | * @return array
57 | * @throws \Magento\Framework\Exception\LocalizedException
58 | */
59 | public function toOptionArray()
60 | {
61 | if (!$this->moduleManager->isEnabled('Magento_Customer')) {
62 | return [];
63 | }
64 | $customerGroups = [];
65 | $groups = $this->groupRepository->getList($this->searchCriteriaBuilder->create());
66 | /** @var GroupInterface $group */
67 | foreach ($groups->getItems() as $group) {
68 | $customerGroups[] = [
69 | 'label' => $group->getCode(),
70 | 'value' => $group->getId(),
71 | ];
72 | }
73 |
74 | return $customerGroups;
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Ui/Component/Listing/Columns/EditActions.php:
--------------------------------------------------------------------------------
1 | urlBuilder = $urlBuilder;
44 | parent::__construct($context, $uiComponentFactory, $components, $data);
45 | }
46 |
47 | /**
48 | * Prepare Data Source
49 | *
50 | * @param array $dataSource
51 | * @return array
52 | */
53 | public function prepareDataSource(array $dataSource)
54 | {
55 | if (isset($dataSource['data']['items'])) {
56 | $storeId = $this->context->getFilterParam('store_id');
57 | $fieldId = $this->getDataByPath('config/indexField');
58 | if ($fieldId) {
59 | $routePath = $this->getDataByPath('options/routePath') ?: '*/*/edit';
60 | foreach ($dataSource['data']['items'] as &$item) {
61 | $item[$this->getData('name')]['edit'] = [
62 | 'href' => $this->urlBuilder->getUrl(
63 | $routePath,
64 | ['id' => $item[$fieldId], 'store' => $storeId]
65 | ),
66 | 'label' => __('Edit'),
67 | 'hidden' => false,
68 | ];
69 | }
70 | }
71 | }
72 |
73 | return $dataSource;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/etc/db_schema_whitelist.json:
--------------------------------------------------------------------------------
1 | {
2 | "boolfly_productlabel_rule": {
3 | "column": {
4 | "rule_id": true,
5 | "title": true,
6 | "type": true,
7 | "description": true,
8 | "priority": true,
9 | "status": true,
10 | "from_date": true,
11 | "to_date": true,
12 | "conditions_serialized": true,
13 | "display_in_cat": true,
14 | "cat_position": true,
15 | "cat_label_type": true,
16 | "cat_image": true,
17 | "cat_text": true,
18 | "css_style_cat": true,
19 | "display_in_product": true,
20 | "product_position": true,
21 | "product_label_type": true,
22 | "product_image": true,
23 | "product_text": true,
24 | "css_style_product": true,
25 | "created_at": true,
26 | "updated_at": true
27 | },
28 | "index": {
29 | "BOOLFLY_PRODUCTLABEL_RULE_RULE_ID": true
30 | },
31 | "constraint": {
32 | "PRIMARY": true
33 | }
34 | },
35 | "boolfly_productlabel_store": {
36 | "column": {
37 | "rule_id": true,
38 | "store_id": true
39 | },
40 | "index": {
41 | "BOOLFLY_PRODUCTLABEL_STORE_RULE_ID": true,
42 | "BOOLFLY_PRODUCTLABEL_STORE_STORE_ID": true
43 | },
44 | "constraint": {
45 | "PRIMARY": true,
46 | "BOOLFLY_PRDLBL_STORE_RULE_ID_BOOLFLY_PRDLBL_RULE_RULE_ID": true,
47 | "BOOLFLY_PRODUCTLABEL_STORE_STORE_ID_STORE_STORE_ID": true
48 | }
49 | },
50 | "boolfly_productlabel_customer_group": {
51 | "column": {
52 | "rule_id": true,
53 | "customer_group_id": true
54 | },
55 | "constraint": {
56 | "PRIMARY": true,
57 | "BOOLFLY_PRDLBL_CSTR_GROUP_RULE_ID_BOOLFLY_PRDLBL_RULE_RULE_ID": true,
58 | "BOOLFLY_PRDLBL_CSTR_GROUP_CSTR_GROUP_ID_CSTR_GROUP_CSTR_GROUP_ID": true
59 | }
60 | },
61 | "boolfly_productlabel_product_index_rule": {
62 | "column": {
63 | "rule_id": true,
64 | "product_id": true
65 | },
66 | "index": {
67 | "BOOLFLY_PRODUCTLABEL_PRODUCT_INDEX_RULE_RULE_ID": true,
68 | "BOOLFLY_PRODUCTLABEL_PRODUCT_INDEX_RULE_PRODUCT_ID": true
69 | },
70 | "constraint": {
71 | "PRIMARY": true,
72 | "BOOLFLY_PRDLBL_PRD_IDX_RULE_RULE_ID_BOOLFLY_PRDLBL_RULE_RULE_ID": true
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/Model/Rule/Condition/Combine.php:
--------------------------------------------------------------------------------
1 | productFactory = $conditionFactory;
40 | parent::__construct($context, $data);
41 | $this->setType(get_class($this));
42 | }
43 |
44 | /**
45 | * @return array
46 | */
47 | public function getNewChildSelectOptions()
48 | {
49 | $productAttributes = $this->productFactory->create()->loadAttributeOptions()->getAttributeOption();
50 | $attributes = [];
51 | foreach ($productAttributes as $code => $label) {
52 | $attributes[] = [
53 | 'value' => Product::class . '|' . $code,
54 | 'label' => $label,
55 | ];
56 | }
57 | $conditions = parent::getNewChildSelectOptions();
58 | $conditions = array_merge_recursive(
59 | $conditions,
60 | [
61 | [
62 | 'value' => get_class($this),
63 | 'label' => __('Conditions Combination'),
64 | ],
65 | ['label' => __('Product Attribute'), 'value' => $attributes]
66 | ]
67 | );
68 | return $conditions;
69 | }
70 |
71 | /**
72 | * @param array $productCollection
73 | * @return $this
74 | */
75 | public function collectValidatedAttributes($productCollection)
76 | {
77 | foreach ($this->getConditions() as $condition) {
78 | /** @var Product|Combine $condition */
79 | $condition->collectValidatedAttributes($productCollection);
80 | }
81 | return $this;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/view/frontend/web/css/source/_module.less:
--------------------------------------------------------------------------------
1 | .product-label-info {
2 | position: absolute;
3 | top: 0;
4 | left: 0;
5 | z-index: 100;
6 | .product-label{
7 | text-align: center;
8 | color: #fff;
9 | font-size: 18px;
10 | display: table;
11 | line-height: 20px;
12 | padding: 4px 6px 2px 5px;
13 | margin-bottom: 5px;
14 | box-shadow: 1px 1px 1px dimgray;
15 | img {
16 | max-height: 48px;
17 | }
18 | span {
19 | padding: 2px 4px;
20 | display: block;
21 | font-size: 1.3rem;
22 | font-weight: bold;
23 | }
24 | &.sale {
25 | background: #f71602;
26 |
27 | }
28 | &.best-seller {
29 | background: #007fd4;
30 | }
31 | &.new {
32 | background: #048500d6;
33 | }
34 | &.custom {
35 | color: #000;
36 | box-shadow: none;
37 | }
38 | }
39 | &.top-right {
40 | top: 0;
41 | right: 0;
42 | margin-top: 0 !important;
43 | left: auto !important;
44 | margin-left: 0 !important;
45 | }
46 | &.top-left {
47 | top: 0;
48 | margin-top: 0 !important;
49 | left: 0 !important;
50 | margin-left: 0 !important;
51 | right: auto;
52 | }
53 | &.bot-right {
54 | top: auto !important;
55 | margin-top: 0 !important;
56 | left: auto !important;
57 | margin-left: 0 !important;
58 | bottom: 0;
59 | right: 0;
60 | }
61 | &.bot-left {
62 | top: auto !important;
63 | margin-top: 0 !important;
64 | left: 0 !important;
65 | margin-left: 0 !important;
66 | bottom: 0;
67 | right: auto;
68 | }
69 | &.mid-left {
70 | top: 50%;
71 | left: 0;
72 | margin-left: 0 !important;
73 | right: auto;
74 | }
75 | &.mid-right {
76 | top: 50%;
77 | left: auto;
78 | margin-left: 0 !important;
79 | right: 0;
80 | }
81 | &.mid-mid {
82 | top: 50%;
83 | left: 50%;
84 | right: auto;
85 | bottom: auto;
86 | }
87 | &.top-mid {
88 | top: 0;
89 | margin-top: 0 !important;
90 | left: 50%;
91 | right: auto;
92 | bottom: auto;
93 | }
94 | &.bot-mid {
95 | top: auto;
96 | bottom: 0;
97 | margin-top: 0 !important;
98 | left: 50%;
99 | right: auto;
100 | }
101 | }
102 | .product-image-container {
103 | position: relative;
104 | }
105 |
106 | .product.media {
107 | position: relative;
108 | }
109 |
110 | .products-grid {
111 | .product-item {
112 | .product-item-info:hover {
113 | z-index: 1501;
114 | .product-label {
115 | box-shadow: none;
116 | }
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/Observer/ProcessingImageUpload.php:
--------------------------------------------------------------------------------
1 | imageUploader = $imageUploader;
41 | }
42 |
43 | /**
44 | * @param Observer $observer
45 | * @throws \Magento\Framework\Exception\LocalizedException
46 | */
47 | public function execute(Observer $observer)
48 | {
49 | $rule = $observer->getEvent()->getData('label_rule');
50 | if ($rule instanceof RuleInterface) {
51 | foreach (ImageField::getField() as $field) {
52 | $this->processFile($rule, $field);
53 | }
54 | }
55 | }
56 |
57 | /**
58 | * Process File
59 | *
60 | * @param RuleInterface|\Magento\Framework\DataObject $object
61 | * @param $key
62 | * @return $this
63 | * @throws \Magento\Framework\Exception\LocalizedException
64 | */
65 | protected function processFile(RuleInterface $object, $key)
66 | {
67 | $files = $object->getData($key);
68 | $object->setData($key, null);
69 | if (is_array($files) && !empty($files)) {
70 | foreach ($files as $file) {
71 | if (is_array($file) && empty($file['name'])) {
72 | continue;
73 | }
74 | $name = $file['name'];
75 | // Upload New File
76 | if (isset($file['type']) && $file['tmp_name']) {
77 | $this->imageUploader->moveFileFromTmp($name);
78 | }
79 | $object->setData($key, $name);
80 | }
81 | }
82 |
83 | return $this;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 | - BoolflyLabelRuleCollection
18 |
19 |
20 |
21 |
22 |
23 | boolfly_productlabel_rule
24 | Boolfly\ProductLabel\Model\ResourceModel\Rule
25 |
26 |
27 |
28 |
29 |
30 | tmp/boolfly/label
31 | boolfly/label
32 |
33 |
34 |
35 |
36 | LabelImageUploader
37 |
38 |
39 |
40 |
41 | LabelImageUploader
42 |
43 |
44 |
45 |
46 | LabelImageUploader
47 |
48 |
49 |
50 |
51 | LabelImageUploader
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Rule/MassDelete.php:
--------------------------------------------------------------------------------
1 | collectionFactory = $collectionFactory;
57 | $this->filter = $filter;
58 | }
59 |
60 | /**
61 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface
62 | * @throws LocalizedException
63 | */
64 | public function execute()
65 | {
66 | $collections = $this->filter->getCollection($this->collectionFactory->create());
67 | $totals = 0;
68 | try {
69 | /** @var \Boolfly\ProductLabel\Model\Rule $item */
70 | foreach ($collections as $item) {
71 | $item->delete();
72 | $totals++;
73 | }
74 | $this->messageManager->addSuccessMessage(__('A total of %1 record(s) have been updated.', $totals));
75 | } catch (\Exception $e) {
76 | $this->messageManager->addErrorMessage(__('Something went wrong while delete the rule(s).'));
77 | }
78 |
79 | /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
80 | $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
81 | return $resultRedirect->setPath('*/*/');
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Rule/MassStatus.php:
--------------------------------------------------------------------------------
1 | collectionFactory = $collectionFactory;
56 | $this->filter = $filter;
57 | }
58 |
59 | /**
60 | * @return \Magento\Framework\App\ResponseInterface|\Magento\Framework\Controller\ResultInterface
61 | * @throws LocalizedException
62 | */
63 | public function execute()
64 | {
65 | $collections = $this->filter->getCollection($this->collectionFactory->create());
66 | $status = $this->getRequest()->getParam('status');
67 | $totals = 0;
68 | try {
69 | /** @var \Boolfly\ProductLabel\Model\Rule $item */
70 | foreach ($collections as $item) {
71 | $item->load($item->getId());
72 | $item->setStatus($status);
73 | $item->save();
74 | $totals++;
75 | }
76 | $this->messageManager->addSuccessMessage(__('A total of %1 record(s) have been updated.', $totals));
77 | } catch (\Exception $e) {
78 | $this->messageManager->addErrorMessage(__('Something went wrong while update the rule(s).'));
79 | }
80 |
81 | /** @var \Magento\Framework\Controller\Result\Redirect $resultRedirect */
82 | $resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
83 | return $resultRedirect->setPath('*/*/');
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Model/ResourceModel/Rule/Collection.php:
--------------------------------------------------------------------------------
1 | _init(Rule::class, RuleResourceModel::class);
40 | }
41 |
42 | /**
43 | * Only get enable Rule
44 | *
45 | * @return Collection
46 | */
47 | public function addActiveStatusFilter()
48 | {
49 | return $this->addFieldToFilter('status', Status::STATUS_ENABLED);
50 | }
51 |
52 |
53 | /**
54 | * Order By Type
55 | *
56 | * @param $type
57 | * @return $this
58 | */
59 | public function addOrderByType($type)
60 | {
61 | $field = $type == 'category' ? RuleInterface::CATEGORY_POSITION : RuleInterface::PRODUCT_POSITION;
62 | $this->addOrder($field, 'DESC');
63 | $this->addOrder(RuleInterface::PRIORITY, 'ASC');
64 |
65 | return $this;
66 | }
67 |
68 | /**
69 | * Add Store To Filter
70 | *
71 | * @param null $storeId
72 | * @return $this
73 | */
74 | public function addStoreToFilter($storeId = null)
75 | {
76 | if ($storeId && is_numeric($storeId)) {
77 | $conditions = $this->getConnection()->quoteInto(
78 | 'main_table.rule_id = rule_store.rule_id AND rule_store.store_id = ?',
79 | $storeId
80 | );
81 | $this->getSelect()->joinInner(
82 | ['rule_store' => $this->getTable('boolfly_productlabel_store')],
83 | $conditions
84 | );
85 | }
86 |
87 | return $this;
88 | }
89 |
90 | /**
91 | * Add Customer Group To Filter
92 | *
93 | * @param null $groupId
94 | * @return $this
95 | */
96 | public function addCustomerGroupToFilter($groupId = null)
97 | {
98 | if ($groupId && is_numeric($groupId)) {
99 | $conditions = $this->getConnection()->quoteInto(
100 | 'main_table.rule_id = rule_customer.rule_id AND rule_customer.customer_group_id = ?',
101 | $groupId
102 | );
103 | $this->getSelect()->joinInner(
104 | ['rule_customer' => $this->getTable('boolfly_productlabel_customer_group')],
105 | $conditions
106 | );
107 | }
108 |
109 | return $this;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/Model/Rule/DataProvider.php:
--------------------------------------------------------------------------------
1 | collection = $collectionFactory->create();
73 | $this->coreRegistry = $registry;
74 | parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
75 | $this->imageUploader = $imageUploader;
76 | }
77 |
78 | /**
79 | * {@inheritdoc}
80 | */
81 | public function getData()
82 | {
83 | if (isset($this->loadedData)) {
84 | return $this->loadedData;
85 | }
86 | /** @var RuleInterface | \Boolfly\ProductLabel\Model\Rule $model */
87 | $model = $this->coreRegistry->registry('current_label_rule');
88 | if ($model->getId()) {
89 | $data = $model->getData();
90 | foreach (ImageField::getField() as $field) {
91 | unset($data[$field]);
92 | $imageName = $model->getData($field);
93 | if ($imageSrc = $this->imageUploader->getImageUrl($imageName)) {
94 | try {
95 | $size = $this->imageUploader->getSize($imageName);
96 | } catch (\Exception $e) {
97 | $size = 'undefined';
98 | }
99 | $data[$field][] = [
100 | 'name' => $imageName,
101 | 'url' => $imageSrc,
102 | 'previewType' => 'image',
103 | 'size' => $size
104 | ];
105 | } else {
106 | $data[$field] = [];
107 | }
108 | }
109 | $this->loadedData[$model->getId()] = $data;
110 | } else {
111 | $this->loadedData = [];
112 | }
113 |
114 | return $this->loadedData;
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/Rule/Save.php:
--------------------------------------------------------------------------------
1 | logger = $logger;
55 | $this->backendSession = $backendSession;
56 | }
57 |
58 | /**
59 | * @return mixed
60 | * @throws LocalizedException
61 | */
62 | public function execute()
63 | {
64 | $data = $this->getRequest()->getPostValue();
65 | /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
66 | $resultRedirect = $this->resultRedirectFactory->create();
67 | if ($data) {
68 | /** @var \Boolfly\ProductLabel\Model\Rule $model */
69 | $model = $this->ruleFactory->create();
70 |
71 | if (!empty($data['rule_id'])) {
72 | $model->load($data['rule_id']);
73 | if (!$model->getId()) {
74 | throw new LocalizedException(__('Wrong Label Rule ID.'));
75 | }
76 | }
77 | unset($data['rule_id']);
78 |
79 | if (isset($data['rule']['conditions'])) {
80 | $data['conditions'] = $data['rule']['conditions'];
81 | unset($data['rule']);
82 | }
83 | $model->loadPost($data);
84 | $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($model->getData());
85 | try {
86 | $this->_eventManager->dispatch(
87 | 'controller_boolfly_label_rule_save_entity_before',
88 | ['controller' => $this, 'label_rule' => $model]
89 | );
90 | $model->save();
91 | $this->messageManager->addSuccessMessage(__('The rule has been saved.'));
92 | $this->backendSession->setPageData(false);
93 | if ($this->getRequest()->getParam('back')) {
94 | return $resultRedirect->setPath('*/*/edit', ['id' => $model->getId(), '_current' => true]);
95 | }
96 | return $resultRedirect->setPath('*/*/');
97 | } catch (LocalizedException $e) {
98 | $this->logger->critical($e);
99 | $this->messageManager->addErrorMessage($e->getMessage());
100 | } catch (\Exception $e) {
101 | echo $e->getMessage();
102 | $this->messageManager->addErrorMessage($e, __('Something went wrong while saving the rule.'));
103 | $this->logger->critical($e);
104 | $this->backendSession->setPageData($data);
105 | return $resultRedirect->setPath('*/*/edit', ['id' => $this->getRequest()->getParam('id')]);
106 | }
107 | }
108 |
109 | return $resultRedirect->setPath('*/*/');
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/Block/Adminhtml/Rule/Conditions.php:
--------------------------------------------------------------------------------
1 | coreRegistry = $registry;
77 | $this->rendererFieldset = $rendererFieldset;
78 | $this->conditions = $conditions;
79 | parent::__construct($context, $data);
80 | $this->formFactory = $formFactory;
81 | }
82 |
83 | /**
84 | * @return mixed
85 | * @throws \Magento\Framework\Exception\LocalizedException
86 | */
87 | protected function _prepareForm()
88 | {
89 | $model = $this->coreRegistry->registry('current_label_rule');
90 | /** @var \Magento\Framework\Data\Form $form */
91 | $form = $this->addTabToForm($model);
92 | $this->setForm($form);
93 |
94 | return parent::_prepareForm();
95 | }
96 |
97 | /**
98 | * @param Rule $model
99 | * @param string $fieldSetId
100 | * @return \Magento\Framework\Data\Form
101 | * @throws \Magento\Framework\Exception\LocalizedException
102 | */
103 | protected function addTabToForm($model, $fieldSetId = 'conditions_fieldset')
104 | {
105 | /** @var \Magento\Framework\Data\Form $form */
106 | $form = $this->formFactory->create();
107 | $form->setHtmlIdPrefix('rule_');
108 | $renderer = $this->rendererFieldset->setTemplate($this->rendererFieldsetTemplate)
109 | ->setNewChildUrl($this->getNewChildUrl($model))
110 | ->setFieldSetId($model->getConditionsFieldSetId($this->formName));
111 |
112 | $fieldset = $form->addFieldset(
113 | $fieldSetId,
114 | ['legend' => __('Conditions (don\'t add conditions if rule is applied to all products)')]
115 | )->setRenderer($renderer);
116 |
117 | $fieldset->addField(
118 | 'conditions',
119 | 'text',
120 | [
121 | 'name' => 'conditions',
122 | 'label' => __('Conditions'),
123 | 'title' => __('Conditions'),
124 | 'required' => true,
125 | 'data-form-part' => $this->formName
126 | ]
127 | )->setRule($model)->setRenderer($this->conditions);
128 |
129 | $form->setValues($model->getData());
130 | $this->setConditionFormName($model->getConditions(), $this->formName);
131 | return $form;
132 | }
133 |
134 | /**
135 | * @param Rule $model
136 | * @return string
137 | */
138 | private function getNewChildUrl($model)
139 | {
140 | return $this->getUrl(
141 | '*/*/newConditionHtml',
142 | [
143 | 'form' => $model->getConditionsFieldSetId($this->formName),
144 | 'form_namespace' => $this->formName
145 | ]
146 | );
147 | }
148 |
149 | /**
150 | * @param AbstractCondition $conditions
151 | * @param $formName
152 | */
153 | private function setConditionFormName(AbstractCondition $conditions, $formName)
154 | {
155 | $conditions->setFormName($formName);
156 | $conditions->setJsFormObject($formName);
157 | if ($conditions->getConditions() && is_array($conditions->getConditions())) {
158 | foreach ($conditions->getConditions() as $condition) {
159 | $this->setConditionFormName($condition, $formName);
160 | }
161 | }
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Product Label
2 |
3 |
4 | ## Installation
5 |
6 | ##### Using Composer (we recommended)
7 |
8 | ```
9 | composer require boolfly/module-product-label
10 | ```
11 |
12 | ## 1. Configuration
13 |
14 | ### General Configuration
15 |
16 | Login to Magento Admin, go to **Stores > Configuration > Boolfly > Product Label**
17 |
18 | 
19 |
20 | #### General Settings
21 |
22 | ##### Enable :
23 |
24 | Select “Yes” to display the product label on front-end.
25 | Select “No” to hide the product label on front-end.
26 |
27 |
28 | ## 2. Add new rule for the product menu
29 |
30 | Login to Magento Admin, go to **Catalog > Manager Rule > Add New**
31 |
32 | 
33 |
34 | ### General
35 |
36 | 
37 |
38 | ##### Enable :
39 |
40 | Select “Yes” to turn on rule for the product label.
41 | Select “No” to turn off rule for the product label.
42 |
43 |
44 | ##### Title:
45 | Enter name for the product label.
46 |
47 | ##### Type:
48 |
49 | New: The product label display with green background.
50 | Sale: The product label display for products are discounted with red background.
51 | Best Seller: The product label display with blue background.
52 | Custom: The product label display without background.
53 |
54 |
55 | ##### Description:
56 | Enter note for the rule of product label.
57 |
58 | ##### Store View:
59 | Select store view to display the product label.
60 |
61 | ##### Customer Groups:
62 | Select customer groups to apply the rule
63 |
64 | ##### From:
65 | A beginning date applies the rule.
66 |
67 | ##### To:
68 | An ending date applies the rule.
69 |
70 | ##### Priority:
71 | Enter the priority number showing the product label (the smaller number is the higher priority)
72 |
73 |
74 | ### Conditions
75 |
76 | 
77 |
78 | 
79 |
80 | Conditions (don't add conditions if rule is applied to all products) : Select the rule to apply for all products
81 |
82 |
83 | #### Product Listing
84 |
85 | ##### Is Display:
86 |
87 | Select “Yes” to display the product label on the product list page of front-end.
88 | Select “No” to hide the product label on the product list page of front-end.
89 |
90 |
91 | ##### Position:
92 | select position to display the product label.
93 |
94 | ##### Label Type:
95 |
96 | Text: Display text for the product label.
97 | Image: Display image for the product label.
98 |
99 |
100 | ##### Text:
101 | Enter text to display on the product label (only apply when selecting text for label type)
102 |
103 | ##### Image:
104 | Upload image to display on the product label (only apply when selecting image for label type).
105 |
106 | ##### Css Style Code:
107 | Style inline css for the product label.
108 |
109 | #### Product Page
110 |
111 | ##### Is Display:
112 |
113 | Select “Yes” to display the product label on the product detail page of front-end.
114 | Select “No” to hide the product label on the product detail page of front-end.
115 |
116 |
117 | ##### Position:
118 | select position to display the product label.
119 |
120 | ##### Label Type:
121 |
122 | Text: Display text for the product label.
123 | Image: Display image for the product label.
124 |
125 |
126 | ##### Text:
127 | Enter text to display on the product label (only apply when selecting text for label type)
128 |
129 | ##### Image:
130 | Upload image to display on the product label (only apply when selecting image for label type).
131 |
132 | ##### Css Style Code:
133 | Style inline css for the product label.
134 |
135 | ## 3. How does it work?
136 |
137 | ### Product Listing
138 | 
139 |
140 | ### Product Page
141 | 
142 |
143 |
144 | Contribution
145 | ---
146 | Want to contribute to this extension? The quickest way is to open a [pull request on GitHub](https://help.github.com/articles/using-pull-requests)
147 |
148 | Magento 2 Extensions
149 | ---
150 |
151 | - [Ajax Wishlist](https://github.com/boolfly/ajax-wishlist)
152 | - [Quick View](https://github.com/boolfly/quick-view)
153 | - [Banner Slider](https://github.com/boolfly/banner-slider)
154 | - [Product Label](https://github.com/boolfly/product-label)
155 | - [ZaloPay](https://github.com/boolfly/zalo-pay)
156 | - [Momo](https://github.com/boolfly/momo-wallet)
157 | - [Blog](https://github.com/boolfly/blog)
158 | - [Brand](https://github.com/boolfly/brand)
159 | - [Product Question](https://github.com/boolfly/product-question)
160 | - [Sales Sequence](https://github.com/boolfly/sales-sequence)
161 |
162 | Support
163 | ---
164 | If you encounter any problems or bugs, please open an issue on [GitHub](https://github.com/boolfly/product-label/issues).
165 |
166 | Need help settings up or want to customize this extension to meet your business needs? Please email boolfly.inc@gmail.com and if we like your idea we will add this feature for free or at a discounted rate.
167 |
168 |
--------------------------------------------------------------------------------
/Model/Indexer/Full.php:
--------------------------------------------------------------------------------
1 | productCollectionFactory = $collectionFactory;
92 | $this->builder = $builder;
93 | $this->resourceConnection = $resourceConnection;
94 | $this->productVisibility = $productVisibility;
95 | $this->metadataPool = $metadataPool;
96 | }
97 |
98 | /**
99 | * Set Rule
100 | *
101 | * @param Rule $rule
102 | * @return $this
103 | */
104 | public function setRule(Rule $rule)
105 | {
106 | $this->rule = $rule;
107 | return $this;
108 | }
109 |
110 | /**
111 | * Get Rule
112 | *
113 | * @return Rule
114 | */
115 | public function getRule()
116 | {
117 | return $this->rule;
118 | }
119 |
120 | /**
121 | * Get all Product map with rule
122 | *
123 | * @throws \Exception
124 | */
125 | public function execute()
126 | {
127 | if ($this->getRule() && $this->getRule()->getId()) {
128 | $this->cleanData();
129 | $productCollection = $this->getProductCollection();
130 | $conditions = $this->getRule()->getConditions();
131 | $this->builder->attachConditionToCollection($productCollection, $conditions);
132 | $productCollection->setPageSize(self::PAGE_SIZE);
133 | $totalsPage = $productCollection->getLastPageNumber();
134 | $connection = $this->resourceConnection->getConnection();
135 | $currentPage = 1;
136 | if ($productCollection->getSize() > 0) {
137 | do {
138 | $productCollection->setCurPage($currentPage);
139 | $productCollection->load();
140 | $importData = [];
141 | foreach ($productCollection as $product) {
142 | $importData[] = [
143 | 'rule_id' => $this->getRule()->getId(),
144 | 'product_id' => $product->getData($this->getProductIdentifierField())
145 | ];
146 | }
147 | $connection->insertOnDuplicate($connection->getTableName(self::FLAT_INDEX_RULE_TABLE), $importData);
148 | $currentPage++;
149 | $productCollection->clear();
150 | } while ($currentPage <= $totalsPage);
151 | }
152 | }
153 | }
154 |
155 | /**
156 | * @param boolean $isVisibility
157 | * @return \Magento\Catalog\Model\ResourceModel\Product\Collection
158 | * @throws \Exception
159 | */
160 | protected function getProductCollection($isVisibility = true)
161 | {
162 | $productCollection = $this->productCollectionFactory->create();
163 | $productCollection->addFieldToFilter('status', ProductStatus::STATUS_ENABLED);
164 | if ($isVisibility) {
165 | $productCollection->setVisibility(
166 | $this->productVisibility->getVisibleInSiteIds()
167 | )->addStoreFilter();
168 | }
169 | $productCollection->setOrder($this->getProductIdentifierField());
170 |
171 | return $productCollection;
172 | }
173 |
174 | /**
175 | * Clean All Old Data
176 | */
177 | private function cleanData()
178 | {
179 | $connection = $this->resourceConnection->getConnection();
180 | $connection->delete(
181 | $connection->getTableName(self::FLAT_INDEX_RULE_TABLE),
182 | $connection->quoteInto('rule_id = ?', $this->getRule()->getId())
183 | );
184 | }
185 |
186 | /**
187 | * @return MetadataPool
188 | */
189 | protected function getMetadataPool()
190 | {
191 | return $this->metadataPool;
192 | }
193 |
194 | /**
195 | * Get product entity identifier field
196 | *
197 | * @return string
198 | * @throws \Exception
199 | */
200 | private function getProductIdentifierField()
201 | {
202 | if ($this->productEntityIdentifierField === null) {
203 | $this->productEntityIdentifierField = $this->getMetadataPool()
204 | ->getMetadata(ProductInterface::class)
205 | ->getIdentifierField();
206 | }
207 | return $this->productEntityIdentifierField;
208 | }
209 | }
210 |
--------------------------------------------------------------------------------
/Model/Indexer/Row.php:
--------------------------------------------------------------------------------
1 | productCollectionFactory = $collectionFactory;
99 | $this->builder = $builder;
100 | $this->resourceConnection = $resourceConnection;
101 | $this->productVisibility = $productVisibility;
102 | $this->metadataPool = $metadataPool;
103 | $this->helperRule = $helperRule;
104 | }
105 |
106 | /**
107 | * Set Rule
108 | *
109 | * @param Rule $rule
110 | * @return $this
111 | */
112 | public function setRule(Rule $rule)
113 | {
114 | $this->rule = $rule;
115 | return $this;
116 | }
117 |
118 | /**
119 | * Get Rule
120 | *
121 | * @return Rule
122 | */
123 | public function getRule()
124 | {
125 | return $this->rule;
126 | }
127 |
128 | /**
129 | * Set Product Id
130 | *
131 | * @param $id
132 | * @return $this
133 | */
134 | public function setProductId($id)
135 | {
136 | $this->productId = (int)$id;
137 | return $this;
138 | }
139 |
140 | /**
141 | * Get Product Id
142 | *
143 | * @return integer
144 | */
145 | public function getProductId()
146 | {
147 | return $this->productId;
148 | }
149 |
150 | /**
151 | * @param null $id
152 | * @return $this
153 | * @throws \Exception
154 | */
155 | public function execute($id = null)
156 | {
157 | $this->setProductId($id);
158 | $this->cleanData();
159 | $connection = $this->resourceConnection->getConnection();
160 | $ruleCollection = $this->helperRule->getRuleCollection();
161 | $dataImport = [];
162 | /** @var Rule $rule */
163 | foreach ($ruleCollection as $rule) {
164 | $productCollection = $this->getProductCollection();
165 | $productCollection->addFieldToFilter($this->getProductIdentifierField(), $id);
166 | $this->builder->attachConditionToCollection($productCollection, $rule->getConditions());
167 | if ($productCollection->getSize() > 0) {
168 | $dataImport[] = [
169 | 'rule_id' => $rule->getId(),
170 | 'product_id' => $id
171 | ];
172 | }
173 | }
174 | if (!empty($dataImport)) {
175 | $connection->insertOnDuplicate($connection->getTableName(self::FLAT_INDEX_RULE_TABLE), $dataImport);
176 | }
177 |
178 | return $this;
179 | }
180 |
181 | /**
182 | * @param boolean $isVisibility
183 | * @return \Magento\Catalog\Model\ResourceModel\Product\Collection
184 | * @throws \Exception
185 | */
186 | protected function getProductCollection($isVisibility = true)
187 | {
188 | $productCollection = $this->productCollectionFactory->create();
189 | $productCollection->addFieldToFilter('status', ProductStatus::STATUS_ENABLED);
190 | if ($isVisibility) {
191 | $productCollection->addFieldToFilter('visibility', ['in' => $this->productVisibility->getVisibleInSiteIds()]);
192 | }
193 | $productCollection->setOrder($this->getProductIdentifierField());
194 |
195 | return $productCollection;
196 | }
197 |
198 | /**
199 | * Clean All Old Data
200 | */
201 | private function cleanData()
202 | {
203 | $connection = $this->resourceConnection->getConnection();
204 | $connection->delete(
205 | $connection->getTableName(self::FLAT_INDEX_RULE_TABLE),
206 | $connection->quoteInto('product_id = ?', $this->getProductId())
207 | );
208 | }
209 |
210 | /**
211 | * @return MetadataPool
212 | */
213 | protected function getMetadataPool()
214 | {
215 | return $this->metadataPool;
216 | }
217 |
218 | /**
219 | * Get product entity identifier field
220 | *
221 | * @return string
222 | * @throws \Exception
223 | */
224 | private function getProductIdentifierField()
225 | {
226 | if ($this->productEntityIdentifierField === null) {
227 | $this->productEntityIdentifierField = $this->getMetadataPool()
228 | ->getMetadata(ProductInterface::class)
229 | ->getIdentifierField();
230 | }
231 | return $this->productEntityIdentifierField;
232 | }
233 | }
234 |
--------------------------------------------------------------------------------
/etc/db_schema.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
14 |
16 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
49 |
51 |
53 |
54 |
55 |
56 |
57 |
62 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
87 |
92 |
93 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/Model/ResourceModel/Rule.php:
--------------------------------------------------------------------------------
1 | dateTime = $dateTime;
44 | }
45 |
46 | /**
47 | * Initialize resource
48 | *
49 | * @return void
50 | */
51 | public function _construct()
52 | {
53 | $this->_init('boolfly_productlabel_rule', 'rule_id');
54 | }
55 |
56 | /**
57 | * @param AbstractModel $object
58 | * @return mixed
59 | */
60 | protected function _afterLoad(AbstractModel $object)
61 | {
62 | $this->getLinkData($object);
63 | return parent::_afterLoad($object);
64 | }
65 |
66 | /**
67 | * Get Link Data
68 | *
69 | * @param AbstractModel $object
70 | */
71 | private function getLinkData(AbstractModel $object)
72 | {
73 | $this->getStoreLink($object);
74 | $this->getCustomerGroupLink($object);
75 | }
76 |
77 | /**
78 | * @param AbstractModel $object
79 | */
80 | protected function getStoreLink($object)
81 | {
82 | $stores = $this->lookupStoreIds($object->getId());
83 | $object->setData('store_ids', $stores);
84 | }
85 |
86 | /**
87 | * @param AbstractModel $object
88 | */
89 | protected function getCustomerGroupLink($object)
90 | {
91 | $stores = $this->lookupCustomerGroupsIds($object->getId());
92 | $object->setData('customer_group_ids', $stores);
93 | }
94 |
95 | /**
96 | * Get Label Store Table
97 | *
98 | * @return string
99 | */
100 | private function getStoreTable()
101 | {
102 | return $this->getTable('boolfly_productlabel_store');
103 | }
104 |
105 | /**
106 | * Get Customer Group Table Name
107 | *
108 | * @return string
109 | */
110 | private function getCustomerGroupsTable()
111 | {
112 | return $this->getTable('boolfly_productlabel_customer_group');
113 | }
114 |
115 | /**
116 | * Before save
117 | *
118 | * @param AbstractModel $object
119 | * @return mixed
120 | */
121 | protected function _beforeSave(AbstractModel $object)
122 | {
123 | $gmtDate = $this->dateTime->gmtDate();
124 | if ($object->isObjectNew()) {
125 | $object->setData('created_at', $gmtDate);
126 | }
127 | $object->setData('updated_at', $gmtDate);
128 |
129 | return parent::_beforeSave($object);
130 | }
131 |
132 | /**
133 | * @param AbstractModel $object
134 | * @return mixed
135 | */
136 | protected function _afterSave(AbstractModel $object)
137 | {
138 | $this->processLinkTable($object);
139 | return parent::_afterSave($object);
140 | }
141 |
142 | /**
143 | * Process data to link table
144 | *
145 | * @param AbstractModel $object
146 | * @return $this
147 | */
148 | private function processLinkTable(AbstractModel $object)
149 | {
150 | $this->processStoreTable($object);
151 | $this->processCustomerGroupTable($object);
152 |
153 | return $this;
154 | }
155 |
156 | /**
157 | * Save data to boolfly_productlabel_store table
158 | *
159 | * @param \Boolfly\ProductLabel\Model\Rule|AbstractModel $object
160 | */
161 | private function processStoreTable(AbstractModel $object)
162 | {
163 | $oldIds = $this->lookupStoreIds($object->getId());
164 | $newIds = (array)$object->getStoreIds();
165 | $this->updateForeignKey(
166 | $object->getId(),
167 | $newIds,
168 | $oldIds,
169 | $this->getStoreTable(),
170 | 'store_id'
171 | );
172 | }
173 |
174 | /**
175 | * Save data to boolfly_productlabel_store table
176 | *
177 | * @param \Boolfly\ProductLabel\Model\Rule|AbstractModel $object
178 | */
179 | private function processCustomerGroupTable(AbstractModel $object)
180 | {
181 | $oldIds = $this->lookupCustomerGroupsIds($object->getId());
182 | $newIds = (array)$object->getCustomerGroupIds();
183 | $this->updateForeignKey(
184 | $object->getId(),
185 | $newIds,
186 | $oldIds,
187 | $this->getCustomerGroupsTable(),
188 | 'customer_group_id'
189 | );
190 | }
191 |
192 | /**
193 | * Get Store ids to which specified item is assigned
194 | *
195 | * @param integer $id
196 | * @return array
197 | */
198 | public function lookupStoreIds($id)
199 | {
200 | return $this->lookupIds(
201 | $id,
202 | $this->getStoreTable(),
203 | 'store_id'
204 | );
205 | }
206 |
207 | /**
208 | * @param $id
209 | * @return array
210 | */
211 | protected function lookupCustomerGroupsIds($id)
212 | {
213 | return $this->lookupIds(
214 | $id,
215 | $this->getCustomerGroupsTable(),
216 | 'customer_group_id'
217 | );
218 | }
219 |
220 | /**
221 | * Get ids to which specified item is assigned
222 | *
223 | * @param integer $id
224 | * @param string $tableName
225 | * @param string $field
226 | * @return array
227 | */
228 | protected function lookupIds($id, $tableName, $field)
229 | {
230 | $adapter = $this->getConnection();
231 |
232 | $select = $adapter->select()->from(
233 | $this->getTable($tableName),
234 | $field
235 | )->where(
236 | 'rule_id = ?',
237 | (int)$id
238 | );
239 |
240 | return $adapter->fetchCol($select);
241 | }
242 |
243 | /**
244 | * @param $ruleId
245 | * @param array $newIds
246 | * @param array $oldIds
247 | * @param $table
248 | * @param $field
249 | */
250 | protected function updateForeignKey(
251 | $ruleId,
252 | array $newIds,
253 | array $oldIds,
254 | $table,
255 | $field
256 | ) {
257 | $insert = array_diff($newIds, $oldIds);
258 | $delete = array_diff($oldIds, $newIds);
259 | if ($delete) {
260 | $where = [
261 | 'rule_id = ?' => (int)$ruleId,
262 | $field.' IN (?)' => $delete,
263 | ];
264 | $this->getConnection()->delete($table, $where);
265 | }
266 | if ($insert) {
267 | $data = [];
268 | foreach ($insert as $storeId) {
269 | $data[] = [
270 | 'rule_id' => (int)$ruleId,
271 | $field => (int)$storeId,
272 | ];
273 | }
274 |
275 | $this->getConnection()->insertMultiple($table, $data);
276 | }
277 | }
278 | }
279 |
--------------------------------------------------------------------------------
/Api/Data/RuleInterface.php:
--------------------------------------------------------------------------------
1 | " or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.
--------------------------------------------------------------------------------
/Model/Rule/Condition/Product.php:
--------------------------------------------------------------------------------
1 | storeManager = $storeManager;
78 | parent::__construct(
79 | $context,
80 | $backendData,
81 | $config,
82 | $productFactory,
83 | $productRepository,
84 | $productResource,
85 | $attrSetCollection,
86 | $localeFormat,
87 | $data
88 | );
89 | }
90 |
91 | /**
92 | * {@inheritdoc}
93 | */
94 | public function loadAttributeOptions()
95 | {
96 | /** @var Attribute[] $productAttributes */
97 | $productAttributes = $this->_productResource->loadAllAttributes()->getAttributesByCode();
98 |
99 | $attributes = [];
100 | foreach ($productAttributes as $attribute) {
101 | if (!$attribute->getFrontendLabel() || $attribute->getFrontendInput() == 'text') {
102 | continue;
103 | }
104 | $attributes[$attribute->getAttributeCode()] = $attribute->getFrontendLabel();
105 | }
106 |
107 | $this->_addSpecialAttributes($attributes);
108 |
109 | asort($attributes);
110 | $this->setAttributeOption($attributes);
111 |
112 | return $this;
113 | }
114 |
115 | /**
116 | * {@inheritdoc}
117 | */
118 | protected function _addSpecialAttributes(array &$attributes)
119 | {
120 | parent::_addSpecialAttributes($attributes);
121 | $attributes['sku'] = __('SKU');
122 | }
123 |
124 | /**
125 | * Retrieve value element chooser URL
126 | *
127 | * @return string
128 | */
129 | public function getValueElementChooserUrl()
130 | {
131 | $url = false;
132 | switch ($this->getAttribute()) {
133 | case 'sku':
134 | case 'category_ids':
135 | $url = 'catalog_rule/promo_widget/chooser/attribute/' . $this->getAttribute();
136 | if ($this->getJsFormObject()) {
137 | if ($this->getRule()->getId()) {
138 | $url .= '/form/' . $this->getRule()->getConditionsFieldSetId('boolfly_label_rule_form');
139 | } else {
140 | $url .= '/form/' . $this->getJsFormObject();
141 | }
142 | }
143 | break;
144 | default:
145 | break;
146 | }
147 | return $url !== false ? $this->_backendData->getUrl($url) : '';
148 | }
149 |
150 | /**
151 | * @param $collection
152 | * @return $this
153 | * @throws \Magento\Framework\Exception\LocalizedException
154 | * @throws \Magento\Framework\Exception\NoSuchEntityException
155 | */
156 | public function addToCollection($collection)
157 | {
158 | $attribute = $this->getAttributeObject();
159 |
160 | if ($collection->isEnabledFlat()) {
161 | $alias = array_keys($collection->getSelect()->getPart('from'))[0];
162 | $this->joinedAttributes[$attribute->getAttributeCode()] = $alias . '.' . $attribute->getAttributeCode();
163 | return $this;
164 | }
165 |
166 | if ('category_ids' == $attribute->getAttributeCode() || $attribute->isStatic()) {
167 | return $this;
168 | }
169 |
170 | if ($attribute->getBackend() && $attribute->isScopeGlobal()) {
171 | $this->addGlobalAttribute($attribute, $collection);
172 | } else {
173 | $this->addNotGlobalAttribute($attribute, $collection);
174 | }
175 |
176 | $attributes = $this->getRule()->getCollectedAttributes();
177 | $attributes[$attribute->getAttributeCode()] = true;
178 | $this->getRule()->setCollectedAttributes($attributes);
179 |
180 | return $this;
181 | }
182 |
183 | /**
184 | * @param Attribute $attribute
185 | * @param ProductCollection $collection
186 | * @return $this
187 | * @throws \Magento\Framework\Exception\NoSuchEntityException
188 | */
189 | protected function addGlobalAttribute(
190 | Attribute $attribute,
191 | ProductCollection $collection
192 | ) {
193 | $storeId = $this->storeManager->getStore()->getId();
194 |
195 | switch ($attribute->getBackendType()) {
196 | case 'decimal':
197 | case 'datetime':
198 | case 'int':
199 | $alias = 'at_' . $attribute->getAttributeCode();
200 | $collection->addAttributeToSelect($attribute->getAttributeCode(), 'inner');
201 | break;
202 | default:
203 | $alias = 'at_'. md5($this->getId()) . $attribute->getAttributeCode();
204 | $collection->getSelect()->join(
205 | [$alias => $collection->getTable('catalog_product_index_eav')],
206 | "($alias.entity_id = e.entity_id) AND ($alias.store_id = $storeId)" .
207 | " AND ($alias.attribute_id = {$attribute->getId()})",
208 | []
209 | );
210 | }
211 |
212 | $this->joinedAttributes[$attribute->getAttributeCode()] = $alias . '.value';
213 |
214 | return $this;
215 | }
216 |
217 | /**
218 | * @param Attribute $attribute
219 | * @param ProductCollection $collection
220 | * @return $this
221 | * @throws \Magento\Framework\Exception\NoSuchEntityException
222 | */
223 | protected function addNotGlobalAttribute(
224 | Attribute $attribute,
225 | ProductCollection $collection
226 | ) {
227 | $storeId = $this->storeManager->getStore()->getId();
228 | $values = $collection->getAllAttributeValues($attribute);
229 | $validEntities = [];
230 | if ($values) {
231 | foreach ($values as $entityId => $storeValues) {
232 | if (isset($storeValues[$storeId])) {
233 | if ($this->validateAttribute($storeValues[$storeId])) {
234 | $validEntities[] = $entityId;
235 | }
236 | } else {
237 | if ($this->validateAttribute($storeValues[Store::DEFAULT_STORE_ID])) {
238 | $validEntities[] = $entityId;
239 | }
240 | }
241 | }
242 | }
243 | $this->setOperator('()');
244 | $this->unsetData('value_parsed');
245 | if ($validEntities) {
246 | $this->setData('value', implode(',', $validEntities));
247 | } else {
248 | $this->unsetData('value');
249 | }
250 |
251 | return $this;
252 | }
253 |
254 | /**
255 | * {@inheritdoc}
256 | */
257 | public function getMappedSqlField()
258 | {
259 | $result = '';
260 | if ($this->getAttribute() == 'category_ids') {
261 | $result = parent::getMappedSqlField();
262 | } elseif (isset($this->joinedAttributes[$this->getAttribute()])) {
263 | $result = $this->joinedAttributes[$this->getAttribute()];
264 | } elseif ($this->getAttributeObject()->isStatic()) {
265 | $result = $this->getAttributeObject()->getAttributeCode();
266 | } elseif ($this->getAttributeObject()->getIsGlobal()) {
267 | $result = parent::getMappedSqlField();
268 | } elseif ($this->getValueParsed()) {
269 | $result = 'e.entity_id';
270 | }
271 |
272 | return $result;
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/Helper/Rule.php:
--------------------------------------------------------------------------------
1 | collectionFactory = $collectionFactory;
100 | $this->dateTime = $dateTime;
101 | $this->storeManager = $storeManager;
102 | $this->metadataPool = $metadataPool;
103 | $this->resourceConnection = $resourceConnection;
104 | $this->httpContext = $httpContext;
105 | }
106 |
107 | /**
108 | * Get Customer Group Id
109 | *
110 | * @return int
111 | */
112 | private function getCustomerGroupId()
113 | {
114 | return (int)$this->httpContext->getValue(CustomerContext::CONTEXT_GROUP);
115 | }
116 |
117 | /**
118 | * Get Rule Collection
119 | *
120 | * @param boolean $storeFilter
121 | * @param boolean $groupFilter
122 | * @return $this|Collection
123 | * @throws \Magento\Framework\Exception\NoSuchEntityException
124 | */
125 | public function getRuleCollection($storeFilter = false, $groupFilter = false)
126 | {
127 | if ($this->ruleCollection === null) {
128 | $dateTime = $this->dateTime->gmtDate();
129 | $startDate = [
130 | 'or' => [
131 | [
132 | 'date' => true,
133 | 'to' => $dateTime,
134 | ],
135 | ['is' => new Zend_Db_Expr('null')]
136 | ]
137 | ];
138 | $endDate = [
139 | 'or' => [
140 | [
141 | 'date' => true,
142 | 'from' => $dateTime,
143 | ],
144 | ['is' => new Zend_Db_Expr('null')]
145 | ]
146 | ];
147 |
148 | $collection = $this->collectionFactory->create()
149 | ->addActiveStatusFilter()
150 | ->addFieldToFilter('from_date', $startDate)
151 | ->addFieldToFilter('to_date', $endDate);
152 | if ($storeFilter) {
153 | $collection->addStoreToFilter($this->storeManager->getStore()->getId());
154 | }
155 | if ($groupFilter) {
156 | $collection->addCustomerGroupToFilter($this->getCustomerGroupId());
157 | }
158 |
159 | $this->ruleCollection = $collection;
160 | }
161 |
162 | return $this->ruleCollection;
163 | }
164 |
165 | /**
166 | * Get Apply Category Rule
167 | *
168 | * @param Product $product
169 | * @return array
170 | * @throws \Magento\Framework\Exception\NoSuchEntityException
171 | */
172 | public function getAppliedCategoryRule(Product $product)
173 | {
174 | return $this->getAppliedRule($product, 'cat');
175 | }
176 |
177 | /**
178 | * Get Applied Product Rule
179 | *
180 | * @param Product $product
181 | * @return array
182 | * @throws \Magento\Framework\Exception\NoSuchEntityException
183 | */
184 | public function getAppliedProductRule(Product $product)
185 | {
186 | return $this->getAppliedRule($product);
187 | }
188 |
189 | /**
190 | * Get Applied Rule for Product
191 | *
192 | * @param Product $product
193 | * @param $type
194 | * @return array
195 | * @throws \Magento\Framework\Exception\NoSuchEntityException
196 | */
197 | private function getAppliedRule(Product $product, $type = 'product')
198 | {
199 | $ruleIds = $this->getRuleIdsValue($product);
200 | $result = [];
201 | if (!empty($ruleIds)) {
202 | $displayField = $type == 'product' ? RuleInterface::DISPLAY_IN_PRODUCT : RuleInterface::DISPLAY_IN_CATEGORY;
203 | $position = $type == 'product' ? RuleInterface::PRODUCT_POSITION : RuleInterface::CATEGORY_POSITION;
204 | $collection = $this->getRuleCollection(true, true);
205 | $collection->addFieldToFilter($displayField, 1);
206 | $collection->addOrderByType($type);
207 | /** @var \Boolfly\ProductLabel\Model\Rule $rule */
208 | foreach ($collection as $rule) {
209 | if (in_array($rule->getId(), $ruleIds)) {
210 | if ($rule->getType() == Type::SALE_LABEL && !$this->isSale($product)) {
211 | continue;
212 | }
213 | $result[$rule->getData($position)][] = $rule;
214 | }
215 | }
216 | }
217 |
218 | return $result;
219 | }
220 |
221 | /**
222 | * Get All Rule Ids for Product
223 | *
224 | * @param Product $product
225 | * @return array
226 | */
227 | public function getRuleIdsValue(Product $product)
228 | {
229 | $value = (string)$product->getData(self::ALIAS_LABEL_RULE_ID);
230 | return $value ? array_unique(explode(',', $value)) : [];
231 | }
232 |
233 | /**
234 | * Check Is Sale Product
235 | *
236 | * @param Product $product
237 | * @return mixed
238 | */
239 | private function isSale(Product $product)
240 | {
241 | $regularPrice = $product->getPriceInfo()
242 | ->getPrice(Price\RegularPrice::PRICE_CODE)
243 | ->getAmount()
244 | ->getValue();
245 | $finalPrice = $product->getPriceInfo()
246 | ->getPrice(Price\FinalPrice::PRICE_CODE)
247 | ->getAmount()
248 | ->getValue();
249 |
250 | if ($regularPrice > $finalPrice) {
251 | return true;
252 | }
253 |
254 | return false;
255 | }
256 |
257 | /**
258 | * Add Rule Ids to Product Collection
259 | *
260 | * @param ProductCollection $collection
261 | * @throws \Exception
262 | */
263 | public function addRuleIdsToCollection($collection)
264 | {
265 | if ($collection instanceof ProductCollection && !$collection->isLoaded()) {
266 | $connection = $collection->getConnection();
267 | $col = new Zend_Db_Expr('GROUP_CONCAT(rule_id)');
268 | $cond = $connection->quoteColumnAs('e.' . $this->getProductIdentifierField(), null)
269 | . ' = ' . $connection->quoteColumnAs('label_rule.product_id', null);
270 | $select = $connection->select()
271 | ->from($connection->getTableName(IndexerRow::FLAT_INDEX_RULE_TABLE),
272 | ['product_id', self::ALIAS_LABEL_RULE_ID => $col]
273 | )->group('product_id');
274 | $collection->getSelect()
275 | ->joinLeft(
276 | ['label_rule' => $select],
277 | $cond,
278 | self::ALIAS_LABEL_RULE_ID
279 | );
280 | }
281 | }
282 |
283 | /**
284 | * Add Rule Ids to Product
285 | *
286 | * @param Product $product
287 | * @throws \Exception
288 | */
289 | public function addRuleIds(Product $product)
290 | {
291 | if ($product->getData(self::ALIAS_LABEL_RULE_ID) === null) {
292 | $productId = $product->getId();
293 | $connection = $this->resourceConnection->getConnection();
294 | $column = new Zend_Db_Expr('GROUP_CONCAT(rule_id)');
295 | $select = $connection->select()->from(
296 | $connection->getTableName(IndexerRow::FLAT_INDEX_RULE_TABLE),
297 | $column
298 | )->where('product_id = ?', (int)$productId);
299 | $product->setData(self::ALIAS_LABEL_RULE_ID, $connection->fetchOne($select));
300 | }
301 | }
302 |
303 | /**
304 | * Get Meta Data
305 | *
306 | * @return MetadataPool
307 | */
308 | protected function getMetadataPool()
309 | {
310 | return $this->metadataPool;
311 | }
312 |
313 | /**
314 | * Get product entity identifier field
315 | *
316 | * @return string
317 | * @throws \Exception
318 | */
319 | private function getProductIdentifierField()
320 | {
321 | if ($this->productEntityIdentifierField === null) {
322 | $this->productEntityIdentifierField = $this->getMetadataPool()
323 | ->getMetadata(ProductInterface::class)
324 | ->getIdentifierField();
325 | }
326 | return $this->productEntityIdentifierField;
327 | }
328 | }
329 |
--------------------------------------------------------------------------------
/view/adminhtml/ui_component/boolfly_label_rule_listing.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 | -
15 |
- boolfly_label_rule_listing.boolfly_label_rule_listing_data_source
16 | - boolfly_label_rule_listing.boolfly_label_rule_listing_data_source
17 |
18 | - label_rule_columns
19 | -
20 |
-
21 |
- add
22 | - Add New
23 | - primary
24 | - */*/new
25 |
26 |
27 |
28 |
29 |
30 | Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider
31 | boolfly_label_rule_listing_data_source
32 | rule_id
33 | id
34 |
35 | -
36 |
37 | -
38 |
- rule_id
39 |
40 |
41 |
42 |
43 |
44 | -
45 |
- Magento_Ui/js/grid/provider
46 |
47 |
48 |
49 |
50 |
51 | -
52 |
- ui/grid/toolbar
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | Magento\Store\Ui\Component\Listing\Column\Store\Options
61 |
62 |
63 | -
64 |
- ${ $.parentName }
65 | - store_id
66 | - All Store Views
67 | - Store View
68 |
69 |
70 |
71 |
72 |
73 |
74 | -
75 |
- boolfly_label_rule_listing.boolfly_label_rule_listing.label_rule_columns.ids
76 | - Magento_Ui/js/grid/tree-massactions
77 | - entity_id
78 |
79 |
80 |
81 |
82 | -
83 |
- delete
84 | - Delete
85 |
86 | -
87 |
- Delete items
88 | - Are you sure to delete selected items?
89 |
90 |
91 |
92 |
93 |
94 |
95 | -
96 |
- status
97 | - Change status
98 |
99 |
100 |
101 | -
102 |
- enable
103 | - Enable
104 | -
105 |
1
106 |
107 |
108 | -
109 |
- disable
110 | - Disable
111 | -
112 |
2
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | -
123 |
-
124 |
- boolfly_label_rule_listing.boolfly_label_rule_listing.listing_top.bookmarks
125 | - current
126 |
127 | -
128 |
- boolfly_label_rule_listing.boolfly_label_rule_listing.label_rule_columns.ids
129 | - true
130 | - id
131 | -
132 |
133 | - false
134 |
135 |
136 | -
137 |
-
138 |
- boolfly_label_rule_listing.boolfly_label_rule_listing.label_rule_columns_editor
139 | - startEdit
140 | -
141 |
- ${ $.$data.rowIndex }
142 | - true
143 |
144 |
145 | -
146 |
- boolfly_label_rule_listing.boolfly_label_rule_listing.listing_top.bookmarks
147 | - columns.${ $.index }
148 | - current.${ $.storageConfig.root }
149 |
150 |
151 |
152 |
153 |
154 |
155 | -
156 |
- rule_id
157 | - 10
158 |
159 |
160 |
161 |
162 |
163 | -
164 |
- textRange
165 | - asc
166 | - ID
167 | - 20
168 |
169 |
170 |
171 |
172 |
173 | -
174 |
- text
175 | - Title
176 | - 30
177 |
178 |
179 |
180 |
181 |
182 | -
183 |
- dateRange
184 | - From Date
185 | - 40
186 |
187 |
188 |
189 |
190 |
191 | -
192 |
- dateRange
193 | - To Date
194 | - 50
195 |
196 |
197 |
198 |
199 |
200 | -
201 |
- text
202 | - Priority
203 | - 70
204 |
205 |
206 |
207 |
208 |
209 | - Boolfly\ProductLabel\Model\Source\Config\Status
210 | -
211 |
- select
212 | - Magento_Ui/js/grid/columns/select
213 | - select
214 | - Status
215 | - 90
216 |
217 |
218 |
219 |
220 |
221 | -
222 |
- text
223 | - false
224 | - Description
225 | - 100
226 |
227 |
228 |
229 |
230 |
231 | rule_id
232 |
233 | product_label/rule/edit
234 |
235 |
236 |
237 |
238 |
239 |
--------------------------------------------------------------------------------
/Model/Condition/Sql/Builder.php:
--------------------------------------------------------------------------------
1 | 'eq',
49 | '!=' => 'neq',
50 | '>=' => 'gteq',
51 | '>' => 'gt',
52 | '<=' => 'lteq',
53 | '<' => 'lt',
54 | '{}' => 'in',
55 | '!{}' => 'nin',
56 | '()' => 'in',
57 | '!()' => 'nin',
58 | ];
59 |
60 | protected $stockStatusAttributeCode = 'quantity_and_stock_status';
61 |
62 |
63 | /**
64 | * @var ExpressionFactory
65 | */
66 | protected $expressionFactory;
67 |
68 | /**
69 | * @var EavConfig
70 | */
71 | protected $eavConfig;
72 |
73 | /**
74 | * @var string
75 | */
76 | protected $productEntityIdentifierField;
77 |
78 | /**
79 | * @var MetadataPool
80 | */
81 | protected $metadataPool;
82 |
83 | /**
84 | * Builder constructor.
85 | *
86 | * @param ExpressionFactory $expressionFactory
87 | * @param ResourceConnection $resourceConnection
88 | * @param MetadataPool $metadataPool
89 | * @param EavConfig $eavConfig
90 | */
91 | public function __construct(
92 | ExpressionFactory $expressionFactory,
93 | ResourceConnection $resourceConnection,
94 | MetadataPool $metadataPool,
95 | EavConfig $eavConfig
96 | ) {
97 | $this->expressionFactory = $expressionFactory;
98 | $this->connection = $resourceConnection->getConnection();
99 | $this->eavConfig = $eavConfig;
100 | $this->metadataPool = $metadataPool;
101 | }
102 |
103 | /**
104 | * @param AbstractCollection $collection
105 | * @param Combine $combine
106 | * @throws \Exception
107 | */
108 | public function attachConditionToCollection(
109 | AbstractCollection $collection,
110 | Combine $combine
111 | ) {
112 | $joinTables = $this->getCombineTablesToJoin($combine);
113 | $this->joinTablesToCollection($collection, $joinTables);
114 | $whereExpression = (string)$this->getMappedSqlCombination($combine);
115 | if (!empty($whereExpression)) {
116 | $collection->getSelect()->where($whereExpression);
117 | }
118 | }
119 |
120 | /**
121 | * Get Connection
122 | *
123 | * @return \Magento\Framework\DB\Adapter\AdapterInterface
124 | */
125 | private function getConnection()
126 | {
127 | return $this->connection;
128 | }
129 |
130 | /**
131 | * @param Combine $combine
132 | * @return array
133 | * @throws \Exception
134 | */
135 | protected function getCombineTablesToJoin(Combine $combine)
136 | {
137 | $joinTables = [];
138 |
139 | /** @var Product|Combine $condition */
140 | foreach ($combine->getConditions() as $condition) {
141 | if ($condition instanceof Combine) {
142 | $joinTables[] = ['sub' => $this->getCombineTablesToJoin($condition)];
143 | } else {
144 | $attribute = $condition->getAttributeObject();
145 | if ($attribute->getId()) {
146 | if ($attribute->getAttributeCode() === $this->stockStatusAttributeCode) {
147 | $joinTables[] = $this->getTableJoinStockStatus();
148 | } elseif ($attribute->getBackendType() != 'static') {
149 | $joinTables[] = $this->getTableJoin($attribute);
150 | }
151 | }
152 | }
153 | }
154 |
155 | return $joinTables;
156 | }
157 |
158 | /**
159 | * Get Info to join cataloginventory_stock_status
160 | *
161 | * @return array
162 | * @throws \Exception
163 | */
164 | private function getTableJoinStockStatus()
165 | {
166 | $alias = 'stock_status';
167 | $connection = $this->getConnection();
168 | $productIdentifierField = $this->getProductIdentifierField();
169 | $joinCondition = $connection->quoteColumnAs($alias . '.product_id', null)
170 | . ' = ' . $connection->quoteColumnAs('e.'. $productIdentifierField, null);
171 |
172 | return [
173 | 'alias' => $alias,
174 | 'table' => 'cataloginventory_stock_status',
175 | 'column' => $alias . '.stock_status' . ' AS stock_status',
176 | 'conditions' => [
177 | $joinCondition
178 | ]
179 | ];
180 | }
181 |
182 | /**
183 | * @param \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute
184 | * @return array
185 | * @throws \Exception
186 | */
187 | protected function getTableJoin($attribute)
188 | {
189 | $connection = $this->getConnection();
190 | $alias = $this->getAlias($attribute->getAttributeCode());
191 | $productIdentifierField = $this->getProductIdentifierField();
192 | $joinCondition = $connection->quoteColumnAs($alias . '.' . $productIdentifierField, null)
193 | . ' = ' . $connection->quoteColumnAs('e.'. $productIdentifierField, null);
194 |
195 | return [
196 | 'alias' => $alias,
197 | 'table' => 'catalog_product_entity_' . $attribute->getBackendType(),
198 | 'column' => $this->checkIfExistColumn($alias) . ' AS ' . $attribute->getAttributeCode(),
199 | 'conditions' => [
200 | $joinCondition,
201 | $connection->quoteInto($alias . '.attribute_id = ?', $attribute->getId()),
202 | $connection->quoteInto($alias . '.store_id = ?', Store::DEFAULT_STORE_ID),
203 | ]
204 | ];
205 | }
206 |
207 | /**
208 | * Get Alias
209 | *
210 | * @param $attributeCode
211 | * @return string
212 | */
213 | protected function getAlias($attributeCode)
214 | {
215 | return 'at_'. $attributeCode;
216 | }
217 |
218 | /**
219 | * Get Expression Column
220 | *
221 | * @param $alias
222 | * @return Expression
223 | */
224 | protected function checkIfExistColumn($alias)
225 | {
226 | $out = 'IF(' . $alias . '.value_id > 0, '. $alias .'.value, null)';
227 | return $this->expressionFactory->create(['expression' => $out]);
228 | }
229 |
230 | /**
231 | * Join tables from conditions combination to collection
232 | *
233 | * @param AbstractCollection $collection
234 | * @param $joinTables
235 | * @param array $joined
236 | * @throws \Zend_Db_Select_Exception
237 | */
238 | protected function joinTablesToCollection(AbstractCollection $collection, $joinTables, $joined = [])
239 | {
240 | $joined = array_merge_recursive(
241 | array_keys($collection->getSelect()->getPart(Zend_Db_Select::FROM)),
242 | $joined
243 | );
244 | if (is_array($joinTables)) {
245 | foreach ($joinTables as $table) {
246 | if (isset($table['sub'])) {
247 | $this->joinTablesToCollection($collection, $table['sub'], $joined);
248 | } else {
249 | if (isset($table['alias'])
250 | && !in_array($table['alias'], $joined)
251 | && !empty($table)
252 | ) {
253 | $cond = implode(' AND ', $table['conditions']);
254 | $tableName = $this->connection->getTableName($table['table']);
255 | $collection->getSelect()->joinLeft([$table['alias'] => $tableName], $cond, $table['column']);
256 | $joined[] = $table['alias'];
257 | }
258 | }
259 | }
260 | }
261 | }
262 |
263 | /**
264 | * Mapped Sql Combination
265 | *
266 | * @param Combine $combine
267 | * @param string $value
268 | * @return Expression
269 | * @throws \Exception
270 | */
271 | protected function getMappedSqlCombination(Combine $combine, $value = '')
272 | {
273 | $out = $value ? $value : '';
274 | $value = $combine->getValue() ? '' : ' NOT ';
275 | $getAggregator = $combine->getAggregator();
276 | $conditions = $combine->getConditions();
277 | /** @var AbstractCondition|Combine $condition */
278 | foreach ($conditions as $key => $condition) {
279 | $con = $getAggregator == 'any' ? Select::SQL_OR : Select::SQL_AND;
280 | $con = isset($conditions[$key + 1]) ? $con : '';
281 | if ($condition instanceof Combine) {
282 | $out .= $this->getMappedSqlCombination($condition, $value);
283 | } else {
284 | $out .= ' ' . $this->getMappedSqlCondition($condition, $value);
285 | }
286 | $out .= $out ? (' ' . $con) : '';
287 | }
288 | return $this->expressionFactory->create(['expression' => $out]);
289 | }
290 |
291 | /**
292 | * Mapped Sql Condition
293 | *
294 | * @param AbstractCondition $condition
295 | * @param string $out
296 | * @return string
297 | * @throws \Exception
298 | */
299 | protected function getMappedSqlCondition(AbstractCondition $condition, $out = '')
300 | {
301 | /** @var Product $condition */
302 | $attribute = $condition->getAttributeObject();
303 | if ($attribute->getId()) {
304 | $value = $condition->getValue();
305 | $connection = $this->getConnection();
306 | $operator = $condition->getOperator();
307 | $alias = $this->getAlias($attribute->getAttributeCode());
308 | $column = $this->checkIfExistColumn($alias);
309 | if ($attribute->getAttributeCode() === $this->stockStatusAttributeCode) {
310 | $column = 'stock_status.stock_status';
311 | }
312 | $conditionOperator = $this->getConditionOperator($operator);
313 | if ($attribute->getBackendType() !== 'static' && $conditionOperator) {
314 | if ($attribute->getFrontendInput() === 'multiselect') {
315 | return $this->getMappedSqlConditionMultiselect($operator, $column, $value);
316 | } elseif (is_string($value)) {
317 | return $connection->prepareSqlCondition($column, [$conditionOperator => $value]);
318 | }
319 | } elseif ($attribute->getAttributeCode() == 'sku') {
320 | $value = strpos('in', $conditionOperator) === false ?: $condition->getValueParsed();
321 | return $connection->prepareSqlCondition($attribute->getAttributeCode(), [$conditionOperator => $value]);
322 | } elseif ($attribute->getAttributeCode() == 'category_ids') {
323 | return $this->getMappedSqlConditionCategoryIds($operator, $condition->getValueParsed());
324 | }
325 | }
326 | return $out;
327 | }
328 |
329 | /**
330 | * @param $operator
331 | * @return mixed|null
332 | */
333 | private function getConditionOperator($operator)
334 | {
335 | return isset($this->conditionOperatorMaps[$operator]) ? $this->conditionOperatorMaps[$operator] : null;
336 | }
337 |
338 | /**
339 | * Mapped Sql Condition Multiselect
340 | *
341 | * @param $operator
342 | * @param $column
343 | * @param $value
344 | * @return string
345 | */
346 | protected function getMappedSqlConditionMultiselect($operator, $column, $value)
347 | {
348 | if (is_array($value)) {
349 | $conditionOperator = strpos($operator, '!') === false ? 'finset' : 'nfinset';
350 | $multiValue = [];
351 | foreach ($value as $val) {
352 | $multiValue[] = $this->connection->prepareSqlCondition($column, [$conditionOperator => $val]);
353 | }
354 | $cond = strpos($operator, '()') !== false ? ' OR ' : ' AND ';
355 | return implode($cond, $multiValue);
356 | }
357 |
358 | return '';
359 | }
360 |
361 | /**
362 | * Sql Condition for Category Ids
363 | *
364 | * @param $operator
365 | * @param $valueParsed
366 | * @return mixed
367 | * @throws \Exception
368 | */
369 | protected function getMappedSqlConditionCategoryIds($operator, $valueParsed)
370 | {
371 | if (is_array($valueParsed) && !empty($valueParsed)) {
372 | $conditionCategory = $this->connection->select()
373 | ->from(
374 | $this->connection->getTableName('catalog_category_product'),
375 | ['product_id']
376 | )->where(
377 | 'category_id IN (?)',
378 | $valueParsed
379 | )->__toString();
380 | if ($operator == '==') {
381 | $operator = '{}';
382 | }
383 | if ($operator == '!=') {
384 | $operator = '!{}';
385 | }
386 | $productIdentifierField = $this->connection->quoteColumnAs('e.' . $this->getProductIdentifierField(), null);
387 | $conditionOperator = $this->getConditionOperator($operator);
388 | $sqlCondition = $this->connection->prepareSqlCondition($productIdentifierField, [$conditionOperator => self::FAKE_VALUE]);
389 | return str_replace(self::FAKE_VALUE, $conditionCategory, $sqlCondition);
390 | }
391 |
392 | return '';
393 | }
394 |
395 | /**
396 | * @return MetadataPool
397 | */
398 | protected function getMetadataPool()
399 | {
400 | return $this->metadataPool;
401 | }
402 |
403 | /**
404 | * Get product entity identifier field
405 | *
406 | * @return string
407 | * @throws \Exception
408 | */
409 | private function getProductIdentifierField()
410 | {
411 | if ($this->productEntityIdentifierField === null) {
412 | $this->productEntityIdentifierField = $this->getMetadataPool()
413 | ->getMetadata(ProductInterface::class)
414 | ->getIdentifierField();
415 | }
416 | return $this->productEntityIdentifierField;
417 | }
418 | }
419 |
--------------------------------------------------------------------------------
/Model/Rule.php:
--------------------------------------------------------------------------------
1 | combineFactory = $combineFactory;
103 | $this->actionCollectionFactory = $actionCollectionFactory;
104 | $this->storeManager = $storeManager;
105 | $this->imageUploader = $imageUploader;
106 | parent::__construct(
107 | $context,
108 | $registry,
109 | $formFactory,
110 | $localeDate,
111 | $resource,
112 | $resourceCollection,
113 | $data
114 | );
115 | }
116 |
117 | /**
118 | * Initialize resource model
119 | *
120 | * @return void
121 | */
122 | public function _construct()
123 | {
124 | $this->_init(RuleResourceModel::class);
125 | }
126 |
127 | /**
128 | * Getter for rule conditions collection
129 | *
130 | * @return \Magento\Rule\Model\Condition\Combine
131 | */
132 | public function getConditionsInstance()
133 | {
134 | return $this->combineFactory->create();
135 | }
136 |
137 | /**
138 | * @return \Magento\Rule\Model\Action\Collection
139 | */
140 | public function getActionsInstance()
141 | {
142 | return $this->actionCollectionFactory->create();
143 | }
144 |
145 | /**
146 | * @param string $formName
147 | * @return string
148 | */
149 | public function getConditionsFieldSetId($formName = '')
150 | {
151 | return $formName . 'rule_conditions_fieldset_' . $this->getId();
152 | }
153 |
154 | /**
155 | * @param string $formName
156 | * @return string
157 | */
158 | public function getActionsFieldSetId($formName = '')
159 | {
160 | $this->getActions();
161 | return $formName . 'rule_actions_fieldset_' . $this->getId();
162 | }
163 |
164 | /**
165 | * Return unique ID(s) for each object in system
166 | *
167 | * @return string[]
168 | */
169 | public function getIdentities()
170 | {
171 | $identities = [
172 | self::CACHE_TAG . '_' . $this->getId(),
173 | ];
174 |
175 | if (!$this->getId() || $this->isDeleted()) {
176 | $identities[] = self::CACHE_TAG;
177 | }
178 |
179 | return array_unique($identities);
180 | }
181 |
182 | /**
183 | * Get Title
184 | *
185 | * @return string|null
186 | * @since 1.0.0
187 | */
188 | public function getTitle()
189 | {
190 | return $this->_getData(self::TITLE);
191 | }
192 |
193 | /**
194 | * Set Title
195 | *
196 | * @param string $title
197 | *
198 | * @return $this
199 | * @since 1.0.0
200 | */
201 | public function setTitle($title)
202 | {
203 | return $this->setData(self::TITLE, $title);
204 | }
205 |
206 | /**
207 | * Get Type
208 | *
209 | * @return string|null
210 | * @since 1.0.0
211 | */
212 | public function getType()
213 | {
214 | return (int)$this->_getData(self::TYPE);
215 | }
216 |
217 | /**
218 | * Set Type
219 | *
220 | * @param string $type
221 | *
222 | * @return $this
223 | * @since 1.0.0
224 | */
225 | public function setType($type)
226 | {
227 | return $this->setData(self::TYPE, $type);
228 | }
229 |
230 | /**
231 | * Get Status
232 | *
233 | * @return boolean
234 | * @since 1.0.0
235 | */
236 | public function getStatus()
237 | {
238 | return (boolean)$this->_getData(self::STATUS);
239 | }
240 |
241 | /**
242 | * Set Status
243 | *
244 | * @param integer|boolean $status
245 | *
246 | * @return $this
247 | * @since 1.0.0
248 | */
249 | public function setStatus($status)
250 | {
251 | return $this->setData(self::STATUS, $status);
252 | }
253 |
254 | /**
255 | * Get Priority
256 | *
257 | * @return mixed
258 | * @since 1.0.0
259 | */
260 | public function getPriority()
261 | {
262 | return $this->_getData(self::PRIORITY);
263 | }
264 |
265 | /**
266 | * Set Priority
267 | *
268 | * @param integer $priority
269 | * @return $this
270 | */
271 | public function setPriority($priority)
272 | {
273 | return $this->setData(self::PRIORITY, $priority);
274 | }
275 |
276 | /**
277 | * Get Conditions Serialized
278 | *
279 | * @return mixed
280 | */
281 | public function getConditionsSerialized()
282 | {
283 | return $this->_getData(self::CONDITIONS_SERIALIZED);
284 | }
285 |
286 | /**
287 | * Set Conditions Serialized
288 | *
289 | * @param string $conditions
290 | * @return $this
291 | */
292 | public function setConditionsSerialized($conditions)
293 | {
294 | return $this->setData(self::CONDITIONS_SERIALIZED, $conditions);
295 | }
296 |
297 | /**
298 | * Display Label in Product List, Category
299 | *
300 | * @return boolean
301 | */
302 | public function isDisplayInCategory()
303 | {
304 | return (boolean)$this->_getData(self::DISPLAY_IN_CATEGORY);
305 | }
306 |
307 | /**
308 | * Set Display In Category
309 | *
310 | * @param boolean $isDisplay
311 | * @return $this
312 | */
313 | public function setDisplayInCategory($isDisplay)
314 | {
315 | return $this->setData(self::DISPLAY_IN_CATEGORY, $isDisplay);
316 | }
317 |
318 | /**
319 | * Get Category Type
320 | *
321 | * @return integer
322 | */
323 | public function getCategoryType()
324 | {
325 | return $this->_getData(self::CATEGORY_LABEL_TYPE);
326 | }
327 |
328 | /**
329 | * Set Category Type
330 | *
331 | * @param integer $type
332 | * @return $this
333 | */
334 | public function setCategoryType($type)
335 | {
336 | return $this->setData(self::CATEGORY_LABEL_TYPE, $type);
337 | }
338 |
339 | /**
340 | * Get Category Image
341 | *
342 | * @return mixed
343 | */
344 | public function getCategoryImage()
345 | {
346 | return $this->_getData(self::CATEGORY_IMAGE);
347 | }
348 |
349 | /**
350 | * Set Category Image
351 | *
352 | * @param string $image
353 | * @return mixed
354 | */
355 | public function setCategoryImage($image)
356 | {
357 | return $this->setData(self::CATEGORY_LABEL_TYPE, $image);
358 | }
359 |
360 | /**
361 | * Text Label in Category
362 | *
363 | * @return string
364 | */
365 | public function getCategoryText()
366 | {
367 | return $this->_getData(self::CAT_TEXT);
368 | }
369 |
370 | /**
371 | * Set Text label in Category
372 | *
373 | * @param string $text
374 | * @return $this
375 | */
376 | public function setCategoryText($text)
377 | {
378 | return $this->setData(self::CAT_TEXT, $text);
379 | }
380 |
381 | /**
382 | * Get Css Style in Category
383 | *
384 | * @return string
385 | */
386 | public function getCssStyleCategory()
387 | {
388 | return $this->_getData(self::CSS_STYLE_CATEGORY);
389 | }
390 |
391 | /**
392 | * Set Css Style in Category
393 | *
394 | * @param string $css
395 | * @return $this
396 | */
397 | public function setCssStyleCategory($css)
398 | {
399 | return $this->setData(self::CSS_STYLE_CATEGORY, $css);
400 | }
401 |
402 | /**
403 | * Display Label in Product List, Product
404 | *
405 | * @return boolean
406 | */
407 | public function isDisplayInProduct()
408 | {
409 | return (boolean)$this->_getData(self::DISPLAY_IN_PRODUCT);
410 | }
411 |
412 | /**
413 | * Set Display In Product
414 | *
415 | * @param boolean $isDisplay
416 | * @return $this
417 | */
418 | public function setDisplayInProduct($isDisplay)
419 | {
420 | return $this->setData(self::DISPLAY_IN_PRODUCT, $isDisplay);
421 | }
422 |
423 | /**
424 | * Get Product Type
425 | *
426 | * @return integer
427 | */
428 | public function getProductType()
429 | {
430 | return $this->_getData(self::PRODUCT_LABEL_TYPE);
431 | }
432 |
433 | /**
434 | * Set Product Type
435 | *
436 | * @param integer $type
437 | * @return $this
438 | */
439 | public function setProductType($type)
440 | {
441 | return $this->setData(self::PRODUCT_LABEL_TYPE, $type);
442 | }
443 |
444 | /**
445 | * Get Product Image
446 | *
447 | * @return mixed
448 | */
449 | public function getProductImage()
450 | {
451 | return $this->_getData(self::PRODUCT_IMAGE);
452 | }
453 |
454 | /**
455 | * Set Product Image
456 | *
457 | * @param string $image
458 | * @return mixed
459 | */
460 | public function setProductImage($image)
461 | {
462 | return $this->setData(self::PRODUCT_IMAGE, $image);
463 | }
464 |
465 | /**
466 | * Text Label in Product
467 | *
468 | * @return string
469 | */
470 | public function getProductText()
471 | {
472 | return $this->_getData(self::PRODUCT_TEXT);
473 | }
474 |
475 | /**
476 | * Set Text label in Product
477 | *
478 | * @param string $text
479 | * @return $this
480 | */
481 | public function setProductText($text)
482 | {
483 | return $this->setData(self::PRODUCT_TEXT, $text);
484 | }
485 |
486 | /**
487 | * Get Css Style in Product
488 | *
489 | * @return string
490 | */
491 | public function getCssStyleProduct()
492 | {
493 | return $this->_getData(self::CSS_STYLE_PRODUCT);
494 | }
495 |
496 | /**
497 | * Set Css Style in Product
498 | *
499 | * @param string $css
500 | * @return $this
501 | */
502 | public function setCssStyleProduct($css)
503 | {
504 | return $this->setData(self::CSS_STYLE_PRODUCT, $css);
505 | }
506 |
507 | /**
508 | * Get Category Position
509 | *
510 | * @return string
511 | */
512 | public function getCategoryPosition()
513 | {
514 | return $this->_getData(self::CATEGORY_POSITION);
515 | }
516 |
517 | /**
518 | * Set Category Position
519 | *
520 | * @param $pos
521 | * @return $this
522 | */
523 | public function setCategoryPosition($pos)
524 | {
525 | return $this->setData(self::CATEGORY_POSITION, $pos);
526 | }
527 |
528 | /**
529 | * Get Product Position
530 | *
531 | * @return string
532 | */
533 | public function getProductPosition()
534 | {
535 | return $this->_getData(self::PRODUCT_POSITION);
536 | }
537 |
538 | /**
539 | * Set Product Position
540 | *
541 | * @param $pos
542 | * @return $this
543 | */
544 | public function setProductPosition($pos)
545 | {
546 | return $this->setData(self::PRODUCT_POSITION, $pos);
547 | }
548 |
549 | /**
550 | * @return boolean
551 | */
552 | public function isUseImageInList()
553 | {
554 | return $this->getCategoryType() == LabelType::IMAGE_TYPE;
555 | }
556 |
557 | /**
558 | * @return boolean
559 | */
560 | public function isUseImageInProduct()
561 | {
562 | return $this->getProductType() == LabelType::IMAGE_TYPE;
563 | }
564 |
565 | /**
566 | * Label Image in Product Listing
567 | *
568 | * @return boolean|string
569 | * @throws \Magento\Framework\Exception\NoSuchEntityException
570 | */
571 | public function getCategoryImageUrl()
572 | {
573 | return $this->imageUploader->getImageUrl($this->getCategoryImage());
574 | }
575 |
576 | /**
577 | * Label Image in Product Page
578 | *
579 | * @return boolean|string
580 | * @throws \Magento\Framework\Exception\NoSuchEntityException
581 | */
582 | public function getProductImageUrl()
583 | {
584 | return $this->imageUploader->getImageUrl($this->getProductImage());
585 | }
586 |
587 | /**
588 | * Get Additional Class
589 | *
590 | * @return string
591 | */
592 | public function getAdditionalClass()
593 | {
594 | $type = $this->getType();
595 | $types = Type::getOptionArray();
596 | $additionalClass = '';
597 | if (!empty($types[$type])) {
598 | $additionalClass = str_replace(' ', '-', strtolower($types[$type]));
599 | }
600 |
601 | return $additionalClass;
602 | }
603 | }
604 |
--------------------------------------------------------------------------------