Ves al contingut principal

Exemple complet

Aquest plugin és una demo pràctica integral. L'objectiu no és només mostrar un missatge a la web, sinó aplicar tot el cicle de vida i les capes tècniques que intervenen en el desenvolupament professional per a WordPress.

Què estem construint?

Imagina que un client et demana un sistema per mostrar avisos o promocions a la seva web, però vol poder canviar el color de fons des de l'administració sense tocar ni una sola línia de codi. El "Banner Pro" soluciona això combinant:

  1. Capa de Dades (BBDD): En lloc d'utilitzar la taula estàndard de configuracions de WordPress, crearem una taula personalitzada (wp_bpp_config) per aprendre a gestionar SQL directament amb $wpdb.

  2. Capa d'Administració (Back-end): Crearem un panell de control exclusiu per al plugin amb el seu propi logotip i un formulari segur. Aplicarem mesures de seguretat essencials com els Nonces (per evitar atacs de tercers) i la verificació de capacitats d'usuari.

  3. Capa de Presentació (Front-end): Utilitzarem un Shortcode flexible. Aquesta és la part que permet a l'editor de la web posar el banner on vulgui. A més, separarem el codi PHP de l'HTML mitjançant una vista (template), seguint les millors pràctiques d'arquitectura.

  4. Disseny i Actius: El plugin gestiona els seus propis estils CSS i imatges (el logo corporatiu), aprenent a generar rutes dinàmiques que funcionin en qualsevol servidor.

Flux de funcionament:

  • Activació: El plugin es presenta a la base de dades i crea el seu espai.

  • Configuració: L'administrador tria un color (ex: Blau). Aquesta dada viatja de forma segura i es desa a la nostra taula.

  • Execució: Quan un usuari visita la web, el shortcode fa una consulta a la base de dades, recupera el color i renderitza el banner amb l'estil aplicat.

  • Neteja: Si el plugin ja no es necessita, al eliminar-lo esborrem la taula per no deixar residus (un pas sovint oblidat però vital).


banner-pro.php

<?php
/**
 * Plugin Name: Banner Personalitzat Pro
 * Description: Plugin complet amb BBDD, Menús, Formularis i Shortcodes.
 * Version: 1.0
 * Author: JMFXR
 */



/* EXEMPLE D'ÚS DEL SHORTCODE:
[banner_pro]
Aquest és un missatge estàndard. Utilitza el color que hem configurat al panell de control del plugin.
[/banner_pro]

[banner_pro titol="OFERTA DE TEMPORADA"]
Subscriu-te ara a la nostra newsletter i rep un 20% de descompte en la teva propera compra.
[/banner_pro]

[banner_pro titol="URGENT" color="#ff0000"]
El servei estarà interromput demà de 08:00 a 10:00 per tasques de manteniment.
[/banner_pro]

*/
if ( ! defined( 'ABSPATH' ) ) exit; // Seguretat 

// Constants de ruta 
define( 'BPP_PATH', plugin_dir_path( __FILE__ ) );
define( 'BPP_URL', plugin_dir_url( __FILE__ ) );

// 1. Activació: Crear taula a la BBDD 
function bpp_activar_plugin() {
    global $wpdb;
    $taula_nom = $wpdb->prefix . 'bpp_config';
    require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); // Per dbDelta 

    $sql = "CREATE TABLE $taula_nom (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        clau varchar(50) NOT NULL,
        valor varchar(255) NOT NULL,
        PRIMARY KEY (id),
        UNIQUE KEY clau (clau)
    ) {$wpdb->get_charset_collate()};"; 

    dbDelta( $sql );
    
    // Valor inicial 
    $wpdb->insert( $taula_nom, array( 'clau' => 'color_fons', 'valor' => '#f0f0f0' ) );
}
register_activation_hook( __FILE__, 'bpp_activar_plugin' ); 

// 2. Càrrega de fitxers i assets 
require_once( BPP_PATH . 'includes/admin.php' );
require_once( BPP_PATH . 'includes/shortcode.php' );

function bpp_carregar_assets() {
    wp_enqueue_style( 'bpp-style', BPP_URL . 'assets/css/style.css' ); 
}
add_action( 'wp_enqueue_scripts', 'bpp_carregar_assets' ); 

uninstall.php

<?php
/**
 * Fitxer de desinstal·lació del plugin.
 * S'executa només quan l'usuari elimina el plugin des de l'escriptori.
 */

// Si WordPress no crida aquest fitxer, morim (seguretat)
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
    exit;
}

global $wpdb;
$taula_nom = $wpdb->prefix . 'bpp_config';

// 1. Esborrar la taula de la base de dades
$wpdb->query( "DROP TABLE IF EXISTS $taula_nom" );

// 2. Opcional: Si haguessim fet servir la taula wp_options, també l'esborraríem aquí
// delete_option('bpp_configuracio_global');

- Per què uninstall.php i no un hook?

Encara que existeix un hook anomenat register_uninstall_hook, la documentació oficial de WordPress recomana l'ús del fitxer uninstall.php perquè:

  • És més segur.

  • Manté el fitxer principal del plugin més net.

  • T'assegures que només s'executa quan el plugin s'elimina definitivament, no quan només es desactiva.

includes\admin.php

<?php
// Afegir Menú i Submenú 
function bpp_afegir_menus() {
    add_menu_page( 'Banner Pro', 'Banner Pro', 'manage_options', 'bpp-main', 'bpp_html_principal', 'dashicons-megaphone', 60 );
    add_submenu_page( 'bpp-main', 'Configuració', 'Configuració', 'manage_options', 'bpp-config', 'bpp_html_config' );
}
add_action( 'admin_menu', 'bpp_afegir_menus' );

// Processar Formulari 
function bpp_processar_formulari() {
    if ( isset( $_POST['bpp_save_config'] ) ) {
        // Seguretat: Nonce i Permisos
        if ( ! isset( $_POST['bpp_nonce'] ) || ! wp_verify_nonce( $_POST['bpp_nonce'], 'bpp_action_config' ) ) return;
        if ( ! current_user_can( 'manage_options' ) ) return;

        global $wpdb;
        $nou_color = sanitize_text_field( $_POST['bpp_color'] ); 
        $wpdb->update( $wpdb->prefix . 'bpp_config', array( 'valor' => $nou_color ), array( 'clau' => 'color_fons' ) ); 
        
        add_settings_error( 'bpp_msg', 'bpp_updated', 'Configuració desada!', 'success' ); 
    }
}
add_action( 'admin_init', 'bpp_processar_formulari' ); 

// HTML de la pàgina de configuració 
function bpp_html_config() {
    global $wpdb;
    $color = $wpdb->get_var( "SELECT valor FROM {$wpdb->prefix}bpp_config WHERE clau = 'color_fons'" );
    ?>
    <div class="wrap">
        <h1 style="display: flex; align-items: center;">
            <img src="<?php echo esc_url( BPP_URL . 'assets/img/logo.png' ); ?>" 
                 style="width: 40px; height: auto; margin-right: 15px;">
            Configuració del Banner Pro
        </h1>
        
        <hr>

        <form method="post">
            <input type="hidden" name="bpp_save_config" value="1">
            <?php wp_nonce_field( 'bpp_action_config', 'bpp_nonce' ); ?>
            <table class="form-table">
                <tr>
                    <th scope="row">Tria el color corporatiu:</th>
                    <td>
                        <input type="color" name="bpp_color" value="<?php echo esc_attr($color); ?>">
                    </td>
                </tr>
            </table>
            <?php submit_button(); ?>
        </form>
    </div>
    <?php
}

includes\shortcode.php

<?php
function bpp_shortcode_banner( $atts, $content = null ) {
    global $wpdb;
    
    // 1. Prioritat: Valor de la BBDD
    $color_db = $wpdb->get_var( "SELECT valor FROM {$wpdb->prefix}bpp_config WHERE clau = 'color_fons'" );

    // 2. Atributs del shortcode (per si l'usuari vol sobreescriure-ho manualment en un post concret)
    $params = shortcode_atts( array(
        'titol' => 'Avís Especial',
        'color' => ( $color_db ) ? $color_db : '#f1f1f1' // Si no hi ha BBDD, gris clar
    ), $atts );

    $titol = $params['titol'];
    $color_fons = $params['color'];

    ob_start();
    // Passem la variable $color_fons al template
    include BPP_PATH . 'templates/banner-view.php';
    return ob_get_clean();
}
add_shortcode( 'banner_pro', 'bpp_shortcode_banner' );

templates\banner-view.php

<?php if ( ! defined( 'ABSPATH' ) ) exit; ?>

<div class="bpp-banner" style="background-color: <?php echo esc_attr( $color_fons ); ?>;">
    
    <div class="bpp-logo-container">
        <img src="<?php echo esc_url( BPP_URL . 'assets/img/logo.png' ); ?>" 
             alt="Logo Plugin" 
             style="max-width: 50px; height: auto; margin-right: 15px;">
    </div>

    <div class="bpp-contingut">
        <h3 style="margin-top: 0;"><?php echo esc_html( $titol ); ?></h3>
        <div class="bpp-text">
            <?php echo wp_kses_post( $content ); ?>
        </div>
    </div>
</div>

<?php 
// wp_kses_post és una funció de WordPress que permet mostrar contingut HTML però només 
// amb les etiquetes i atributs permesos, evitant així possibles vulnerabilitats de seguretat. 
//En aquest cas, s'utilitza per mostrar el contingut del banner de manera segura. 
?>

assets\css\style.css

/* ==========================================================================
   Estils per al Banner del Plugin (Front-end)
   ========================================================================== */

.bpp-banner {
    display: flex;
    align-items: center;
    padding: 20px;
    margin: 20px 0;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    border-left: 5px solid #333;
    font-family: sans-serif;
}

.bpp-banner img {
    max-width: 80px;
    height: auto;
    margin-right: 20px;
    border-radius: 4px;
}

.bpp-banner h3 {
    margin: 0 0 5px 0;
    color: #2c3e50;
    font-size: 1.4rem;
}

.bpp-banner .contingut {
    color: #555;
    line-height: 1.5;
}

/* ==========================================================================
   Estils per a la pàgina d'Administració (Back-end)
   ========================================================================== */
.wrap form table.form-table {
    background: #fff;
    padding: 20px;
    border: 1px solid #ccd0d4;
    box-shadow: 0 1px 1px rgba(0,0,0,.04);
}

.bpp-color-preview {
    display: inline-block;
    width: 20px;
    height: 20px;
    border: 1px solid #000;
    vertical-align: middle;
    margin-left: 10px;
}

assets\img\logo.jpg

logo.jpg