Seeing as how there's no clear answer on this yet, this might help some people. To add an e-mail field (or any other field) to the frontend review form and display it in the admin we have to create a custom module.
With this module we'll:
- Create a custom field in the database
- Save data
- Display in the admin
NOTE: Be sure to replace "Vendor" with your desired vendor name.
app\code\Vendor\ReviewEmail\registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_ReviewEmail',
__DIR__
);
app\code\Vendor\ReviewEmail\etc\module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Vendor_ReviewEmail" setup_version="1.0.0">
<sequence>
<module name="Magento_Review" />
</sequence>
</module>
</config>
app\code\Vendor\ReviewEmail\etc\di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Review\Block\Adminhtml\Edit\Form">
<plugin name="modify_review_edit_form" type="Vendor\ReviewEmail\Plugin\Magento\Review\Block\Adminhtml\Edit\Form" />
</type>
</config>
app\code\Vendor\ReviewEmail\etc\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='review_save_after'>
<observer name='vendor_reviewemail_save_after' instance='Vendor\ReviewEmail\Model\Observer\ReviewSave'/>
</event>
</config>
app\code\Vendor\ReviewEmail\Setup\InstallSchema.php
<?php
namespace Vendor\ReviewEmail\Setup;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
/**
* @codeCoverageIgnore
*/
class InstallSchema implements InstallSchemaInterface
{
/**
* {@inheritdoc}
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$installer = $setup;
$installer->startSetup();
$installer->getConnection()->addColumn(
$installer->getTable('review_detail'),
'email',
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 255,
'nullable' => true,
'comment' => 'Email address'
]
);
$setup->endSetup();
}
}
app\code\Vendor\ReviewEmail\Model\Observer\ReviewSave.php
<?php
namespace Vendor\ReviewEmail\Model\Observer;
use Magento\Framework\Event\ObserverInterface;
class ReviewSave implements ObserverInterface
{
public function __construct(
\Magento\Framework\App\ResourceConnection $resource
) {
$this->_resource = $resource;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$review = $observer->getEvent()->getDataObject();
$connection = $this->_resource;
$tableName = $connection->getTableName('review_detail');
$detail = [
'email' => $review->getEmail(),
];
if (empty($review->getEmail())) return;
$select = $connection->getConnection()->select()->from($tableName)->where('review_id = :review_id');
$detailId = $connection->getConnection()->fetchOne($select, [':review_id' => $review->getId()]);
if ($detailId) {
$condition = ["detail_id = ?" => $detailId];
$connection->getConnection()->update($tableName, $detail, $condition);
} else {
$detail['store_id'] = $review->getStoreId();
$detail['customer_id'] = $review->getCustomerId();
$detail['review_id'] = $review->getId();
$connection->getConnection()->insert($tableName, $detail);
}
}
}
app\code\Vendor\ReviewEmail\Plugin\Magento\Review\Block\Adminhtml\Edit\Form.php
<?php
namespace Vendor\ReviewEmail\Plugin\Magento\Review\Block\Adminhtml\Edit;
class Form extends \Magento\Review\Block\Adminhtml\Edit\Form
{
public function beforeSetForm(\Magento\Review\Block\Adminhtml\Edit\Form $object, $form) {
$review = $object->_coreRegistry->registry('review_data');
$fieldset = $form->addFieldset(
'review_details_extra',
['legend' => __('Review Details Extra Data'), 'class' => 'fieldset-wide']
);
$fieldset->addField(
'email',
'text',
['label' => __('E-mail'), 'required' => false, 'name' => 'email']
);
$form->setValues($review->getData());
return [$form];
}
}
app\code\Vendor\ReviewEmail\view\adminhtml\ui_component\review_listing.xml (Optional, only if you want to show the field in the admin grid as well)
<?xml version="1.0" encoding="UTF-8"?>
<listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<columns name="review_columns">
<column name="email">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="filter" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">E-mail</item>
<item name="sortOrder" xsi:type="number">45</item>
<item name="truncate" xsi:type="number">50</item>
<item name="nl2br" xsi:type="boolean">true</item>
<item name="escape" xsi:type="boolean">true</item>
</item>
</argument>
</column>
</columns>
</listing>
After this all we have left to do is add the field to the review form.
In app\design\frontend\Vendor\yourtheme\Magento_Review\templates\form.phtml
<input type="text" name="email" id="email_field" class="block mb2 full-width validate-email" data-validate="{required:true}"/>
Make sure to add this between the form tags.
After installing the module and clearing your caches you should now have an e-mail field in your review form. Which should be visible in the admin grid and admin review detail view.