[SI-LINDER-PARTNER-2][OSC] - Refonte du site Internet pour supporter le Responsive Design
/*
ATTENTION - le design du site ne peut pas être passé en doctype html (html 5) dans la révision 1 du design.
bien qu'une révision 2 sera instanciée plus tard (l'année prochaine), il faudra se contenter de nombreux workaround en restant en HTML TRANSITIONAL 4.01
Du fait du nombre massif des éléments DE CETTE PAGE (et de ce qui en découlerait) qui seront à revoir pour transformer le design en design responsive..
.. il est alors plus judicieux de globaliser un TAG unique pour cette tâche pour ne pas alourdir de commentaires le code déjà suffisemment alourdi comme cela!
En gros, ici, pour cette méga-tâche, je vais utiliser un format maison de commentaires pour cette tâche précise:
--> pour en comprendre les méandres, voir le fichier /[!] - Saphyra-Interactive-TaskList-Explanations/[SI-LINDER-PARTNER-2][OSC]--semantic.php
*/
// <- [SI-LINDER-PARTNER-2][OSC] - Refonte du site Internet pour supporter le Responsive Design
?>add(NAVBAR_TITLE, tep_href_link(FILENAME_SHOPPING_CART));
?>
>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on déclare une petite variable, sous forme de tableau associatif,
ce tableau servira à identifier la page (au lieu d'utiliser PHP_SELF etc..)
et cette identification servira dans le nouveau fichier d'inclusion de design dynamique inclu en [2]
c'est tout simple !
- 2/ inclusion du fichier PHP chargeur du design, ce sera à ce fichier inclu de décider quels assets (scripts, feuilles de styles, autres) charger!
}
*/
?>
[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
// [RESPONSIVE_DESIGN_2020_IMPLEMENTATION_CARDBOARD_2020_SAPHYRA_INTERACTIVE_ETAPE_1]
$_SI__NewDesign = array(
'pageFilepath' => '/shopping_cart.php'
);
// ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
// ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
require_once('--SI--2020DesignInitializer.php');
/*
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]
************************************************************************/
?>
[SI-LINDER-PARTNER-2][OSC][AddClassDescription(isPage--ShoppingCart isResponsive--Main)]:{" ATTENTION (ne pas oublier cette ligne!) servira à cibler cette page précise dans un sélecteur css..
// [RESPONSIVE_DESIGN_2020_IMPLEMENTATION_CARDBOARD_2020_SAPHYRA_INTERACTIVE_ETAPE_2] "} ?>
[SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on modifie la taille de cette cellule, qui est celle de gauche (avant) gérée via la constante PHP BOX_WIDTH de OSCommerce, (désormais), gérée par une valeur en dur, pourquoi? (1) la valeur initiale est gérée par une constante PHP, mais sa valeur... est aussi la modificatrice de la cellule de droite.. Ce qui pose problème quand on veut juste modifier celle de gauche et ne pas intervenir sur celle de droite, donc, ici, on modifie le echo BOX_WIDTH par une valeur fixée plus souple et enfin, on ajoute une classe pour pouvoir cibler cette cellule de tableau afin de la masquer en responsive ou autres !
// [RESPONSIVE_DESIGN_2020_IMPLEMENTATION_CARDBOARD_2020_SAPHYRA_INTERACTIVE_ETAPE_3] "} ?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ petits changements sur la structure et sur le texte
sert uniquement à restyliser l'élément pour le centrer par exemple et le re-marger
- 2/ à l'origine, ici, il y avait une image, désormais, en attendant d'éventuellement lui trouver une belle image, on va alors la commenter
}
*/
?>
[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN ?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va ajouter une petite structure pour faire contenir le listing dans un TABLEAU
au lieu de l'initial conteneur qui était une bête cellule
- 2/ on ajoute ici une structure de tableau possédant attributs et classe CSS, une ligne, et une cellule non-nommée,
car, la logique du nouveau design requière un tableau PAS une cellule pour contenir le listing des produits,
or, à l'origine,
le code '
' était représentait la cellule unique de contenu, sauf que ce n'est pas bien de contenir dans une cellule
au lieu de '
'
ce qui provoquait intréséquement un souci de logique de design car ce serait une cellule
qui contiendrait le listing produits et non un tableau
,
maintenant grâce à notre structure,
on a bien UN TABLEAU qui englobe LA CELLULE du Listing des produits, beaucoup plus crédible pour le bien-être du design!
cette nouvelle structure se referme à un emplacement précis (voir CODETAG [NOW_LISTING_IS_CONTAINED_INSIDE_A_TABLE_NO_MORE_ONLY_AN_UNIQUE_CELL_CLOSETAG])
}
*/
// ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
// [NOW_LISTING_IS_CONTAINED_INSIDE_A_TABLE_NO_MORE_ONLY_AN_UNIQUE_CELL_OPENTAG]
?>
BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END ?>
[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
/*
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]
************************************************************************/
?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va plus joliment styliser cet endroit afin d'afficher le tableau de listing (entête), avec beaucoup plus de style et proprement
- 2/ on modifie l'ancien nom de classe nommée 'productListing-heading' par 'shoppingCart-heading', pour plus de précision dans le code source PHP/HTML de la page
- 3/ on donne à cette cellule (
) (qui sera générée par PHP et la classe OSCommerce 'productListingBox') un tout nouvel attribut design-element-target
ce nouvel attribut nous permettra d'identifier la colonne d'entête, ça ne servira qu'à ça, pas de ciblage via Javascript, rien de ça!
on ajoute cela avec pour but de simplement pouvoir cibler la cellule plus tard, vu que chaque cellule est généré à la fin en PHP, on a pas le luxe du choix, c'est la seule manière de dynamiser!
- 4/ à l'origine l'image est dans la même cellule que les informations du produit (prix et nom (rien à voir avec le total à payer)).. ce qui est à mon sens une grossière erreur de design
donc, on va ajouter une cellule supplémentaire pour dissocier l'image du produit vis-à-vis des informations du produit
évidemment, on doit modifier le nom de la cellule d'entête en conséquence, un simple str_replace() suffira, (on garde ainsi le nom ancien de référence)
là encore, tout logiquement, il faut aussi renseigner les cellules sous cette ligne du tableau, sinon, les données ne seront pas bien agencées,
(pour cela, voir CODETAG [DISSOCIATED_CELL_PRODUCT_IMAGE_FROM_PRODUCT_NAME_AND_PRICE_DATA])
- 5/ le terme initial ici ne me convient pas, il est abrégé, et c'est pour moi un manque de respect car il y a suffisemment d'espace pour écrire le terme au complet !
}
*/
// ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
$info_box_contents = array();
$info_box_contents[0][] = array('align' => 'center',
// ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'params' => 'class="shoppingCart-heading"'
// ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
. ' ' . 'design-element-target="SHOPPING_CART_REMOVE_HEADING"',
// ([5])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'text' => str_replace(TABLE_HEADING_REMOVE, 'Retirer', TABLE_HEADING_REMOVE));
// ([4])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
// ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
$info_box_contents[0][] = array('params' => 'class="shoppingCart-heading"'
// ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
. ' ' . 'design-element-target="SHOPPING_CART_IMAGE_HEADING"',
// ([5])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'text' => str_replace(TABLE_HEADING_PRODUCTS, 'Visuel Réduit', TABLE_HEADING_PRODUCTS));
// ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
$info_box_contents[0][] = array('params' => 'class="shoppingCart-heading"'
// ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
. ' ' . 'design-element-target="SHOPPING_CART_NAME_AND_PRICE_HEADING"',
// ([5])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'text' => str_replace(TABLE_HEADING_PRODUCTS, 'Informations Produit', TABLE_HEADING_PRODUCTS));
// ([4])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
$info_box_contents[0][] = array('align' => 'center',
// ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'params' => 'class="shoppingCart-heading"'
// ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
. ' ' . 'design-element-target="SHOPPING_CART_QUANTITY_ADJUST_HEADING"',
// ([5])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'text' => str_replace(TABLE_HEADING_QUANTITY, 'Ajustement de Quantité', TABLE_HEADING_QUANTITY));
$info_box_contents[0][] = array('align' => 'right',
// ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'params' => 'class="shoppingCart-heading"'
// ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
. ' ' . 'design-element-target="SHOPPING_CART_TOTAL_EVALUATED_HEADING"',
// ([5])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'text' => str_replace(TABLE_HEADING_TOTAL, 'Total Calculé', TABLE_HEADING_TOTAL));
// ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
/*
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]
************************************************************************/
$any_out_of_stock = 0;
$products = $cart->get_products();
for ($i=0, $n=sizeof($products); $i<$n; $i++) {
// Push all attributes information in an array
if (isset($products[$i]['attributes']) && is_array($products[$i]['attributes'])) {
while (list($option, $value) = each($products[$i]['attributes'])) {
echo tep_draw_hidden_field('id[' . $products[$i]['id'] . '][' . $option . ']', $value);
$attributes = tep_db_query("select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix
from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa
where pa.products_id = '" . (int)$products[$i]['id'] . "'
and pa.options_id = '" . (int)$option . "'
and pa.options_id = popt.products_options_id
and pa.options_values_id = '" . (int)$value . "'
and pa.options_values_id = poval.products_options_values_id
and popt.language_id = '" . (int)$languages_id . "'
and poval.language_id = '" . (int)$languages_id . "'");
$attributes_values = tep_db_fetch_array($attributes);
$products[$i][$option]['products_options_name'] = $attributes_values['products_options_name'];
$products[$i][$option]['options_values_id'] = $value;
$products[$i][$option]['products_options_values_name'] = $attributes_values['products_options_values_name'];
$products[$i][$option]['options_values_price'] = $attributes_values['options_values_price'];
$products[$i][$option]['price_prefix'] = $attributes_values['price_prefix'];
}
}
}
// -> OSC-86: inverser l'ordre d'affichage des articles dans le panier
for ($i=sizeof($products)-1, $n=0; $i>=$n; $i--) {
// <- OSC-86: inverser l'ordre d'affichage des articles dans le panier
if (($i/2) == floor($i/2)) {
// [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on modifie l'ancien nom de classe nommée 'productListing-even' par 'shoppingCart-even', pour une meilleur intégration dans le nouveau design "}
$info_box_contents[] = array('params' => 'class="shoppingCart-even"');
} else {
// [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on modifie l'ancien nom de classe nommée 'productListing-odd' par 'shoppingCart-odd', pour une meilleur intégration dans le nouveau design "}
// [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" "}
$info_box_contents[] = array('params' => 'class="shoppingCart-odd"');
}
/************************************************************************
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va plus joliment styliser cet endroit afin d'afficher le tableau de listing (données), avec beaucoup plus de style et proprement
- 2/ on modifie l'ancien nom de classe nommée 'productListing-data' par 'shoppingCart-data', pour plus de précision dans le code source PHP/HTML de la page
- 3/ on donne à cette cellule (
) (qui sera générée par PHP et la classe OSCommerce 'productListingBox') un tout nouvel attribut design-element-target
ce nouvel attribut nous permettra d'identifier la colonne d'entête, ça ne servira qu'à ça, pas de ciblage via Javascript, rien de ça!
on ajoute cela avec pour but de simplement pouvoir cibler la cellule plus tard, vu que chaque cellule est généré à la fin en PHP, on a pas le luxe du choix, c'est la seule manière de dynamiser!
- 4/ à l'origine l'image est dans la même cellule que les informations du produit (prix et nom (rien à voir avec le total à payer)).. ce qui est à mon sens une grossière erreur de design
(cf CODETAG [OLD_LOCATION_FOR_CELL_PRODUCT_IMAGE_FROM_PRODUCT_NAME_AND_PRICE_DATA])
donc, on va ajouter une cellule supplémentaire pour dissocier l'image du produit vis-à-vis des informations du produit
on doit ajouter aussi en conséquence les cellules d'entête au tableau, sinon, les données vis-à-vis de l'entête ne seront pas bien agencées,
(pour cela, voir CODETAG [DISSOCIATED_CELL_PRODUCT_IMAGE_FROM_PRODUCT_NAME_AND_PRICE_HEADING])
exceptionnellement on créé une variable $si_products_image spécialement pour ici,
il ne s'agit absolument pas d'une variable de référence, elle ne resservira pas, donc, on la supprime après l'avoir utilisée
on profite aussi pour restructurer proprement le code
- 5/ on ajoute un index shoppingCartImage afin de pouvoir garder en mémoire l'image
cela servira plus tard afin d'afficher l'image du produit ou une image placeholder (en cas que l'image est absente du serveur)
on ajoute un index productPrices afin de pouvoir garder en mémoire le prix plus tard
cela servira plus tard afin d'afficher l'image du produit ou une image placeholder (en cas que l'image est absente du serveur)
- 6/ on intègre un code concernant un test d'existence des images des produits, on reseigne un index de la variable déclarée en [5]
- 7/ on utilise un index précis ici de la variable déclarée en [5], cela nous permettra d'avoir la bonne image à afficher
- 8/ on supprime la classe initiale 'productListing-data' ici, car ça sert à rien,
et si on la renomme en 'shoppingCart-data', on sera en conflit avec un code CSS de style de feuilles de style, ce qui ne fera pas joli
- 9/ on ajoutes des classes UI-Kit à l'élément de formulaire afin de lui donner plus de style,
que l'on réadaptera peut-être en overrides dans le fichier CSS principal du design 2020
- 10/ on ajoute juste un petit attribut à l'image du produit, cet attribut est un ID, utilisé par CSS pour cibler CES images
- 11/ on reformate le lien : retrait des éléments HTML , inutile, ajout de classes au lien, et d'une structure HTML amusante, pour l'avoir désormais géré par UI Kit, mais aussi, avec une classe précise,
oh, et on précède le lien d'une icone UI Kit
- 12/ on ajoute ici une classe CSS afin de cibler précisemment cet élément via du style CSS plus tard
- 13/ on restructure l'ancien code, 'text' =>
- 14/ déjà on commente l'ancien code, 'text' => car il est vraiment pas joli, mais on le conserve au cas-où !
- 15/ usage de UI Kit pour styliser le champ de formulaire ici
ici aussi on ajoutera l'empêcheur de suggestions parmis celles déjà tapées pour ce champ (ça fait moche). -> autocomplete = off
on ajoutera un motif à respecter (pattern regexp) pour n'autoriser que des chiffres de 0 à 9 autant de fois que désiré! -> pattern = [0-9]{0,}
- 16/ remplacement de l'ancien bouton (lien) ou (soumission), pour l'avoir désormais géré par UI Kit, mais aussi, avec une classe précise
- 17/ après refléxion, on intervertit la position de $more, (dans le code commenté à [14] il est après l'élément de formulaire, pas avant, maintenant, il est avant)
- 18/ et on ajoute un petit texte statique stipulant la quantité demandée, sans l'afficher ici, on parle juste d'un texte "STATIQUE", mais on lui donne une classe CSS pour cibler et le styliser plus tard
- 19/ ici, on va commenter (afin de le garder au besoin de le restaurer) l'ancien code d'affichage du tableau des prix, on va utiliser une toute nouvelle méthode pour afficher le tableau des prix par paliers
voir la nouvelle méthode ici (voir CODETAG [NEW_PRICE_BREAK_DISPLAY_METHOD])
- 20 ici, on va instancer la nouvelle méthode d'affichage du tableau des prix, à noter que l'ancienne méthode est toujours disponible ici (voir CODETAG [OLD_PRICE_BREAK_DISPLAY_METHOD])
- 21/ on va revoir les éléments de grilles tarifaires, et aussi la structure (du code), ainsi que les conditions afin de mieux filtrer les cas d'affichage (tableau ou prix direct)
utiliser les nouvelles versions de méthodes de PriceFormatter ici (getPricePartnerVersion2), (getPriceStringVersion2), est très utile,
dans le sens où le tableau est très chargé, on a que très peu d'espace, et le peu que l'on a en terme d'espace nécéssite absolument de fonctionner en responsive
et pour le reste des cas, gérés par (getPriceString) et (getPricePartner) nous allons uniquement remplacer les termes "EUR" par le symbole € spécialement créé pour la nouvelle version du design
- 22/ gestion du cas professionnel, qui n'était pas géré avant, on avait que le cas partenaire...
ATTENTION si cela pose problème, supprimer cette sous-tâche. (ou la commenter, le reste fonctionnera comme avant, sans autres modifications!)
- 23/ usage de (getPricePartnerVersion2) à la place de (getPricePartner)
usage de (getPriceStringVersion2) à la place de (getPriceString)
- 24/ revue des conditions (cas) d'affichage, partenaire, professionnel ou client particulier
remplacement du symbole monétaire EUR par € (et plus précisemment son entité HTML: € pour un affichage impeccable)
différenciation des cas d'affichage des prix (palier/prix direct)
revue des prix barrés en EUROS, afin d'éviter les prix barrés barrant le symbole € (ce qui fait pas joli)
pour les prix directs, on ajoutera une classe directPriceStringHT ou directPriceStringTTC selon le type de prix, afin de le styliser plus tard
- 25/ on reformate le bloc du prix de produits, on lui donne un et une classe à ce section, pour le cibler plus tard via CSS
oh, et on ne précède pas ici l'élément d'un icone UI Kit, on le fait plutôt ailleurs (voir CODETAG [UIKIT_ICON_IS_DEFINED_HERE])
on affiche pas via un echo, mais on renseigne plutôt un index précis ici de la variable déclarée en [5], cela nous permettra d'avoir la chaîne de prix à afficher
- 26/ ATTENTION - exceptionnellement ici on est forcé d'utiliser $pf->lowPrice
pour trouver le prix le plus bas du produit (équivalent à son prix de base sans les taxes, plutôt que $products[$i]['cost'] car relatif aux prix HT partenaire au prorata
- 27/ ATTENTION - exceptionnellement ici on est forcé d'utiliser une condition if de type intégrée (ternaire), afin de rajouter ou non un texte précis selon le résultat de la condition
(ici la vérification de l'existence du tableau de prix)
- 28/ là on restructure le code d'affichage des sous-totaux calculés pour chaque produits et quantité du-dit produit ajouté au panier, (uniquement pour le produit en cours)
- 29/ ici, on va faire quelque chose de particulier ceci dans le but de ne pas altérer la requête PHP existante (voir CODETAG [NOT_ALTERATE_THAT_SQL_REQUEST_FROM_THERE]),
le but est simple, on va détecter si le produit est dans la catégorie des specials/offres spéciales qui signifie surtout fin de série
plus loin dans le code, on va utiliser cette vérification afin de bloquer la quantité du panier à la quantité restante à l'exactitude du stock pour le dit-produit (voir CODETAG [LOCK_TO_STOCK_IF_IT_IS_A_SPECIALS_CATEGORY_PRODUCT])
cela se fera via un bloquage Javascript, rien n'est bloqué à l'achat, mais comme ce système sera aussi présent à un autre endroit crucial: le listing du panier, ça suffira pour bloquer la quantité
évidemment, un bloquage au niveau des classes PHP de OSCommerce aurait été plus malin, mais bien entendu, aussi plus difficile à en calculer les effets indésirables à côté, tandis qu'ici, bloquer ce fichier
suffira et évitera justement ces désagréments d'indésirabilité
l'idée est donc de procéder ainsi au travers des étapes suivantes [30] à [33]
- 30/ déjà, on créé une variable temporaire qui contiendra le résultat de la vérification
- 31/ ensuite, on se sert de la vérification de quantité des produits trouvés, (en effet, si le produit n'existe pas ou n'a pas le bon statut, on va plutôt éviter cette vérification, ceci induirait une quantité à vide!)
- 32/ on créé une requête SQL, qui nous aidera à définir ici, si le produit a son product_id dans la base de données du site, table specials (définie par la constante PHP TABLE_SPECIALS)
- 33/ finalement, si le product_id est trouvé dans cette table (requête sql en [31]) alors, on change le vérificateur (variable déclarée en [30]) et c'est tout, sinon, on ne fait rien
et on pourra s'en servir partout plus loin dans le code (étape [34])!
- 34/ on créé deux variables temporaires ici, que l'on utilisera en [35] et qu'on détruira en [36]
la première variable établira que si un chiffre est en inférieur ( -XXX ) on place la valeur à 0 pour la vérification de quantité maximale, et parfois, on peut avoir des chaînes
ajoutées, ce qu'on supprime ici
la deuxième variable contiendra simplement un évènement onchange, mais dynamique,
il ne faut pas que cet évènement Javascript existe pour des produits qui ne sont pas issu de fin de séries/offres spéciales
on a créé une variable PHP qui nous permet de savoir si le produit est oui (true) ou non (false) (voir CODETAG [CHECK_IF_IT_IS_A_SPECIALS_CATEGORY_PRODUCT])
et pour savoir cela, très facile, à un endroit de ce même fichier (voir CODETAG [CHECK_IF_IT_IS_A_SPECIALS_CATEGORY_PRODUCT])
un produit issu de fin de série/offres spéciales, et cette variable est donc vérifiée ici,
ici on renseigne une variable temporaire spéciale définissant un code Javascript qui sera ajouté (ou non) à un champ de formulaire input,
pour ce faire, on utilise une structure conditionnelle ternaire en PHP, afin de réduire la taille de notre code,
PHP nous permet aussi décrire sur plusieures lignes notre déclaration ternaire,, alors, on ne va pas s'en priver!
- 35) on utilise la variable créée en [34]
- 36) on supprime la variable créée en [34]
- 37/ ATTENTION
depuis janvier 2021, suite à une demande tardive du client, on va devoir afficher désormais les prix différemments selon le profil du client
de un masquer les prix HT aux clients PARTICULIERS et non-identifiés (donc VISITEURS), et donc, afficher le prix TTC uniquement à ces clients
de deux masquer les prix TTC aux clients PROFESSIONNELS et PARTENAIRES (ils doivent êtres identifiés au préalable comme tels), et donc, afficher le prix HT uniquement à ces clients
pour ce faire, rien de plus simple, on créé déjà un index vierge dans la variable de référence
qui sera valorisée au travers d'une condition PHP qui sera construite pour détecter le profil du client
puis, on se servira de cette variable, qui contiendra à terme le nom d'une classe CSS qui sera stylisée (affichée/ou non) par des règles CSS depuis le fichier de styles CSS principal..
elle servira aussi ici, (voir CODETAG[USE_VARIABLE_FOR_BEING_ABLE_TO_STYLIZE_PRICES_FOR_CUSTOMERS_PROFILES_1] et [USE_VARIABLE_FOR_BEING_ABLE_TO_STYLIZE_PRICES_FOR_CUSTOMERS_PROFILES_2])
- 38/ ATTENTION
depuis février 2021, suite à une demande tardive du client, on va devoir afficher désormais le prix TTC unitaire (pré-calculé) si il n'existe ni solde et que le client ne soit pas un professionel/partenaire
- pour ce faire, on va ajouter un nouvel index au tableau vu en [5] (comme son nom l'indique, ce nouvel index sera une bidouille (un hack)) (voir CODETAG[NEW_INDEX_TO_HACK_PRICE_IN_TTC_UNIT_PRICE])
- puis, plus loin on va structurer tout un système de condition pour afficher un texte indiquant le prix TTC unitaire SI
(et uniquement SI) le profil du client n'est ni professionnel, ni partenaire et que le prix ne soit pas un prix soldé et renseigner l'index (voir CODETAG[VALORIZE_INDEX_TO_HACK_PRICE_IN_TTC_UNIT_PRICE])
- finalement, on va se servir de ce nouvel index à travers un code HTML à un endroit précis dans la zone d'affichage du nom du produit (voir CODETAG[USE_INDEX_TO_HACK_PRICE_IN_TTC_UNIT_PRICE])
[VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique:
- 1/ ajout du nouveau bouton vtab à la place de l'ancien bouton, géré par la fonction vtab_tep_button() qui se trouve dans le fichier vtab_html_output.php
cela remplace l'étape [16] de la tâche [SI-LINDER-PARTNER-2][OSC]
- 2/ suite à la révision du fichier /includes/classes/PriceFormatter.php
qui implique le retrait de tout élément raturé/barré dans la sortie construite des prix barrés !
nous supprimons désormais à différents endroits du code la détection (qui symbolise une balise de fermeture de rature d'un élément (ex: 0.90 € = prix barré de 0.90 € !).
ces changements opéreront dans des endroits spécifiques du code: les expressions régulières de remplacement/de recherche et de stockage
- 3/ dans le but de davantage pouvoir avoir en [5] et valorisé en [4] un granularité beaucoup plus précise dans le ciblage CSS
on ajoute un index spécial au tableau PHP qui nous aidera à délimiter le profil commercial du client
- 4/ on va valoriser l'index déclaré en [3] selon si le client est un partenaire ou bien si le client est un professionnel
à travers une petite vérification qui trouvera le profil du client
si le client est un partenaire : Partenaire
si le client est un professionnel : Professionnel
si le client n'est ni l'un ni l'autre : Standard
l'instruction (else if) évite le cas où le client est en même temps un Professionnel qui est un Partenaire:
si le client est un Partenaire, la vérification sera résultante en Partenaire, peu importe si il est Professionnel.
- 5/ on injecte la nouvelle donnée dynamique renseignée en [4] de manière à donner à chaque colonne un ciblage bien plus précis du profil client
cela pourra ensuite servir dans une règle CSS pour cibler l'élément généré
- 6/ retrait du texte : "mais pour vous".
- 7/ désormais les Partenaires ont une nouvelle appelation, on les appelle: VIP
ici donc on prévoit l'usage de ce nom pour eux
- 8/ on a besoin de filtrer davantage plus précisemment les groupes de clients,
on avait initialement 3 groupes de clients: particulier, professionnel et partenaire
de nos jours, il n'y a pas grand chose qui change par rapport à ce qu'on voulait, mais, une terminologie a changé: les Partenaires sont devenus des VIP
en théorie on souhaite qu'un compte client soit :
- particulier (connecté ou non)
- pro
- VIP
précisons qu'en théorie il ne peut pas être à la fois pro et VIP, ça n’a pas de sens
donc introduction de cette étape, on va filtrer ça dans ce sens
sachant qu'en pratique, comme configurable depuis l'administration du site, un compte client peut être:
- Particulier (connecté ou non)
- Professionnel
- VIP + Particulier
- VIP + Professionnel
(la faute à un ensemble de bouton-radio pour le groupe de client "Particulier" et "Professionnel")
(et usage d'une case-à-cocher pour le groupe de client "VIP" (encore configuré comme Partenaire dans la base de données et administration)
donc, ce qui en théorie devrait être appliqué ne peut pas être appliqué tel quel..
du coup, on doit ruser:
on va vérifier si un compte (identifié ou non) n'est PAS VIP mais est Professionnel, SINON SI un compte est juste VIP OU Particulier
initialement on vérifiait comme suit:
si un compte était Professionnel alors:
si un compte était Professionnel ET VIP alors (on appellait ça le double-check, mais de nos jours, il n'est plus viable de se servir de cette condition, on la supprimera):
sinon si un compte était juste VIP (ce qui n'arrivait jamais donc à cause de la logique développée du système des boutons-radios et des anciennes conditions)
ou sinon si un compte était juste Particulier (ça, en revanche, ça pouvait arriver)
on va aussi ajouter une logique bien spéciale aux VIP:
les VIP auront toujours une mention au-dessus de leur prix (ou à côté/en-dessous): Prix VIP
les VIP auront par extension le statut Professionnel en plus d'être VIP, mais la condition d'être Professionnel quand on est VIP ne doit pas exister
les VIP n'ont jamais de promotions (ils ont toujours le même prix, donc, on n'affichera pas l'étiquette de 'PROMOTION' pour les VIP
les VIP n'ont jamais de prix degressifs (donc pas de palier/de tableaux de prix!), ça c'est déjà fonctionnel pas d'étapes supplémentaires à ajouter ici
}
*/
// ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
$cur_row = sizeof($info_box_contents) - 1;
// ([5])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
$pageShoppingCart__referencers = array(
'shoppingCartImage' => DIR_WS_IMAGES . $products[$i]['image'],
'productPrices' => '',
// ([37])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
// [DECLARE_VARIABLE_FOR_BEING_ABLE_TO_STYLIZE_PRICES_FOR_CUSTOMERS_PROFILES]
'cssClassOfPriceBox' => '',
// ([3])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END
'customerProfile' => 'Standard',
// ([8])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END
'mentionVIP' => '',
// ([38])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
// [NEW_INDEX_TO_HACK_PRICE_IN_TTC_UNIT_PRICE]
'visitorOrTTC_hack_ProductPrices' => ''
);
// ([5])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
// ([37])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
if (tep_session_is_registered('customer_id')) {
if ($is_partner == true OR is_pro_customer() == true) {
$pageShoppingCart__referencers['cssClassOfPriceBox'] = '--pleaseAdaptForProOrPartnerCustomer';
// ([4])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN
if ($is_partner == true) {
$pageShoppingCart__referencers['customerProfile'] = 'Partenaire';
}
else if (is_pro_customer() == true) {
$pageShoppingCart__referencers['customerProfile'] = 'Professionnel';
}
// ([4])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END
} else {
$pageShoppingCart__referencers['cssClassOfPriceBox'] = '--pleaseAdaptForStandardOrVisitorCustomer';
}
} else {
$pageShoppingCart__referencers['cssClassOfPriceBox'] = '--pleaseAdaptForStandardOrVisitorCustomer';
}
// ([37])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
// ([6])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
if (!file_exists($pageShoppingCart__referencers['shoppingCartImage'])) {
$pageShoppingCart__referencers['shoppingCartImage'] = DIR_WS_DESIGN . 'SI_DesignV2/placeholder__products.jpg';
}
// ([6])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
$info_box_contents[$cur_row][] = array('align' => 'center',
// ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
// TEST
'params' => 'class="shoppingCart-data test" valign="top"'
// ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
. ' ' . 'design-element-target="SHOPPING_CART_REMOVE_DATA"'
// ([5])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END
. ' ' . 'design-customer-profile="' . $pageShoppingCart__referencers['customerProfile'] . '"',
// ([9])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'text' => tep_draw_checkbox_field('cart_delete[]', $products[$i]['id'], false, 'onclick="checkBox(\'cart_delete\')" class="uk-checkbox --inputCheckbox__type3"'));
// ([4])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
// [DISSOCIATED_CELL_PRODUCT_IMAGE_FROM_PRODUCT_NAME_AND_PRICE_DATA]
$si_products_image = ''
. tep_image(
// ([7])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
$pageShoppingCart__referencers['shoppingCartImage'],
$products[$i]['name'],
SMALL_IMAGE_WIDTH,
SMALL_IMAGE_HEIGHT,
// ([10])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'id="thumbnail"'
)
. '';
$info_box_contents[$cur_row][] = array('align' => 'center',
// ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
'params' => 'class="shoppingCart-data" valign="top"'
// ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
. ' ' . 'design-element-target="SHOPPING_CART_IMAGE_DATA"'
// ([5])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END
. ' ' . 'design-customer-profile="' . $pageShoppingCart__referencers['customerProfile'] . '"',
'text' => $si_products_image);
$si_products_image = null;
$products_name = '
' /* HT: prix base */ . '
'
. str_replace(
'EUR',
'€',
$currencies->display_price(
$products[$i]['final_price'],
tep_get_tax_rate($products[$i]['tax_class_id']), $products[$i]['quantity']) . ' HT'
)
. '
' /* Séparateur des types de prix */ . '
' /* TTC: prix base (encadré de gras) */ . '
'
. str_replace(
'EUR',
'€',
$currencies->afficher_prix_ttc(
$products[$i]['final_price'],
tep_get_tax_rate($products[$i]['tax_class_id']), $products[$i]['quantity']) . ' TTC'
)
. '
');
// ([28])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
// ([13])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
// -> OSC-70 : Gestion HT/TTC : affichage prix HT et TTC
// ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END
/*
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]
************************************************************************/
}
new productListingBox($info_box_contents);
?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va ajouter une petite structure pour faire contenir le listing dans un TABLEAU
au lieu de l'initial conteneur qui était une bête cellule
- 2/ on ajoute ici une structure refermante de tableau, sa ligne, et sa cellule non-nommée,
car, la logique du nouveau design requière un tableau PAS une cellule pour contenir le listing des produits,
or, à l'origine,
le code '
' était représentait la cellule unique refermante de contenu, sauf que ce n'est pas bien de contenir dans une cellule
au lieu de '
'
ce qui provoquait intréséquement un souci de logique de design car ce serait une cellule
qui contiendrait le listing produits et non un tableau
,
maintenant grâce à notre structure,
on a bien UN TABLEAU REFERMANT qui englobe LA CELLULE du Listing des produits, beaucoup plus crédible pour le bien-être du design!
l'ouverture de cette nouvelle structure se fait à un emplacement précis (voir CODETAG [NOW_LISTING_IS_CONTAINED_INSIDE_A_TABLE_NO_MORE_ONLY_AN_UNIQUE_CELL_OPENTAG])
}
*/
// ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
?>
BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END ?>
OSC-70 : Gestion HT/TTC : affichage prix HT et TTC
// <- OSC-70 : Gestion HT/TTC : affichage prix HT et TTC Affichage prix normal si le client n'est pas partenaire ?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va ajouter une petite structure pour faire contenir le total à payer en HT et TTC
- 2/ on restructure l'ancien code, 'text' =>
- 3/ déjà on commente l'ancien code, 'text' => car il est vraiment pas joli, mais on le conserve au cas-où !
- 4/ l'affichage de l'intitulé sous-total (aka: SUB_TITLE_SUB_TOTAL)
sera exactement pareillement reformaté
comme celui du prix total affiché dans le PANIER de prévisualisation: --containerNestedShoppingCartPreviewer__modalStructure__previewContainer_lineProductQuantity
(renommé ici pour l'occasion)
- 5/ l'affichage du prix total
sera exactement pareillement reformaté
comme celui du prix total affiché dans le PANIER de prévisualisation: --containerNestedShoppingCartPreviewer__modalStructure__previewContainer_totalPrice
- 6/ ATTENTION
- avant décembre 2020, le client, aimait l'affichage de cet élément dans son format: --symbolSmall
- depuis décembre 2020, le client, finalement préfère un autre affichage, le format: --symbolLarge
- 7/ ATTENTION
BUGFIX - un span ici était incorrectement fermé
- avant janvier 2021, ''
- depuis janvier 2021, ''
- 8/ ATTENTION
depuis janvier 2021, suite à une demande tardive du client, on va devoir afficher désormais les prix différemments selon le profil du client
de un masquer les prix HT aux clients PARTICULIERS et non-identifiés (donc VISITEURS), et donc, afficher le prix TTC uniquement à ces clients
de deux masquer les prix TTC aux clients PROFESSIONNELS et PARTENAIRES (ils doivent êtres identifiés au préalable comme tels), et donc, afficher le prix HT uniquement à ces clients
pour ce faire, rien de plus simple, on réutilise la variable de référence déjà déclarée dans la page ici (voir CODETAG[DECLARE_VARIABLE_FOR_BEING_ABLE_TO_STYLIZE_PRICES_FOR_CUSTOMERS_PROFILES])
qui sera valorisée au travers d'une condition PHP qui sera construite pour détecter le profil du client
puis, on se servira de cette variable, qui contiendra à terme le nom d'une classe CSS qui sera stylisée (pro ou partenaire/particulier ou visiteur) par des règles CSS depuis le fichier de styles CSS principal..
elle servira aussi ici, (voir CODETAG[USE_VARIABLE_FOR_BEING_ABLE_TO_STYLIZE_PRICES_FOR_CUSTOMERS_PROFILES_1] et [USE_VARIABLE_FOR_BEING_ABLE_TO_STYLIZE_PRICES_FOR_CUSTOMERS_PROFILES_2])
on va aussi devoir désormais donner une classe --textHT à un tout nouveau que l'on pourra désormais cibler depuis le fichier de styles CSS principal/mediaqueries
dans lequel on va désormais encadrer le prix HT
}
*/
// ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
// ([2])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
/*
// ([3])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va revoir les éléments de boutons, tout simplement par ici
- 2/ remplacement de l'ancien bouton (lien) ou (soumission), pour l'avoir désormais géré par UI Kit, mais aussi, avec une classe précise
[VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique:
- 1/ ajout du nouveau bouton vtab à la place de l'ancien bouton, géré par la fonction vtab_tep_button() qui se trouve dans le fichier vtab_html_output.php
cela remplace l'étape [2] de la tâche [SI-LINDER-PARTNER-2][OSC]
- 2/ Ajout d'une classe qui permet de contenir les boutons "tout recalculer, poursuivre les achats, passer la commande
- 3/ Ajout d'une classe pour pouvoir permettre l'alignement des boutons en fonction du mode responsive
}
*/
?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va revoir les éléments de boutons, tout simplement par ici
- 2/ remplacement de l'ancien bouton (lien) ou (soumission), pour l'avoir désormais géré par UI Kit, mais aussi, avec une classe précise
[VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique:
- 1/ ajout du nouveau bouton vtab à la place de l'ancien bouton, géré par la fonction vtab_tep_button() qui se trouve dans le fichier vtab_html_output.php
cela remplace l'étape [2] de la tâche [SI-LINDER-PARTNER-2][OSC]
}
*/
?>
[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN ?>
[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN ?>
[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END ?>
[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END ?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]
************************************************************************
*/
?>
path)-2;
if (isset($navigation->path[$back])) {
?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va revoir les éléments de boutons, tout simplement par ici
- 2/ remplacement de l'ancien bouton (lien) ou (soumission), pour l'avoir désormais géré par UI Kit, mais aussi, avec une classe précise
[VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique:
- 1/ ajout du nouveau bouton vtab à la place de l'ancien bouton, géré par la fonction vtab_tep_button() qui se trouve dans le fichier vtab_html_output.php
cela remplace l'étape [2] de la tâche [SI-LINDER-PARTNER-2][OSC]
}
*/
?>
[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN ?>
[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN ?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va revoir les éléments de boutons, tout simplement par ici
- 2/ remplacement de l'ancien bouton (lien) ou (soumission), pour l'avoir désormais géré par UI Kit, mais aussi, avec une classe précise
[VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique:
- 1/ ajout du nouveau bouton vtab à la place de l'ancien bouton, géré par la fonction vtab_tep_button() qui se trouve dans le fichier vtab_html_output.php
cela remplace l'étape [2] de la tâche [SI-LINDER-PARTNER-2][OSC]
}
*/
?>
[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN ?>
[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN ?>
[SI-LINDER-PARTNER-2][OSC][AddClassDescription(--cellShoppingCartIsEmpty)]:{" classe que l'on ajoute afin de pouvoir cibler plus tard cette cellule "} ?>
TEXT_CART_EMPTY))); ?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{
- 1/ on va revoir les éléments de boutons, tout simplement par ici
- 2/ remplacement de l'ancien bouton (lien) ou (soumission), pour l'avoir désormais géré par UI Kit, mais aussi, avec une classe précise
[VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique:
- 1/ ajout du nouveau bouton vtab à la place de l'ancien bouton, géré par la fonction vtab_tep_button() qui se trouve dans le fichier vtab_html_output.php
cela remplace l'étape [2] de la tâche [SI-LINDER-PARTNER-2][OSC]
}
*/
?>
[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN ?>
[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN ?>
[SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une classe pour pouvoir cibler cette cellule de tableau afin de la masquer en responsive ou autres !
// [RESPONSIVE_DESIGN_2020_IMPLEMENTATION_CARDBOARD_2020_SAPHYRA_INTERACTIVE_ETAPE_4] "} ?>
[SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute un élément HTML et une classe pour pouvoir cibler cette zone afin de la styliser en responsive ou autres ! "} ?>