Scope delle variabili nei moduli

9 contenuti / 0 new
Ultimo contenuto
Scope delle variabili nei moduli

Ciao,
è il primo modulo che scrivo con Drupal, per cui spero siate pazienti.
Senza scendere troppo nel dettaglio, il mio modulo deve leggere de dati da un DB (e lo fa) e scrivermeli a video (e non lo fa!!).

Ho due files:
il primo è gestione_pratiche.inc

$myFlag = 0;
function retrieveData($u,$p){
global $myFlag;
$myFlag=1;
$res = db_query("SELECT p.* FROM {pratiche} p WHERE p.email='%s' and p.password='%s'", $u, $p);
$row = db_fetch_object($res);
return $row->nomecognome;
}

l'altro è il file vero e proprio del modulo, gestione_pratiche.module:

function gestione_pratiche_menu() {
  $items['gestione_pratiche/form'] = array(
    'title' => t('Consulta lo stato della tua pratica'),
    'page callback' => 'gestione_pratiche_form',
    'access arguments' => array('access content'),
    'description' => t('Gestione Pratiche'),
'type' => MENU_SUGGESTED_ITEM,
  );
  return $items;
}
function gestione_pratiche_form() {
  require_once('./'. drupal_get_path('module', 'gestione_pratiche') .'/gestione_pratiche.inc');
  return drupal_get_form('frm_gestione_pratiche');
}
function frm_gestione_pratiche($form_state) {
if (!$myFlag):
$form['email'] = array(
'#type' => 'textfield',
'#title' => t('Indirizzo email'),
'#description' => "Inserisci l'indirizzo email che hai fornito al momento della presentazione della pratica.",
'#size' => 30,
'#maxlength' => 50,
);
$form['password'] = array(
'#type' => 'password',
'#title' => t('Password'),
'#description' => "Inserisci la password che ti è stata inviata per email.",
'#size' => 30,
'#maxlength' => 50,
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => 'Invia',
);
return $form;
else:
echo $myFlag;
endif;
}
function frm_gestione_pratiche_submit($form, &$form_state) {
$u = $form_state['values']['email'];
$p = $form_state['values']['password'];
$r = retrieveData($u, $p);
}

Come mai non riesco a lavorare sulla variabile $flag e visualizzare correttamente l'output in frm_gestione_pratiche?
Ci sto lavorando da ore ma comincio a sospettare di star tralasciando qualcosa!!
Grazie

Inizia ad ordinare u pò il codice, se vuoi usare due file ti consiglio di iniziare ad usare la direttiva 'file' del menu, quindi nel module avresti:

<?php
function gestione_pratiche_menu() {
 
$items['gestione_pratiche/form'] = array(
   
'title' => t('Consulta lo stato della tua pratica'),
   
'page callback' => 'drupal_get_form',
   
'page argument' => array('gestione_pratiche_form'),
   
'access arguments' => array('access content'),
   
'description' => t('Gestione Pratiche'),
   
'type' => MENU_SUGGESTED_ITEM,
   
'file' => 'gestione_pratiche.inc',
  );
  return
$items;
}
?>

e nel file gestione_pratiche.inc dovresti metterci

<?php
function _gestione_pratiche_retrieveData($u,$p) {
 
$res = db_query("SELECT p.nomecognome FROM {pratiche} p WHERE p.email='%s' and p.password='%s'", $u, $p);
 
$data = db_fetch_data($res);
  return
$data;
}
function
gestione_pratiche_form($form_state) {
 
$form = array();
 
// Qui da qualche parti devi avere le info da passare..
 
$data = _gestione_pratiche_retrieveData($u,$p);
  if (
$data) {
   
$form['email'] = array(
     
'#type' => 'textfield',
     
'#title' => t('Indirizzo email'),
     
'#description' => "Inserisci l'indirizzo email che hai fornito al momento della presentazione della pratica.",
     
'#size' => 30,
     
'#maxlength' => 50,
    );
   
$form['password'] = array(
     
'#type' => 'password',
     
'#title' => t('Password'),
     
'#description' => "Inserisci la password che ti &egrave; stata inviata per email.",
     
'#size' => 30,
     
'#maxlength' => 50,
    );
   
$form['submit'] = array(
     
'#type' => 'submit',
     
'#value' => 'Invia',
    );
  }
  return
$form;
}
?>

Il resto della logica inseriscila tu.

Usare le variabili globali è sconsigliato e problematico, perché la gestione è definita nel core, inoltre da quello che hai scritto tu la variabile viene settata al post del form, ma il form viene stampato prima del submit, quindi la variabile non viene mai settata, rendendola di fatto inutile.

PS: strano che utilizzo if(COND): else: endif; anziché if(COND) {} else {} posso chiederti il motivo?

Ciao
Marco
--
My blog
Working at @agavee

Quote:
...ti consiglio di iniziare ad usare la direttiva 'file' del menu..

Ci avevo provato ma probabilmente non avevo scritto bene qualcosa perché non mi considerava per nulla il file

Quote:
PS: strano che utilizzo if(COND): else: endif; anziché if(COND) {} else {} posso chiederti il motivo?

Nessun motivo preciso, avevo trovato la sintassi con i due punti da qualche parte e mi era sembrata interessante. Non avendo rilevato alcuno svantaggio nel farlo, ho deciso di utilizzarla.

Quote:

// Qui da qualche parti devi avere le info da passare..
$data = _gestione_pratiche_retrieveData($u,$p);

E' il "da qualche parte" che mi preoccupa, visto che fino ad ora non sono riuscito a far dialogare i due files... comunque grazie mille della preziosa risposta che mi hai dato, cercherò di metter mano al codice quanto prima per vedere se funziona tutto come dovrebbe.

In linea di massima mi par di comprendere che sia una buona abitudine inserire le varie funzioni "operative" nel file inc, lasciando la logica più spicciola a file module... giusto?
Inoltre, il fatto di usare l'underscore nel nome delle funzioni è un vezzo/abitudine oppure drupal impone qualche regola in merito?

Grazie.

normalmente si tiene tutto in *.module e poi si ottimizza spostando nei vari file una volta che tutto funziona. Tieni presente che il module viene caricato nel bootstrap di drupal (quindi più è grosso più impiega ad essere compilato da PHP, più memoria occupa, ...), mentre i fari include vengono caricati solo su richiesta della voce di menu specifica.

L?untercore iniziale di solito si usa per le funzioni "private" del modulo, non è obbligatorio, ma consigliato.

L'IF con le parentesi graffe è consigliato nella sintassi di codice PHP, rende il tutto più leggibile (assieme ad una buona indentazione).

Ciao
Marco
--
My blog
Working at @agavee

Salve mavimo
ho provato a fare come suggerisci ma ottengo un risultato poco incoraggiante.
A parte la logica gestionale mancante, che inserirò poi, il tuo script non mi mostra la form: ho messo per debug una condizione if(1) dunque la form deve comparire sempre... invece ottengo questo messaggio:

Quote:
warning: Missing argument 1 for drupal_get_form() in /var/www/comune.radda.it/includes/form.inc on line 69.
warning: call_user_func_array() expects parameter 1 to be a valid callback, no array or string given in /var/www/comune.radda.it/includes/form.inc on line 376

Il che mi riporta secondo me al problema iniziale: secondo me non mi legge il file gestione_pratiche.inc tramite la direttiva "file". Che ne pensi?

Giusto per completezza... magari ho fatto male a non specificarlo prima, lavoro su drupal 6

Grazie

Hai svuotato la cache del menu prima di provare?

Ciao
Marco
--
My blog
Working at @agavee

In effetti era un problema sul menu, ma rimane sempre il problema più grosso.

Riassumendo:

<?php
function gestione_pratiche_form($form_state) {
 
$form = array();
 
$data = _gestione_pratiche_retrieveData($u,$p);
  if (!
$data) {
   
// qui tutte le componenti della form...
 
}
  return
$form;
}
 
?>

Qui mi sorgono 2 dubbi:
1) se quando non ho valorizzato la variabile $data visualizzo la form, come faccio a fargli visualizzare il resto ne caso contrario? Mi spiego. Se dentro a $data ho il mio array coi risultati della query, cosa gli faccio scrivere visto che poi, in fondo a questa funzione gli restituisco $form? Inoltre, visto che gestione_pratiche_form() un parametro della funzione drupal_get_form, non sono forse obbligato a restituire sempre una form?? (mentre a me serve un testo, per esempio).

2) da dove leggo le variabili $p e $u? Nel precedente esempio che avevo postato ritrovavo i valori dentro a $form_state, variabile però che mi risulta disponibile solo in nella funzione frm_gestione_pratiche_submit($form, &$form_state) e mi risulta invece invisibile altrove.

Per cercare di risolvere in parte la faccenda del punto 1 mi ero ingegnato con una soluzione del genere inserita nel .module:

<?php
function gestione_pratiche_menu() {
 
$items['gestione_pratiche/form'] = array(
    .......
   
'page callback' => 'custom_function',
    .......
   
'file' => 'gestione_pratiche.inc',
  );
  return
$items;
}
function
custom_function(){
   
$u = $form_state['values']['email'];
   
$p = $form_state['values']['password'];
   
$data = _gestione_pratiche_retrieveData($u,$p);
    if(!
$data)
        return
drupal_get_form('gestione_pratiche_form');
    else
        echo
"risultati a video";
};
?>

Questa soluzione però, ne converrai, ha dei difetti grossolani. Intanto non riesco a valorizzare $u e $p e di conseguenza $data mi rimane vuota.
Inoltre, anche riuscendo a trovare il modo di pescare le due variabili, il ramo else del costrutto if(!$data) mi sputerebbe la stringa su pagina bianca e non al posto della form (che invece si trova nella colonna destra del mio layout complesso).

Spero di non aver creato troppa confusione e che si possa trovare una soluzione al mio problema. Come ho detto nel primo post, ancora non sono troppo pratico di moduli per cui spero abbiate pazienza! :)

1) non so se ho capito cosa vuoi, ma -per esempio- potresti usare markup come FAPI per stampare un testo nel caso in cu iil fato non sia presente, mentre per quanto riguarda la tua domanda:

Quote:
Se dentro a $data ho il mio array coi risultati della query, cosa gli faccio scrivere visto che poi, in fondo a questa funzione gli restituisco $form?

<?php
foreach ($data as $dato) {
 
$form['miocampo'] = array(
   
'#type' => 'textfield',
   
'#defaul_value' => $dato,
  );
}
?>

tanto per fare un esempio, dipende da cosa ti serve.

2) non riesco a capire cosa stai cercando di ottenere quindi mi astengo dal risponderti, ma ad occhio credo che inizialmente quelle variabili siano "prevalorizzate".

Ciao
Marco
--
My blog
Working at @agavee

Ciao
ho ottenuto la risposta che volevo nel forum in lingua inglese di drupal.
Essendo un po' lunga da spiegare, ti linko direttamente la discussione, ad uso e consumo che chi volesse servirsene:
http://drupal.org/node/1153972

Ovviamente poi ho adattato il codice alle mie esigenze.
Per rispondere alla tua curiosità "non riesco a capire cosa stai cercando di ottenere quindi...", ti dico che la mia necessità ultima è quella di avere un form che, una volta inseriti i dati, mi legga delle informazioni da un db e me le visualizzi. Nel dettaglio: metto user e password, pesco i dati di una pratica edilizia, li visualizzo al disotto o al posto della form.

Per evitare il problema di sicurezza evidenziato nella discussione di cui sopra ho optato per l'uso di una variabile di sessione che contiene solo l'ID dell'oggetto che devo andare a pescare nel DB.

Ciao e grazie