Rediriger les fiches produits dans WooCommerce

Dans WooCommerce chaque produit a une page dédiée. Dans le panier, les produits renvoient à celles-ci.

Si vous voulez désactiver cette fonctionnalité et afficher une page avec tous vos produits, vous pouvez ajouter ce code à functions.php

// redirige les pages produits add_action('wp','prevent_access_to_product_page'); function prevent_access_to_product_page(){ if ( is_product() ) { wp_redirect( get_permalink( 269 ) ); } }
Code language: PHP (php)

Ainsi toutes les pages produits redirigeront vers la page 269.

Source : How to disable/hide woocommerce single product page?

Autoriser les images avec des longs ID dans PrestaShop

Par construction PrestaShop ne peut pas gérer les images avec des ID supérieurs à 9 999 999 (7 chiffres). C’est déjà beaucoup et on a pas souvent besoin de plus mais j’ai eu affaire à un script d’import qui impose les ID d’images et donc ça arrive.

Pourquoi PrestaShop ne les gèrent pas ?

En fait, PrestaShop n’a pas de soucis avec les ID de 8 chiffres ou plus, tant que la base de données l’accepte, lui aussi. Le problème vient de la façon d’accéder aux images.

L’URL d’une image est https://example.com/123-large/mon-image.jpg soit [url de la boutique]/[ID de l'image]-[format à afficher]/[texte pour le référencement].jpg et le fichier .htaccess explique au serveur que quand on a une url de ce type, il faut aller chercher le fichier qu’il faut dans le dossier des images /img/p/

Le fichier .htaccess de PrestaShop ressemble à ça

RewriteRule ^([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$1$2$3.jpg [L] RewriteRule ^([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$1$2$3$4.jpg [L] RewriteRule ^([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$1$2$3$4$5.jpg [L] RewriteRule ^([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$1$2$3$4$5$6.jpg [L] RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$1$2$3$4$5$6$7.jpg [L] RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$1$2$3$4$5$6$7$8.jpg [L] RewriteRule ^([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])([0-9])(\-[_a-zA-Z0-9-]*)?(-[0-9]+)?/.+\.jpg$ %{ENV:REWRITEBASE}img/p/$1/$2/$3/$4/$5/$6/$7/$1$2$3$4$5$6$7$8$9.jpg [L]
Code language: JavaScript (javascript)

Donc quand le serveur reçoit l’URL https://example.com/123-large/mon-image.jpg il affiche le fichier /img/p/1/2/3/123-large.jpg. C’est rapide et ça ne demande pas de ressource, PrestaShop n’est même pas appelé quand on veut afficher une image produit.

Mais on ne peut pas utiliser $10 dans un fichier .htaccess, il est interprété comme $1 puis le caractère 0. Comme dans la dernière ligne de l’extrait ci-dessus on utilise $9, on ne peut pas aller plus loin.

Ma solution

Si on appelle l’URL https://example.com/123456789-large/mon-image.jpg, le serveur ne reconnait pas ce format et essaye simplement d’afficher le fichier /123456789-large/mon-image.jpg qui n’existe pas et renvoie donc une erreur 404. PrestaShop affiche donc une jolie page pour dire que le fichier n’a pas été trouvée.

L’astuce consiste à utiliser cette page pour afficher l’image demandée en complétant le controller PageNotFound.

<?php class PageNotFoundController extends PageNotFoundControllerCore { public function initContent() { list($filename) = explode('?', $_SERVER['REQUEST_URI']); if (preg_match('/([0-9]+)(\-[_a-zA-Z0-9-]*)?\/.*\.jpg/', $filename, $matches)) { $path = _PS_ROOT_DIR_.'/img/p/'.implode('/', str_split($matches[1], 1)).'/'.$matches[1].$matches[2].'.jpg'; if (file_exists($path)) { header('Content-Type: '.mime_content_type($path)?:'image/jpg'); readfile($path); die(); } else { header('HTTP/1.1 404 Not Found'); header('Status: 404 Not Found'); header('Content-Type: image/gif'); readfile(_PS_ROOT_DIR_.'/img/404.gif'); die(); } } return parent::initContent(); } }
Code language: PHP (php)

Code à placer dans /override/controllers/front/PageNotFoundController.php

Le principe est le suivant :

  • quand le controller PageNotFound est appelé, on regarde si l’URL correspond à celle d’une image produit,
  • si oui on regarde si elle existe,
    • si oui on l’affiche et c’est terminé
    • si non on affiche une image d’erreur
  • si non on laisse le controller gérer

Sources :

input-date pour Vue3

Pareil que pour nl2br, j’ai voulu utiliser un champ date dans Vue3 mais le code que j’utilisais dans vue.js ne fonctionne pas.

Voici mon adaptation

// adapted from https://acdcjunior.github.io/how-bind-date-object-to-input-date-vue.js-v-model.html { props: ['modelValue'], emits: ['update:modelValue'], setup() { const dateToYYYYMMDD = (d) => { // alternative implementations in https://stackoverflow.com/q/23593052/1850609 try { return d && new Date(d.getTime()-(d.getTimezoneOffset()*60*1000)).toISOString().split('T')[0]; } catch(e) { return null; } }; return { dateToYYYYMMDD, } }, template: ` <input v-model="value" type="date" @input="$emit('update:modelValue', $event.target.valueAsDate)" /> `, computed: { value: { get() { return this.dateToYYYYMMDD(this.modelValue); }, set(value) { } } } }
Code language: JavaScript (javascript)

nl2br pour Vue3

J’ai voulu utiliser nl2br pour vue.js mais il n’est pas compatible avec Vue3.

Voici mon adaptation

// Adapted from https://github.com/inouetakuya/vue-nl2br/ { props: { tag: { type: String, required: true, }, text: { type: String, required: true, }, className: { type: String, required: false, }, }, setup(props) { return () => Vue.h( props.tag, { 'class': props.className }, props.text.split('\n').reduce((accumulator, string) => { if (!Array.isArray(accumulator)) { return [accumulator, Vue.h('br'), string] } return accumulator.concat([Vue.h('br'), string]) }) ); }, };
Code language: JavaScript (javascript)

iframe remplacé par i-frame dans Joomla

Si dans Joomla les balises <iframe>  sont remplacées par <i-frame> , c’est peut être à cause de RSFirewall!

La solution pour désactiver ce comportement est là : Scrambled tags (iframe becomes i-frame)

Le plus simple est de désactiver la protection pour son IP en l’ajoutant dans Composants > RSFirewall! > Blocklist/Safelist, bouton « Nouveau » et en sélectionnant « Safelist ».

 

Télécharger un dossier depuis Google Drive à partir du terminal

Pour faire suite à Télécharger un fichier depuis Google Drive à partir du terminal, j’ai eu à télécharger tout un dossier et la méthode décrite ne peut pas fonctionner.

J’ai donc utilisé rclone et ça fonctionne très bien. C’est plus long parce qu’il faut créer une application comme décrit dans la documentation mais une fois configuré c’est simple.

rclone copy drive:dossier_source ../dossier_destination

Il est dit sur la page de téléchargement comment l’installer mais ce n’est pas utile. Il fonctionne en décompressant l’archive et en l’exécutant dans le dossier créé.

Erreur xxx.live is not a function dans WordPress

A partir de la version 5.5 de WordPress, jQuery Migrate n’est plus activé par défaut. Par conséquent les vieux plugins (dans mon cas un Divi version 3) peuvent ne plus fonctionner.

L’erreur la plus commune semble être xxx.live is not a function

Pour corriger ce problème il faut installer Enable jQuery Migrate Helper qui le réactive.

Source : https://wordpress.org/support/topic/jqeuery-error-live-is-not-a-function/#post-13256885

Destinataires de mails avec Contact Form 7

Ça n’a rien de nouveau mais je ne m’en souviens jamais donc voici comment avoir un destinataire du mail envoyé par contact form 7 en fonction du choix fait par l’utilisateur dans le formulaire.

Mettre un champ select dans le formulaire avec comme choix « Texte à afficher|e-mail destinataire »

[select your-recipient "CEO|ceo@example.com"
                    "Sales|sales@example.com"
                    "Support|support@example.com"]

Dans l’onglet e-mail, mettre [your-recipient] comme destinataire.

Si on veut la valeur choisie dans le corps du mail, il faut mettre [_raw_{field name}] soit ici [_raw_your-recipient]

Source : https://contactform7.com/selectable-recipient-with-pipes/

Télécharger un fichier depuis Google Drive à partir du terminal

J’ai eu à restaurer un site dont les archives sont envoyées automatiquement sur Google Drive. C’est un peu compliqué pour les rapatrier depuis la console.

Voici la méthode la plus simple que j’ai trouvée:

    1. Rendre le fichier public
    2. Trouver l’ID du fichier
      Gdoc advanced sharing
      C’est le code qui ressemble à 1DQDioijcvsdf78qsdqsd586 dans le lien de partage. entre les /
    3. Si le fichier est suffisamment petit pour pouvoir être analysé par l’antivirus de Google :
      wget --no-check-certificate 'https://drive.google.com/uc?export=download&id=DOCUMENT_ID' -O FILENAME
    4. S’il est trop gros :
      curl -c /tmp/cookies "https://drive.google.com/uc?export=download&id=DOCUMENT_ID" > /tmp/confirmation.html
      curl -L -b /tmp/cookies "https://drive.google.com$(cat /tmp/confirmation.html | grep -Po 'uc-download-link" [^>]* href="\K[^"]*' | sed 's/\&amp;/\&/g')" > FILENAME

Sources :

Contact Form 7 et Popup Maker

Popup Maker peut réagir aux validations des formulaires de Contact Form 7. Enfin il devrait parce que ça ne fonctionne plus.

Je ne sais pas à quel moment Contact Form 7 a changé le nom de ses événements : wpcf7:mailsent  est devenu wpcf7mailsent

Pour remédier à ça, il faut ajouter au JavaScript du site

    jQuery(document).on('wpcf7mailsent', '.wpcf7', function (e, t) {         var event = new CustomEvent( 'wpcf7:mailsent', {             bubbles: true,             detail: e.detail         } );         e.target.dispatchEvent(event);     });
Code language: JavaScript (javascript)

comme cela les 2 événements sont envoyés.