lunedì 10 ottobre 2011

Drupal - Custom Tables per un Modulo

Nel post precedente abbiamo creato un modulo di base molto semplice.
Io però vengo da una storia di programmazione spinta quindi la domanda 2 che mi sono fatto è stata?

Come creo tabelle personali per il mio bel modulo?


Drupal ha ovviamente un hook apposito chiamato modulo_schema()


Per prima cosa cosa creiamo un nuovo file nella dir del modulo chiamato modulo.install ed andiamo ad aggiungerlo all'array files[] dentro il file .info.



name = PNG Cretgor
description = Modulo per la creazione di un PNG
package = Pathfinder
version = "0.1"
core = 7.x
files[] = png_creator.test
files[] = png_creator.install


Non è strettamente necessario ma è meglio metterlo.

Ora andiamo a riempire il .install. Qua dentro occorre mettere lo schema della/e tabelle che però non possono, ovviamente, essere scritte con un sql standard (sarebbe troppo facile). Occorre passare per una struttura array specifica di drupal piuttosto complessa.

Per crearla però possiamo passare per un modulo drupal fatto apposta chiamato SCHEMA

Dopo averlo installato quello che dovete fare è creare la/le tabelle sul DB manualmente con il vostro strumento preferito (es. phpmyadmin).
Assicuratevi che il nome della tabella inizi con: drupal_nomemodulo_nometabella.
Quel drupal_ è in realtà il prefisso che avete deciso di mettere, eventualmente, durante l'installazione di drupal.

Una volta create le vostre tabelle, andate nel modulo SCHEMA che trovate nella scheda STRUTTURA dopo averlo installato. Questo modulo farà un'analisi automatica di tutte le tabelle del DB producendo anche l'array schema che si aspetta lo stesso drupal.
Trovate tutti gli schemi nella scheda INSPECT.

Nel mio esempio ho creato due tabelle, una delle quali si chiama drupal_png_creator_races.

$schema['drupal_png_creator_races'] = array(
  'description' => 'TODO: please describe this table!',
  'fields' => array(
    'id_race' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'serial',
      'size' => 'small',
      'not null' => TRUE,
    ),
    'race_name' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'varchar',
      'length' => '100',
      'not null' => TRUE,
    ),
    'mod_for' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'int',
      'size' => 'small',
      'not null' => TRUE,
      'default' => 0,
    ),
    'mod_dex' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'int',
      'size' => 'small',
      'not null' => TRUE,
      'default' => 0,
    ),
    'mod_cos' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'int',
      'size' => 'small',
      'not null' => TRUE,
      'default' => 0,
    ),
    'mod_int' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'int',
      'size' => 'small',
      'not null' => TRUE,
      'default' => 0,
    ),
    'mod_sag' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'int',
      'size' => 'small',
      'not null' => TRUE,
      'default' => 0,
    ),
    'mod_car' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'int',
      'size' => 'small',
      'not null' => TRUE,
      'default' => 0,
    ),
    'mod_cus' => array(
      'description' => 'TODO: please describe this field!',
      'type' => 'int',
      'size' => 'small',
      'not null' => TRUE,
      'default' => 0,
    ),
  ),
  'primary key' => array('id_race'),
);


Nel mio caso sto creando la tabella equivalente a questo codice.

CREATE TABLE IF NOT EXISTS `drupal_png_creator_races` (
  `id_race` smallint(6) NOT NULL AUTO_INCREMENT COMMENT 'TODO: please describe this field!',
  `race_name` varchar(100) NOT NULL COMMENT 'TODO: please describe this field!',
  `mod_for` smallint(6) NOT NULL DEFAULT '0' COMMENT 'TODO: please describe this field!',
  `mod_dex` smallint(6) NOT NULL DEFAULT '0' COMMENT 'TODO: please describe this field!',
  `mod_cos` smallint(6) NOT NULL DEFAULT '0' COMMENT 'TODO: please describe this field!',
  `mod_int` smallint(6) NOT NULL DEFAULT '0' COMMENT 'TODO: please describe this field!',
  `mod_sag` smallint(6) NOT NULL DEFAULT '0' COMMENT 'TODO: please describe this field!',
  `mod_car` smallint(6) NOT NULL DEFAULT '0' COMMENT 'TODO: please describe this field!',
  `mod_cus` smallint(6) NOT NULL DEFAULT '0' COMMENT 'TODO: please describe this field!',
  PRIMARY KEY (`id_race`)
)

A questo punto apriamo il file .install e inseriamo l'hook per fargli leggere 'sta roba.



function png_creator_schema() {
      $schema['png_creator_races'] = [...]
}


Dentro l'hook schema inserirete tutti gli array $schema che avrete ricavato da quel modulo.

INSERIRE GIAQQUALCOSA!


Ci sono molti casi in cui vorrete pre-inserire dei dati nella/e tabelle appena create in fase di installazione. Per farlo dobbiamo andare a fare queste insert manuali, dentro l'hook chiamato nomemodulo_install().

Per rendere le cose più belle, nel mio esempio ho creato un file .inc con un array di tutte i dati da inserire:

<?php 

$races[] = array ('race_name'=>'human',
                    'mod_cus'=>2);

$races[] = array ('race_name'=>'half-elven',
                    'mod_cus'=>2);

$races[] = array ('race_name'=>'half-orc',
                    'mod_cus'=>2);

$races[] = array ('race_name'=>'dwarf',
                    'mod_cos'=>2,
                    'mod_sag'=>2,
                    'mod_car'=>-2);

$races[] = array ('race_name'=>'elf',
                    'mod_dex'=>2,
                    'mod_cos'=>-2,
                    'mod_int'=>2);

$races[] = array ('race_name'=>'gnomes',
                    'mod_car'=>2,
                    'mod_for'=>-2,
                    'mod_cos'=>2);

$races[] = array ('race_name'=>'halfing',
                    'mod_car'=>2,
                    'mod_for'=>-2,
                    'mod_dex'=>2);

$GLOBALS['pathfinder_races'] = $races;

?>

Purtroppo includerlo direttamente nel file .install non basta a dare lo scope alla variabile quindi occorre per forza metterlo in una global. L'alternativa è scrivere tutto questo codice, direttamente nell'hook _install.

L'hook install diventa quindi:

<?php
function png_creator_install() {
        global $pathfinder_races;
      foreach ($pathfinder_races as $oneRace)
          $result =  drupal_write_record ('png_creator_races',$oneRace);
  }
?>

Da notare l'uso di drupal_write_record. Nonostante abbia provato anche db_query, non c'è stato verso di farla funzionare quindi ho usato questa.

Questo metodo accetta due parametri fondamentali. La tabella ed un array con chiave-valore dove chiave è la colonna della tabella e valore il valore corrispondente.

Nessun commento:

Posta un commento