Magento – Magento2 product review captcha

layoutmagento2overrides

I want to rewrite Magento-review layout catalog_product_view.xml to show Recaptcha on a product review. How can I achieve this?

Best Answer

Note: I assume that you are okay with modifying Msp Recaptcha module.

Step 1: Open /vendor/msp/recaptcha/etc/adminhtml/system.xml and paste below code before </group> tag

<field id="enabled_review" translate="label" type="select" sortOrder="230" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
    <label>Use in Product Review</label>
    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
    <depends>
        <field id="enabled">1</field>
    </depends>
</field>

This will add review page option in the reCaptcha settings.

Step 2: Create new file under /vendor/msp/recaptcha/view/frontend/layout/catalog_product_view.xml and paste below code

<?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="review_product_form_component"/>
    <body>
        <referenceContainer name="form.additional.info">
            <block class="MSP\ReCaptcha\Block\Frontend\ReCaptcha" name="msp-recaptcha" after="-"
                   template="MSP_ReCaptcha::msp_recaptcha.phtml">

                <arguments>
                    <argument name="jsLayout" xsi:type="array">
                        <item name="components" xsi:type="array">
                            <item name="msp-recaptcha" xsi:type="array">
                                <item name="component" xsi:type="string">MSP_ReCaptcha/js/reCaptcha</item>
                                <item name="zone" xsi:type="string">review</item>
                            </item>
                        </item>
                    </argument>
                </arguments>
            </block>
        </referenceContainer>
    </body>
</page>

Step 3: Override form.phtml by editing /vendor/msp/recaptcha/etc/frontend/di.xml file.

Add the following code in di.xml file (just before </config> tag) mentioned above to override template file.

<type name="Magento\Review\Block\Form">
    <plugin name="review-form-override" type="MSP\ReCaptcha\Plugin\Block\Review\Form" />
</type>

Step 4: Create a block file /vendor/msp/recaptcha/Plugin/Block/Review/Form.php and paste below code:

<?php
namespace MSP\ReCaptcha\Plugin\Block\Review;

class Form
{
    public function beforeToHtml(\Magento\Review\Block\Form $block)
    {
        $block->setTemplate('MSP_ReCaptcha::review/form.phtml');
    }
}

Step 5: Edit /vendor/msp/recaptcha/Model/LayoutSettings.php file and add the following line just after 'contact' => $this->config->isEnabledFrontendContact(),:

'review' => $this->config->isEnabledFrontendReview(),

Step 6: Edit /vendor/msp/recaptcha/Model/Config.php file and define the following constant where other constants have been defined:

const XML_PATH_ENABLED_FRONTEND_REVIEW = 'msp_securitysuite_recaptcha/frontend/enabled_review';

Step 7: In the same file (/vendor/msp/recaptcha/Model/Config.php) add the following function just before closing braces of class:

public function isEnabledFrontendReview()
{
    if (!$this->isEnabledFrontend()) {
        return false;
    }

    return (bool) $this->scopeConfig->getValue(static::XML_PATH_ENABLED_FRONTEND_REVIEW);
 }

Step 8: Now copy form.phtml file from /vendor/magento/module-review/view/frontend/templates and paste it into /vendor/msp/recaptcha/view/frontend/templates/review folder.

then

Step 9: Add the following code in the form.phtml file under /vendor/msp/recaptcha/view/frontend/templates/review folder:

<?= $block->getChildHtml('form_additional_info') ?>

Above code should be pasted just before the following:

</fieldset>
<div class="actions-toolbar review-form-actions">

This will add the reCaptcha in the review form.

If you want code for validation of captcha also, please let me know. I will update soon.

Update: Steps for reCaptcha validation

Since this module is validating reCaptcha using /vendor/msp/recaptcha/Observer/ReCaptchaObserver.php, I tried to find call to this observer, but could not find direct call to this observer.

But I found definition of validation observers in /vendor/msp/recaptcha/etc/frontend/events.xml, so follow from step 10 now.

Step 10: Edit /vendor/msp/recaptcha/etc/frontend/events.xml and add below code just before </config> tag:

<event name="controller_action_predispatch_review_product_post">
    <observer name="msp_captcha" instance="MSP\ReCaptcha\Observer\Frontend\ReviewFormObserver" />
</event>

The observer classes defined in /vendor/msp/recaptcha/etc/frontend/events.xml file don't exist. Instead they are being replaced by virtualType.

Step 11: Add the follwoing code just before </config> tag in /vendor/msp/recaptcha/etc/frontend/di.xml:

<virtualType name="MSP\ReCaptcha\Observer\Frontend\ReviewFormObserver"
                 type="MSP\ReCaptcha\Observer\ReCaptchaObserver">
        <arguments>
            <argument name="isCheckRequired"
                      xsi:type="object">MSP\ReCaptcha\Model\Provider\IsCheckRequired\Frontend\ReviewForm</argument>
            <argument name="failureProvider"
                      xsi:type="object">MSP\ReCaptcha\Model\Provider\Failure\ReviewFormObserver</argument>
        </arguments>
    </virtualType>

    <virtualType name="MSP\ReCaptcha\Model\Provider\Failure\ReviewFormObserver"
                 type="MSP\ReCaptcha\Model\Provider\Failure\ObserverRedirectFailure">
        <arguments>
            <argument name="redirectUrlProvider"
                      xsi:type="object">MSP\ReCaptcha\Model\Provider\Failure\RedirectUrl\ReviewForm</argument>
        </arguments>
    </virtualType>

    <virtualType name="MSP\ReCaptcha\Model\Provider\IsCheckRequired\Frontend\ReviewForm"
                 type="MSP\ReCaptcha\Model\IsCheckRequired">
        <arguments>
            <argument name="enableConfigFlag"
                      xsi:type="string">msp_securitysuite_recaptcha/frontend/enabled_review</argument>
            <argument name="area" xsi:type="string">frontend</argument>
        </arguments>
    </virtualType>

    <virtualType name="MSP\ReCaptcha\Model\Provider\Failure\RedirectUrl\ReviewForm"
                 type="MSP\ReCaptcha\Model\Provider\Failure\RedirectUrl\SimpleUrlProvider">
        <arguments>
            <argument name="urlPath" xsi:type="string">cms/index/index</argument>
        </arguments>
    </virtualType>

Now the only problem remaining is redirecting to correct URL if reCaptcha validation fails. Currently I have redirected to cms/index/index action.

Please share the code if you get success in redirecting to the product URL on which the user filled the review.

Please let me know if you have any query.