Tabele SQL custom în WordPress

Vine o zi în viața fiecărui dezvoltator de teme, plugin-uri și/sau soluții custom de WP când set_option() nu este suficient (de exemplu vrei să ai o indexare rapidă a unor adrese de email). Dacă faci un script „la cheie”, ce nu va fi folosit de altcineva, poți genera tabelele folosind phpmyadmin (sau un tool asemănător). Nu e recomandat (ce se întâmplă dacă se pierde accidental baza de date? faci iar un db design?), dar se poate. Sigur, această soluție este un mare NU pentru un plugin/script public.

O altă soluție – folosită de mine până nu demult – a fost $wpdb->query. Doar că există mici probleme: un eventual update al tabelelor ar însemna altă interogare (ALTER …) și ar putea fi o sursă înfloritoare de erori și orori.

O a treia variantă ar fi dbDelta. O funcție foarte tare din WP pentru care scrii doar structura. Vrei să adaugi o tabelă nouă? O adaugi pur și simplu în structura nouă!
Versiunea

Nu am efectuat benchmarks pentru a vedea cât consumă rularea acestei funcții, dar bunul simț îmi zice că atunci când poți elimina rularea unui script ar fi bine să o faci. Prin urmare, toată povestea se întâmplă într-un fișier separat, să-i zicem sql_schema.php, pe care îl includem din functions.php.

// functions.php
$ntz_db_version = '1'; // se schimbă versiunea la fiecare update
$ntz_db_current_version = get_option('ntz_db_version');
global $wpdb;

// pentru fiecare tabelă facem o șmecherie de asta
$wpdb->custom_table = $wpdb->prefix.'custom_table';

if($ntz_db_version != $ntz_db_current_version){
  require_once( 'sql_schema.php' );
}

Simplu, nu?

Următoarea mișcare se întâmplă în sql_schema.php:

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');

$charset_collate = '';

if($wpdb->supports_collation()) {
  if(!empty($wpdb->charset)) {
    $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
  }
  if(!empty($wpdb->collate)) {
    $charset_collate .= " COLLATE $wpdb->collate";
  }
}

// pentru fiecare $wpdb->custom_table definit de mai sus
// avem câte un element în array-ul $sql_tables
// pe care îl iterăm copăcel-copăcel

$sql_tables[] = "CREATE TABLE $wpdb->custom_table (
    `id` INT NOT NULL AUTO_INCREMENT,
    `start_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
    `name` VARCHAR(255) NOT NULL ,
    `some_integer` INT DEFAULT '10',
    UNIQUE KEY id (id)
  ) $charset_collate;";

foreach( $sql_tables as $create_table ){
  dbDelta($create_table);
}

// actualizăm db_version, pentru a nu include fișierul minune de fiecare dată
update_option('ntz_db_version', $ntz_db_version);

În cazul în care îi dai seama că ai uitat să adaugi o coloană (sau pur și simplu ai nevoie de încă o coloană peste câteva luni), nu trebuie decât să schimbi valoarea variabilei $ntz_db_version din functions.php și să actualizezi sql_schema.php:

[...]
$sql_tables[] = "CREATE TABLE $wpdb->custom_table (
    `id` INT NOT NULL AUTO_INCREMENT,
    `start_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
    `end_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP , // o coloană nouă!
    `name` VARCHAR(255) NOT NULL ,
    `some_integer` INT DEFAULT '10',
    UNIQUE KEY id (id)
  ) $charset_collate;";
[...]

Gata!

La următorul refresh tabela SQL se va actualiza și toata lumea va fi fericită.

Acest articol este o traducere destul de vagă a paginii din Codex.

2 Comentarii to “Tabele SQL custom în WordPress”

  1. The power of function dbDelta() resides in its capability to update a table with the same syntax used to create it: It examines the current table structure if found, compares it to the desired table structure, and either adds or modifi es the table as required.

    Deci e suficient:

    <?php
    $tablename = $wpdb- > prefix . “hits”;
            
    $sql = “CREATE TABLE `$tablename` (
        `hit_id` INT( 11 ) NOT NULL AUTO_INCREMENT,
        `hit_ip` VARCHAR( 100 ) NOT NULL ,
        `hit_date` DATETIME
    );”;
            
    require_once(ABSPATH . ‘wp-admin/includes/upgrade.php');
            
    dbDelta($sql);
    ?>

    De aici: http://www.amazon.co.uk/Professional-WordPress-Plugin-Development-Williams/dp/0470916222

  2. Staicu Ionuț-Bogdan

    @Ps: păi e cam ce am zis și eu în post.

    Also, te rog ca următoarele comentarii să fie semnate cu un nume real. Mulțumesc.

Show trackbacks

Ți-a plăcut articolul? Lasă un comentariu!

You can insert code snippets using BBcode:
[js].[/js] [html].[/html] [php].[/php] [css].[/css]
You can also use some HTML tags:
<blockquote>.</blockquote> <code>.</code> <a href="">.</a> <strong>.</strong> <em>.</em>

windows apple dropbox facebook twitter