Comment implémenter un système d'avis personnalisé dans Magento 2
Why You Might Need a Custom Review System in Magento 2
Magento 2 comes with a built-in product avis system, but sometimes it just doesn’t cut it. Maybe you need extra champs, a different note system, or tighter moderation controls. That’s where a custom avis system comes in handy.
Dans ce guide, nous’ll walk through comment build a custom avis module à partir de zéro. No fluff, just clear étapes and code exemples to get you up and running.
Setting Up the Basic Module Structure
Premièrement, let’s create our module skeleton. Place this in app/code/Magefine/CustomReviews:
app/code/Magefine/CustomReviews/
├── etc/
│ ├── module.xml
│ ├── db_schema.xml
│ └── frontend/
│ └── routes.xml
├── registration.php
└── composer.json
Here’s what goes in registration.php:
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Magefine_CustomReviews',
__DIR__
);
And your 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="Magefine_CustomReviews" setup_version="1.0.0">
<sequence>
<module name="Magento_Review"/>
</sequence>
</module>
</config>
Creating the Database Tables
We’ll need a table to store our custom avis data. Add this to db_schema.xml:
<?xml version="1.0"?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="magefine_custom_reviews" resource="default" engine="innodb" comment="Custom Reviews Table">
<column xsi:type="int" name="review_id" padding="10" unsigned="true" nullable="false" identity="true" comment="Review ID"/>
<column xsi:type="int" name="parent_review_id" padding="10" unsigned="true" nullable="false" comment="Original Review ID"/>
<column xsi:type="varchar" name="custom_field" nullable="true" length="255" comment="Custom Field Example"/>
<column xsi:type="smallint" name="custom_rating" padding="5" unsigned="true" nullable="true" comment="Additional Rating"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="review_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="MAGEFINE_CUSTOM_REVIEWS_PARENT_ID_REVIEW_REVIEW_ID" table="magefine_custom_reviews" column="parent_review_id" referenceTable="review" referenceColumn="review_id" onDelete="CASCADE"/>
</table>
</schema>
Extending the Review Model
Now let’s create our custom avis model. Premièrement, the classe de modèle at Model/Review.php:
<?php
namespace Magefine\CustomReviews\Model;
class Review extends \Magento\Review\Model\Review
{
protected function _construct()
{
parent::_construct();
$this->_init('Magefine\CustomReviews\Model\ResourceModel\Review');
}
public function getCustomField()
{
return $this->getData('custom_field');
}
public function getCustomRating()
{
return $this->getData('custom_rating');
}
}
And its resource model at Model/ResourceModel/Review.php:
<?php
namespace Magefine\CustomReviews\Model\ResourceModel;
class Review extends \Magento\Review\Model\ResourceModel\Review
{
protected function _construct()
{
$this->_init('review', 'review_id');
}
protected function _afterLoad(\Magento\Framework\Model\AbstractModel $object)
{
$connection = $this->getConnection();
$select = $connection->select()
->from($this->getTable('magefine_custom_reviews'))
->where('parent_review_id = ?', $object->getId());
$customData = $connection->fetchRow($select);
if ($customData) {
$object->addData($customData);
}
return parent::_afterLoad($object);
}
}
Creating the Admin Form
To let admins see our custom champs, we need to extend the avis edit form. Create view/adminhtml/ui_component/review_form.xml:
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="review_details">
<field name="custom_field">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">text</item>
<item name="label" xsi:type="string" translate="true">Custom Field</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">review</item>
<item name="dataScope" xsi:type="string">custom_field</item>
</item>
</argument>
</field>
<field name="custom_rating">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="dataType" xsi:type="string">number</item>
<item name="label" xsi:type="string" translate="true">Additional Rating</item>
<item name="formElement" xsi:type="string">input</item>
<item name="validation" xsi:type="array">
<item name="validate-number" xsi:type="boolean">true</item>
<item name="validate-greater-than-zero" xsi:type="boolean">true</item>
<item name="validate-less-than-equal-ten" xsi:type="boolean">true</item>
</item>
<item name="source" xsi:type="string">review</item>
<item name="dataScope" xsi:type="string">custom_rating</item>
</item>
</argument>
</field>
</fieldset>
</form>
Frontend Display
To show our custom data on the frontend, we’ll need to override the avis templates. Premièrement, create a layout update at view/frontend/layout/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">
<body>
<referenceBlock name="reviews.tab">
<action method="setTemplate">
<argument name="template" xsi:type="string">Magefine_CustomReviews::product/view/review.phtml</argument>
</action>
</referenceBlock>
</body>
</page>
Then create the template at view/frontend/templates/product/view/review.phtml:
<?php
/** @var \Magento\Review\Block\Product\Review $block */
/** @var \Magento\Framework\Escaper $escaper */
?>
<div id="product-review-container" data-role="product-review"></div>
<?= $block->getChildHtml() ?>
<script type="text/x-magento-init">
{
"*": {
"Magento_Review/js/process-reviews": {
"productReviewUrl": "<?= $block->escapeJs($block->getProductReviewUrl()) ?>",
"reviewsTabSelector": "#tab-label-reviews"
}
}
}
</script>
<!-- Our custom review display -->
<div class="custom-review-fields">
<?php foreach ($block->getReviewsCollection() as $review): ?>
<?php if ($review->getCustomField() || $review->getCustomRating()): ?>
<div class="custom-review-item">
<?php if ($review->getCustomField()): ?>
<p class="custom-field"><?= $escaper->escapeHtml($review->getCustomField()) ?></p>
<?php endif; ?>
<?php if ($review->getCustomRating()): ?>
<div class="custom-rating">
<span>Additional Rating: <?= (int)$review->getCustomRating() ?>/10</span>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
Saving Custom Data
Nous devons save our custom champs when a avis is submitted. Create an observateur at Observer/SaveCustomReviewData.php:
<?php
namespace Magefine\CustomReviews\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
class SaveCustomReviewData implements ObserverInterface
{
protected $resourceConnection;
public function __construct(
\Magento\Framework\App\ResourceConnection $resourceConnection
) {
$this->resourceConnection = $resourceConnection;
}
public function execute(Observer $observer)
{
$review = $observer->getEvent()->getObject();
$request = $observer->getEvent()->getRequest();
$customData = [
'parent_review_id' => $review->getId(),
'custom_field' => $request->getParam('custom_field'),
'custom_rating' => $request->getParam('custom_rating')
];
$connection = $this->resourceConnection->getConnection();
$connection->insertOnDuplicate(
$this->resourceConnection->getTableName('magefine_custom_reviews'),
$customData,
['custom_field', 'custom_rating']
);
}
}
Register this observateur in 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="magefine_custom_reviews_save" instance="Magefine\CustomReviews\Observer\SaveCustomReviewData"/>
</event>
</config>
Adding Custom Fields to the Review Form
Enfin, let’s add our custom champs to the client avis form. Create view/frontend/layout/review_product_list.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">
<body>
<referenceBlock name="product.review.form">
<block class="Magento\Review\Block\Form" name="product.review.form.custom.fields" template="Magefine_CustomReviews::form/custom_fields.phtml"/>
</referenceBlock>
</body>
</page>
And the template at view/frontend/templates/form/custom_fields.phtml:
<div class="field custom-field">
<label for="custom_field" class="label"><span><?= $block->escapeHtml(__('Custom Feedback')) ?></span></label>
<div class="control">
<textarea name="custom_field" id="custom_field" cols="5" rows="3" class="input-text"></textarea>
</div>
</div>
<div class="field custom-rating">
<label for="custom_rating" class="label"><span><?= $block->escapeHtml(__('Additional Rating (1-10)')) ?></span></label>
<div class="control">
<input type="number" name="custom_rating" id="custom_rating" min="1" max="10" class="input-text"/>
</div>
</div>
Testing Your Custom Review System
Après setting up everything:
- Run
bin/magento setup:upgrade - Clear cache with
bin/magento cache:clean - Submit a test avis on a page produit
- Check the panneau d'administration to see if your custom champs appear
- Verify the frontend display shows your custom data
If everything works, congratulations! You’ve successfully implemented a custom avis system in Magento 2.
Réflexions finales
Building a custom avis system vous donne the flexibility to collect exactly the feedback you need from clients. Tandis que this exemple covers basic custom champs, you could extend it further with:
- Photo/video uploads in avis
- Review verification badges
- Custom moderation flux de travails
- Advanced filtreing options
Remember to always back up your store before making core changes, and consider using our Magefine extensions for ready-made solutions that save development time.