Jump to content

[Résolu] Création d'une page dynamique qui affiche les produits en précommande


Recommended Posts

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 !

Edited by PouletMiel
solved (see edit history)
Link to comment
Share on other sites

Bonjour et merci pour votre réponse,

Honnêtement c'est un module que j'avais supprimé et dont j'avais oublié l'existence. Vous pensez qu'il serait plus simple de créer un module afin de créer une nouvelle page dynamique semblable à celle du site que j'ai donné dans le message initial ? En prenant en compte que je ne suis pas intéressé par un block qui peut se fixer sur différents hooks mais uniquement par une page dynamique monsite.fr/preorders

Link to comment
Share on other sites

il y a une heure, PouletMiel a dit :

Bonjour et merci pour votre réponse,

Honnêtement c'est un module que j'avais supprimé et dont j'avais oublié l'existence. Vous pensez qu'il serait plus simple de créer un module afin de créer une nouvelle page dynamique semblable à celle du site que j'ai donné dans le message initial ? En prenant en compte que je ne suis pas intéressé par un block qui peut se fixer sur différents hooks mais uniquement par une page dynamique monsite.fr/preorders

Le module propose déjà d'accéder à une page spécifique listant les meilleures vente donc il fait exactement ce que vous voulez il faut juste changer le SQL pour récupérer les produits et les afficher dans la page en la nommant comme il faut, cela semble plus logique, plus simple et surtout une meilleur idée que d'attaquer le coeur de Prestashop et planter toute mise à jour future.

Link to comment
Share on other sites

1 hour ago, Mediacom87 said:

Le module propose déjà d'accéder à une page spécifique listant les meilleures vente donc il fait exactement ce que vous voulez il faut juste changer le SQL pour récupérer les produits et les afficher dans la page en la nommant comme il faut, cela semble plus logique, plus simple et surtout une meilleur idée que d'attaquer le coeur de Prestashop et planter toute mise à jour future.

Si l'on parle bien du module ps_bestsellers que je viens de re-télécharger, et sauf erreur de ma part, il permet simplement d'ajouter un bloc qui affiche les meilleures ventes de la boutique, mais n'est pas lié à la page best-sales en elle-même et n'intervient pas dans son fonctionnement; j'ai d'ailleurs accès à cette page sans avoir le module.

Il n'y a pas de requête SQL/ProductSearchProvider/Controller dans ce module, la méthode utilisée pour récupérer les produits venant du fichier PrestaShop\PrestaShop\Adapter\BestSales\BestSalesProductSearchProvider ;

use PrestaShop\PrestaShop\Adapter\BestSales\BestSalesProductSearchProvider;
protected function getBestSellers()
    {
        if (Configuration::get('PS_CATALOG_MODE')) {
            return false;
        }

        $searchProvider = new BestSalesProductSearchProvider(
            $this->context->getTranslator()
        );

Quelque chose m'échappe probablement, on ne parle peut-être pas du même module ? Ou sinon, pourriez-vous m'indiquer le code de ce module qui permet d'accéder à une page spécifique listant les meilleures ventes ou éventuellement le SQL qui récupère les produits ?

Link to comment
Share on other sites

7 minutes ago, ndiaga said:

Bonjour,

Il  faut  utiliser  une  page  CMS,   nommer  la  Précommande  par  exemple  et  avec  ce  module  appelez  ces  produits  via  le  custom  hook :

 

 

Bonjour, merci pour votre réponse.

Je ne cherche pas à créer une page CMS mais une page dynamique telle que "best-sales".

De plus, si je comprends bien, votre module permet de lister les produits d'une catégorie spécifique, ce qui sous-entend qu'il faut créer une catégorie nommée "Précommande" et y ajouter tous les articles disponibles en précommande. Ce n'est pas vraiment ce dont j'ai besoin non plus, il est déjà possible et facilement réalisable d'appeler et de lister les produits d'une certaine catégorie sur une page CMS sans aucun module... 

Link to comment
Share on other sites

Petit up pour ajouter que tout est quasiment fonctionnel désormais, j'ai ma page dynamique exactement comme je voulais, elle apparait dans Paramètres de la boutique > Trafic et SEO, elle apparait sur le site web dans les différentes langues, accessible depuis monsite.fr/fr/precommandes ou monsite.fr/en/preorders, dans le sitemap, modifiable avec Creative Elements, etc... tout est parfait.

Dernier point à corriger, la fonction getPreordersProducts . Quelque chose ne va pas dans ma fonction censée me renvoyer les articles disponibles en précommandes, mais je n'arrive pas à identifier l'erreur. Si quelqu'un la trouve ou parvient à identifier ce qui cloche (j'ai partagé le code de la fonction dans le premier message du topic), je suis preneur, en attendant je vais continuer à chercher.

J'ai rédigé un document qui recense toutes les différentes étapes, les fichiers créés et modifiés, si jamais quelqu'un passe par ici et veut réaliser la même chose pour sa boutique sans avoir à acheter un module, c'est avec plaisir que je le partagerai. 

Link to comment
Share on other sites

  • PouletMiel changed the title to [Résolu] Création d'une page dynamique qui affiche les produits en précommande

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...