Jump to content

Griser déclinaisons (texture) indisponibles prestashop 1.7


GBPro

Recommended Posts

Bonjour à tous.

Comme indiqué dans le titre, je souhaite griser les déclinaisons indisponibles qui sont sous forme de texture dans les fiches produits. Cela pour que le client voit directement les déclinaisons temporairement indisponibles.

Je vous remercie d'avance pour vos retours. Je connais bien la structure de Prestashop, donc s'il faut ajouter du code, il n'y a pas trop de soucis, si c'est bien expliqué.

Link to comment
Share on other sites

  • 4 weeks later...

Bonjour @Guipau,

Avant toute chose, je vous conseille de créer un thème enfant en suivant la documentation officielle si ce n'est pas déjà fait : https://devdocs.prestashop.com/1.7/themes/reference/template-inheritance/parent-child-feature/
Ainsi, les changements que vous apporterez au thème ne seront pas écrasés si ce dernier doit être mis à jour.

Ensuite, j'ai une question : vos déclinaisons varient-elles selon la texture seulement ou selon plusieurs attributs ?

  • Premier cas : on peut rajouter un peu de code dans le fichier /themes/votre_theme/templates/catalog/_partials/products-variants.tpl :
              <label aria-label="{$group_attribute.name}">
                {assign var="attributes" value=[$id_attribute]}
                {assign var="id_product_attribute" value=Product::getIdProductAttributeByIdAttributes(Tools::getValue('id_product'), $attributes)}
                {assign var="out_of_stock" value=$combinations[$id_product_attribute].quantity <= 0}
                <input class="input-color" type="radio" data-product-attribute="{$id_attribute_group}" name="group[{$id_attribute_group}]" value="{$id_attribute}" title="{$group_attribute.name}"{if $group_attribute.selected && !$out_of_stock} checked="checked"{/if}{if $out_of_stock} disabled{/if}>
                <span
                  {if $group_attribute.texture}
                    class="color texture" style="background-image: url({$group_attribute.texture});{if $out_of_stock} opacity: 60%; cursor: not-allowed;{/if}"
                  {elseif $group_attribute.html_color_code}
                    class="color" style="background-color: {$group_attribute.html_color_code}" 
                  {/if}
                ><span class="sr-only">{$group_attribute.name}</span></span>
              </label>

Il remplace le code des lignes 44 à 53, à savoir :

              <label aria-label="{$group_attribute.name}">
                <input class="input-color" type="radio" data-product-attribute="{$id_attribute_group}" name="group[{$id_attribute_group}]" value="{$id_attribute}" title="{$group_attribute.name}"{if $group_attribute.selected} checked="checked"{/if}>
                <span
                  {if $group_attribute.texture}
                    class="color texture" style="background-image: url({$group_attribute.texture})"
                  {elseif $group_attribute.html_color_code}
                    class="color" style="background-color: {$group_attribute.html_color_code}" 
                  {/if}
                ><span class="sr-only">{$group_attribute.name}</span></span>
              </label>

Je suis pas très fan de ma méthode, puisqu'elle encombre un template avec de la logique, mais c'est la seule que j'ai trouvé sans passer par de l'override.
Parce que oui, je suppose qu'on pourrait aussi override la fonction "assignAttributesGroups" du ProductController.php.

  • Deuxième cas : il faut tenir compte des autres attributs sélectionnés.

Il faudrait ainsi remplacer la ligne :

{assign var="attributes" value=[$id_attribute]}

par

{assign var="attributes" value=Tools::getValue('group')}
{if $group_attribute.texture}
	{$attributes[$id_attribute_group] = $id_attribute}
{/if}

Mais le problème, c'est que si l'utilisateur arrive sur la page produit et ne modifie aucun attribut, la variable 'group' n'est pas définie.
Donc je pense qu'il faudrait trouver une autre méthode si vous êtes dans cette situation...

Je pourrais me pencher sur la création d'un module si besoin est, ce serait peut-être plus propre. 😅

Bonne fin de journée,
Kaudaj.

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

Bonjour @Kaudaj,

Merci pour votre retour.

En fait, sur la fiche produit, les clients choisissent une texture tout simplement. Puis ils ajoutent au panier.

Donc si une déclinaison (texture) n'est plus en stock, alors je souhaite la griser pour que les clients voient directement en arrivant sur la fiche produit les déclinaisons en rupture de stock.

Dans ce cas, je suis dans le premier cas ?

Merci

Link to comment
Share on other sites

Bonjour,

Pour m'expliquer plus clairement, prenons l'exemple d'un T-Shirt.

  • 1er cas : le client choisit une couleur.
  • 2ème cas : le client choisit une taille et une couleur.

Donc oui, vous êtes dans le premier cas 😉

Bonne journée.

  • Like 1
Link to comment
Share on other sites

  • 2 years later...

Bonjour Kaudaj,

Je suis dans le "Deuxième cas" mais le problème est que je suis dans un fichier .php.

J'ai 2 groupes "taille" et "couleur". Je souhaite juste barrer les déclinaisons taille, lorsque le stock est à 0.

Pourrais-tu me donner cette partie, mais en php ?

{assign var="attributes" value=Outils::getValue('group')}
{if $group_attribute.texture}
	{$attributs[$id_attribute_group] = $id_attribute}
{/si}

Je ne connais pas les variables disponibles en php pour remplacer tes variables smarty.

Voici ma fonction render()

protected function render()
    {
        $settings = $this->getSettingsForDisplay();
        $context = \Context::getContext();
        $groups = &$context->smarty->tpl_vars['groups']->value;
		$combinations = &$context->smarty->getTemplateVars('combinations');

		// Récupérer l'ID du produit
		if (isset($_GET['id_product']) && is_numeric($_GET['id_product'])) {
			$id_product = (int)$_GET['id_product'];
		} else {
			// Gérer le cas où l'ID du produit n'est pas valide
			die('ID de produit non valide.');
		}
		?>
		
        <div class="ce-product-variants">
        <?php foreach ($groups as $id_attr_group => $group) { ?>
            <?php if (!empty($group['attributes'])) { ?>
                <div class="ce-product-variants__item">
                    <span class="ce-product-variants__label"><?php echo esc_html($group['name']); ?></span>
                <?php if ('stacked' === $settings['layout'] && $settings['show_value']) { ?>
                    <span class="ce-product-variants__value">
                    <?php foreach ($group['attributes'] as $value) { ?>
                        <?php echo $value['selected'] ? $value['name'] : ''; ?>
                    <?php } ?>
                    </span>
                <?php } ?>
                <?php if ('select' === $group['group_type']) { ?>
                    <div class="ce-product-variants__select">
                        <select class="elementor-field elementor-field-textual elementor-size-<?php echo esc_attr($settings['select_size']); ?>" oninput="$(this.form[this.name]).val(this.value)"
                            form="add-to-cart-or-refresh" name="group[<?php echo (int) $id_attr_group; ?>]" data-product-attribute="<?php echo (int) $id_attr_group; ?>">
                        <?php foreach ($group['attributes'] as $id_attr => $group_attr) { ?>
                            <option <?php echo $group_attr['selected'] ? 'selected' : ''; ?> value="<?php echo (int) $id_attr; ?>"><?php echo esc_html($group_attr['name']); ?></option>
                        <?php } ?>
                        </select>
                    </div>
                <?php } elseif ('radio' === $group['group_type']) { ?>
                    <div class="ce-product-variants__options">
                    <?php foreach ($group['attributes'] as $id_attr => $group_attr) { ?>
                        <label class="ce-product-variants__radio-wrapper" aria-label="<?php echo esc_attr($group_attr['name']); ?>">
						
						<?php							
							$id_attribute = $id_attr; // Valeur de l'attribut
							$combinations = $combinations; // Tableau des combinaisons de produits
							$id_product = $id_product; // Id du produit

							// Assignation de la valeur de l'attribut dans un tableau (équivalent à {assign var="attributes" value=[$id_attribute]})
							//$attributes = array($id_attribute);							
							
							/**************************************/
							// Assignation de la valeur de l'attribut à partir de Tools::getValue('group') dans un tableau (équivalent à {assign var="attributes" value=Tools::getValue('group')})
							$attributes = \Tools::getValue('group');

							// Vérification si $group_attribute.couleur existe (équivalent à {if $group_attribute.texture})
							if (isset($group_attribute['couleur'])) {
								// Ajout de la valeur $id_attribute dans le tableau $attributes sous la clé $id_attribute_group (équivalent à {$attributes[$id_attribute_group] = $id_attribute})
								$attributes[$id_attribute_group] = $id_attribute;
							}													
							/**************************************/						

							// Récupération de l'ID de l'attribut du produit à partir de ses attributs (équivalent à {assign var="id_product_attribute" value=Product::getIdProductAttributeByIdAttributes(Tools::getValue('id_product'), $attributes)})
							$id_product_attribute = \Product::getIdProductAttributeByIdAttributes($id_product, $attributes);

							// Vérification si la combinaison est en rupture de stock (équivalent à {assign var="out_of_stock" value=$combinations[$id_product_attribute].quantity <= 0})
							$out_of_stock = $combinations[$id_product_attribute]['quantity'] <= 0;						

						?>
						
                            <input class="ce-product-variants__radio" form="add-to-cart-or-refresh" type="radio" <?php echo $group_attr['selected'] ? 'checked' : ''; ?>
                                name="group[<?php echo (int) $id_attr_group; ?>]" value="<?php echo (int) $id_attr; ?>" data-product-attribute="<?php echo (int) $id_attr_group; ?>">
                            <span class="ce-product-variants__option <?php if($out_of_stock){ echo 'out-of-stock';} ?>"><?php echo esc_html($group_attr['name']); ?></span>
                        </label>
                    <?php } ?>
                    </div>
                <?php } elseif ('color' === $group['group_type']) { ?>
                    <div class="ce-product-variants__patterns">
                    <?php foreach ($group['attributes'] as $id_attr => $group_attr) { ?>
                        <label class="ce-product-variants__radio-wrapper" title="<?php echo esc_attr($group_attr['name']); ?>">
                            <input class="ce-product-variants__radio" form="add-to-cart-or-refresh" type="radio" <?php echo $group_attr['selected'] ? 'checked' : ''; ?>
                                name="group[<?php echo (int) $id_attr_group; ?>]" value="<?php echo (int) $id_attr; ?>" data-product-attribute="<?php echo (int) $id_attr_group; ?>">
                        <?php if ($group_attr['html_color_code']) { ?>
                            <span class="ce-product-variants__pattern ce-product-variants__color" style="background-color: <?php echo esc_attr($group_attr['html_color_code']); ?>"></span>
                        <?php } elseif ($group_attr['texture']) { ?>
                            <span class="ce-product-variants__pattern ce-product-variants__texture" style="background-image: url(<?php echo esc_attr($group_attr['texture']); ?>)"></span>
                        <?php } ?>
                        </label>
                    <?php } ?>
                    </div>
                <?php } ?>
                </div>
            <?php } ?>
        <?php } ?>
        </div>
        <?php
    }

C'est la partie entre /**************************************/ qui me pose problème.

Si quelqu'un a des pistes, je suis preneur.

Merci d'avance ;-)

Link to comment
Share on other sites

Bonjour,

J'ai trouvé une solution. Je la partage donc, si cela peut aider quelqu'un.

Pour un peu plus de précision, ce développement complémentaire concerne la fonction "render()" dans "modules/creativeelements/modules/catalog/widgets/product-variants.php" du constructeur de page "Creative elements".

protected function render()
	{
		$settings = $this->getSettingsForDisplay();
		$context = \Context::getContext();
		$groups = &$context->smarty->tpl_vars['groups']->value; 		
		
		// Récupérer les stocks réels des déclinaisons depuis le tableau $combinations
		$combinations = &$context->smarty->tpl_vars['combinations']->value;			
		$stockData = [];
		
		// Boucle pour afficher chaque combinaison avec la classe CSS appropriée
		foreach ($combinations as $combination) {
			$attributesList = $combination['list'];			
			$attributesListArray = explode(',', $attributesList);
			$combinedAttributes = implode('-', $attributesListArray);
			$stockData[$combinedAttributes] = $combination['quantity'];
			
			// Enlever les guillemets simples des clés du tableau $stockData
			$stockData = array_combine(array_map(function($key) {
				return str_replace("'", "", $key);
			}, array_keys($stockData)), $stockData);			
		}		
		?>			
		
		<div class="ce-product-variants">
			<?php foreach ($groups as $id_attr_group => $group) { ?>
				<?php if (!empty($group['attributes'])) { ?>
					<div class="ce-product-variants__item">
						<span class="ce-product-variants__label"><?php echo esc_html($group['name']); ?></span>
						<?php if ('stacked' === $settings['layout'] && $settings['show_value']) { ?>
							<span class="ce-product-variants__value">
								<?php foreach ($group['attributes'] as $value) { ?>
									<?php echo $value['selected'] ? $value['name'] : ''; ?>
								<?php } ?>
							</span>
						<?php } ?>
						<?php if ('select' === $group['group_type']) { ?>
							<div class="ce-product-variants__select">
								<select class="elementor-field elementor-field-textual elementor-size-<?php echo esc_attr($settings['select_size']); ?>" oninput="$(this.form[this.name]).val(this.value)"
									form="add-to-cart-or-refresh" name="group[<?php echo (int) $id_attr_group; ?>]" data-product-attribute="<?php echo (int) $id_attr_group; ?>">
								<?php foreach ($group['attributes'] as $id_attr => $group_attr) { ?>
									<option <?php echo $group_attr['selected'] ? 'selected' : ''; ?> value="<?php echo (int) $id_attr; ?>"><?php echo esc_html($group_attr['name']); ?></option>
								<?php } ?>
								</select>
							</div>
						<?php } elseif ('radio' === $group['group_type']) { ?>						
							<div class="ce-product-variants__options">
								<?php 									
									foreach ($group['attributes'] as $id_attr => $group_attr) {
										if($selected_color_id != NULL) {
											$attributesList = $selected_color_id . '-' . $id_attr;										
											$isOutOfStock = isset($stockData[$attributesList]) && $stockData[$attributesList] === 0;
										}
										else {
											$isOutOfStock = isset($stockData[$id_attr]) && $stockData[$id_attr] === 0;
										}
									?>
										<label class="ce-product-variants__radio-wrapper" aria-label="<?php echo esc_attr($group_attr['name']); ?>">
											<input class="ce-product-variants__radio" form="add-to-cart-or-refresh" type="radio" <?php echo $group_attr['selected'] ? 'checked' : ''; ?> name="group[<?php echo (int)$id_attr_group; ?>]" value="<?php echo (int)$id_attr; ?>" data-product-attribute="<?php echo (int)$id_attr_group; ?>">
											<span class="ce-product-variants__option <?php echo $isOutOfStock ? 'out-of-stock' : ''; ?>"><?php echo esc_html($group_attr['name']); ?></span>
										</label>
								<?php } ?>
							</div>						
						<?php } elseif ('color' === $group['group_type']) { ?>
							<div class="ce-product-variants__patterns">
							<?php foreach ($group['attributes'] as $id_attr => $group_attr) { ?>
								<label class="ce-product-variants__radio-wrapper" title="<?php echo esc_attr($group_attr['name']); ?>">
									<input class="ce-product-variants__radio" form="add-to-cart-or-refresh" type="radio" <?php echo $group_attr['selected'] ? 'checked' : ''; ?>
										name="group[<?php echo (int) $id_attr_group; ?>]" value="<?php echo (int) $id_attr; ?>" data-product-attribute="<?php echo (int) $id_attr_group; ?>">
								<?php if ($group_attr['html_color_code']) { ?>
									<span class="ce-product-variants__pattern ce-product-variants__color" style="background-color: <?php echo esc_attr($group_attr['html_color_code']); ?>"></span>
								<?php } elseif ($group_attr['texture']) { ?>
									<span class="ce-product-variants__pattern ce-product-variants__texture" style="background-image: url(<?php echo esc_attr($group_attr['texture']); ?>)"></span>
								<?php } ?>
								</label>
							<?php 
							
							if($group_attr['selected'] == 1) { $selected_color_id = $id_attr; }
							
							} ?>
							</div>
						<?php } ?>
					</div>
				<?php } ?>
			<?php } ?>
		</div>
		<?php
	}

Dans un premier temps, je récupère les valeurs des différentes déclinaisons :



Ensuite, j'initialise la variable "$selected_color_id" suivant le choix de l'internaute :

J'initialise ensuite la variable "$attributesList" en concaténant la valeur sélectionnée de l'attribut "color" et l'ID des valeurs de l'attribut "radio" :

Puis, j'initialise la variable "$isOutOfStock" à true ou false, suivant si le stock de la déclinaison est à 0 ou non, afin d'appliquer une condition dans le span, dans le but de lui affecter une classe css "out -de-stock" :


     

Et enfin, je stylise mon span avec du css :

Le but final est de barrer les déclinaisons ayant un stock à 0, pour que l'internaute soit une visibilité immédiate des déclinaisons disponibles.

 

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

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...