There is a custom tab “Ask Question” in a product that has a form (it has a logic for saving data to the database).
My task is to create an event observer for the attribute that I have created programmatically via Setup/Patch/Data and remove the tab if the value is set to “No” (“Yes” is the default).
This is my observer:
<?php
namespace AlexAskQuestionObserver;
use MagentoFrameworkEventObserver;
use MagentoFrameworkEventObserverInterface;
use MagentoCatalogModelProduct;
class AddQuestionTab implements ObserverInterface
{
/**
* @param Observer $observer
* @return void
*/
public function execute(Observer $observer)
{
/** @var Product $product */
$product = $observer->getEvent()->getData('product');
// Check if the product has the "allow_to_ask_questions" attribute set to "No"
if ($product->getData('allow_to_ask_questions') === 0) {
// Remove the "Ask a Question" tab from the layout
$layout = $observer->getData('layout');
$layout->getUpdate()->addHandle('ask_question_form');
}
}
}
events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="catalog_product_save_after">
<observer name="askquestion_tab"
instance="AlexAskQuestionObserverAddQuestionTab"
/>
</event>
<event name="controller_action_predispatch_catalog_product_view">
<observer name="alex_ask_question"
instance="AlexAskQuestionObserverCatalogControllerProductViewPredispatch"
/>
</event>
<event name="catalog_product_load_after">
<observer name="alex_ask_question"
instance="AlexAskQuestionObserverCatalogModelProductLoadAfter"
/>
</event>
</config>
catalog_product_view.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="ask_question_form"/>
<body>
<referenceBlock name="product.info.details">
<block class="MagentoCatalogBlockProductView"
name="ask.question.tab"
as="ask.question"
template="Alex_AskQuestion::product/view/ask_question.phtml"
group="detailed_info">
<arguments>
<argument translate="true" name="title" xsi:type="string">Ask a question</argument>
</arguments>
<block class="AlexAskQuestionBlockQuestions"
name="question.list"
template="Alex_AskQuestion::product/view/questions_list.phtml">
<arguments>
<argument name="limit" xsi:type="number">20</argument>
</arguments>
</block>
</block>
</referenceBlock>
</body>
</page>
Installer
<?php
namespace AlexAskQuestionSetupPatchData;
use MagentoCatalogModelProduct;
use MagentoCatalogModelProductAttributeSourceBoolean;
use MagentoEavModelEntityAttributeScopedAttributeInterface;
use MagentoEavSetupEavSetup;
use MagentoEavSetupEavSetupFactory;
use MagentoFrameworkExceptionLocalizedException;
use MagentoFrameworkSetupModuleDataSetupInterface;
use MagentoFrameworkSetupPatchDataPatchInterface;
use MagentoFrameworkValidatorValidateException;
class AddAskQuestionAttribute implements DataPatchInterface
{
/**
* @var ModuleDataSetupInterface
*/
private $moduleDataSetup;
/**
* @var EavSetupFactory
*/
private $eavSetupFactory;
/**
* AddAskQuestionAttribute constructor.
*
* @param ModuleDataSetupInterface $moduleDataSetup
* @param EavSetupFactory $eavSetupFactory
*/
public function __construct(ModuleDataSetupInterface $moduleDataSetup, EavSetupFactory $eavSetupFactory)
{
$this->moduleDataSetup = $moduleDataSetup;
$this->eavSetupFactory = $eavSetupFactory;
}
/**
* @return void
* @throws LocalizedException
* @throws ValidateException
*/
public function apply()
{
/** @var EavSetup $eavSetup */
$eavSetup = $this->eavSetupFactory->create(['setup' => $this->moduleDataSetup]);
$eavSetup->addAttribute(
Product::ENTITY,
'allow_to_ask_questions',
[
'type' => 'int',
'backend' => '',
'frontend' => '',
'label' => 'Allow to ask question',
'input' => 'select',
'class' => '',
'source' => Boolean::class,
'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
'visible' => true,
'required' => true,
'sort_order' => 90,
'user_defined' => false,
'default' => '1',
'searchable' => false,
'filterable' => false,
'comparable' => false,
'visible_on_front' => false,
'used_in_product_listing' => true,
'unique' => false,
'apply_to' => ''
]
);
}
/**
* @return array|string[]
*/
public static function getDependencies(): array
{
return [];
}
/**
* @return array|string[]
*/
public function getAliases(): array
{
return [];
}
/**
* @return string
*/
public static function getVersion(): string
{
return '1.0.1';
}
}