[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 ?>[SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" en octobre 2020 le client souhaitait qu'on aie plus de 20 artiles par page, en fait, cela est géré par une option paramétrable depuis la zone administrative: "Configuration" -> "Valeur Maximum" -> "Résultat de recherche", c'était sur 20, on l'a mis sur 50, et tant mieux, sinon, il aurait fallu adapter 41 fichiers, même de non-structure HTML, cela est géré globalement par la valorisation de la constante PHP MAX_DISPLAY_SEARCH_RESULTS tirée d'une option depuis la base de données, transformée en constante PHP par OSCommerce "} $listing_split = new splitPageResults($listing_sql, MAX_DISPLAY_SEARCH_RESULTS, 'p.products_id'); // -> QPBPP135 global $language, $languages_id; require(DIR_WS_LANGUAGES . $language . '/' . FILENAME_PRODUCT_LISTING); require('includes/classes/suppliers_orders.php'); // <- QPBPP135 /************************************************************************ [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{ - 1/ on modifie la valeur vérifiée de PREV_NEXT_BAR_LOCATION, par 2, au lieu de 1, afin d'afficher le tableau de pagination, proprement - 2/ on ajoute au tableau ces classes CSS: infoTableCounterPagination et uk-table - 3/ on ajoute à la suite de cette cellule qui a déjà la classe 'smallText' ces classes CSS: infoCellCounterPagination et productsCounter et on modifie aussi le terme 'Afficher' par 'Affichage de' - 4/ on ajoute à la suite de cette cellule qui a déjà la classe 'smallText' ces classes CSS: infoCellCounterPagination et paginationLinks [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique: - 1/ provisoirement je met l'affichage en display:none table.infoTableCounterPagination en lien avec le décalage qu'il créait on insère le nom d'une classe afin de pouvoir aligner l'affichage 1 à 50 au dessus des numéros de pages } */ // ([1])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END if ( ($listing_split->number_of_rows > 0) && ( (PREV_NEXT_BAR_LOCATION == '2') || (PREV_NEXT_BAR_LOCATION == '3') ) ) { // ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END ?> [VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN ?> BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END ?> BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END ?> [VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END ?>
display_count(str_replace('Afficher', 'Affichage de', TEXT_DISPLAY_NUMBER_OF_PRODUCTS)); ?>
[SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions] ************************************************************************/ /************************************************************************ [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions]:{ - 1/ // [VTAB_REORDERING_SORTED_COLUMNS_ORDER] pour les besoins de la nouvelle charte graphique, il a été décidé que l'on ne doit plus avoir l'ordre de colonnes suivants pour les éléments: PRODUCT_LIST_IMAGE PRODUCT_LIST_NAME PRODUCT_LIST_MANUFACTURER PRODUCT_LIST_QUANTITY PRODUCT_LIST_PRICE PRODUCT_LIST_BUY_NOW PRODUCT_LIST_WEIGHT PRODUCT_LIST_MODEL mais plutôt celui-ci: PRODUCT_LIST_IMAGE PRODUCT_LIST_NAME PRODUCT_LIST_QUANTITY PRODUCT_LIST_PRICE PRODUCT_LIST_WEIGHT PRODUCT_LIST_MODEL PRODUCT_LIST_BUY_NOW au départ j'ai pensé que l'ordre se faisait depuis les colonnes SQL de la base de données, mais il n'en est rien... en réalité, l'ordre des colonnes se décide ailleurs, et cette décision a lieu dans le fichier '/index.php' (voir le commentaire: "// create column list" initialement déposé par l'équipe OSCommerce ) - 2/ on créé un backup de l'ancienne variable $column_list (construite dans le fichier 'index.php' (voir bloc d'instruction: while (list($key, $value) = each($define_list)))) ou plutôt de son contenu, car on va l'altérer ET la restaurer à la fin du fichier actuel, en gros, à la fin du listing on revalorisera notre variable issue de /index.php à la valeur du backup (qui aura alors la valeur initiale de /index.php) (voir CODETAG[VTAB_1_OSC_RESTORING_BACKUP_OSCOMMERCE_SORT_ORDERED_LISTING]) simple possible exemple de retour debug du $column_list original: Array ( [0] => PRODUCT_LIST_IMAGE [1] => PRODUCT_LIST_NAME [2] => PRODUCT_LIST_QUANTITY [3] => PRODUCT_LIST_PRICE [4] => PRODUCT_LIST_BUY_NOW [5] => PRODUCT_LIST_WEIGHT [6] => PRODUCT_LIST_MODEL ) - 3/ on a donc besoin de recréer l'ordre nous même, et pour cela, on doit alors aussi et surtout, redéfinir le tableau d'ordre } */ // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN // ([2])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END $VTAB_productListing_backupOSCommerceSortOrderedListing = $column_list; // echo ''; // ([3])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN $column_list = array( 'PRODUCT_LIST_IMAGE', 'PRODUCT_LIST_NAME', 'PRODUCT_LIST_QUANTITY', 'PRODUCT_LIST_PRICE', 'PRODUCT_LIST_WEIGHT', 'PRODUCT_LIST_MODEL', 'PRODUCT_LIST_BUY_NOW' ); // ([3])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END /* [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] ************************************************************************/ $list_box_contents = array(); for ($col=0, $n=sizeof($column_list); $col<$n; $col++) { /* ************************************************************************ [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions]:{ - 1/ ici on va ajouter un petit système pour effectuer un meilleur ciblage du profil client - 2/ dans le but de davantage pouvoir avoir en [4] et valorisé en [3] un granularité beaucoup plus précise dans le ciblage CSS on ajoute une variable spéciale PHP qui nous aidera à délimiter le profil commercial du client - 3/ on va valoriser la variable déclarée en [2] 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. - 4/ ce procédé servira à différents autres endroits du fichier où lui on injectera la nouvelle donnée dynamique renseignée en [3] 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é (voir CODETAG[VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE]) } */ // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN // ([2])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END $customerProfile = 'Standard'; // ([3])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN if ($is_partner == true) { $customerProfile = 'Partenaire'; } else if (is_pro_customer() == true) { $customerProfile = 'Professionnel'; } // ([3])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END /* [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] ************************************************************************ */ switch ($column_list[$col]) { case 'PRODUCT_LIST_MODEL': // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" dans les besoins de cette tâche, on doit masquer cet en-tête de colonne, la façon la plus simple ici, c'est de rajouter un 'break' pour sortir de la boucle si ce cas est spécifiquement rencontré dans la boucle for() et dans l'interrupteur switch(), on conserve alors le code du bas, avant le deuxième 'break', mais ce code avant ce deuxième 'break' ne sera alors jamais lu ni interprété, on peut le conserver dans le code, il ne sera jamais exécuté à cause du premier 'break', c'est ce que l'on veut, vu qu'on veut zapper l'exécution de cet élément, et ce premier 'break' effectue le zapping à la perfection, en une seule ligne, sans besoin de commenter l'ancien code en place ! "} break; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_MODEL_HEADING" design-customer-profile="' . $customerProfile .'"'; $lc_text = TABLE_HEADING_MODEL; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on change juste ici l'alignement de $lc_align de '' vers 'center' "} $lc_align = 'center'; break; case 'PRODUCT_LIST_NAME': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_NAME_HEADING" design-customer-profile="' . $customerProfile .'"'; $lc_text = TABLE_HEADING_PRODUCTS; $lc_align = 'center'; break; case 'PRODUCT_LIST_MANUFACTURER': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_MANUFACTURER_HEADING" design-customer-profile="' . $customerProfile .'"'; $lc_text = TABLE_HEADING_MANUFACTURER; $lc_align = ''; break; case 'PRODUCT_LIST_PRICE': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_PRICE_HEADING" design-customer-profile="' . $customerProfile .'"'; // -> OSC-70 : Gestion HT/TTC : affichage prix HT et TTC // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on avait initialement changé le texte 'Prix' en 'Prix unitaire', sauf que en y réfléchissant, ce prix n'est pas le meilleur prix si on a ou non un statut spécifique (sur le site il existe 3 statut: Particulier (statut normal), Professionnel (statut normal), Partenaire (statut spécial), ça considère juste le prix du dernier palier disponible, si on est particulier, ça affiche le bon prix, car en particulier, ce prix est de toute façon bloqué au seul palier disponible (+1), donc, depuis octobre 2020, on s'est rendu compte (moi comme le client) un peu tard que le prix degressif affiché ici n'est pas valide si l'on est en Professionnel ou Partenaire, car, le prix ici cherche le TOUT DERNIER PALIER vu que les Professionnel et Partenaire ont accès au dernier palier degressif, donc on renomme en "Prix" "} $lc_text = "Prix"; // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on modifie le texte ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_text .= ($customerProfile == 'Partenaire') ? ' VIP' : ''; // <- OSC-70 : Gestion HT/TTC : affichage prix HT et TTC $lc_align = 'center'; break; case 'PRODUCT_LIST_QUANTITY': // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" dans les besoins de cette tâche, on doit masquer cet en-tête de colonne, la façon la plus simple ici, c'est de rajouter un 'break' pour sortir de la boucle si ce cas est spécifiquement rencontré dans la boucle for() et dans l'interrupteur switch(), on conserve alors le code du bas, avant le deuxième 'break', mais ce code avant ce deuxième 'break' ne sera alors jamais lu ni interprété, on peut le conserver dans le code, il ne sera jamais exécuté à cause du premier 'break', c'est ce que l'on veut, vu qu'on veut zapper l'exécution de cet élément, et ce premier 'break' effectue le zapping à la perfection, en une seule ligne, sans besoin de commenter l'ancien code en place ! "} break; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_QUANTITY_HEADING" design-customer-profile="' . $customerProfile .'"'; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" ATTENTION - avant octobre 2020, le client, aimait le terme renvoyé par la constante TABLE_HEADING_QUANTITY"= MAIS depuis octobre 2020, le client, finalement préfère que cela soit écrit 'Stock' "} $lc_text = 'Stock'; $lc_align = 'center'; break; case 'PRODUCT_LIST_WEIGHT': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_WEIGHT_HEADING" design-customer-profile="' . $customerProfile .'"'; $lc_text = 'Disponibilité'; $lc_align = 'center'; break; case 'PRODUCT_LIST_IMAGE': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_IMAGE_HEADING" design-customer-profile="' . $customerProfile .'"'; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on change juste le texte TABLE_HEADING_IMAGE en une notification qu'en cliquant sur une colonne on peut trier "} $lc_text = 'Trier par:'; $lc_align = 'center'; break; case 'PRODUCT_LIST_BUY_NOW': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_BUY_NOW_HEADING" design-customer-profile="' . $customerProfile .'"'; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" dans IMAGE_BUTTON_OUT_OF_STOCK on ajoute un saut de ligne à un endroit stratégique, ainsi qu'englober le texte dans un avec une classe, pour qu'on puisse le cibler en responsive afin de le masquer! - ATTENTION - avant octobre 2020, le client, aimait l'affichage issu du code str_replace('Acheter', 'Acheter
', TABLE_HEADING_BUY_NOW) - depuis octobre 2020, le client, finalement préfère n'avoir que 'Acheter' "} $lc_text = '' . str_replace(TABLE_HEADING_BUY_NOW, 'Acheter', TABLE_HEADING_BUY_NOW) . ''; $lc_align = 'center'; break; } /* ************************************************************************ [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{ - 1/ on va ajouter un tas de petites modifications, des classes, des styles, et peut-être du comportement à différents éléments de la génération de cette partie du générateur du tableau - 2/ on va vérifier si notre précédente variable $lc_si_classProductListingElement existe (elle est créée dans chaque cas plus haut!), sinon, on la créé mais on la valorise à rien notre précédente variable $lc_si_cellBlockTDElement existe (elle est créée dans chaque cas plus haut!), sinon, on la créé mais on la valorise à rien - 3/ on modifie l'ancien code, params => ... afin d'y ajouter notre nouvelle variable $lc_si_classProductListingElement à la suite des classes on veut que notre $lc_si_cellBlockTDElement précédemment déclaré en [5] nous serve dans la cellule (car par défaut, le tri n'est basé que sur le texte, ce qui est peu pratique). cette action résulte d'ajouter le tri au clic sur la cellule (en plus du texte $lc_text) - 4/ on revalorise ici la variable $lc_si_classProductListingElement et $lc_si_cellBlockTDElement à rien.. afin d'éviter toutes sortes de conflits ! - 5/ on déclare une variable $lc_si_cellBlockTDElement, elle contiendra le lien de TRI! ce lien de tri est créé par la fonction tep_create_sort_heading() mais, problème, cette fonction créé une balise html en plus... notre regex (celle commentée) devait donc détruire toute chose qui ne sont pas -le lien-, en gros, tout ce qu'il y a dans href="(ICI)", on gardait, le reste on jettait! bien que ça fonctionnait sans aucuns soucis, cela nous donnait pas assez de contrôle sur l'infobulle.. ainsi, à la place, maintenant, on utilise un preg_match() et des groupes de captures nommés, de cette façon on fait comme attendu, MAIS en plus de ça on garde le moyen de réutiliser l'adresse/infobulle n'importe où dans la page - 6/ de la même façon, là, on va juste remplacer ici toute l'ancienne façon de générer le lien on va en outre lui ajouter aussi une partie "title" par un uk-tooltip comme avant en [5] [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique: - 1/ pour les besoins de la nouvelle charte graphique, et donc, intrinséquement du nouveau design, on va devoir désormais effectuer quelques étapes-clefs, il a été décidé que dans la nouvelle charte graphique on ne doit plus avoir de colonne d'en-tête (en terme de génération de données HTML): 'Stock' 'Modèle' au final on empêche la génération d'une colonne si le nom de la colonne coincide avec ça: PRODUCT_LIST_MODEL qui correspond à la colonne 'Modèle' PRODUCT_LIST_QUANTITY qui correspond à la colonne 'Stock' pour ce faire, un simple if() suffira ici.. - 2/ ISSUE BUG BUGFIX en rapport avec l'intégration de la solution localisée de la réorganisation des colonnes (voir CODETAG[VTAB_REORDERING_SORTED_COLUMNS_ORDER], étape [1]) nous avons provoqué une légère anomalie (car facilement réparable) mais fatale (car faisant planter le site...) mise en situation: chaque colonne ont un évènement 'onclick' (sauf certaines en particuliers) ce lien symbolise le type (case) de filtre qui sera utilisé à l'emplacement du fichier 'index.php' (voir son bloc d'instruction: switch ($column_list[$sort_col-1])) mais curieusement, si n'importe quelle colonne (nom, prix, etc..) fonctionne, il s'avère que... ... en voulant trier les produits par disponibilité, on obtient au final à coups sûr une erreur SQL de syntaxe cause de l'erreur: l'ordre initial des colonnes se décide ailleurs, et cette décision a lieu dans le fichier '/index.php' (voir le commentaire: "// create column list" initialement déposé par l'équipe OSCommerce ) l'ordre que nous avons demandé et développé se trouve ici, dans ce fichier, (voir CODETAG[VTAB_REORDERING_SORTED_COLUMNS_ORDER]) comme on peut le constater, (voir CODETAG[OSC_GENERATED_SORTED_COLUMNS_ORDER]) le lien de filtrage des colonnes génère un paramètre $_GET['sort'] égal à un code du genre: chiffre + a ou d ce lien est généré par la fonction OSCommerce et les arguments: tep_create_sort_heading($HTTP_GET_VARS['sort'], $col+1, $lc_text) le chiffre = indique en réalité un index numérique du tableau associatif $column_list, et il utilise l'instance du fichier '/index.php' et non celle du fichier là le tableau associatif $column_list sera donc lu comme une association de l'index numérique avec une clef qui lui est attachée (1 = PRODUCT_LIST_MODEL ; ... 4 = PRODUCT_LIST_PRICE) le tableau associatif $column_list de ce fichier où vous pouvez lire ce bugfix n'est pas prioritaire (car modifié par la suite, et uniquement dans ce fichier) d'où la mauvaise association 'index numérique' => 'clef attachée' le caractère a = symbolise juste un repère pour la logique du code du switch, le a indique donc un tri SQL Ascendant: asc(ending) le caractère d = symbolise juste un repère pour la logique du code du switch, le d indique donc un tri SQL Descendant: desc(ending) que se passe t-il? et bien, on remarque le lien de filtrage généré pour la colonne du TABLEAU HTML: PRODUCT_LIST_WEIGHT est égal à 5a DONC: si l'on se refère à notre tableau PHP $column_list (voir CODETAG[]), le 5 est égal à: PRODUCT_LIST_WEIGHT CE: qui est théoriquement correct, vu que PRODUCT_LIST_WEIGHT est utilisé pour la colonne de disponibilité OR: c'est pas bon, car, le tableau PHP sur lequel se baser sera celui prioritaire et non le tableau de ce fichier.. et ça devrait donc être égal à 6a et non 5a ET: où est le tableau PHP prioritaire? ICI: dans le fichier '/index.php' (voir le commentaire: "// create column list" initialement déposé par l'équipe OSCommerce ) DONC: on doit à tout prix éviter que tep_create_sort_heading() n'utilise comme référent de construction des colonnes de filtrages le tableau PHP non-prioritaire AINSI: on doit développer une petite logique d'interception qui ne nécéssite pas d'ajustements supplémentaires si l'on décide de remodifier le tableau $column_list.. Pour ce faire, on va se servir du tableau PHP original que l'on a backup plus haut dans: $VTAB_productListing_backupOSCommerceSortOrderedListing , on va aussi rechercher l'index numérique de la colonne indiquée par : $column_list[$col] , on stocke tout ça dans une nouvelle variable (qui sera nullifiée juste après le $lc_si_cellBlockTDElement): $VTAB_productListing_trickOSCommerceSortColumnIndex , mais on la stocke sans le +1 directement, car, on incrémentera plutôt lors de l'usage de la variable au sein de la fonction tep_create_sort_heading() , pour proprifier un peu le factoring, on refactorise un peu le preg_match() pour l'écrire sur plusieures lignes au lieu d'une seule , et enfin, on se sert de notre notre variable au sein de la fonction tep_create_sort_heading() à qui l'on incrémente de 1 la valeur à l'intérieur , pourquoi le +1 ? simplement car le filtrage ne considère pas l'élément 0 (index 0) comme un index de filtrage valide.., donc +1 à chaque fois ! , et juste après tout cela, on nullifie la variable qui aura servi au compteur trafiqué : $VTAB_productListing_trickOSCommerceSortColumnIndex , fin - 3/ ISSUE BUG BUGFIX on ne veut pas de liens dans l'en-tête des colonnes qui n'ont pas de filtres (non-filtrables) on vide juste la variable: $lc_si_cellBlockTDElement } */ // ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN if ( ($column_list[$col] != 'PRODUCT_LIST_BUY_NOW') && ($column_list[$col] != 'PRODUCT_LIST_IMAGE') ) { // ([5])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN // ([2])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN $VTAB_productListing_trickOSCommerceSortColumnIndex = array_search($column_list[$col], $VTAB_productListing_backupOSCommerceSortOrderedListing); // [OSC_GENERATED_SORTED_COLUMNS_ORDER] preg_match( '/\s{0,}(?P.*)\s{0,}<\/a>/', tep_create_sort_heading($HTTP_GET_VARS['sort'], ($VTAB_productListing_trickOSCommerceSortColumnIndex+1), $lc_text), $dataArrayRegex__1 ); $lc_si_cellBlockTDElement = 'onmouseover="this.style.cursor=\'pointer\';"' . ' ' //. 'onclick="window.location.href=\'' . preg_replace('/([VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([5])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([6])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN $lc_text = '' . $dataArrayRegex__1['texte_lien'] . ''; // ([6])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END } // ([3])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN else { $lc_si_cellBlockTDElement = ''; } // ([3])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN if ($column_list[$col] != 'PRODUCT_LIST_MODEL' and $column_list[$col] != 'PRODUCT_LIST_QUANTITY') { // ([2])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN if (empty($lc_si_classProductListingElement)) { $lc_si_classProductListingElement = ''; } if (empty($lc_si_cellBlockTDElement)) { $lc_si_cellBlockTDElement = ''; } // ([2])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END $list_box_contents[0][] = array('align' => $lc_align, // ([3])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN 'params' => 'class="productListing-heading"' . ' ' . $lc_si_classProductListingElement . ' ' . $lc_si_cellBlockTDElement, // ([3])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END 'text' => ' ' . $lc_text . ' '); // ([4])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN $lc_si_classProductListingElement = ''; $lc_si_cellBlockTDElement = ''; // ([4])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END } // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END /* [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions] ************************************************************************ */ } if ($listing_split->number_of_rows > 0) { $rows = 0; $listing_query = tep_db_query($listing_split->sql_query); // -> QPBPP135 $no_of_listings = tep_db_num_rows($listing_query); while ($_listing = tep_db_fetch_array($listing_query)) { $_listing['discount_categories_id'] = NULL; $listing[] = $_listing; $list_of_prdct_ids[] = $_listing['products_id']; } $list_of_prdct_ids = array_unique($list_of_prdct_ids); $price_breaks_query = tep_db_query("select products_id, products_price, products_qty from " . TABLE_PRODUCTS_PRICE_BREAK . " where products_id in (" . implode(',', $list_of_prdct_ids) . ") order by products_id, products_qty"); while ($price_break = tep_db_fetch_array($price_breaks_query)) { $price_breaks_array[$price_break['products_id']][] = array('products_price' => $price_break['products_price'], 'products_qty' => $price_break['products_qty']); } $discount_category_query = tep_db_query("select p.products_id, p.products_quantity, p.products_weight, discount_categories_id from " . TABLE_PRODUCTS ." p left join " . TABLE_PRODUCTS_TO_DISCOUNT_CATEGORIES . " using(products_id) where p.products_id in (" . implode(',', $list_of_prdct_ids) . ")"); while ($dc_array = tep_db_fetch_array($discount_category_query)) { $discount_categories[] = array ('products_id' => $dc_array['products_id'], 'products_quantity' => $dc_array['products_quantity'], 'products_weight' => $dc_array['products_weight'], 'discount_categories_id' => $dc_array['discount_categories_id']); } for ($x = 0; $x < $no_of_listings; $x++) { // add discount categories to the listing array if(!empty($discount_categories)) { for ($i = 0; $i < count($discount_categories); $i++) { if ($listing[$x]['products_id'] == $discount_categories[$i]['products_id'] ) { $listing[$x]['discount_categories_id'] = $discount_categories[$i]['discount_categories_id']; $listing[$x]['products_quantity'] = $discount_categories[$i]['products_quantity']; $listing[$x]['products_weight'] = $discount_categories[$i]['products_weight']; } } } // end if(!empty($discount_categories) } // while ($listing = tep_db_fetch_array($listing_query)) { (was original code) for ($x = 0; $x < $no_of_listings; $x++) { $rows++; /* ************************************************************************ [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{ - 1/ ATTENTION - depuis février 2021, suite à une demande tardive du client, on va devoir créer un système intelligent d'auto-scroll pour ré-atteindre le même endroit de la page lorsqu'on a ajouté un produit au panier - 2/ ici on va ajouter un attribut 'page-position' à chacun des éléments en réalité, ces éléments plus tard seront transformés en : bref, ça, ce n'est pas important, l'important ici est de construire la valeur du nouvel attribut page-position, de manière à retrouver exactement une position unique de fait, comme l'identifiant du produit (id pas model_number), est unique, alors, on va l'utiliser et faire l'auto-scroll à la fin de la page grâce à UIKit et son composant Scroll ATTENTION il est requis pour fonctionner avec UIKit et son composant Scroll, que le 1er caractère de la valeur de l'attribut ciblé, SOIT OBLIGATOIREMENT une lettre ATTENTION sinon, UIKit renverra une erreur javascript ici on construit la cible de l'auto-scroll (voir CODETAG[AUTO_SCROLL_TARGET_PAGE_POSITION_IN_PRODUCT_LISTING]) et on construit ailleurs le déclencheur de l'auto-scroll (voir CODETAG[AUTO_SCROLL_TRIGGER_PAGE_POSITION_IN_PRODUCT_LISTING]) [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique: - 1/ on ajoute une classe CSS à cet élément afin de pouvoir le cibler plus tard via une règle CSS } */ // ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN if (($rows/2) == floor($rows/2)) { // ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // [AUTO_SCROLL_TARGET_PAGE_POSITION_IN_PRODUCT_LISTING] // ([1])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END $list_box_contents[] = array('params' => 'class="productListing-even border-productListing"' .' page-position="pp'.$listing[$x]['products_id'].'"'); } else { // ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // [AUTO_SCROLL_TARGET_PAGE_POSITION_IN_PRODUCT_LISTING] // ([1])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END $list_box_contents[] = array('params' => 'class="productListing-odd border-productListing"' .' page-position="pp'.$listing[$x]['products_id'].'"'); } // ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END /* [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions] ************************************************************************ */ $cur_row = sizeof($list_box_contents) - 1; for ($col=0, $n=sizeof($column_list); $col<$n; $col++) { $lc_align = ''; /* ************************************************************************ [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions]:{ - 1/ ici on va ajouter un petit système pour effectuer un meilleur ciblage du profil client - 2/ dans le but de davantage pouvoir avoir en [4] et valorisé en [3] un granularité beaucoup plus précise dans le ciblage CSS on ajoute une variable spéciale PHP qui nous aidera à délimiter le profil commercial du client - 3/ on va valoriser la variable déclarée en [2] 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. - 4/ ce procédé servira à différents autres endroits du fichier où lui on injectera la nouvelle donnée dynamique renseignée en [3] 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é (voir CODETAG[VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE]) } */ // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN // ([2])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END $customerProfile = 'Standard'; // ([3])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN if ($is_partner == true) { $customerProfile = 'Partenaire'; } else if (is_pro_customer() == true) { $customerProfile = 'Professionnel'; } // ([3])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END /* [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] ************************************************************************ */ switch ($column_list[$col]) { case 'PRODUCT_LIST_MODEL': // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" dans les besoins de cette tâche, on doit masquer cet en-tête de colonne, la façon la plus simple ici, c'est de rajouter un 'break' pour sortir de la boucle si ce cas est spécifiquement rencontré dans la boucle for() et dans l'interrupteur switch(), on conserve alors le code du bas, avant le deuxième 'break', mais ce code avant ce deuxième 'break' ne sera alors jamais lu ni interprété, on peut le conserver dans le code, il ne sera jamais exécuté à cause du premier 'break', c'est ce que l'on veut, vu qu'on veut zapper l'exécution de cet élément, et ce premier 'break' effectue le zapping à la perfection, en une seule ligne, sans besoin de commenter l'ancien code en place ! "} break; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_MODEL_DATA" design-customer-profile="' . $customerProfile .'"'; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on change juste ici l'alignement de $lc_align de '' vers 'center' "} $lc_align = 'center'; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on encadre ici le nom du modèle par une balise div, et on lui donne une classe CSS pour la cibler plus tard "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" on ajoute ici une petite mention textuelle avant le nom de modèle "} $lc_text = '
Ref. ' . $listing[$x]['products_model'] . '
'; break; case 'PRODUCT_LIST_NAME': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_NAME_DATA" design-customer-profile="' . $customerProfile .'"'; $lc_align = ''; // -> PEF : Product Extra fields $extra_fields_text = ''; $extra_fields_query = tep_db_query(" SELECT pef.languages_id, pef.products_extra_fields_status as status, pef.products_extra_fields_name as name, ptf.products_extra_fields_value as value FROM ". TABLE_PRODUCTS_EXTRA_FIELDS ." pef LEFT JOIN ". TABLE_PRODUCTS_TO_PRODUCTS_EXTRA_FIELDS ." ptf ON ptf.products_extra_fields_id=pef.products_extra_fields_id WHERE ptf.products_id=". (int) $listing[$x]['products_id'] ." and pef.languages_id=" . (int)$languages_id . " and ptf.products_extra_fields_value<>'' ORDER BY products_extra_fields_order"); while ($extra_fields = tep_db_fetch_array($extra_fields_query)) { if (! $extra_fields['status']) continue; $extra_fields_text = $extra_fields_text. ''.$extra_fields['name'].': ' . '' .$extra_fields['value'].'
'; } // -> VD : ajout du tableau des prix par pallier � cot� du nom des produits $pf->loadProduct($listing[$x]['products_id'], $languages_id); // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on appelle juste ici la nouvelle méthode ->getPriceStringVersion2 introduite dans la classe PriceFormatter au lieu de la vieille et ancienne méthode ->getPriceString, et on n'oublie pas de choisir le mode nouvellement introduit: OnlyPriceBreaker*, afin de masquer les prix dégressifs, si il n'y a pas de tableau de PriceFormatter à afficher, on affiche alors 4 sauts de lignes avec '
' afin de conserver une hauteur minimale à l'affichage (*)ATTENTION - avant octobre 2020, le client, aimait l'affichage où le 1+ n'apparaissait plus (OnlyPriceBreaker) NOTE depuis octobre 2020, le client, finalement préfère l'affichage à l'ancienne, avec le +1 (Standard) "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" désormais, si il n'existe rien à afficher ici, on évite d'afficher les 4 sauts de lignes
initiaux, on renvoie plutôt une chaîne vide "} $extra = ($pf->hasQuantityPrice())?$pf->getPriceStringVersion2('productPriceInBox', 'left', 'Standard'):''; /* ************************************************************************ [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{ - 1/ on va ajouter un tas de petites modifications, des classes, des styles, et peut-être du comportement à différents éléments de la génération de cette cellule du tableau - 2/ 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 - 3/ on commente l'ancien code, $lc_text [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique: - 1/ pour les besoins de la nouvelle charte graphique, et donc, intrinséquement du nouveau design, on va devoir désormais effectuer quelques étapes-clefs, il a été décidé que comme dans la nouvelle charte graphique on ne doit plus avoir de colonne d'en-tête (en terme de génération de données HTML) pour les éléments : 'Stock' 'Modèle' au final on a empêché aussi la génération des valeurs liées à ces colonnes : PRODUCT_LIST_MODEL qui correspond à la colonne 'Modèle' PRODUCT_LIST_QUANTITY qui correspond à la colonne 'Stock' on va donc devoir ajouter les données de 'Stock' et de 'Modèle' à d'autres colonnes dans cette colonne on va ajouter, par concaténation, la donnée de 'Modèle' telle que la colonne initiale PRODUCT_LIST_MODEL l'avait, ( on encadre aussi ici le nom du modèle par une balise div, et on lui donne une classe CSS pour la cibler plus tard ) concernant la colonne PRODUCT_LIST_QUANTITY, ce sera plus loin dans un autre - 2/ on va devoir afficher le nom du modèle (référence) après les éventuels [champs d'attributs spéciaux] ($extra_fields_text) et après l'éventuel [tableau de prix productPriceInBox] ($extra) au lieu d'inclure le $extra_fields_text et les $extra à la suite du lien, on va l'inscrire ailleurs, donc à la place de: $listing[$x]['products_name'] . $extra_fields_text . '

' . $extra; (voir CODETAG[VTAB_1_OSC_MOVE_EXTRA_FIELDS_EXTRA_FROM_THERE]) on écrira $listing[$x]['products_name'] . ''; (voir CODETAG[VTAB_1_OSC_MOVE_EXTRA_FIELDS_EXTRA_INTO_THERE]) - 3/ il y a désormais besoin de précéder le nom de modèle (référence) du produit par un terme 'ref. ' dans la nouvelle version de cette refonte visuelle } */ // ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN if (isset($HTTP_GET_VARS['manufacturers_id'])) { // ([2])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN $lc_text = ' ' // ([2])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN // [VTAB_1_OSC_MOVE_EXTRA_FIELDS_EXTRA_FROM_THERE] . $listing[$x]['products_name'] . ''; // ([2])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // $lc_text = '' . $listing[$x]['products_name'] . $extra_fields_text . '

' . $extra; // ([1])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([3])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END $lc_text .= '
Ref. ' . $listing[$x]['products_model'] . '
'; // [VTAB_1_OSC_MOVE_EXTRA_FIELDS_EXTRA_INTO_THERE] $lc_text .= $extra_fields_text . $extra; // ([2])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END } else { // ([2])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN $lc_text = ' ' // ([2])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN // [VTAB_1_OSC_MOVE_EXTRA_FIELDS_EXTRA_FROM_THERE] . $listing[$x]['products_name'] . ''; // ([2])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([3])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // $lc_text = ' ' . $listing[$x]['products_name'] . $extra_fields_text . '

' . $extra; // ([1])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([3])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END $lc_text .= '
Ref. ' . $listing[$x]['products_model'] . '
'; // [VTAB_1_OSC_MOVE_EXTRA_FIELDS_EXTRA_INTO_THERE] $lc_text .= $extra_fields_text . $extra; // ([2])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END /* [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions] ************************************************************************ */ // <- VD // <- PEF } break; case 'PRODUCT_LIST_MANUFACTURER': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_MANUFACTURER_DATA" design-customer-profile="' . $customerProfile .'"'; $lc_align = ''; $lc_text = ' ' . $listing[$x]['manufacturers_name'] . ' '; break; case 'PRODUCT_LIST_PRICE': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_PRICE_DATA" design-customer-profile="' . $customerProfile .'"'; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on change juste ici l'alignement de $lc_align de 'right' vers 'center' "} $lc_align = 'center'; $price_breaks_from_listing = array(); if (isset($price_breaks_array[$listing[$x]['products_id']])) { $price_breaks_from_listing = $price_breaks_array[$listing[$x]['products_id']]; } $pf->loadProduct($listing[$x]['products_id'], $languages_id); // -> OSC-70 : Gestion HT/TTC : affichage prix HT et TTC // exemple: "A partir de 0.10EUR HT / 0.12EUR TTC" // On ajoute un espace apr�s le prix HT, ceci permet de d�caler un peu le prix du bord, ce qui l'ajuste � peu pr�s au prix TTC en terme de positionnement horizontal /************************************************************************ [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{ - 1/ on reformate visuellement le code - 2/ on appelle ici la nouvelle méthode ->getPriceStringShortVersion2 introduite dans la classe PriceFormatter au lieu de la vieille et ancienne méthode ->getPriceStringShort, pour restyliser le symbole EUR - 3/ usage de symbole € plutôt d'EUR qui vont servir à reformater le prix avec le nouveau design de reformatage de monnaie euros pour cela, on va simplement trouver et remplacer EUR par €, avec en outre une classe CSS pour cibler! - 4/ remplacement de l'ancien " /" par une balise HTML
, afin de rendre plus clair la dissociation du prix HT vis-à-vis du prix TTC - 5/ ici on va restructurer non seulement le code du prix partenaire, mais aussi revoir entièrement la structure HTML - 6/ ici on va tester une regex, si le texte 'En solde' est manquant dans la variable $price alors, ajoute notre symbole € dans le style du design et la mention HT, sinon elle serait absente.. - 7/ ATTENTION - avant octobre 2020, le client, aimait l'affichage en noir du prix TTC - depuis octobre 2020, le client, finalement préfère un autre affichage (donc on va englober l'élément dans un HTML et lui donner une classe CSS afin de le styliser plus tard) - 8/ ATTENTION - avant octobre 2020, le client, aimait l'affichage du prix TTC aux clients PRO - depuis octobre 2020, le client, finalement préfère un autre affichage donc on va devoir ruser.. - on va ajouter une condition pour vérifier si le client est un compte professionnel - si oui, on va renseigner une variable (qu'on aura déclaré au préalable pour éviter les erreurs d'avertissements de UNDEFINED VARIABLE - dans la variable, si on est face à un client professionnel, on aura le nom d'une classe CSS supplémentaire que l'on introduira dans le
et le HTML afin de le styliser plus tard) - et on supprime la variable qui n'était qu'à titre temporaire pas référenceuse - 9/ ATTENTION - depuis janvier 2021, suite à une demande tardive du client, on va devoir revoir le terme (si le produit est en solde/promotion/à prix réduit) par un autre - on renomme à nouveau le terme (contenu dans !preg_match) de "En solde" vers "Promotion" - on pourrait le faire dans la constante PHP, sans str_replace, mais, cela nous obligerait à nous assurer que partout ce texte serait correct, tandis que là, on fait selon l'utilité, c'est mieux! - à noter que ce terme est aussi à remplacer par le même terme dans le fichier: - includes/classes/PriceFormatter.php - (voir CODETAG[TEXT_ON_SALE_BASED_HERE]) - 10/ ATTENTION - depuis octobre 2021, suite à une prise de considération tardive, on s'est rendu compte que les prix partenaires étaient érronnés à l'affichage depuis ce module (includes/modules/product_listing.php) - il semblerait que l'ancienne méthode ->getPriceStringShort() ORIGINALE était depuis toujours incorrecte (cette ancienne méthode a été développée et mise en place par un certain Thibault, (et à ce que l'on a pu apprendre, il s'agirait d'un ancien stagiaire en formation: dont malheureusement le contact avec lui est devenu impossible de nos jours) - la nouvelle méthode ->getPriceStringShortVersion2() que l'on a mise en place nous-même, et qui fut basée sur l'ancienne méthode ->getPriceStringShort() pour ce qui concerne le calcul du prix correct .., .. a hérité du même bug de mauvais calcul du prix - la nouvelle méthode ->getPriceStringShortVersion2() est censée calculer le prix sur le prix de vente MOINS le coeeficient réduit attaché au partenaire (depuis sa fiche client dans le backoffice), or là, elle calculait le prix de vente normal, et ommétait le calcul du coeeficient (le fameux $coeff_partner) .. .. ce qui inéluctablement menait à un prix complètement biaisé ! - RAPPEL : la nouvelle méthode ->getPriceStringShortVersion2() n'a de différence que la structure HTML, pas la logique de conditions (hormis un argument HT/TTC additionnel, pour formater les couleurs CSS différamments à travers de nouvelles balises HTML attachées à de nouvelles classes CSS) ni de différentes façons de traiter les données, l'ancienne méthode ->getPriceStringShort() même restaurée ne fixe pas le problème, bref, le mauvais calcul est apparent lors du passage d'un prix partenaire coeeficient passé à ->getPriceStringShort() ou même à ->getPriceStringShortVersion2(), le problème c'est que: dans ces deux méthodes on a aucun moyen (développé initialement) pour détecter si le client EST OU NON un partenaire .. .. et que de modifier cette logique de calcul depuis la méthode ->getPriceStringShortVersion2() en elle-même fausserait alors le calcul du prix d'un simple client PROFESSIONNEL ! - DONC : pour éviter les ennuis de calcul et de conditions bien trop complexe... et vu que ces dux méthodes ne sont utilisées, QUE dans ce fichier, ET QUE lors de la refonte du design, on a déjà fait la dissociation dans le module product_listing alors on peut aisément bricoler un changement local au lieu d'une révision de la méthode en elle-même - NOTE : si jamais la méthode ->getPriceStringShortVersion2() doit être réutilisée AILLEURS que dans le fichier du module product_listing, alors il faudra REVOIR la méthode en elle-même, pour le moment, on va alors commenter la ligne d'appel à la méthode ->getPriceStringShortVersion2 introduite à l'étape [2] et valoriser la valeur de $price à celle de $partner_price, sans aucunes autres modifications et apparemment, ça fonctionnera ainsi (même si, ce n'est que du bricolage, mais un bricolage propre!) - 11/ ATTENTION - depuis octobre 2021, suite à une prise de considération tardive, on s'est rendu compte que les prix partenaires étaient érronnés à l'affichage depuis ce module (includes/modules/product_listing.php) (voir [10] pour les explications complètes), ici on va juste encadrer la valeur du prix partenaire entre une structure HTML capable de styliser proprement avec une classe déjà existante dans la nouvelle version du design [VTAB-TEAM-LINDER-PARTNER-1][OSC][MultiTaskDescriptions] - Revue de la charte Graphique: - 1/ sur la demande du client, nous effectuons le retrait de ces éléments nous les mettons en commentaires - 2/ retrait ' ' afin de faciliter de remonter le mot "promotion" dans la cellule des prix - 3/ initialement pour évaluer le prix Partenaire (VIP) quand on a besoin de l'afficher sous forme de chaîne on faisait appel à PriceFormatter, et à sa méthode: getPartnerPrice() mais on avait un souci, le prix fort (donc prix non-promotionnel) était ce qui en résultait... et forcément, bah ce n'est pas correct cela se voyait uniquement dans le cas suivant: si on avait un prix promotionnel, avec un tableau dégressif, Incorrect: le prix fort HT (donc non-promotionnel) est affiché dans la page listing Correct : il faut afficher le prix le plus bas cela se voyait uniquement dans le cas suivant: si on avait un prix promotionnel, sans tableau dégressif, Incorrect: le prix fort HT (donc non-promotionnel) est affiché dans la page listing Correct : il faut afficher le prix le plus bas un petit debug est laissé en commentaire pour voir les différences (voir CODETAG[VTAB_DEBUG_COEFFICIENT_PRICE_PARTNER]) entre avant [getPartnerPrice()], un test [getPricePartnerVersion2()] et après [getStringPricePartner()] } */ // ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN if ($is_partner == true) { // ([3])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END $partner_price = number_format((float)$pf->getStringPricePartner($coeff_partner), 2, '.', ''); /* // [VTAB_DEBUG_COEFFICIENT_PRICE_PARTNER] if ($listing[$x]['products_model'] == 'rnmst-006 fin de série') { echo '
méthode: getPartnerPrice() = '; var_dump(number_format((float)$pf->getPartnerPrice($coeff_partner), 2, '.', '')); echo '
'; } if ($listing[$x]['products_model'] == 'rnmst-006 fin de série') { echo '
méthode: getPricePartnerVersion2() = '; echo $pf->getPricePartnerVersion2(); echo '
'; } if ($listing[$x]['products_model'] == 'rnmst-006 fin de série') { echo '
méthode: getStringPricePartner() = '; var_dump(number_format((float)$pf->getStringPricePartner($coeff_partner), 2, '.', '')); echo '
'; } */ // ([10])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN // ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END //$price = min($partner_price, $pf->getPriceStringShortVersion2( 'HT' )); $price = $partner_price; // ([10])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([6])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([9])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // CODETAG[TEXT_ON_SALE_BASED_HERE] if ( !preg_match('/Promotion/', $price) ) { $price = $price . '' . ' HT'; } $percent_vip = tep_get_specials_indicator_vip(tep_get_products_cost($listing[$x]['products_id']), $coeff_partner, $listing[$x]["specials_new_products_price"]); if ($percent_vip != '' ){ $percent_vip_text = '
' . '' . str_replace(TEXT_ON_SALE, '' . $percent_vip .'', TEXT_ON_SALE) . ' ' . '
'; } else{ $percent_vip_text = ""; } // ([5])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN $lc_text = ' ' // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::BEGIN /* . 'Prix partenaire' . '
' */ // ([1])-->[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END // ([11])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END . '' . $price . '
' . '
' . $percent_vip_text ; // ([5])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([3])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN $lc_text = str_replace( 'EUR', '', $lc_text ); // ([3])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END } else { // ([8])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN $cssClassTTCPriceIfFacedToAProCustomer = ''; if (is_pro_customer()) { $cssClassTTCPriceIfFacedToAProCustomer = ' --globalUsageText__--stylishPriceInInvisible'; } // ([8])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END $lc_text = $pf->getPriceStringShortVersion2( 'HT' ) // ([4])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::BEGIN // .' ' // ([8])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END . '
' // ([4])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([2])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([7])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([8])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END // ([2])-->BEGIN[VTAB-TEAM-LINDER-PARTNER-1][OSC][SubTaskDescription]::END . '' . str_replace(TEXT_PRICE_BREAKS, '', $pf->getPriceStringShortVersion2( 'TTC' )) . ''; // ([8])-->BEGIN[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END $cssClassTTCPriceIfFacedToAProCustomer = null; } // ([1])-->[SI-LINDER-PARTNER-2][OSC][SubTaskDescription]::END /* [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions] ************************************************************************/ break; case 'PRODUCT_LIST_QUANTITY': // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" dans les besoins de cette tâche, on doit masquer cet en-tête de colonne, la façon la plus simple ici, c'est de rajouter un 'break' pour sortir de la boucle si ce cas est spécifiquement rencontré dans la boucle for() et dans l'interrupteur switch(), on conserve alors le code du bas, avant le deuxième 'break', mais ce code avant ce deuxième 'break' ne sera alors jamais lu ni interprété, on peut le conserver dans le code, il ne sera jamais exécuté à cause du premier 'break', c'est ce que l'on veut, vu qu'on veut zapper l'exécution de cet élément, et ce premier 'break' effectue le zapping à la perfection, en une seule ligne, sans besoin de commenter l'ancien code en place ! "} break; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_QUANTITY_DATA" design-customer-profile="' . $customerProfile .'"'; $lc_align = 'center'; // -> 0000013: ajustement quantit� affich�e selon fournisseur $lc_text = ' 
' . find_qty_by_manufacturer($listing[$x]['manufacturers_id'], $listing[$x]['products_quantity']) . '
 '; // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on répète cette variable, (en la concaténant) mais cette fois avec le même div mais un autre attribut id, servira à afficher en responsive, tout en masquant celui de base un ligne plus haute "} $lc_text = $lc_text . ' 
' . find_qty_by_manufacturer($listing[$x]['manufacturers_id'], $listing[$x]['products_quantity']) . '
 '; // <- 0000013 break; case 'PRODUCT_LIST_WEIGHT': // [SI-LINDER-PARTNER-2][OSC][SimpleTaskDescription]:{" on ajoute une variable 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 (petite précision, il s'agit de la destination de la colonne "Disponibilité" ! "} // [VTAB-TEAM-LINDER-PARTNER-1][OSC][SimpleTaskDescription]:{" en référence à la granularité ciblable du profil client, on ajoute un attribut HTML ici, [VTAB_1_OSC_ADD_DESIGN_CUSTOMER_PROFILE_ATTRIBUTE] "} $lc_si_classProductListingElement = 'design-element-target="PRODUCT_LIST_WEIGHT_DATA" design-customer-profile="' . $customerProfile .'"'; $lc_align = 'center'; $suppliers_orders = new SuppliersOrders(); $suppliers_orders->retrieveOrderedProducts($listing[$x]['products_id']); $lc_text = $suppliers_orders->getProductInfoDescription($listing[$x]['products_id']); /************************************************************************ [SI-LINDER-PARTNER-2][OSC][MultiTaskDescriptions]:{ - 1/ on va devoir modifier différents textes statiques afin de leur donner une balise HTML pour pouvoir plus tard les cibler via CSS - 2/ on ajoute une balise