CCCPaste

Check Elementor Pro widgets in all databases...

#!/bin/bash

# ==============================================================================
# SCANNER ELEMENTOR PRO POUR SERVEURS WHM/CPANEL (CENTOS)
# Recherche les widgets Elementor Pro actifs dans toutes les bases de données
# ==============================================================================

# On utilise le fichier de conf root par défaut sur WHM pour ne pas mettre de mot de passe en clair
MYSQL_CMD="mysql --defaults-extra-file=/root/.my.cnf -N -B"

# Liste des bases de données système à ignorer
IGNORE_DBS="information_schema|performance_schema|mysql|sys|cphulkd|eximstats|modsec|roundcube|whmxfer"

echo "---------------------------------------------------------------------------------"
echo "Démarrage du scan des sites WordPress..."
echo "Format de sortie : [NOM DU SITE] (URL) -> [WIDGETS TROUVÉS]"
echo "---------------------------------------------------------------------------------"

# 1. Récupérer toutes les bases de données
DBS=$($MYSQL_CMD -e "SHOW DATABASES")

for DB in $DBS; do
    # Ignorer les bases système
    if [[ "$DB" =~ ^($IGNORE_DBS)$ ]]; then continue; fi

    # 2. Chercher les préfixes WordPress dans cette base (tables finissant par _options)
    # On récupère le nom complet de la table (ex: wp_options, site2_options)
    TABLES=$($MYSQL_CMD $DB -e "SHOW TABLES LIKE '%_options'")

    for TABLE in $TABLES; do
        # Extraire le préfixe (on retire 'options' de la fin)
        PREFIX=${TABLE%options}

        # Vérifier si la table postmeta correspondante existe (pour éviter les erreurs sur des DB corrompues)
        CHECK_META=$($MYSQL_CMD $DB -e "SHOW TABLES LIKE '${PREFIX}postmeta'")
        if [ -z "$CHECK_META" ]; then continue; fi

        # Récupérer le nom du site et l'URL pour l'affichage
        SITENAME=$($MYSQL_CMD $DB -e "SELECT option_value FROM ${PREFIX}options WHERE option_name = 'blogname' LIMIT 1")
        SITEURL=$($MYSQL_CMD $DB -e "SELECT option_value FROM ${PREFIX}options WHERE option_name = 'siteurl' LIMIT 1")

        # 3. La requête SQL Magique
        # Note : J'ai encapsulé la requête précédente pour faire un GROUP_CONCAT
        # Cela permet d'avoir 1 seule ligne par site avec tous les widgets uniques trouvés

        QUERY="
        SELECT GROUP_CONCAT(DISTINCT elements_pro_trouves SEPARATOR ', ')
        FROM (
            SELECT
                CONCAT_WS(', ',
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"loop-grid\"%' THEN 'Loop Grid' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"taxonomy-filter\"%' THEN 'Taxonomy Filter' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"form\"%' THEN 'Formulaire' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"nav-menu\"%' THEN 'Menu Nav' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"slides\"%' THEN 'Slides' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"animated-headline\"%' THEN 'Titre Animé' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"price-list\"%' THEN 'Liste de prix' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"price-table\"%' THEN 'Tableau de prix' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"media-carousel\"%' THEN 'Carrousel Média' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"testimonial-carousel\"%' THEN 'Carrousel Témoignages' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"reviews\"%' THEN 'Avis' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"table-of-contents\"%' THEN 'Sommaire' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"countdown\"%' THEN 'Compte à rebours' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"share-buttons\"%' THEN 'Boutons Partage' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"call-to-action\"%' THEN 'Call to Action' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"flip-box\"%' THEN 'Boîte Retournable' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"lottie\"%' THEN 'Lottie' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"gallery\"%' THEN 'Galerie Pro' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"portfolio\"%' THEN 'Portfolio' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"login\"%' THEN 'Connexion' END,
                    CASE WHEN pm.meta_value LIKE '%\"widgetType\":\"global\"%' THEN 'Widget Global' END,
                    CASE WHEN pm.meta_value LIKE '%\"custom_css\":%' THEN 'CSS Personnalisé' END
                ) AS elements_pro_trouves
            FROM ${PREFIX}posts p
            INNER JOIN ${PREFIX}postmeta pm ON p.ID = pm.post_id
            WHERE pm.meta_key = '_elementor_data' AND p.post_status = 'publish'
            HAVING elements_pro_trouves IS NOT NULL AND elements_pro_trouves != ''
        ) AS scan_results;
        "

        # Exécution de la requête
        WIDGETS_FOUND=$($MYSQL_CMD $DB -e "$QUERY")

        # 4. Affichage du résultat si des widgets sont trouvés
        if [ ! -z "$WIDGETS_FOUND" ] && [ "$WIDGETS_FOUND" != "NULL" ]; then
            echo "SITE: $SITENAME ($SITEURL)"
            echo "   -> Widgets Pro: $WIDGETS_FOUND"
            echo "---------------------------------------------------------------------------------"
        fi

    done
done