Jump to content

Edit History

PouletMiel

PouletMiel


solved

Bonjour à tous,

Tout d'abord, je précise que j'utilise Prestashop 1.7.7.1 et PHP 7.2.34. Ma version MySQL est 10.3.34-MariaDB.

Je souhaiterais créer une nouvelle page dynamique type listing comme les pages "best-sales", "new-products" et "prices-drop" permettant d'afficher les produits disponibles en précommande.

Pour définir qu'un article est disponible en précommande, j'utilise simplement cette option du back-office :

Precommande_BO.thumb.jpg.fb6ba1f2241554e389be347f08aff0f2.jpg

Lorsque la quantité est à 0 et que les préférences de disponibilité sont réglées sur "Accepter les commandes", l'article est considéré comme étant disponible en précommande. Niveau BDD, cette information est identifiable dans la table ps_stock_available grâce à l'attribut out_of_stock pouvant posséder 3 valeurs (0 : Le produit n'est pas en stock et le comportement consiste à refuser les commandes / 1 : Le produit n'est pas en stock, mais le comportement autorise les commandes (la valeur qui va nous intéresser ici) / 2 : Le produit est en stock et peut être commandé). Cette table possède également l'attribut 'id_product' , qui permet d'identifier chaque article. On peut donc facilement identifier les articles disponibles en précommande grâce à la requête :

requete.png.f0d30c2ab695c74c161619042ffcb2d7.png

Après un rapide test, la requête renvoie bien l'id de tous mes articles dispos en précommande. Cette requête sera utile par la suite pour mettre en place la fonction getPreordersProducts dans le fichier/dans un override du fichier Product.php.

 

Je créé un fichier preorders.tpl dans le dossier monsite.fr/themes/MonTheme/templates/catalog/listing qui contient :

{*
 * This file allows you to customize your preorders page.
 * You can safely remove it if you want it to appear exactly like all other product listing pages
 *}
{extends file='catalog/listing/product-list.tpl'}

Je créé ensuite un fichier PreordersProductSearchProvider.php dans le dossier monsite.fr/src/Adapter/Preorders/PreordersProductSearchProvider.php (le dossier Preorders venant d'être créé) qui contient :

<?php

namespace PrestaShop\PrestaShop\Adapter\Preorders;

use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory;
use Product;
use Symfony\Component\Translation\TranslatorInterface;

/**
 * Used to query the products available on preorder, see PreordersController in Front Office.
 */
class PreordersProductSearchProvider implements ProductSearchProviderInterface
{
    /**
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @var SortOrderFactory
     */
    private $sortOrderFactory;

    public function __construct(
        TranslatorInterface $translator
    ) {
        $this->translator = $translator;
        $this->sortOrderFactory = new SortOrderFactory($this->translator);
    }

    /**
     * @param ProductSearchContext $context
     * @param ProductSearchQuery $query
     * @param string $type
     *
     * @return array
     */
    private function getProductsOrCount(
        ProductSearchContext $context,
        ProductSearchQuery $query,
        $type = 'products'
    ) {
        return Product::getPreordersProducts(
            $context->getIdLang(),
            $query->getPage(),
            $query->getResultsPerPage(),
            $type !== 'products',
            $query->getSortOrder()->toLegacyOrderBy(),
            $query->getSortOrder()->toLegacyOrderWay()
        );
    }

    /**
     * {@inheritdoc}
     */
    public function runQuery(
        ProductSearchContext $context,
        ProductSearchQuery $query
    ) {
        if (!$products = $this->getProductsOrCount($context, $query, 'products')) {
            $products = [];
        }
        $count = $this->getProductsOrCount($context, $query, 'count');

        $result = new ProductSearchResult();

        if (!empty($products)) {
            $result
                ->setProducts($products)
                ->setTotalProductsCount($count);

            $result->setAvailableSortOrders(
                [
                    (new SortOrder('product', 'date_add', 'desc'))->setLabel(
                        $this->translator->trans('Date added, newest to oldest', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'date_add', 'asc'))->setLabel(
                        $this->translator->trans('Date added, oldest to newest', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'name', 'asc'))->setLabel(
                        $this->translator->trans('Name, A to Z', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'name', 'desc'))->setLabel(
                        $this->translator->trans('Name, Z to A', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'price', 'asc'))->setLabel(
                        $this->translator->trans('Price, low to high', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'price', 'desc'))->setLabel(
                        $this->translator->trans('Price, high to low', [], 'Shop.Theme.Catalog')
                    ),
                ]
            );
        }

        return $result;
    }
}

 

Ainsi que le controller  PreordersController.php dans le dossier monsite.fr/controllers/front/listing/ qui contient :

PreordersController.thumb.png.9f5181630ea54ff691f4b759bba2224c.png

Je me suis également occupé de tout ce qui est relatif à la traduction/cryptage MD5 et config (monsite.fr/app/Resources/translations/default/ShopNavigation.xlfmonsite.fr/classes/lang/KeysReference/MetaLang.php , monsite.fr/config/xml/themes/default.xmlmonsite.fr/themes/Montheme/config/theme.ymlmonsite.fr/controllers/front/SitemapController.php , etc...

 

Voilà où j'en suis actuellement, j'ai copié au maximum la syntaxe des fichiers relatifs à la page dynamique "new-products". Quelqu'un pourrait-il m'aiguiller sur ce qu'il me manque à réaliser, et éventuellement m'aider à compléter la fonction getPreordersProducts si nécessaire ? Je suppose ne pas être loin du but, mais je galère à rendre tout ceci concret et fonctionnel. Jusque là, aucun changement, la page d'apparaît nulle part, et je ne sais pas vraiment quoi faire d'autre. Il me manque une ou plusieurs pièces du puzzle, mais je bloque.

En remerciant par avance ceux qui prendront la peine de lire tout ça !

PouletMiel

PouletMiel

Bonjour à tous,

Tout d'abord, je précise que j'utilise Prestashop 1.7.7.1 et PHP 7.2.34. Ma version MySQL est 10.3.34-MariaDB.

Je souhaiterais créer une nouvelle page dynamique type listing comme les pages "best-sales", "new-products" et "prices-drop" permettant d'afficher les produits disponibles en précommande. À titre d'exemple, j'ai réussi à trouver un site web utilisant Prestashop qui est parvenu à réaliser exactement ce que je voudrais moi-même réaliser pour ma boutique (page en question https://www.pikastore.fr/precommandes/ ).

Pour définir qu'un article est disponible en précommande, j'utilise simplement cette option du back-office :

Precommande_BO.thumb.jpg.fb6ba1f2241554e389be347f08aff0f2.jpg

Lorsque la quantité est à 0 et que les préférences de disponibilité sont réglées sur "Accepter les commandes", l'article est considéré comme étant disponible en précommande. Niveau BDD, cette information est identifiable dans la table ps_stock_available grâce à l'attribut out_of_stock pouvant posséder 3 valeurs (0 : Le produit n'est pas en stock et le comportement consiste à refuser les commandes / 1 : Le produit n'est pas en stock, mais le comportement autorise les commandes (la valeur qui va nous intéresser ici) / 2 : Le produit est en stock et peut être commandé). Cette table possède également l'attribut 'id_product' , qui permet d'identifier chaque article. On peut donc facilement identifier les articles disponibles en précommande grâce à la requête :

requete.png.f0d30c2ab695c74c161619042ffcb2d7.png

Après un rapide test, la requête renvoie bien l'id de tous mes articles dispos en précommande. Cette requête sera utile par la suite pour mettre en place la fonction getPreordersProducts dans le fichier/dans un override du fichier Product.php.

Mise en place de la fonction getPreordersProducts :

Fonction_getpreordersproducts2.thumb.jpg.9e6a8e734c57e2ad3cb3540f17fb0afd.jpg

Je créé un fichier preorders.tpl dans le dossier monsite.fr/themes/MonTheme/templates/catalog/listing qui contient :

{*
 * This file allows you to customize your preorders page.
 * You can safely remove it if you want it to appear exactly like all other product listing pages
 *}
{extends file='catalog/listing/product-list.tpl'}

Je créé ensuite un fichier PreordersProductSearchProvider.php dans le dossier monsite.fr/src/Adapter/Preorders/PreordersProductSearchProvider.php (le dossier Preorders venant d'être créé) qui contient :

<?php

namespace PrestaShop\PrestaShop\Adapter\Preorders;

use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrderFactory;
use Product;
use Symfony\Component\Translation\TranslatorInterface;

/**
 * Used to query the products available on preorder, see PreordersController in Front Office.
 */
class PreordersProductSearchProvider implements ProductSearchProviderInterface
{
    /**
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @var SortOrderFactory
     */
    private $sortOrderFactory;

    public function __construct(
        TranslatorInterface $translator
    ) {
        $this->translator = $translator;
        $this->sortOrderFactory = new SortOrderFactory($this->translator);
    }

    /**
     * @param ProductSearchContext $context
     * @param ProductSearchQuery $query
     * @param string $type
     *
     * @return array
     */
    private function getProductsOrCount(
        ProductSearchContext $context,
        ProductSearchQuery $query,
        $type = 'products'
    ) {
        return Product::getPreordersProducts(
            $context->getIdLang(),
            $query->getPage(),
            $query->getResultsPerPage(),
            $type !== 'products',
            $query->getSortOrder()->toLegacyOrderBy(),
            $query->getSortOrder()->toLegacyOrderWay()
        );
    }

    /**
     * {@inheritdoc}
     */
    public function runQuery(
        ProductSearchContext $context,
        ProductSearchQuery $query
    ) {
        if (!$products = $this->getProductsOrCount($context, $query, 'products')) {
            $products = [];
        }
        $count = $this->getProductsOrCount($context, $query, 'count');

        $result = new ProductSearchResult();

        if (!empty($products)) {
            $result
                ->setProducts($products)
                ->setTotalProductsCount($count);

            $result->setAvailableSortOrders(
                [
                    (new SortOrder('product', 'date_add', 'desc'))->setLabel(
                        $this->translator->trans('Date added, newest to oldest', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'date_add', 'asc'))->setLabel(
                        $this->translator->trans('Date added, oldest to newest', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'name', 'asc'))->setLabel(
                        $this->translator->trans('Name, A to Z', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'name', 'desc'))->setLabel(
                        $this->translator->trans('Name, Z to A', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'price', 'asc'))->setLabel(
                        $this->translator->trans('Price, low to high', [], 'Shop.Theme.Catalog')
                    ),
                    (new SortOrder('product', 'price', 'desc'))->setLabel(
                        $this->translator->trans('Price, high to low', [], 'Shop.Theme.Catalog')
                    ),
                ]
            );
        }

        return $result;
    }
}

 

Ainsi que le controller  PreordersController.php dans le dossier monsite.fr/controllers/front/listing/ qui contient :

PreordersController.thumb.png.9f5181630ea54ff691f4b759bba2224c.png

Je me suis également occupé de tout ce qui est relatif à la traduction/cryptage MD5 et config (monsite.fr/app/Resources/translations/default/ShopNavigation.xlfmonsite.fr/classes/lang/KeysReference/MetaLang.php , monsite.fr/config/xml/themes/default.xmlmonsite.fr/themes/Montheme/config/theme.ymlmonsite.fr/controllers/front/SitemapController.php , etc...

 

Voilà où j'en suis actuellement, j'ai copié au maximum la syntaxe des fichiers relatifs à la page dynamique "new-products". Quelqu'un pourrait-il m'aiguiller sur ce qu'il me manque à réaliser, et éventuellement m'aider à compléter la fonction getPreordersProducts si nécessaire ? Je suppose ne pas être loin du but, mais je galère à rendre tout ceci concret et fonctionnel. Jusque là, aucun changement, la page d'apparaît nulle part, et je ne sais pas vraiment quoi faire d'autre. Il me manque une ou plusieurs pièces du puzzle, mais je bloque.

En remerciant par avance ceux qui prendront la peine de lire tout ça !

×
×
  • Create New...