Commit 0831ffd6 by lmf

详情页面优化图片位置

parent 2f68d974
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "magento/theme-frontend-joshine",
"description": "N/A",
"config": {
"sort-packages": true
},
"require": {
"php": "~7.2.0||~7.3.0",
"magento/framework": "*",
"magento/theme-frontend-blank": "*"
},
"type": "magento2-theme",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"autoload": {
"files": [
"registration.php"
]
}
}
<?xml version="1.0"?>
<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
<media>
<images module="Magento_Catalog">
<!-- Image demensions and srcsets -->
<image id="category_page_grid" type="small_image">
<width>300</width>
<height>375</height>
</image>
<image id="category_page_grid-srcset-1" type="small_image">
<width>600</width>
<height>750</height>
</image>
</images>
</media>
<vars module="Magento_Catalog">
<var name="gallery">
<!-- Gallery settings -->
<var name="allowfullscreen">true</var>
<var name="keyboard">true</var>
<var name="loop">true</var>
<var name="nav">true</var>
<var name="navdir">horizontal</var>
</var>
</vars>
<vars module="Swissup_Breeze">
<!-- Breeze module settings -->
<var name="enabled">1</var>
<var name="turbo">1</var>
<var name="responsive_images">1</var>
<!-- Image sizes to use per screen size -->
<var name="sizes">
<var name="category_page_grid">...</var>
<var name="category_page_grid-1column">...</var>
</var>
</vars>
</view>
<!--
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
<title>Joshine Theme</title>
<parent>Swissup/breeze-blank</parent>
<media>
<preview_image>media/preview.jpg</preview_image>
</media>
</theme>
...@@ -78,7 +78,8 @@ ...@@ -78,7 +78,8 @@
"phpseclib/mcrypt_compat": "1.0.8", "phpseclib/mcrypt_compat": "1.0.8",
"phpseclib/phpseclib": "2.0.*", "phpseclib/phpseclib": "2.0.*",
"ramsey/uuid": "~4.1.0", "ramsey/uuid": "~4.1.0",
"swissup/breeze-blank": "1.1.7", "rltsquare/product-review-images": "1.0.6",
"swissup/breeze-blank": "1.2.0",
"symfony/console": "~4.4.0", "symfony/console": "~4.4.0",
"symfony/event-dispatcher": "~4.4.0", "symfony/event-dispatcher": "~4.4.0",
"symfony/process": "~4.4.0", "symfony/process": "~4.4.0",
......
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Block\Adminhtml\Edit;
use Magento\Backend\Block\Template\Context;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\ProductFactory;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\Data\FormFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Registry;
use Magento\Review\Helper\Data;
use Magento\Store\Model\System\Store;
use Magento\Framework\Escaper;
/**
* Class Form
*
* @package RLTSquare\ProductReviewImages\Block\Adminhtml\Edit
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class Form extends \Magento\Review\Block\Adminhtml\Edit\Form
{
/**
* Review data
*
* @var Data
*/
protected Data $reviewData;
/**
* @var CustomerRepositoryInterface
*/
protected $customerRepository;
/**
* Catalog product factory
*
* @var ProductFactory
*/
protected ProductFactory $productFactory;
/**
* Catalog product factory
*
* @var ProductRepositoryInterface
*/
protected ProductRepositoryInterface $productRepository;
/**
* Core system store model
*
* @var Store
*/
protected Store $systemStore;
/**
*
* @var Escaper $escaper
*/
protected Escaper $escape;
/**
* @param Context $context
* @param Registry $registry
* @param FormFactory $formFactory
* @param Store $systemStore
* @param CustomerRepositoryInterface $customerRepository
* @param ProductFactory $productFactory
* @param Data $reviewData
* @param ProductRepositoryInterface $productRepository
* @param Escaper $escape
* @param array $data
*/
public function __construct(
Context $context,
Registry $registry,
FormFactory $formFactory,
Store $systemStore,
CustomerRepositoryInterface $customerRepository,
ProductFactory $productFactory,
Data $reviewData,
ProductRepositoryInterface $productRepository,
Escaper $escape,
array $data = []
) {
$this->reviewData = $reviewData;
$this->customerRepository = $customerRepository;
$this->productFactory = $productFactory;
$this->systemStore = $systemStore;
$this->productRepository = $productRepository;
$this->escape = $escape;
parent::__construct($context, $registry, $formFactory,$systemStore,$customerRepository, $productFactory,$reviewData,$data);
}
/**
* override,
* add custom fieldsets in form
*
* @return $this
* @throws LocalizedException
*/
protected function _prepareForm(): Form
{
$review = $this->_coreRegistry->registry('review_data');
$product = $this->productRepository->getById($review->getEntityPkValue());
$form = $this->_formFactory->create(
[
'data' => [
'id' => 'edit_form',
'action' => $this->getUrl(
'review/*/save',
[
'id' => $this->getRequest()->getParam('id'),
'ret' => $this->_coreRegistry->registry('ret')
]
),
'method' => 'post'
],
]
);
$fieldset = $form->addFieldset(
'review_details',
['legend' => __('Review Details'), 'class' => 'fieldset-wide']
);
$fieldset->addField(
'product_name',
'note',
[
'label' => __('Product'),
'text' => '<a href="' . $this->getUrl(
'catalog/product/edit',
['id' => $product->getId()]
) . '" onclick="this.target=\'blank\'">' . $this->escapeHtml(
$product->getName()
) . '</a>'
]
);
try {
$customer = $this->customerRepository->getById($review->getCustomerId());
$customerText = __(
'<a href="%1" onclick="this.target=\'blank\'">%2 %3</a> <a href="mailto:%4">(%4)</a>',
$this->getUrl('customer/index/edit', ['id' => $customer->getId(), 'active_tab' => 'review']),
$this->escape->escapeHtml($customer->getFirstname()),
$this->escape->escapeHtml($customer->getLastname()),
$this->escape->escapeHtml($customer->getEmail())
);
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
$customerText = ($review->getStoreId() == \Magento\Store\Model\Store::DEFAULT_STORE_ID)
? __('Administrator') : __('Guest');
}
$fieldset->addField('customer', 'note', ['label' => __('Author'), 'text' => $customerText]);
$fieldset->addField(
'summary-rating',
'note',
[
'label' => __('Summary Rating'),
'text' => $this->getLayout()->createBlock(
\Magento\Review\Block\Adminhtml\Rating\Summary::class
)->toHtml()
]
);
$fieldset->addField(
'detailed-rating',
'note',
[
'label' => __('Detailed Rating'),
'required' => true,
'text' => '<div id="rating_detail">' . $this->getLayout()->createBlock(
\Magento\Review\Block\Adminhtml\Rating\Detailed::class
)->toHtml() . '</div>'
]
);
$fieldset->addField(
'status_id',
'select',
[
'label' => __('Status'),
'required' => true,
'name' => 'status_id',
'values' => $this->_reviewData->getReviewStatusesOptionArray()
]
);
/**
* Check is single store mode
*/
if (!$this->_storeManager->hasSingleStore()) {
$field = $fieldset->addField(
'select_stores',
'multiselect',
[
'label' => __('Visibility'),
'required' => true,
'name' => 'stores[]',
'values' => $this->systemStore->getStoreValuesForForm()
]
);
$renderer = $this->getLayout()->createBlock(
\Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element::class
);
$field->setRenderer($renderer);
$review->setSelectStores($review->getStores());
} else {
$fieldset->addField(
'select_stores',
'hidden',
['name' => 'stores[]', 'value' => $this->_storeManager->getStore(true)->getId()]
);
$review->setSelectStores($this->_storeManager->getStore(true)->getId());
}
$fieldset->addField(
'nickname',
'text',
['label' => __('Nickname'), 'required' => true, 'name' => 'nickname']
);
$fieldset->addField(
'title',
'text',
['label' => __('Summary of Review'), 'required' => true, 'name' => 'title']
);
$fieldset->addField(
'detail',
'textarea',
['label' => __('Review'), 'required' => true, 'name' => 'detail', 'style' => 'height:24em;']
);
$fieldset->addField(
'review-media',
'note',
[
'label' => __('Review Media'),
'text' => $this->getLayout()->createBlock(
\RLTSquare\ProductReviewImages\Block\Adminhtml\Edit\Media::class
)->toHtml()
]
);
$fieldset->addField(
'deleted_media',
'text',
[
'name' => 'deleted_media',
'style' => 'visibility:hidden;'
]
);
$form->setUseContainer(true);
$form->setValues($review->getData());
$this->setForm($form);
return \Magento\Backend\Block\Widget\Form::_prepareForm();
}
}
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Block\Adminhtml\Edit;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Exception\NoSuchEntityException;
use RLTSquare\ProductReviewImages\Model\ResourceModel\ReviewMedia\CollectionFactory;
/**
* Class Media
*
* @package RLTSquare\ProductReviewImages\Block\Adminhtml\Edit
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class Media extends \Magento\Backend\Block\Template
{
/**
* @var CollectionFactory
*/
protected CollectionFactory $collectionFactory;
/**
* Media constructor
*
* \Magento\Backend\Block\Template\Context $context
* @param Context $context
* @param CollectionFactory $collectionFactory
*/
public function __construct(
Context $context,
CollectionFactory $collectionFactory
)
{
$this->collectionFactory = $collectionFactory;
$this->setTemplate("media.phtml");
parent::__construct($context);
}
/**
* function
* get media collection for a review
*
* @return object
*/
public function getMediaCollection(): object
{
return $this->collectionFactory->create()->addFieldToFilter('review_id', $this->getRequest()->getParam('id'));
}
/**
* function
* get review_images directory path
*
* @return string
* @throws NoSuchEntityException
*/
public function getReviewMediaUrl(): string
{
return $this->_storeManager->getStore()
->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'review_images';
}
}
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Block;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Customer\Model\Url;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Serialize\Serializer\Json;
use Magento\Framework\Url\EncoderInterface;
use Magento\Framework\View\Element\Template\Context;
use Magento\Review\Helper\Data;
use Magento\Review\Model\RatingFactory;
/**
* Class Form
*
* @package RLTSquare\ProductReviewImages\Block
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class Form extends \Magento\Review\Block\Form
{
/**
* Form constructor.
* @param Context $context
* @param EncoderInterface $urlEncoder
* @param Data $reviewData
* @param ProductRepositoryInterface $productRepository
* @param RatingFactory $ratingFactory
* @param ManagerInterface $messageManager
* @param \Magento\Framework\App\Http\Context $httpContext
* @param Url $customerUrl
* @param array $data
* @param Json|null $serializer
*/
public function __construct(
Context $context,
EncoderInterface $urlEncoder,
Data $reviewData,
ProductRepositoryInterface $productRepository,
RatingFactory $ratingFactory,
ManagerInterface $messageManager,
\Magento\Framework\App\Http\Context $httpContext,
Url $customerUrl,
array $data = [],
Json $serializer = null
)
{
parent::__construct($context, $urlEncoder, $reviewData, $productRepository, $ratingFactory, $messageManager, $httpContext, $customerUrl, $data, $serializer);
}
protected function _construct()
{
parent::_construct();
$this->setTemplate('RLTSquare_ProductReviewImages::form.phtml');
}
}
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Block\Product\View;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Json\EncoderInterface as JsonEncoderInterface;
use Magento\Catalog\Block\Product\Context;
use Magento\Catalog\Helper\Product;
use Magento\Catalog\Model\ProductTypes\ConfigInterface;
use Magento\Customer\Model\Session;
use Magento\Framework\Locale\FormatInterface;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\Framework\Stdlib\StringUtils;
use Magento\Framework\Url\EncoderInterface;
use Magento\Review\Model\ResourceModel\Review\CollectionFactory;
/**
* Class ListView
*
* @package RLTSquare\ProductReviewImages\Block\Product\View
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class ListView extends \Magento\Review\Block\Product\View\ListView
{
/**
* ListView constructor.
* @param Context $context
* @param EncoderInterface $urlEncoder
* @param JsonEncoderInterface $jsonEncoder
* @param StringUtils $string
* @param Product $productHelper
* @param ConfigInterface $productTypeConfig
* @param FormatInterface $localeFormat
* @param Session $customerSession
* @param ProductRepositoryInterface $productRepository
* @param PriceCurrencyInterface $priceCurrency
* @param CollectionFactory $collectionFactory
* @param array $data
*/
public function __construct(
Context $context,
EncoderInterface $urlEncoder,
JsonEncoderInterface $jsonEncoder,
StringUtils $string,
Product $productHelper,
ConfigInterface $productTypeConfig,
FormatInterface $localeFormat,
Session $customerSession,
ProductRepositoryInterface $productRepository,
PriceCurrencyInterface $priceCurrency,
CollectionFactory $collectionFactory,
array $data = []
)
{
parent::__construct($context, $urlEncoder, $jsonEncoder, $string, $productHelper, $productTypeConfig, $localeFormat, $customerSession, $productRepository, $priceCurrency, $collectionFactory, $data);
}
/**
* Unused class property
* @var false
*/
protected $_forceHasOptions = false;
/**
* Get product id
*
* @return int|null
*/
public function getProductId(): ?int
{
$product = $this->getProduct();
return $product->getId();
}
/**
* Prepare product review list toolbar
*
* @return \Magento\Review\Block\Product\View\ListView
* @throws LocalizedException
*/
protected function _prepareLayout(): \Magento\Review\Block\Product\View\ListView
{
parent::_prepareLayout();
$toolbar = $this->getLayout()->getBlock('product_review_list.toolbar');
if ($toolbar) {
$toolbar->setCollection($this->getReviewsCollection());
$this->setChild('toolbar', $toolbar);
}
return $this;
}
/**
* @return \Magento\Review\Block\Product\View\ListView
*/
protected function _beforeToHtml(): \Magento\Review\Block\Product\View\ListView
{
$this->getReviewsCollection()->load()->addRateVotes();
return parent::_beforeToHtml();
}
/**
* Return review url
*
* @param int $id
* @return string
*/
public function getReviewUrl($id): string
{
return $this->getUrl('*/*/view', ['id' => $id]);
}
}
THIS LICENSE AGREEMENT IS AN AGREEMENT BETWEEN YOU (THE PERSON OR COMPANY WHO IS BEING LICENSED TO USE THE SOFTWARE OR DOCUMENTATION) AND RLTSquare.
1. By purchasing the Software you agree with the content of this Agreement
and agree to use the Software in compliance with this Agreement.
2. You are a user of this Software and RLTSquare is the owner.
3. You may not sell, resell, sub-license or lease any fragment of the Software or its Documentation to anyone.
4. If you distribute original or changed version of the Software, you must include
this Agreement without any changes and original version of the Software.
5. We do not and will not bear responsibility for any damages (including any loss of your profit or savings)
caused to you, your business and your information by use or inability to use this Software.
6. We are not liable for prosecution arising from use of the Software against law or for any illegal use.
7. In case of failure to comply with any condition of this Agreement, your license to use the Software will be revoked.
8. Agreement remains effective without any time limits until it is terminated.
9. RLTSquare reserves the right to change Agreement type for future versions of Software.
\ No newline at end of file
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Model\ResourceModel;
/**
* Class ReviewMedia
*
* @package RLTSquare\ProductReviewImages\Model\ResourceModel
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class ReviewMedia extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb {
/**
* constructor
*
*/
protected function _construct() {
$this->_init('rltsquare_productreviewimages_reviewmedia', 'primary_id');
}
}
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Model\ResourceModel\ReviewMedia;
/**
* Class Collection
*
* @package RLTSquare\ProductReviewImages\Model\ResourceModel\ReviewMedia
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
/**
* constructor
*
*/
protected function _construct()
{
$this->_init('RLTSquare\ProductReviewImages\Model\ReviewMedia','RLTSquare\ProductReviewImages\Model\ResourceModel\ReviewMedia');
}
}
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Model;
/**
* Class ReviewMedia
*
* @package RLTSquare\ProductReviewImages\Model
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class ReviewMedia extends \Magento\Framework\Model\AbstractModel
{
/**
* constructor
*
*/
protected function _construct()
{
$this->_init('RLTSquare\ProductReviewImages\Model\ResourceModel\ReviewMedia');
}
}
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Observer;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Driver\File;
use RLTSquare\ProductReviewImages\Model\ReviewMediaFactory;
use RLTSquare\ProductReviewImages\Model\ResourceModel\ReviewMedia\CollectionFactory;
/**
* Class AdminProductReviewDeleteBefore
*
* @package RLTSquare\ProductReviewImages\Observer
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class AdminProductReviewDeleteBefore implements \Magento\Framework\Event\ObserverInterface
{
/**
* @var RequestInterface
*/
protected RequestInterface $_request;
/**
* @var ReviewMediaFactory
*/
protected ReviewMediaFactory $reviewMediaFactory;
/**
* @var DirectoryList::MEDIA
*/
protected DirectoryList $mediaDirectory;
/**
* @var File
*/
protected File $fileHandler;
/**
* @var CollectionFactory
*/
protected CollectionFactory $collectionFactory;
/**
* AdminProductReviewDeleteBefore constructor.
* @param RequestInterface $request
* @param Filesystem $filesystem
* @param File $fileHandler
* @param ReviewMediaFactory $reviewMediaFactory
* @throws FileSystemException
*/
public function __construct(
RequestInterface $request,
Filesystem $filesystem,
File $fileHandler,
ReviewMediaFactory $reviewMediaFactory
)
{
$this->_request = $request;
$this->fileHandler = $fileHandler;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->reviewMediaFactory = $reviewMediaFactory;
}
/**
* function
* executes before a review is deleted
*
* @param Observer $observer
* @return void
*/
public function execute(Observer $observer): void
{
$target = $this->mediaDirectory->getAbsolutePath('review_images');
// single record deletion
$reviewId = $this->_request->getParam('id', false);
if ($reviewId) {
$this->deleteReviewMedia($reviewId);
return;
}
// mass deletion
$reviewIds = $this->_request->getParam('reviews', false);
if ($reviewIds) {
foreach ($reviewIds as $id) {
$this->deleteReviewMedia($id);
}
return;
}
}
/**
* function
* delete media against a review
*
* @param $reviewId
* @return void
*/
private function deleteReviewMedia($reviewId): void
{
$target = $this->mediaDirectory->getAbsolutePath('review_images');
try {
$thisReviewMediaCollection = $this->collectionFactory->create()->addFieldToFilter('review_id', $reviewId);
foreach ($thisReviewMediaCollection as $m) {
$path = $target . $m->getMediaUrl();
if ($this->fileHandler->isExists($path)) {
$this->fileHandler->deleteFile($path);
}
}
} catch (\Exception $e) {
$this->messageManager->addException($e, __('Something went wrong while deleting review(s) attachment(s).'));
}
}
}
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Observer;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Driver\File;
use RLTSquare\ProductReviewImages\Model\ReviewMediaFactory;
use RLTSquare\ProductReviewImages\Model\ResourceModel\ReviewMedia;
/**
* Class AdminProductReviewSaveAfter
*
* @package RLTSquare\ProductReviewImages\Observer
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class AdminProductReviewSaveAfter implements \Magento\Framework\Event\ObserverInterface
{
/**
* @var RequestInterface
*/
protected RequestInterface $request;
/**
* @var ReviewMediaFactory
*/
protected ReviewMediaFactory $reviewMediaFactory;
/**
* @var DirectoryList::MEDIA
*/
protected DirectoryList $mediaDirectory;
/**
* @var File
*/
protected File $_fileHandler;
/**
* @var ReviewMedia
*/
protected ReviewMedia $reviewMediaResourceModel;
/**
* AdminProductReviewSaveAfter constructor.
* @param RequestInterface $request
* @param Filesystem $filesystem
* @param File $fileHandler
* @param ReviewMediaFactory $reviewMediaFactory
* @param ReviewMedia $reviewMediaResourceModel
* @throws FileSystemException
*/
public function __construct(
RequestInterface $request,
Filesystem $filesystem,
File $fileHandler,
ReviewMediaFactory $reviewMediaFactory,
ReviewMedia $reviewMediaResourceModel
)
{
$this->request = $request;
$this->fileHandler = $fileHandler;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->reviewMediaFactory = $reviewMediaFactory;
$this->reviewMediaResourceModel = $reviewMediaResourceModel;
}
/**
* function
* executes after review is saved
*
* @param Observer $observer
* @return void
*/
public function execute(Observer $observer): void
{
$target = $this->mediaDirectory->getAbsolutePath('review_images');
$deletedMediaString = $this->request->getParam('deleted_media');
if ($deletedMediaString)
try {
$ids = explode(",", trim($deletedMediaString, ","));
foreach ($ids as $id) {
$reviewMedia = $this->reviewMediaFactory->create()->load($id);
$path = $target . $reviewMedia->getMediaUrl();
if ($this->_fileHandler->isExists($path)) {
$this->_fileHandler->deleteFile($path);
}
//$reviewMedia->delete();
$this->reviewMediaResourceModel->delete($reviewMedia);
}
} catch (\Exception $e) {
$this->messageManager->addException($e, __('Something went wrong while updating review attachment(s).'));
}
}
}
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
namespace RLTSquare\ProductReviewImages\Observer;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Exception\FileSystemException;
use Magento\Framework\Filesystem;
use Magento\MediaStorage\Model\File\UploaderFactory;
use RLTSquare\ProductReviewImages\Model\ReviewMediaFactory;
use RLTSquare\ProductReviewImages\Model\ResourceModel\ReviewMedia;
/**
* Class ProductReviewSaveAfter
*
* @package RLTSquare\ProductReviewImages\Observer
* @author Umar Chaudhry <umarch@rltsquare.com>
*/
class ProductReviewSaveAfter implements \Magento\Framework\Event\ObserverInterface
{
/**
* @var RequestInterface
*/
protected RequestInterface $request;
/**
* @var ReviewMediaFactory
*/
protected ReviewMediaFactory $reviewMediaFactory;
/**
* @var DirectoryList::MEDIA
*/
protected $mediaDirectory;
/**
* @var UploaderFactory
*/
protected UploaderFactory $fileUploaderFactory;
/**
* @var ReviewMedia
*/
protected ReviewMedia $reviewMediaResourceModel;
/**
* ProductReviewSaveAfter constructor.
* @param RequestInterface $request
* @param Filesystem $filesystem
* @param UploaderFactory $fileUploaderFactory
* @param ReviewMediaFactory $reviewMediaFactory
* @throws FileSystemException
*/
public function __construct(
RequestInterface $request,
Filesystem $filesystem,
UploaderFactory $fileUploaderFactory,
ReviewMediaFactory $reviewMediaFactory,
ReviewMedia $reviewMediaResourceModel
)
{
$this->request = $request;
$this->fileUploaderFactory = $fileUploaderFactory;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->reviewMediaFactory = $reviewMediaFactory;
$this->reviewMediaResourceModel = $reviewMediaResourceModel;
}
/**
* function
* executed after a product review is saved
*
* @param Observer $observer
* @return void
*/
public function execute(Observer $observer): void
{
$reviewId = $observer->getEvent()->getObject()->getReviewId();
$media = $this->request->getFiles('review_media');
$target = $this->mediaDirectory->getAbsolutePath('review_images');
if ($media) {
try {
for ($i = 0; $i < count($media); $i++) {
$uploader = $this->fileUploaderFactory->create(['fileId' => 'review_media[' . $i . ']']);
$uploader->setAllowedExtensions(['jpg', 'jpeg', 'png']);
$uploader->setAllowRenameFiles(true);
$uploader->setFilesDispersion(true);
$uploader->setAllowCreateFolders(true);
$result = $uploader->save($target);
$reviewMedia = $this->reviewMediaFactory->create();
$reviewMedia->setMediaUrl($result['file']);
$reviewMedia->setReviewId($reviewId);
// $reviewMedia->save();
$this->reviewMediaResourceModel->save($reviewMedia);
}
} catch (\Exception $e) {
if ($e->getCode() == 0) {
$this->messageManager->addError("Something went wrong while saving review attachment(s).");
}
}
}
}
}
# ProductReviewImages-Magento2
# Overview
The Product Review Images for Magento 2 extension has been developed by the product team at RLTSquare. This extension will allow your customers to upload images within default product reviews for the products they buy and can also show the unique ways they are using your products in real life. So, why not let your customers take an active part in your online eCommerce business and eventually get benefit from it?
Here are some of the salient features for the extension:
```
1. Allow your customers to upload images in Magento 2 default product reviews
2. Admin approval required to ensure relevant and appropriate images only to be viewed at frontend
3. Allows uploading of up to 10 product images
4. Allows potential customers to view the review images uploaded by other customers
5. Original image size results in good user experience
```
## Installation
### Magento® Marketplace
This extension will also be available on the Magento® Marketplace when approved.
### Manually
1. Go to Magento® 2 root folder
2. Require/Download this extension:
Enter following commands to install extension.
```
composer require rltsquare/product-review-images
```
Wait while composer is updated.
#### OR
You can also download code from this repo under Magento® 2 following directory:
```
app/code/RLTSquare/ProductReviewImages
```
3. Enter following commands to enable the module:
```
php bin/magento module:enable RLTSquare_ProductReviewImages
php bin/magento setup:upgrade
php bin/magento cache:clean
php bin/magento cache:flush
```
4. If Magento® is running in production mode, deploy static content:
```
php bin/magento setup:static-content:deploy
```
## Requirements
1. This Magento® extension works on Magento 2.1 and 2.2 versions. Tested on versions 2.1.6 and above.
2. Tested on different themes specifically Ultimo, Porto and certain custom themes
For details, read our blog:
https://www.rltsquare.com/blog/product-review-images-magento-2-extension/
{
"name": "rltsquare/product-review-images",
"description": "Magento 2 extension by RLTSquare that allows user to include images while submitting product reviews.",
"require": {
"php": "~7.0.3|~7.4.0|~8.1",
"magento/module-review" : ">100.1.2"
},
"type":"magento2-module",
"version": "1.0.6",
"license":[
"proprietary"
],
"authors":[
{
"name" : "Umar",
"email" : "umarch@rltsquare.com",
"homepage" : "https://www.rltsquare.com",
"role" : "Developer"
}
],
"autoload":{
"files": [
"registration.php"
],
"psr-4": {
"RLTSquare\\ProductReviewImages\\" : ""
}
}
}
<?xml version="1.0"?>
<!--
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
-->
<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="rltsquare_admin_product_review_save_after" instance="RLTSquare\ProductReviewImages\Observer\AdminProductReviewSaveAfter" />
</event>
<event name="review_delete_before">
<observer name="rltsquare_admin_product_review_delete_before" instance="RLTSquare\ProductReviewImages\Observer\AdminProductReviewDeleteBefore" />
</event>
</config>
\ No newline at end of file
<?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="rltsquare_productreviewimages_reviewmedia" resource="default" engine="innodb" comment="RLTSqaure Product Review Images">
<column xsi:type="bigint" name="primary_id" unsigned="true" nullable="false" identity="true" comment="primary id of this table"/>
<column xsi:type="bigint" name="review_id" nullable="false" unsigned="true" comment="foreign key for review id"/>
<column xsi:type="text" name="media_url" nullable="false" comment="media url"/>
<constraint referenceId="PRIMARY" xsi:type="primary">
<column name="primary_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="PROVINCE_PROVINCE_ID_CITY_PROVINCE_ID" table="rltsquare_productreviewimages_reviewmedia" column="review_id" referenceTable="review" referenceColumn="review_id"/>
</table>
</schema>
{
"rltsquare_productreviewimages_reviewmedia": {
"column": {
"primary_id": true,
"review_id": true,
"media_url": true
},
"constraint": {
"PRIMARY": true,
"RLTSQUARE_PRDREVIEWIMAGES_REVIEWMDA_REVIEW_ID_REVIEW_REVIEW_ID": true
}
}
}
\ No newline at end of file
<?xml version="1.0"?>
<!--
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<preference for="Magento\Review\Block\Form" type="RLTSquare\ProductReviewImages\Block\Form" />
<preference for="Magento\Review\Block\Adminhtml\Edit\Form" type="RLTSquare\ProductReviewImages\Block\Adminhtml\Edit\Form" />
</config>
\ No newline at end of file
<?xml version="1.0"?>
<!--
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
-->
<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="rltsquare_product_review_save_after" instance="RLTSquare\ProductReviewImages\Observer\ProductReviewSaveAfter" />
</event>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<!--
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="RLTSquare_ProductReviewImages"/>
<sequence>
<module name="Magento_Review"/>
</sequence>
</config>
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE, 'RLTSquare_ProductReviewImages', __DIR__
);
\ No newline at end of file
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
use Magento\Framework\View\Element\Template;
?>
<?php
/**
*
* @var Escaper $escaper
*/
use Magento\Framework\Escaper;
/** @var $block Template */
?>
<?php if (count($block->getMediaCollection())): ?>
<div class="review-attachments">
<div class="review-media-value">
<?php
foreach ($block->getMediaCollection() as $m) {
$path = $block->getReviewMediaUrl() . $m->getMediaUrl();
?>
<div class="image item base-image" data-role="image">
<div class="product-image-wrapper">
<img class="product-image" data-role="image-element" src="<?php echo $path; ?>" alt="Image">
<div class="actions">
<button type="button" class="action-remove" media-id="<?php echo $m->getPrimaryId(); ?>" data-role="delete-button" title="Delete image">
<span>Delete image</span>
</button>
</div>
</div>
</div>
<?php
}
?>
</div>
</div>
<?php else: ?>
<?= $escaper->escapeHtml(__("No attachment available.")) ?>
<?php endif; ?>
<div id="review-image-modal" style="display:none;">
<img id="review-image-lg" src=""/>
</div>
<script>
require(
[
'jquery',
'Magento_Ui/js/modal/modal'
],
function ($) {
$('.action-remove').on('click', function (e) {
var mediaId = e.target.getAttribute('media-id');
$('#deleted_media').val($('#deleted_media').val() + mediaId + ",");
$(e.target).parent().parent().parent().remove();
});
$(".product-image").on('click', function () {
$("#review-image-modal").html("");
$("#review-image-modal").prepend('<img id="review-image-lg" src="' + $(this).attr("src") + '"/>');
$("#review-image-modal").modal({
type: 'popup',
title: 'Review Image',
clickableOverlay: true,
buttons:[],
responsive: true
}).modal('openModal').css({"text-align":"center"});
});
})
</script>
.image .product-image {
bottom: 0;
left: 0;
margin: auto;
max-height: 100%;
max-width: 100%;
position: absolute;
right: 0;
top: 0;
z-index: 1;
}
.image .product-image-wrapper {
background: #ffffff;
border: 1px solid #cccccc;
box-sizing: border-box;
cursor: pointer;
height: 150px;
line-height: 1;
margin-bottom: 1rem;
overflow: hidden;
position: relative;
width: 150px;
}
.image {
background: #ffffff;
box-sizing: border-box;
display: inline-block;
margin: 1.2rem;
position: relative;
vertical-align: top;
width: 150px;
}
.image .product-image-wrapper:hover .product-image {
opacity: .5;
}
\ No newline at end of file
<?xml version="1.0"?>
<!--
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="RLTSquare_ProductReviewImages::rltsquare_productreviewimages.css"/>
</head>
</page>
<?xml version="1.0"?>
<!--
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<referenceContainer name="product.info.details">
<referenceBlock name="product.info.product_additional_data">
<action method="setTemplate">
<argument name="template" xsi:type="string">RLTSquare_ProductReviewImages::product/view/list.phtml</argument>
</action>
</referenceBlock>
</referenceContainer>
</referenceContainer>Ï
</body>
</page>
<?xml version="1.0"?>
<!--
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
-->
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
<referenceContainer name="root">
<referenceBlock name="product.info.product_additional_data">
<action method="setTemplate">
<argument name="template" xsi:type="string">RLTSquare_ProductReviewImages::product/view/list.phtml</argument>
</action>
</referenceBlock>
</referenceContainer>
</layout>
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
use Magento\Framework\View\Element\Template;
use Magento\Framework\Escaper;
?>
<?php
/** @var $block Template */
/**
*
* @var Escaper $escaper
*/
?>
<div class="block review-add">
<div class="block-title"><strong><?php /* @escapeNotVerified */ echo __('Write Your Own Review') ?></strong></div>
<div class="block-content">
<?php if ($block->getAllowWriteReviewFlag()): ?>
<form enctype="multipart/form-data" action="<?php /* @escapeNotVerified */ echo $block->getAction() ?>" class="review-form" method="post" id="review-form" data-role="product-review-form" data-bind="scope: 'review-form'">
<?php echo $block->getBlockHtml('formkey'); ?>
<?php echo $block->getChildHtml('form_fields_before') ?>
<fieldset class="fieldset review-fieldset" data-hasrequired="<?php __('* Required Fields'); ?>">
<legend class="legend review-legend"><span><?php /* @escapeNotVerified */ echo __("You're reviewing:"); ?></span><strong><?php echo $block->escapeHtml($block->getProductInfo()->getName()) ?></strong></legend><br />
<?php if ($block->getRatings() && $block->getRatings()->getSize()): ?>
<span id="input-message-box"></span>
<fieldset class="field required review-field-ratings">
<legend class="label"><span><?php /* @escapeNotVerified */ echo __('Your Rating') ?><span></legend><br/>
<div class="control">
<div class="nested" id="product-review-table">
<?php foreach ($block->getRatings() as $_rating): ?>
<div class="field choice review-field-rating">
<label class="label" id="<?php echo $escaper->escapeHtml($_rating->getRatingCode()) ?>_rating_label"><span><?php echo $block->escapeHtml($_rating->getRatingCode()) ?></span></label>
<div class="control review-control-vote">
<?php $options = $_rating->getOptions(); ?>
<?php $iterator = 1;
foreach ($options as $_option): ?>
<input
type="radio"
name="ratings[<?php /* @escapeNotVerified */ echo $_rating->getId() ?>]"
id="<?php echo $escaper->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>"
value="<?php /* @escapeNotVerified */ echo $_option->getId() ?>"
class="radio"
data-validate="{required:true, messages:{required:'Please select one of each of the ratings above.'}}"
aria-labelledby="<?php echo $escaper->escapeHtml($_rating->getRatingCode()) ?>_rating_label <?php echo $block->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>_label" />
<label
class="rating-<?php /* @escapeNotVerified */ echo $iterator; ?>"
for="<?php echo $escaper->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>"
title="<?php /* @escapeNotVerified */ echo __('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star') ?>"
id="<?php echo $escaper->escapeHtml($_rating->getRatingCode()) ?>_<?php /* @escapeNotVerified */ echo $_option->getValue() ?>_label">
<span><?php /* @escapeNotVerified */ echo __('%1 %2', $iterator, $iterator > 1 ? 'stars' : 'star') ?></span>
</label>
<?php $iterator++; ?>
<?php endforeach; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<input type="hidden" name="validate_rating" class="validate-rating" value="" />
</div>
</fieldset>
<?php endif ?>
<div class="field review-field-nickname required">
<label for="nickname_field" class="label"><span><?php /* @escapeNotVerified */ echo __('Nickname') ?></span></label>
<div class="control">
<input type="text" name="nickname" id="nickname_field" class="input-text" data-validate="{required:true}" data-bind="value: nickname()" />
</div>
</div>
<div class="field review-field-summary required">
<label for="summary_field" class="label"><span><?php /* @escapeNotVerified */ echo __('Summary') ?></span></label>
<div class="control">
<input type="text" name="title" id="summary_field" class="input-text" data-validate="{required:true}" data-bind="value: review().title" />
</div>
</div>
<div class="field review-field-text required">
<label for="review_field" class="label"><span><?php /* @escapeNotVerified */ echo __('Review') ?></span></label>
<div class="control">
<textarea name="detail" id="review_field" cols="5" rows="3" data-validate="{required:true}" data-bind="value: review().detail"></textarea>
</div>
</div>
<div class="field review-field-media">
<label class="label"><span><?php /* @escapeNotVerified */ echo __('Attachments (jpg, jpeg, png)') ?></span></label>
<div class="control">
<input type="file" name="review_media[]" id="review_media" accept=".png, .jpg, .jpeg" multiple="multiple" />
</div>
<div for="media_field" generated="true" class="mage-error" id="media_field-error" style="display: none;">
<?php /* @escapeNotVerified */ echo __('You can select maximum 10 images.') ?>
</div>
</div>
</fieldset>
<div class="actions-toolbar review-form-actions">
<div class="primary actions-primary">
<button type="submit" class="action submit primary"><span><?php /* @escapeNotVerified */ echo __('Submit Review') ?></span></button>
</div>
</div>
</form>
<script type="text/x-magento-init">
{
"[data-role=product-review-form]": {
"Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout(); ?>
},
"#review-form": {
"Magento_Review/js/error-placement": {}
}
}
</script>
<?php else: ?>
<div class="message info notlogged" id="review-form">
<div>
<?php /* @escapeNotVerified */ echo __('Only registered users can write reviews. Please <a href="%1">Sign in</a> or <a href="%2">create an account</a>', $block->getLoginLink(), $block->getRegisterUrl()) ?>
</div>
</div>
<?php endif ?>
</div>
</div>
<script>
require(
[ 'jquery' ], function ($) {
$(document).on('change','#review_media',function(){
var files = $(this)[0].files;
if(files.length > 10){
$(this).val('');
$("#media_field-error").show();
}else{
$("#media_field-error").hide();
}
});
})
</script>
<?php
/**
* NOTICE OF LICENSE
* You may not sell, distribute, sub-license, rent, lease or lend complete or portion of software to anyone.
*
* DISCLAIMER
* Do not edit or add to this file if you wish to upgrade to newer
* versions in the future.
*
* @package RLTSquare_ProductReviewImages
* @copyright Copyright (c) 2022 RLTSquare (https://www.rltsquare.com)
* @contacts support@rltsquare.com
* @license See the LICENSE.md file in module root directory
*/
?>
<?php
/** @var Magento\Review\Block\Product\View\ListView $block */
/**
*
* @var Escaper $escaper
*/
?>
<?php
use Magento\Framework\Escaper;
?>
<?php
$_items = $block->getReviewsCollection()->getItems();
$format = $block->getDateFormat() ?: \IntlDateFormatter::SHORT;
$_objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$storeManager = $_objectManager->create('\Magento\Store\Model\StoreManagerInterface');
$mediaDirectoryPath = $storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . 'review_images';
?>
<?php if (count($_items)): ?>
<div class="block review-list" id="customer-reviews">
<div class="block-title">
<strong><?php /* @escapeNotVerified */
echo __('Customer Reviews') ?></strong>
</div>
<div class="block-content">
<div class="toolbar review-toolbar">
<?php echo $block->getChildHtml('toolbar') ?>
</div>
<ol class="items review-items">
<?php foreach ($_items as $_review): ?>
<li class="item review-item" itemscope itemprop="review" itemtype="http://schema.org/Review">
<div class="review-title"
itemprop="name"><?php echo $escaper->escapeHtml($_review->getTitle()) ?></div>
<?php if (count($_review->getRatingVotes())): ?>
<div class="review-ratings">
<?php foreach ($_review->getRatingVotes() as $_vote): ?>
<div class="rating-summary item" itemprop="reviewRating" itemscope
itemtype="http://schema.org/Rating">
<span class="label rating-label"><span><?php echo $escaper->escapeHtml($_vote->getRatingCode()) ?></span></span>
<div class="rating-result" title="<?php /* @escapeNotVerified */
echo $_vote->getPercent() ?>%">
<meta itemprop="worstRating" content="1"/>
<meta itemprop="bestRating" content="100"/>
<span style="width:<?php /* @escapeNotVerified */
echo $_vote->getPercent() ?>%">
<span itemprop="ratingValue"><?php /* @escapeNotVerified */
echo $_vote->getPercent() ?>%</span>
</span>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
<div class="review-content" itemprop="description">
<?php echo nl2br($escaper->escapeHtml($_review->getDetail())) ?>
</div>
<div class="review-details">
<p class="review-author">
<span class="review-details-label"><?php /* @escapeNotVerified */
echo __('Review by') ?></span>
<strong class="review-details-value"
itemprop="author"><?php echo $escaper->escapeHtml($_review->getNickname()) ?></strong>
</p>
<p class="review-date">
<span class="review-details-label"><?php /* @escapeNotVerified */
echo __('Posted on') ?></span>
<time class="review-details-value" itemprop="datePublished"
datetime="<?php /* @escapeNotVerified */
echo $block->formatDate($_review->getCreatedAt(), $format) ?>"><?php /* @escapeNotVerified */
echo $block->formatDate($_review->getCreatedAt(), $format) ?></time>
</p>
</div>
<div class="review-attachments">
<p class="review-attachments-label">Attachments</p>
<div class="review-media-value">
<?php
$thisReviewMediaCollection = $_objectManager->get('\RLTSquare\ProductReviewImages\Model\ReviewMediaFactory')
->create()
->getCollection()
->addFieldToFilter('review_id', $_review->getReviewId());
if (count($thisReviewMediaCollection))
foreach ($thisReviewMediaCollection as $m) {
?>
<div class="image item base-image" data-role="image">
<div class="product-image-wrapper">
<img class="product-image" data-role="image-element"
src="<?php echo rtrim($mediaDirectoryPath, '/') . $m->getMediaUrl(); ?>"
alt="Image">
</div>
</div>
<?php
}
else
echo __('No attachment available.');
?>
</div>
</div>
</li>
<?php endforeach; ?>
</ol>
<div id="review-image-modal" style="display:none;">
<img id="review-image-lg" src=""/>
</div>
<script>
require(
[
'jquery',
'Magento_Ui/js/modal/modal'
],
function ($, modal) {
$(".product-image").on('click', function () {
$("#review-image-modal").html("");
$("#review-image-modal").prepend('<img id="review-image-lg" src="' + $(this).attr("src") + '"/>');
$("#review-image-modal").modal({
type: 'popup',
title: 'Review Image',
clickableOverlay: true,
buttons: [],
responsive: true
}).modal('openModal').css({"text-align": "center"});
});
}
);
</script>
<div class="toolbar review-toolbar">
<?php echo $block->getChildHtml('toolbar') ?>
</div>
</div>
</div>
<?php endif; ?>
...@@ -27,9 +27,43 @@ $srcset = $responsiveImageHelper->getSrcset($block->getProduct(), 'product_page_ ...@@ -27,9 +27,43 @@ $srcset = $responsiveImageHelper->getSrcset($block->getProduct(), 'product_page_
$sizes = $responsiveImageHelper->getSizes('product_page_image_medium'); $sizes = $responsiveImageHelper->getSizes('product_page_image_medium');
$thumbSizes = $responsiveImageHelper->getSizes('product_page_image_small'); $thumbSizes = $responsiveImageHelper->getSizes('product_page_image_small');
?> ?>
<style>
.breeze-gallery .thumbnails .item:focus::after, .breeze-gallery .thumbnails .item.active::after{
box-shadow: 0px 0px 2px #3e4040;
}
</style>
<div class="breeze-gallery <?= $block->getGalleryOptions()->getVar('gallery/navdir') ?> row justify-content-start" style="display: contents;">
<div class="thumbnails <?php echo $navType ? '' : 'hidden' ?> col-2" style="justify-content: start;
align-content: center;
align-items: start;justify-content: end;display: grid;">
<?php if (count($images) > 1) : // empty parent wrapper may be used at configurable product page ?>
<?php foreach ($images as $image) : ?>
<?php
$classes = array_filter([
'item',
$block->isMainImage($image) ? 'active' : '',
$image->getVideoUrl() ? 'video' : ''
]);
$srcset = $responsiveImageHelper->getSrcset($image, 'product_page_image_small');
?>
<a class="<?= implode(' ', $classes) ?>" href="<?= $image->getLargeImageUrl() ?>" title="<?= $image->getLabel() ?: __('View Image') ?>">
<img loading="lazy" alt="<?= $image->getLabel() ?>"
src="<?= $image->getSmallImageUrl() ?>"
<?php if ($srcset) : ?>
srcset="<?= $srcset ?>"
sizes="<?= $thumbSizes ?>"
<?php endif ?>
width="<?= $thumbWidth ?>"
height="<?= $thumbHeight ?>"
/>
</a>
<?php endforeach ?>
<?php endif ?>
</div>
<div class="breeze-gallery <?= $block->getGalleryOptions()->getVar('gallery/navdir') ?>"> <div class="stage <?= $mainImage && $mainImage->getVideoUrl() ? 'video' : '' ?> col-10"
<div class="stage <?= $mainImage && $mainImage->getVideoUrl() ? 'video' : '' ?>"
data-gallery-role="gallery-placeholder"> data-gallery-role="gallery-placeholder">
<div class="main-image-wrapper"> <div class="main-image-wrapper">
<img alt="<?= $mainImage ? $mainImage->getLabel() : '' ?>" <img alt="<?= $mainImage ? $mainImage->getLabel() : '' ?>"
...@@ -77,32 +111,6 @@ $thumbSizes = $responsiveImageHelper->getSizes('product_page_image_small'); ...@@ -77,32 +111,6 @@ $thumbSizes = $responsiveImageHelper->getSizes('product_page_image_small');
</a> </a>
</div> </div>
<div class="thumbnails <?php echo $navType ? '' : 'hidden' ?>">
<?php if (count($images) > 1) : // empty parent wrapper may be used at configurable product page ?>
<?php foreach ($images as $image) : ?>
<?php
$classes = array_filter([
'item',
$block->isMainImage($image) ? 'active' : '',
$image->getVideoUrl() ? 'video' : ''
]);
$srcset = $responsiveImageHelper->getSrcset($image, 'product_page_image_small');
?>
<a class="<?= implode(' ', $classes) ?>" href="<?= $image->getLargeImageUrl() ?>" title="<?= $image->getLabel() ?: __('View Image') ?>">
<img loading="lazy" alt="<?= $image->getLabel() ?>"
src="<?= $image->getSmallImageUrl() ?>"
<?php if ($srcset) : ?>
srcset="<?= $srcset ?>"
sizes="<?= $thumbSizes ?>"
<?php endif ?>
width="<?= $thumbWidth ?>"
height="<?= $thumbHeight ?>"
/>
</a>
<?php endforeach ?>
<?php endif ?>
</div>
</div> </div>
<script type="text/x-magento-init"> <script type="text/x-magento-init">
......
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/** @var $block Magento\Catalog\Block\Product\View */
?>
<?php
$required = '';
if ($block->hasRequiredOptions()) {
$required = ' data-hasrequired="' . $block->escapeHtmlAttr(__('* Required Fields')) . '"';
}
?>
<div class="product-options-wrapper" id="product-options-wrapper"<?= /* @noEscape */ $required ?>>
<div class="fieldset" tabindex="0">
<?= $block->getChildHtml('', true) ?>
</div>
</div>
...@@ -3,8 +3,7 @@ ...@@ -3,8 +3,7 @@
* Copyright © Magento, Inc. All rights reserved. * Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details. * See COPYING.txt for license details.
*/ */
?>
<div class="product-options-bottom">
use \Magento\Framework\Component\ComponentRegistrar; <?= $block->getChildHtml('', true) ?>
</div>
ComponentRegistrar::register(ComponentRegistrar::THEME, 'frontend/Magento/joshine', __DIR__);
...@@ -205,11 +205,11 @@ ...@@ -205,11 +205,11 @@
</image> </image>
<image id="product_page_main_image" type="image"> <image id="product_page_main_image" type="image">
<width>700</width> <width>800</width>
<height>700</height> <height>700</height>
</image> </image>
<image id="product_page_main_image_default" type="image"> <image id="product_page_main_image_default" type="image">
<width>700</width> <width>800</width>
<height>700</height> <height>700</height>
</image> </image>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment