icon
Avatar
zod
Post: 217
Ciao ragazzi, è tanto che non ci si sente.
Sto usando Contao 3 e vorrei estendere la funzionalità di una form contatto creata con il generatore form di Contao, in pratica non voglio ricevere una email RAW, perché i dati in email TXT fanno caos (ho troppi campi e tutti con etichetta lunga), ma vorrei questi dati bene intabellati in HTML. Purtroppo Contao è lacunoso da questo lato, non permette un invio dei dati con "email html".

Notare che per fare questo non uso EFG, non c'è purtroppo per Contao 3. Invece ho trovato FormAsync per fare il submit ajax.

Ho pensato quindi ad usare gli HOOK, così anche da impararli una buona volta!! Osservando la Form.php ce ne sarebbero 2 in teoria:
http://www.phpkode.com/source/p/contao-open-source-cms-fka-typolight/contao-3.0.0/system/modules/core/forms/Form.php

Uno è "prepareFormData" che avviene prima dell'invio, e l'altro è "processFormData" che avviene dopo.

In ogni caso vorrei sfruttare un Hook per fare i miei bei maneggiamenti dei dati, intabellarli, e inviarli alla mia email. Dovrebbe essere semplice un modulo del genere, niente database, niente templates, niente languages... raccolta dati e invio.

Ho provato a seguire varie istruzioni trovate in giro, in particolare questa: https://community.contao.org/en/viewtopic.php?f=6&t=1895

E poi il tutorial in 3 step che avete anche tradotto voi, sul come fare un modulo custom. Beh... non mi funziona e sto sbattendo la testa, non so cosa sia ma il back-end smette di funzionare, faccio login e mi da pagina bianca.

Spiego cosa ho fatto:

  1. Creato la cartella del mio moduletto nuovo /system/modules/emailraw2html
  2. Inserito dentro le cartelle "classes" e "config"
  3. creato in config, il file config.php
  4. creato in classes, il file emailraw2html.php


Il codice di config.php è il seguente... provati entrambi...

iconphp:
 
#$GLOBALS['TL_HOOKS']['prepareFormData'][] = array('emailraw2html', 'er2hClassMethod');
 
$GLOBALS['TL_HOOKS']['processFormData'][] = array('emailraw2html', 'er2hClassMethod');
 


Il codice di emailraw2html.php è questo...

iconphp:
 
class emailraw2html extends \Form {
 
	public function er2hClassMethod($arrPost, $arrForm){   
 
	//$to = $GLOBALS['TL_ADMIN_EMAIL'];
	$to = "quavalamail@email.it";
	$subject = "messaggio dal sito";
 
	$msg = "<table>";
	foreach ($arrPost as $k => $v) {
		$msg .= "<tr><td>" . $k . "</td><td>" . $v . "</td></tr>";
	}
	$msg .= "</table>";
 
	$headers  = 'MIME-Version: 1.0' . "\r\n";
	$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
	$headers .= 'From: ' . $email . "\r\n";
	$message = '
			<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
			"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
			<html xmlns="http://www.w3.org/1999/xhtml">
			<head>
			<style>td{vertical-align:top;border:1px solid #000000;padding:10px;}</style>
			</head>
			<body>
			'. $msg .'
			<!-- indexer::stop -->
<script type="text/javascript">
<!--//--><![CDATA[//><!--
	document.write(unescape("%3Cscript src='http://www.contaocms.it/statistiche/piwik.js' type='text/javascript'%3E%3C/script%3E"));
	window.addEvent('domready', function() {
		try {
			var piwikTracker = Piwik.getTracker("http://www.contaocms.it/statistiche/piwik.php", 1);
			piwikTracker.setDocumentTitle("Forum");
			piwikTracker.trackPageView();
			piwikTracker.enableLinkTracking();
		} catch( err ) {}
	});
//--><!]]>
</script><noscript><p class="invisible"><img src="http://www.contaocms.it/statistiche/piwik.php?idsite=1" alt="" /></p></noscript>
<!-- indexer::continue -->
</body>
			</html>';
 
	mail($to, $subject, $message, $headers);
 
	//exit;
	}   
}


ho provato a mettere la function con "extends \Form" o anche senza come indicano nel sito ufficiale a riguardo degli hook. Ho provato poi anche ad usare autoloader.ini e autoloader.php dentro alla cartella config, come vedo fare in altri moduli (se volete posto anche quelli ma per ora mi limito al succo)... e non va niente.

Qualcuno riesce a spiegarmi in modo definitivo come usare gli HOOK? e in particolare questo hook? grazie.
[L'ultima modifica di zod, 06/12/2012 21:15]
Marco Damian
www.zod.it
05/12/2012 23:11
Avatar
paolob
Moderatore
Post: 1550
iconzod:

Qualcuno riesce a spiegarmi in modo definitivo come usare gli HOOK? e in particolare questo hook? grazie.


Ciao, ho avuto la necessità di fare una cosa simile in passato.

Dovevo inviare i dati del form a utenti diversi oppure in modo diverso a seconda delle scelte fatte.
Ho creato una piccola estensione che recuperava le info, le lavorava ed inviava l'email.

Ti allego il modulo essenziale.

Qui hai le due funzioni per i due hook
L'hook pre form passa tutti i campi prima di crearli, per cui devi capire attraverso il nome quello che ti serve.
Nell'esempio viene controllato che si tratti del campo denominato "Note"

Nella funzione post form invece puoi testare ad esempio se si tratta di un form in particolare attraverso l'id del form che avrai messo nell'ID del form.
Qui puoi recuperare i dati del form, elaborarli e ad esempio inviarli tramite email.
Nel mio esempio facevo un'email di testo... prova a mettere del codice html...
Per ultima cosa, dico al form che dopo aver processato il tutto, deve saltare alla pagine con ID XX dove magari metto un messaggio di invio corretto.
C'è commentato anche del codice per mostrare tutti i dati che vengono passati al form.

Per finire, questo modulo funziona sia con Contao 2.9.x sia con la versione 2.11.x, provala con una 3, penso che se non funziona, siano minime le variazioni.

Poi voglio vedere il risultato finale del tuo lavoro :)
Paolo B.
paolob@contaocms.it
06/12/2012 09:16
Avatar
zod
Post: 217
Grazie dell'aiuto Paolo, il tuo script è proprio quel che servirebbe per trattare questi dati. Uso processFormData.

Premetto che non ho ancora capito gli HOOK, pensavo fossero molto più semplici visti gli esempi che mostrano, e invece sono molto più complessi dal momento che si devono fare i moduli e quindi entra in gioco altro codice e altre cose da sapere, nessuno spiega in modo completo la logica del modulo con HOOK, con esempi pratici tipo il tuo, e quindi credo resterò con la mia incapacità di usarli.

Cmq tornando al codice, hai tutta una parte prima di "processFormData()" che intuisco ma non capisco, e quindi non l'ho toccata.

Poi veniamo al dunque ecco la mia funzione:

iconphp:
 
	// Sezione per il modulo form
	if ($arrForm[formID] == "f3") {
 
		// Creazione oggetto email
		$infoEmail = new Email();
 
		// imposto email mittente
		$sEmailUtente = $arrSubmitted['email'];
		$infoEmail->from = $sEmailUtente;
 
		// Imposto nome mittente
		$sNomeUtente = trim($arrSubmitted['nome']);
	    if (strlen($sNomeUtente)) {
			$infoEmail->fromName = $sNomeUtente;
		}
 
		$infoEmail->text = "<table>";
		foreach ($arrSubmitted as $k => $v) {
			$infoEmail->text .= "<tr><td>" . $k . "</td><td>" . $v . "</td></tr>";
		}		
		$infoEmail->text .= "</table>";
 
		// Aggiungo i destinatari, anceh più di uno
		$aDestinatari[] = "xxxxx@xxxx.xx";
 
echo $infoEmail->text;
 
		// Invio email a tutti i destinatari
		if (count($aDestinatari)>0)	{
			foreach ($aDestinatari as $sDestinatario) {
				$infoEmail->sendTo($sDestinatario);
			}
		}
 
		// Sezione per verificare la pagina in cui ero e a quale pagine rimandare il visitatore
		// Si salta alla pagine con id XX
		#$this->jumpToOrReload(10);
 
		}
 


Ho quindi impostato form F3... ho mantenuto tutto come il tuo codice cambiando solo le variabili (nel mio caso "nome" e "email"). Infine ho messo la raccolta dei campi col foreach, in quanto non li so di preciso, potrebbero essere in diverso numero e con diverse variabili, visto che userò questo modulo in diverse form leggermente diverse tra loro.
Sospetto che il problema sia qui a sto punto? inoltre ho messo html con i tag... non so però se il tuo sendTo() la interpreti correttamente, e che subject usi. Posso usare un semplice mail() come avevo fatto io?


Situazione: ora il back-end funziona di nuovo... lo script viene eseguito solo al submit della mia form "f3", per ora mi sta ben, purtroppo non funziona ancora. Restituisce pagina bianca. Che cosa può essere?

PS: il mio è un periodo di formazione/rivalutazione, non ho fatto molti lavori ultimamente, con Ilaria ho fatto dei siti che pubblicheremo fra poco, intanto sto rifacendo il mio sito sperimentando appunto Contao 3... e sto vedendo questa parte e altre. Cmq appena pubblico qualcosa lo metto in forum.
Marco Damian
www.zod.it
06/12/2012 11:11
Avatar
paolob
Moderatore
Post: 1550
Il fatto che restituisca pagina bianca vile dire che c'è un errore nel codice. Ho visto un # davanti al codice che indica la pagina a cui saltare.
Eventualmente nelle impostazioni di Contao, digli di mostrare i messaggi di errore.

Il camando Mail che ho usato è quello messo a a disposizione da Contao, che registra ad esempio l'evento.
Per aggiungere l'oggetto fai in questo modo:
iconphp:
 
		// Imposto oggetto della email
		$infoEmail->subject = "Modulo contatto";


Per mostrare qualcosa a video devi interrompere lo script con un die(); ad esempio, altrimenti Contao carica la pagina, la stessa se non viene data una pagina specifica.
Paolo B.
paolob@contaocms.it
06/12/2012 11:56
Avatar
zod
Post: 217
Ho resettato la cache di Contao e parrebbe aver cambiato comportamento, ora ritorna alla pagina della form senza dare pagina bianca. In ogni caso non spedisce la mail.
Per il test sto usando una form normale del core, quindi in teoria dovrebbe essere giusto che sta saltando a se stessa, ma poi vorrei usare il modulo FormAsync.. quindi la pagina non dovrebbe saltare, si arrangia quel modulo a restituire un messaggio, vorrei che il mio HOOK intercettasse e spedisse i dati del POST e basta... inizialmente addirittura volevo usare un insert tag file, messo nella stessa pagina.... ma purtroppo non va, credo sia un sistema a token... il POST è sbagliato e non mi da i miei campi, cmq il metodo che mi pare più corretto è attaccarmi con un hook all'evento processform.

Adesso provo a vedere meglio se da errori... e metto degli echo con dei die(), grazie dei tips... così vediamo cosa combina... uff mi fa diventare matto.

Ma l'oggetto email che usa sei sicuro che supporta HTML?
Marco Damian
www.zod.it
06/12/2012 13:32
Avatar
paolob
Moderatore
Post: 1550
Per l'invio email, se il codice è quello che hai postato, vedo che non è inserito alcun indirizzo, c'è $aDestinatari[] = "xxxxx@xxxx.xx";

iconzod:
Ma l'oggetto email che usa sei sicuro che supporta HTML?


No non ne sono sicuro per nulla. Ti ho indicato di provare in quanto a me non è mai servito.
Paolo B.
paolob@contaocms.it
06/12/2012 14:09
Avatar
zod
Post: 217
Si Paolo perché volevo evitare di postare un indirizzo email in chiaro... sai... robot che harvestano... spam.

Cmq chi la dura la vince! ora ho sistemato, e funziona, ti posto il codice, in più do qualche highlight.

Prima cosa: la "formID", la mia era vuota, quindi non era vero che eseguivo il codice... semplicemente schivava tutto e refreshava la pagina per via del post. Allora ho visto che tra i risultati di $arrForm c'era semplicemente "id" ed è ancora meglio, nel mio caso è la form 3, mi basterà inserire anche i numeri delle altre e sono a posto.

Domanda: se nono metto questo controllo significa che tutte le form del sito faranno questa spedizione al submit? tutte quelle frontend?

Seconda cosa: uso l'email configurata in admin come destinatario grazie a "$GLOBALS['TL_ADMIN_EMAIL'];"
Cmq resta utile questo script perché giustamente se ho una form con vari destinatari, magari in base ad un select, posso ricavarmeli e farmi le varie spedizioni.

Terza cosa: per fare il formato html del body della email basta mettere "$infoEmail->html" invece di "$infoEmail->text" ed ho usato nl2br() per convertire i new line in tag break.

Quarta cosa: ho messo un controllino di questo tipo nel ciclo for:
if($k == "FORM_SUBMIT"){
break;
}
Di modo che quando nel "$arrSubmitted" trova quella variabile si ferma e non restituisce anche i token che sono inutili.

Quinta cosa: il jumpTo può anche stare commentato, esegue tutto e fa refresh nella pagina.


iconphp:
 
	// Sezione per il modulo form
	if ($arrForm[id] == 3) {
 
		// Creazione oggetto email
		$infoEmail = new Email();
 
		// imposto email mittente
		$sEmailUtente = $arrSubmitted['email'];
		$infoEmail->from = $sEmailUtente;
 
		// Imposto nome mittente
		$sNomeUtente = trim($arrSubmitted['nome']);
	    if (strlen($sNomeUtente)) {
			$infoEmail->fromName = $sNomeUtente;
		}
 
		// Imposto oggetto della email
		$infoEmail->subject = "Modulo contatto";
 
		#$infoEmail->text se la mail è formato testo
		$infoEmail->html = "<table style='width:100%'>";
		foreach ($arrSubmitted as $k => $v) {
			if($k == "FORM_SUBMIT"){
				break;
			}
			$infoEmail->html .= "<tr><td style='vertical-align:top;border:1px solid #000000;padding:10px;' >" . nl2br($k) . "</td><td style='vertical-align:top;border:1px solid #000000;padding:10px;'>" . nl2br($v) . "</td></tr>";
		}		
		$infoEmail->html .= "</table>";
 
		// Aggiungo i destinatari, anche più di uno
		$aDestinatari[] = $GLOBALS['TL_ADMIN_EMAIL'];
 
		// Invio email a tutti i destinatari
		if (count($aDestinatari)>0)	{
			foreach ($aDestinatari as $sDestinatario) {
				$infoEmail->sendTo($sDestinatario);
			}
		}
 
		// Sezione per verificare la pagina in cui ero e a quale pagine rimandare il visitatore
		// Si salta alla pagine con id XX
		#$this->jumpToOrReload(10);
 
		}
 
Marco Damian
www.zod.it
06/12/2012 14:57
Avatar
paolob
Moderatore
Post: 1550
Ottimo..

iconzod:

Prima cosa: la "formID", la mia era vuota, quindi non era vero che eseguivo il codice... semplicemente schivava tutto e refreshava la pagina per via del post. Allora ho visto che tra i risultati di $arrForm c'era semplicemente "id" ed è ancora meglio, nel mio caso è la form 3, mi basterà inserire anche i numeri delle altre e sono a posto.


Il formID lo imposti nelle caratteristiche del form, nella maschera hai Configurazione Avanzata -> ID del form

iconzod:

Domanda: se nono metto questo controllo significa che tutte le form del sito faranno questa spedizione al submit? tutte quelle frontend?


Si, se non fai una verifica, la funzione viene lanciata ad ogni form

iconzod:

Terza cosa: per fare il formato html del body della email basta mettere "$infoEmail->html" invece di "$infoEmail->text" ed ho usato nl2br() per convertire i new line in tag break.


OK, come vedi Contao mette a disposizione tante belle funzioni :)
Paolo B.
paolob@contaocms.it
06/12/2012 15:05
Avatar
zod
Post: 217
Grazie del prezioso aiuto Paolo, questo moduletto mi tornerà molto utile, la parte delle form era sempre stata un po' limitata per un sacco di motivi:

1 - impossibilità di spedire a destinatari diversi dall'admin del sito (ma nei casi normali invece i contatti vanno al cliente e magari ufficio tecnico, amministrazione, commerciale eccetera)

2 - impossibilità di invare email in formato html, adesso si può e potenzialmente usando i template si potrebbero fare email formattate addirittura con intestazione, solo che al momento non so usare i template e le language nei moduli... :P piccolo particolare, magari me li spieghi un'altra volta

3 - impossibilità di manipolare i dati raccolti, fare controlli in base alla compilazione di un campo per esempio, salvarli o spedirli altrove prima di spedirli come fa Contao. Adesso abbiamo pieno accesso ai dati.

Nota che mi ero dimenticato di dire: in "generatore form" ho lasciato tutto senza abilitare jump to, spedizione, o salvataggio dati. La form è semplicemente una RAW, ci pensa il nuovo moduletto a fare tutto.
Marco Damian
www.zod.it
06/12/2012 15:23
Avatar
zod
Post: 217
Attenzione ho scoperto un problema, e credo sia un bug di Contao.

al controllo ho aggiunto questo:

iconphp:
 
if (($arrForm[id] == 2) || ($arrForm[id] == 3)) {
 


La form precedente funzionava quando era col controllo solo per la 3... ma adesso ne' la 3 ne' la 2 invece funzionano! Restituiscono un mix di campi della 3 e 2, ma come è possibile :scared: .

Ecco i valori di $arrSubmitted postando dalla form 2.

Metto bold quelli che appartengono alla form 3 ed in italic quelli della form 2 mentre gli altri sono condivisi perché si tratta della stessa form, duplicata e poi ho modificato gli id e label dei campi.

In pratica "tipo azienda" è un select non presente nella form, e al suo posto ci sta "genere musica". E così anche gli altri. Se dal post non ci sono, come mai me li mette? da dove li pesca?


[nome] => asf sa fsd
[email] => sdfasf@sdfsfs.sd
[telefono] => 232423


tipoazienda => produzione industriale
nomeazienda => sf saf asfsaf
specializzazione => sd fsd fs
azionimarketing => f safasf sdf


[ispirazione] => sf sdf s
[materiali] => af as fs
[networks] => af sf sa
[privacy] => si
[FORM_SUBMIT] => auto_form_2
[REQUEST_TOKEN] => bb54430048baa13bb440eeeeb3bfbf47
[c3ea70f2cfa197a91f7f78005c21e2ada] => 13
[c4cac7ff38eb72a03907d3e65434d01dc] => 17
[c16a52d1d03d4b0fe207a61c4990a731c] => 11
[c63d2d5f0bad8e52fa17220d97505e75a] => 11
[c3d63a7e4fda2b93fe4ffc0e54a1334ec] => 3
[cf753e3eb5dcc1855f47a9a7a33a8f95d] => 13
[c4c83b97fbfad83169db42c15af9aa49c] => 9
[c77dd031bc13d98e3e0cacd0aeed987af] => 14
[ca59c34c22d4e8322ff1c06b9c8eb915c] => 9
[cf18a59f3dbeef4fbf9574fa6c2da9724] => 17
[c8f8615caf6663fbf42843fb26ed5d15f] => 8
[c232546f0c4a7d2525357b234301d2a99] => 11
[ca4ac7ba919000fd7c54018fad02b649c] => 14
[cfcc515ef76f70a459661f914e5a5e83f] => 16
[c1e528440b66f932bdce28148a4292245] => 8

[generemusica] => folk o etnica
[nomeband] => sdf sfs fsdf saf sadf
sfd sa fsa
[fama] => sfsa fsadf sdaf


[c0aa0ab4af5f974d4970678816d1b5691] => 7
[c5150bddfdf94ceeb540f67270ce54e73] => 8
[c0c0ed46a0a297c726648f13c67061858] => 5
[c7714ef243a1b2a7c75c20c9d0d3afc98] => 11
[L'ultima modifica di zod, 06/12/2012 16:51]
Marco Damian
www.zod.it
06/12/2012 16:38
Avatar
zod
Post: 217
Risolto .... a metà :( ! credevo di avercela fatta.... e invece...

La questione è che Contao salva in sessione tutti i dati mandati via POST... cosa utile se per caso dobbiamo recuperare dati da invii precedenti, in una catena di form... ma incasina tutto se, come me, ho form con campi simili e devono stare autonome.

Ho trovato una possibile soluzione in Form.php di core.

Bisogna mettere alla fine, prima del redirect eventuale... queste righe di reset:

iconphp:
 
// Reset form data perché i dati dei post restano salvati in sessione
$_SESSION['FORM_DATA'] = array();
$_SESSION['FILES'] = array();
 


Così ad ogni form Contao riparte da una sessione pulita, ma ho un problema diverso... adesso spedisce sempre con i campi della form 2 e non capisco perché. I nomi dei campi sono sempre quelli anche se mando una form 3, però i valori dei campi sono corretti come ho postato. Boh... non capisco....
[L'ultima modifica di zod, 06/12/2012 18:44]
Marco Damian
www.zod.it
06/12/2012 18:17
Avatar
zod
Post: 217
Ho continuato a fare test, e sono giusto alle seguenti conclusioni:

Questi due array sono identici, e posso usare indistintamente entrambi:
$_SESSION['FORM_DATA']
$arrSubmitted

Il problema che ho descritto prima, cioè dei campi che si mescolano, avviene se uso il reset della sessione senza mettere un die(); alla fine. Per questo nei test con output diretto credevo fosse giusto ma mi ero ingannato... al momento di mettere la spedizione via email toglievo il die() e la funzione smetteva di funzionare (la volta dopo che la usavo).

Suppongo che succeda qualcosa dopo l'HOOK di processFormData... probabilmente continuando lo script dentro a Form.php, Contao ricarica i dati in sessione facendo pasticci.

In pratica devo per forza bloccarlo facendo così:

iconphp:
 
		// Reset form data perché i dati dei post restano salvati in sessione
		$_SESSION['FORM_DATA'] = array();
		$_SESSION['FILES'] = array();
 
		echo "<p><span style='color: #008000;'><strong>Grazie del tempo che hai dedicato alla compilazione del modulo, ti rispondo appena possibile</strong></span></p>";
 
		die();
 


La frase la metto qui perché cmq esce via ajax tramite l'estensione FormAsync.

Poi ho ottimizzato anche il controllo if, inizialmente pensavo fosse quello il problema... anche se non lo era, cmq ho fatto così, che mi sembra più comodo:

iconphp:
 
	// elenco id form da processare	
	$formlist = array(2,3);
 
	if (in_array($arrForm[id], $formlist)) {
 


Per oggi basta, penso che ormai questo script sia giunto al termine :D se avete qualche nota da aggiungere, fate pure.
Marco Damian
www.zod.it
06/12/2012 21:09
icon