0

I wish to show best selling products in in my customer My account page.Please provide me a solution to get best selling products and display in home page.

I have getting account file from this path :

From below file I am getting frontend structure

/var/www/html/myproject/app/design/frontend/Megnor/mag110246_4/Magedelight_SMSProfile/templates/account/dashboard/info.phtml

Below is the file from i'm getting code

/var/www/html/myproject/app/code/Magedelight/SMSProfile/Block/Account/Dashboard/Info.php

If anyone have idea how to get bestseller product and display in phtml file. Thanks

1 Answer 1

0

This is concept of show 12 bestsellers for last 3 month

You can change period and limits for your own

app/code/Acme/StackExchange/Block/Bestsellers.php

<?php

namespace Acme\StackExchange\Block;

use Magento\Catalog\Block\Product\AbstractProduct;
use Magento\Catalog\Block\Product\Context;
use Magento\Catalog\Model\Product\Visibility as ProductVisibility;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
use Magento\Framework\DataObject\IdentityInterface;
use Magento\Framework\Locale\ResolverInterface;
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
use Magento\Sales\Model\ResourceModel\Report\Bestsellers\CollectionFactory as BestsellersCollectionFactory;

/**
 * @method int getLimit()
 * @method $this setLimit(int $value)
 */
class Bestsellers extends AbstractProduct implements IdentityInterface
{
    /**
     * @var BestsellersCollectionFactory
     */
    protected $reportCollectionFactory;

    /**
     * @var ProductCollectionFactory
     */
    protected $productCollectionFactory;

    /**
     * @var Collection
     */
    protected $collection;

    /**
     * @var TimezoneInterface
     */
    protected $timezone;

    /**
     * @var string
     */
    protected $locale;

    /**
     * @var ProductVisibility
     */
    protected $productVisibility;

    public function __construct(
        Context $context,
        BestsellersCollectionFactory $reportCollectionFactory,
        ProductCollectionFactory $productCollectionFactory,
        ProductVisibility $productVisibility,
        TimezoneInterface $timezone,
        ResolverInterface $localeResolver,
        array $data = []
    ) {
        $this->reportCollectionFactory  = $reportCollectionFactory;
        $this->productCollectionFactory = $productCollectionFactory;
        $this->timezone                 = $timezone;
        $this->locale                   = $localeResolver->getLocale();
        $this->productVisibility        = $productVisibility;

        if (!isset($data['limit'])) {
            $data['limit'] = 12;
        }

        parent::__construct($context, $data);
    }

    /**
     * @return Collection
     * @throws \Exception
     */
    public function getProductCollection(): Collection
    {
        if ($this->collection === null) {
            $from = $this->timezone->date(
                new \DateTime('3 month ago', new \DateTimeZone('UTC')),
                $this->locale
            );

            $reportCollection = $this->reportCollectionFactory->create()
                ->setDateRange($from)
                // additional buffer of 10 products
                ->setPageSize($this->getLimit() + 10)
                ->load(false, true);

            $productIds = [];
            foreach ($reportCollection as $item) {
                $productIds[] = $item->getData('product_id');
            }

            $this->collection = $this->productCollectionFactory->create();
            $this->collection->addFieldToFilter('entity_id', ['in' => $productIds]);

            if (count($productIds) > 0) {
                $this->collection->getSelect()
                    ->order(new \Zend_Db_Expr('FIELD(e.entity_id,' . implode(',', $productIds) . ')'));
            }

            $this->collection->setVisibility($this->productVisibility->getVisibleInCatalogIds());

            $this->_addProductAttributesAndPrices($this->collection)
                ->addStoreFilter()
                ->setPageSize($this->getLimit());

            $this->collection->load(false, true);
        }

        return $this->collection;
    }

    /**
     * @inheritDoc
     */
    public function getIdentities(): array
    {
        $identities = [];
        foreach ($this->getProductCollection() as $product) {
            $identities[] = $product->getIdentities();
        }

        return $identities;
    }
}

app/code/Acme/StackExchange/view/frontend/layout/customer_account_index.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>
        <referenceContainer name="content">
            <block class="Acme\StackExchange\Block\Bestsellers" name="product-bestsellers"
                   template="Acme_StackExchange::bestsellers.phtml">
                <arguments>
                    <argument name="view_model" xsi:type="object">Magento\Catalog\ViewModel\Product\Listing\PreparePostData</argument>
                </arguments>
            </block>
        </referenceContainer>
    </body>
</page>

app/code/Acme/StackExchange/view/frontend/templates/bestsellers.phtml

<?php
/**
 * @var \Acme\StackExchange\Block\Bestsellers $block
 * @var \Magento\Framework\View\TemplateEngine\Php $this
 * @var \Magento\Framework\Escaper $escaper
 * @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer
 */

use Magento\Catalog\Block\Product\ReviewRendererInterface;
use Magento\Catalog\ViewModel\Product\Listing\PreparePostData;
use Magento\Framework\App\ActionInterface;

$type  = 'bestsellers';
$class = 'widget' . ' ' . $type;
$image = 'new_products_content_widget_grid';
$title = __('Bestsellers');
$items = $block->getProductCollection();

$showAddTo         = true;
$showCart          = true;
$templateType      = ReviewRendererInterface::SHORT_VIEW;
$canItemsAddToCart = false;

?>
<?php if ($items->getSize()): ?>
    <div class="block <?= $escaper->escapeHtmlAttr($class) ?>">
        <div class="block-title title">
            <strong id="block-<?= $escaper->escapeHtmlAttr($class) ?>-heading" role="heading"
                    aria-level="2"><?= $block->escapeHtml($title) ?></strong>
        </div>
        <div class="block-content content" aria-labelledby="block-<?= $escaper->escapeHtmlAttr($class) ?>-heading">
            <div class="products wrapper grid products-grid products-<?= $escaper->escapeHtmlAttr($type) ?>">
                <ol class="products list items product-items">
                    <?php foreach ($items as $_item): ?>
                        <li class="item product product-item">
                            <div class="product-item-info">
                                <?= /* @noEscape */
                                '<!-- ' . $image . '-->' ?>
                                <a href="<?= $escaper->escapeUrl($block->getProductUrl($_item)) ?>"
                                   class="product photo product-item-photo">
                                    <?= $block->getImage($_item, $image)->toHtml() ?>
                                </a>
                                <div class="product details product-item-details">
                                    <strong class="product name product-item-name"><a
                                                class="product-item-link"
                                                title="<?= $escaper->escapeHtmlAttr($_item->getName()) ?>"
                                                href="<?= $escaper->escapeUrl($block->getProductUrl($_item)) ?>">
                                            <?= $block->escapeHtml($_item->getName()) ?></a>
                                    </strong>

                                    <?= /* @noEscape */
                                    $block->getProductPrice($_item) ?>

                                    <?php if ($templateType): ?>
                                        <?= $block->getReviewsSummaryHtml($_item, $templateType) ?>
                                    <?php endif; ?>

                                    <?php if ($showAddTo || $showCart): ?>
                                        <?php // phpcs:disable ?>
                                        <div class="product actions product-item-actions">
                                            <?php if ($showCart): ?>
                                                <div class="actions-primary">
                                                    <?php if ($_item->isSaleable()): ?>
                                                        <?php if (!$_item->getTypeInstance()->isPossibleBuyFromList($_item)): ?>
                                                            <button
                                                                    class="action tocart primary"
                                                                    data-mage-init='{"redirectUrl": {"url": "<?= $escaper->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}'
                                                                    type="button"
                                                                    title="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>">
                                                                <span><?= $block->escapeHtml(__('Add to Cart')) ?></span>
                                                            </button>
                                                        <?php else : ?>
                                                            <?php
                                                            /** @var $viewModel PreparePostData */
                                                            $viewModel = $block->getViewModel();
                                                            $postArray = $viewModel->getPostData(
                                                                $escaper->escapeUrl($block->getAddToCartUrl($_item)),
                                                                ['product' => $_item->getEntityId()]
                                                            );
                                                            $value     = $postArray['data'][ActionInterface::PARAM_NAME_URL_ENCODED];
                                                            ?>
                                                            <form data-role="tocart-form"
                                                                  data-product-sku="<?= $escaper->escapeHtmlAttr($_item->getSku()) ?>"
                                                                  action="<?= $escaper->escapeUrl($block->getAddToCartUrl($_item)) ?>"
                                                                  method="post">
                                                                <input type="hidden" name="product"
                                                                       value="<?= /* @noEscape */
                                                                       (int)$_item->getEntityId() ?>">
                                                                <input type="hidden"
                                                                       name="<?= /* @noEscape */
                                                                       ActionInterface::PARAM_NAME_URL_ENCODED ?>"
                                                                       value="<?= /* @noEscape */
                                                                       $value ?>">
                                                                <?= $block->getBlockHtml('formkey') ?>
                                                                <button type="submit"
                                                                        title="<?= $escaper->escapeHtmlAttr(__('Add to Cart')) ?>"
                                                                        class="action tocart primary">
                                                                    <span><?= $block->escapeHtml(__('Add to Cart')) ?></span>
                                                                </button>
                                                            </form>
                                                        <?php endif; ?>
                                                    <?php else: ?>
                                                        <?php if ($_item->isAvailable()): ?>
                                                            <div class="stock available">
                                                                <span><?= $block->escapeHtml(__('In stock')) ?></span>
                                                            </div>
                                                        <?php else: ?>
                                                            <div class="stock unavailable">
                                                                <span><?= $block->escapeHtml(__('Out of stock')) ?></span>
                                                            </div>
                                                        <?php endif; ?>
                                                    <?php endif; ?>
                                                </div>
                                            <?php endif; ?>

                                            <?php if ($showAddTo): ?>
                                                <div class="secondary-addto-links actions-secondary"
                                                     data-role="add-to-links">
                                                    <?php if ($addToBlock = $block->getChildBlock('addto')): ?>
                                                        <?= $addToBlock->setProduct($_item)->getChildHtml() ?>
                                                    <?php endif; ?>
                                                </div>
                                            <?php endif; ?>
                                        </div>
                                        <?php // phpcs:enable ?>
                                    <?php endif; ?>
                                </div>
                            </div>
                        </li>
                    <?php endforeach ?>
                </ol>
            </div>
        </div>
    </div>
    <?php if (!$block->isRedirectToCartEnabled() && $_item): ?>
        <script type="text/x-magento-init">
    {
        "[data-role=tocart-form], .form.map.checkout": {
            "catalogAddToCart": {
                "product_sku": "<?= $block->escapeJs($_item->getSku()) ?>"
            }
        }
    }

        </script>
    <?php endif; ?>
<?php endif; ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.