Blog

/Blog

Le blog d’un développeur freelance passionné de web, qui partage ici diverses trouvailles et réflexions dans le domaine du web, du développement, du SEO, et des nouvelles technologies.


Prestashop : Exporter factures / avoirs PDF : Cron, Zip, email, FTP, dossier local

Prestashop permet d’exporter les factures en PDF (filtrées par date et statut de commande), cependant il génère un seul fichier PDF contenant toutes les factures, ce qui ne convient pas à ceux qui souhaitent avoir un fichier PDF par facture.

J’ai donc développé un module pour pouvoir faire un export similaire, mais générant un fichier PDF par facture, le tout dans un fichier ZIP.

Ce module propose également des fonctionnalités supplémentaires :

  • Export des avoirs (on choisit d’exporter les factures, les avoirs, ou les deux)
  • Filtrage par pays
  • Envoi de cet export automatiquement par mail, via une tache cron (avec période paramétrable)
  • Enregistrement de cet export automatiquement dans un dossier local, via une tache cron (avec période paramétrable)
  • Enregistrement de cet export automatiquement sur un serveur FTP externe, via une tache cron (avec période paramétrable)

Ce module est disponible sur Prestashop addons : Prestashop : Exporter factures / avoirs PDF : Cron, Zip, email, FTP, dossier local
Il est compatible Prestashop 1.6 et 1.7

N’hésitez pas à me contacter si vous souhaitez des modifications / ajout de fonctionnalités dans ce module, ou pour toute demande de développement spécifique de module Prestashop.

5 novembre 2019|Categories: Blog|Tags: |0 Commentaires

WordPress : en finir avec les boucles de redirection vers le page de connexion

Symptomes : soudainement, vous ne pouvez plus vous connecter à votre site wordpress, vous êtes dans cesse redirigé vers la page de connexion, avec reauth=1 à la fin de l’URL.

Solution : appeller la fonction wp_clear_auth_cookie(). Il suffit par exemple de le rajouter dans le fichier wp-login.php après l’inclusion de wp-load, recharger la page, puis enlever la fonction avant de reessayer de s’identifier.

22 février 2019|Categories: Blog|Tags: |0 Commentaires

MySQL dump : filtrer les tables par préfixe

Pour faire un dump d’une base de données MySQL, mais en prenant uniquement les tables qui ont un certain préfixe :

mysql -u {username} -p{password} -N -e 'show tables like "{prefix}\_%"' {dbname} | xargs mysqldump -u {username} --password={password} --single-transaction {dbname} > {filename}.sql
21 juin 2018|Categories: Blog|Tags: |0 Commentaires

WordPress : Ajouter une option « Device » sur les widgets pour choisir si on les affiche sur mobile, desktop, ou les deux

J’ai publié un nouveau petit module sur wordpress.org pour ajouter sur les widgets une option permettant de les afficher uniquement sur mobile ou sur desktop.

C’est basé sur la fonction wp_is_mobile disponible à partir de wordpress 3.4, qui détermine le type de device utilisé en fonction du user agent.

Vous pouvez télécharger le plugin ici : https://wordpress.org/plugins/widgets-device-display-option/

27 avril 2018|Categories: Blog|Tags: |0 Commentaires

Nouvelle contribution à wordpress.org : éviter que la fonction wp_mail envoie des mails en doublon

J’ai constaté qu’il pouvait arriver que wp_mail envoie des mails en plusieurs exemplaires, dans certains cas particuliers, comme par exemple quand la fonction est appellée depuis un module qui autorise l’éxecution de code PHP dans le contenu des pages / posts, et que le plugin Yoast SEO est installé.

J’ai donc développé un petit module permettant d’éviter ce désagrément.

La page du module est ici : https://wordpress.org/plugins/wp-mail-fix-multiple-send/

9 octobre 2017|Categories: Blog|Tags: |0 Commentaires

Colonnes de même hauteur : la version visual composer

De manière similaire à Bootsrap : colonnes de même hauteur, par ligne, et responsive :

Dans le cadre de la construction d’une page avec visual composer, le script suivant vous permettra de définir automatiquement la hauteur des colonnes d’une même ligne, en se basant sur la colonne la plus haute.

Il suffit d’intégrer ce script et d’assigner la classe « col-same-height » aux colonnes dans visual composer.

Code :

jQuery(window).load(function() {
    jQuery(window).resize(resizeColSameHeight);
    resizeColSameHeight();
});

/**
 * Redimensionnement hauteur des colonnes bootstrap "col-same-height" ligne par ligne selon la taille de la vue
 */
function resizeColSameHeight() {
    if (jQuery('.col-same-height').length > 0) {
        jQuery('.col-same-height > .vc_column-inner').css('height', 'auto');
        if (jQuery('body').width() >= 768) {
            jQuery('.vc_row').has('.col-same-height').each(function() {
                var maxHeight = 0;
                jQuery(this).children('.col-same-height').each(function() {
                    if (jQuery(this).children('.vc_column-inner').first().height() > maxHeight)
                        maxHeight = jQuery(this).height();
                });
                jQuery(this).children('.col-same-height').each(function() {
                    jQuery(this).children('.vc_column-inner').first().css('height', maxHeight + 'px');
                });
            });
        }
    }
}
27 juillet 2016|Categories: Blog|Tags: , |0 Commentaires

Prestashop : Corriger les incohérences (doublons) de positions dans la base de données

Si vous constatez des bugs lorsque vous modifiez les positions d’éléments tels que les catégories, produits, transporteurs, etc., ces changements de positions  ne fonctionnant pas toujours ou de manière un peu aléatoire, il est probable que vous ayez des incohérences dans votre base de données : plusieurs éléments qui sont dans le même élément parent on la même valeur dans le champ « position ».

J’ai développé un petit script pour corriger ce type d’incohérences.

Dans mon cas, il corrige ce problème pour les positions, redéfinissant correctement la valeur du champ « position » pour les sous catégories qui ont une position en doublon dans une même catégorie parent.
Etant dans un contexte multiboutique, il travaille sur la table ps_category_shop et non pas sur la table ps_category.

Il peut servir de modèle pour corriger d’autres tables (catégories dans un contexte non multiboutique, produits, transporteurs, etc.)
Ci dessous le script 🙂

$db = Db::getInstance();
$res = $db->executeS('SELECT DISTINCT id_category, id_shop FROM '._DB_PREFIX_.'category_shop');
foreach ($res as $row) {
    $res2 = $db->executeS('SELECT cs.* FROM '._DB_PREFIX_.'category_shop cs
        INNER JOIN '._DB_PREFIX_.'category c ON c.id_category = cs.id_category
        WHERE cs.id_shop = '.$row['id_shop'].'
        AND c.id_parent='.$row['id_category'].'
        ORDER BY cs.position');
    $i=1;
    foreach ($res2 as $row2) {
        if ($i != $row2['position']) {
            echo 'Position modifiée : '.$i.' catégorie '.$row2['id_category'].' shop '.$row['id_shop'].'
';
             $db->execute('UPDATE '._DB_PREFIX_.'category_shop SET position='.$i.'
                 WHERE id_shop = '.$row['id_shop'].'
                 AND id_category = '.$row2['id_category']);
        }
        $i++;
    }
}
9 juin 2016|Categories: Blog|Tags: |0 Commentaires

Images reponsive dans WordPress 4.4, problèmes de compatibilité et comment le désactiver

Depuis sa version 4.4 sortie le 8 décembre 2015, WordPress a introduit par défaut dans les images des attributs liés aux fonctionnalités responsive : « srcset » et « sizes ».

Le souci est que ces attributs posent des problèmes de compatibilité dans certains cas particuliers. J’ai été confronté à ce type de problèmes sur certaines versions de Safari, sur certaines images d’un site.

Si vous rencontrez ce type de problème, ou si vous voulez tout simplement désactiver ces nouvelles fonctionnalités, il suffit d’ajouter la ligne de code suivante dans votre thème :

add_filter( 'max_srcset_image_width', create_function( '', 'return 1;' ) );

Pour plus d’infos sur ces fonctionnalités :

Responsive Images in WordPress 4.4

15 décembre 2015|Categories: Blog|Tags: |0 Commentaires

Linux : Script bash pour une sauvegarde historisée

Le principe est simple : réaliser une sauvegarde historisée sur un certain nombre de jours d’un serveur Linux.
J’ai personnellement sélectionné :

  • Le répertoire etc pour avoir la conf du serveur et des services utilisés
  • Les bases de données, sous forme de dump MySQL
  • Les répertoires des différents sites web

Le script va créer une archive tar.gz par jour et par élément (etc, bases, répertoires web), enregistrés sous un dossier local qui sera ici /home/sauvegardes/
Il faudra en général prévoir un rsync distant de la dernière version de chaque élément au moins, pour avoir une sauvegarde distante. Ceci pourrait faire l’objet d’un autre article.

Ce script étant à appeler en tache « cron » bien entendu.

En attendant, voilà le script en question.

#!/bin/bash

# DECLARATIONS VARIABLES
mysqldbs=(db1 db2 db3)
wwwdirs=(dir1 dir2 dir3)
nbjours=30
jourtodelete=$((nbjours+1))

# ROTATION ANCIENNES VERSIONS
for ((  jour = ${nbjours[*]};  jour > 1;  jour--  ))
do
    jourprec=$((jour-1))
    # SYSTEME
    mv /home/sauvegardes/etc.$jourprec.tar.gz /home/sauvegardes/etc.$jour.tar.gz

    # MYSQL
    for db in ${mysqldbs[*]}
    do
        mv /home/sauvegardes/mysql_dump/$db.$jourprec.sql.tar.gz /home/sauvegardes/mysql_dump/$db.$jour.sql.tar.gz
    done
    # WWW
    for dir in ${wwwdirs[*]}
    do
        mv /home/sauvegardes/www/$dir.$jourprec.tar.gz /home/sauvegardes/www/$dir.$jour.tar.gz
    done
done

# SUPPRESSION VERSION LA PLUS VIEILLE
# SYSTEME
rm /home/sauvegardes/etc.$jourtodelete.sql.tar.gz
# MYSQL
for db in ${mysqldbs[*]}
do
    rm /home/sauvegardes/mysql_dump/$db.$jourtodelete.sql.tar.gz
done
# WWW
for dir in ${wwwdirs[*]}
do
    rm /home/sauvegardes/www/$dir.$jourtodelete.tar.gz
done

# GENERATION VERSION DU JOUR
# SYSTEME
tar czf /home/sauvegardes/etc.1.tar.gz /etc
# MYSQL
for db in ${mysqldbs[*]}
do
    mysqldump -u root --password=MYSQLROOTPASSWORD $db > /home/sauvegardes/mysql_dump/$db.sql
    tar czf /home/sauvegardes/mysql_dump/$db.1.sql.tar.gz /home/sauvegardes/mysql_dump/$db.sql
    rm /home/sauvegardes/mysql_dump/$db.sql
done
# WWW
for dir in ${wwwdirs[*]}
do
    tar czf /home/sauvegardes/www/$dir.1.tar.gz /var/www/$dir/
done

Pour l’adapter à votre environnement :

  • Remplacer « (db1 db2 db3) » par la liste des bases à sauvegarder
  • Remplacer « (dir1 dir2 dir3) » par la liste des répertoires web à sauvegarder
  • Variable « nbjours » : renseigner le nombre de jours d’historisation souhaités
  • Remplacer « MYSQLROOTPASSWORD » par le mot de passe root MySQL de votre serveur.
  • Remplacer « /home/sauvegardes/ » ainsi que « /home/sauvegardes/mysql_dump/ » et « /home/sauvegardes/www » par les chemins respectifs souhaités : racine des sauvegardes, répertoire des sauvegardes des bases, et répertoire des sauvegardes des répertoires web.

Et roulez jeunesse !

Cela reste artisanal, mais très pratique pour avoir une procédure de sauvegardes historisées suffisante pour pouvoir restaurer des versions antérieures de chaque site, ainsi que le paramétrage du serveur (en cas d’urgence, ce que je ne vous souhaite pas).

La grosse faille du script étant la présence du mot de passe root MySQL en dur, il mériterait de gérer les mots de passe de chaque base sous forme de liste pour éviter d’avoir le mot de passe root. Et dans l’idéal de trouver une solution pour ne pas faire apparaitre les mots de passe dans le script.
La première solution est relativement simple à implémenter, la deuxième beaucoup moins mais est sans doute possible également.
Je n’ai pas appronfondi ces aspects, le serveur concerné dans mon cas personnel étant un serveur de développement et de « gros bordel », les enjeux stratégiques sécuritaires n’en valaient pas la peine.

Si vous utilisez ce script comme base et le faites évoluer dans ce sens, n’hésitez pas à poster des modifications améliorant ces aspects de sécurité (et éventuellement d’autres que je n’aurais pas identifié) 🙂

14 octobre 2015|Categories: Blog|Tags: |1 Commentaire

Bootsrap : colonnes de même hauteur, par ligne, et responsive

Un problème récurrent avec bootsrap est d’avoir une présentation en « grille » avec des colonnes de même hauteur.

En effet, par défaut, les colonnes ont leur hauteur déterminée par leur contenu, et aucune solution CSS n’existe pour modifier ce comportement, car les différentes solutions proposées en cherchant sur le net ont d’autres incidences sur la présentation par défaut des colonnes.

La solution est donc de passer par du javascript pour gérer celà.

J’ai développé une petite fonction permettant de faire ça, et qui semble bien fonctionner, je vais donc vous la proposer ici, elle pourra vous faire gagner du temps !

Cette fonction nécessite que chaque colonne ait les classes de taille pour toutes les tailles de fenêtre possible, soit « col-xs-* », « col-sm-* », « col-md-* », « col-lg-* ».

Il faut également ajouter une classe « col-same-height » aux colonnes que l’on veut avoir de même hauteur.

Elle part également du principe que la taille de la grille est de 12 (valeur par défaut de bootstrap), et que les tailles de containers soient également celles par défaut de Bootsrap.
Si vous n’utilisez pas ces valeurs standard, vous pouvez les modifier facilement dans la fonction.

Code :

$(window).load(function() {
    $(window).resize(resizeColSameHeight);
    resizeColSameHeight();
});

/**
 * Redimensionnement hauteur des colonnes bootstrap "col-same-height" ligne par ligne selon la taille de la vue
 */
function resizeColSameHeight() {
    if ($('.col-same-height').length > 0) {
        var width = $('body').width();
        if (width < 768)
            var size = 'xs';
        else if (width < 992)
            var size = 'sm';
        else if (width < 1200) var size = 'md'; else var size = 'lg'; var classnames = $('.col-same-height').first().attr("class").toString().split(' '); for(var i in classnames) { var classname = classnames[i]; if (classname.indexOf('col-' + size + '-') != -1) var nbCols = 12 / classname.replace('col-' + size + '-', ''); } $('.col-same-height').css('height', 'auto'); if (nbCols > 1) {
            var i = 0;
            do {
                elems = $('.col-same-height').slice(i, i+nbCols);
                var maxHeight = 0;
                $(elems).each(function() {
                    if ($(this).height() > maxHeight)
                        maxHeight = $(this).height();
                });
                $(elems).each(function() {
                    $(this).css('height', maxHeight + 'px');
                });
                i += nbCols;
            } while (elems.length > 0);
        }
    }
}
25 août 2015|Categories: Blog|Tags: |0 Commentaires