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:
-
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. -
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.
-
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.
-
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;
}
