<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>gablog &#187; programmazione</title>
	<atom:link href="http://gabo.homelinux.com/category/programmazione/feed/" rel="self" type="application/rss+xml" />
	<link>http://gabo.homelinux.com</link>
	<description>Fino ad ora ho avuto un sito brutto. Ora ho un blog.</description>
	<lastBuildDate>Fri, 13 Nov 2009 14:29:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>it</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Shared Memory in PHP</title>
		<link>http://gabo.homelinux.com/2009/06/shared-memory-in-php/</link>
		<comments>http://gabo.homelinux.com/2009/06/shared-memory-in-php/#comments</comments>
		<pubDate>Mon, 08 Jun 2009 13:21:07 +0000</pubDate>
		<dc:creator>gabo</dc:creator>
				<category><![CDATA[programmazione]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://gabo.homelinux.com/?p=402</guid>
		<description><![CDATA[Navigando sul web ho trovato poca documentazione a proposito della gestione della shared memory mediante PHP, ed anche il manuale ufficiale non è molto chiaro. Ho deciso di fare un esperimento, ed ho scoperto che è un ottimo metodo per far comunicare due sessioni senza far uso intensivo di database e file temporanei, con il [...]]]></description>
			<content:encoded><![CDATA[<p>Navigando sul web ho trovato poca documentazione a proposito della gestione della shared memory mediante PHP, ed anche il manuale ufficiale non è molto chiaro. Ho deciso di fare un esperimento, ed ho scoperto che è un ottimo metodo per far comunicare due sessioni senza far uso intensivo di database e file temporanei, con il grande vantaggio di poter usare le potenzialità offerte dai semafori, senza dove riscrivere del proprio codice per questa delicata operazione.</p> <p>Gli utilizzi sono molteplici, nel mio caso si tratta di far comunicare due applicazioni flash usando delle pagine php come ponte, nel modo più veloce e meno oneroso possibile. La prima applicazione inizializza semaforo, memoria condivisa  e variabile di comunicazione, sfruttando come discriminante il proprio id di sessione.</p> 

<pre class="brush: php;">
&lt;?php
/* start.php */
session_start();

$MEMSIZE = 512; //  dimensione della memoria condivisa (byte)

$filename = session_save_path() . '/sess_' . session_id();
echo &quot;$filename&lt;br /&gt;\n&quot;;

$SEMKEY = ftok('/','S');    //  key semaforo
$SHMKEY = ftok('/','M');    //  key shared memory
echo &quot;$SEMKEY [semaforo]&lt;br /&gt;\n&quot;;
echo &quot;$SHMKEY [shared mem]&lt;br /&gt;\n&quot;;

// Creo il semaforo
$sem_id = sem_get($SEMKEY, 1);
if ($sem_id !== false) {
	echo &quot;Semaforo creato [$sem_id]&lt;br /&gt;\n&quot;;

	// Acquisisco il semaforo
	if (sem_acquire($sem_id)) {
		echo &quot;Semaforo acquisito [$sem_id]&lt;br /&gt;\n&quot;;

		// Associo la shared mem al semaforo
		$shm_id = shm_attach($SHMKEY, $MEMSIZE);
		if ($shm_id !== false) {
			echo &quot;Memoria condivisa associata [$shm_id]&lt;br /&gt;\n&quot;;

			// Inializzo la variabile
			if (shm_put_var($shm_id, 1, &quot;Variable 1 ciao&quot;)) {
				echo &quot;Variabile inizalizzata&lt;br /&gt;\n&quot;;

				// Rilascio il semaforo
				if (sem_release($sem_id)){
					echo &quot;Semaforo rilasciato&lt;br /&gt;\n&quot;;
				} else {
					echo &quot;Errore nel rilascio del semaforo&lt;br /&gt;\n&quot;;
					sem_remove($sem_id);
					shm_remove($shm_id);
				}
				
			} else {
				echo &quot;Errore nella scrittura della variabile&lt;br /&gt;\n&quot;;
				sem_remove($sem_id);
				shm_remove($shm_id);
			}
		} else {
			echo &quot;Errore nell'associazione della memoria condivisa&lt;br /&gt;\n&quot;;
			sem_remove($sem_id);
		}
	} else {
		echo &quot;Errore nell'acquisizione del semaforo&lt;br /&gt;\n&quot;;
		sem_remove($sem_id);
	}
} else {
	echo &quot;Errore nella creazione del semaforo&lt;br /&gt;\n&quot;;
}
&lt;?
</pre>

<p>A questo punto la sessione paritaria deve soltanto conoscere l'id della sessione con cui vuole comunicare, in modo da poter inizializzare le chiavi del semaforo e della memoria condivisa. Richiamando il codice seguente, per esempio, può leggere il valore della variabile condivisa:</p> 

<pre class="brush: php;">
/* read.php */
&lt;?php
session_start();

if (isset($_GET['file'])){

	$filename = $_GET['file'];
	echo &quot;$filename&lt;br /&gt;\n&quot;;

	$MEMSIZE = 512;             //  dimensione della memoria condivisa (byte)
	$SEMKEY = ftok('/','S');    //  key semaforo
	$SHMKEY = ftok('/','M');    //  key shared memory
	echo &quot;$SEMKEY [semaforo]&lt;br /&gt;\n&quot;;
	echo &quot;$SHMKEY [shared mem]&lt;br /&gt;\n&quot;;

	// Creo il semaforo
	$sem_id = sem_get($SEMKEY, 1);
	if ($sem_id !== false) {
		echo &quot;Semaforo creato [$sem_id]&lt;br /&gt;\n&quot;;

		// Acquisisco il semaforo
		if (sem_acquire($sem_id)) {
			echo &quot;Semaforo acquisito [$sem_id]&lt;br /&gt;\n&quot;;

			// Associo la shared mem al semaforo
			$shm_id = shm_attach($SHMKEY, $MEMSIZE);
			if ($shm_id !== false) {
				echo &quot;Memoria condivisa associata [$shm_id]&lt;br /&gt;\n&quot;;

				// Leggo la variabile
				$var1 = shm_get_var($shm_id, 1);
				if ($var1 !== false) {
					echo &quot;Variabile letta [$var1]&lt;br /&gt;\n&quot;;

					// Rilascio il semaforo
					if (sem_release($sem_id)){
						echo &quot;Semaforo rilasciato&lt;br /&gt;\n&quot;;
					} else {
						echo &quot;Errore nel rilascio del semaforo&lt;br /&gt;\n&quot;;
						sem_remove($sem_id);
						shm_remove($shm_id);
					}
					
				} else {
					echo &quot;Errore nella lettura della variabile&lt;br /&gt;\n&quot;;
					sem_remove($sem_id);
					shm_remove($shm_id);
				}
			} else {
				echo &quot;Errore nell'associazione della memoria condivisa&lt;br /&gt;\n&quot;;
				sem_remove($sem_id);
			}
		} else {
			echo &quot;Errore nell'acquisizione del semaforo&lt;br /&gt;\n&quot;;
			sem_remove($sem_id);
		}
	} else {
		echo &quot;Errore nella creazione del semaforo&lt;br /&gt;\n&quot;;
	}
} else {

?&gt;

&lt;form action='read.php' method='get'&gt;
  &lt;input type='text' name='file' /&gt;&lt;br /&gt;
  &lt;input type='submit' /&gt;
&lt;/form&gt;

&lt;?php
}
?&gt;
</pre>

<p>Richiamando (da un altro browser) la pagina senza parametri viene presentata una form che richiede l'inserimento del path del file di sessione del paritario. In questo caso basta un cut/paste dall'output della pagina precedente, in un applicazione reale ci si appoggierà ad un database. Inserendolo si prende il controllo del semaforo, ed in seguito si può leggere il contenuto della variabile di sessione. In modo del tutto analogo si può modificare il contenuto della variabile:</p> 

<pre class="brush: php;">
/* write.php */
&lt;?php
session_start();

if (isset($_GET['file']) &amp;&amp; isset($_GET['value'])){

	$filename = $_GET['file'];
	echo &quot;$filename&lt;br /&gt;\n&quot;;
	$value = $_GET['value'];
	echo &quot;$value&lt;br /&gt;\n&quot;;

	$MEMSIZE = 512;             //  dimensione della memoria condivisa (byte)
	$SEMKEY = ftok('/','S');    //  key semaforo
	$SHMKEY = ftok('/','M');    //  key shared memory
	echo &quot;$SEMKEY [semaforo]&lt;br /&gt;\n&quot;;
	echo &quot;$SHMKEY [shared mem]&lt;br /&gt;\n&quot;;

	// Creo il semaforo
	$sem_id = sem_get($SEMKEY, 1);
	if ($sem_id !== false) {
		echo &quot;Semaforo creato [$sem_id]&lt;br /&gt;\n&quot;;

		// Acquisisco il semaforo
		if (sem_acquire($sem_id)) {
			echo &quot;Semaforo acquisito [$sem_id]&lt;br /&gt;\n&quot;;

			// Associo la shared mem al semaforo
			$shm_id = shm_attach($SHMKEY, $MEMSIZE);
			if ($shm_id !== false) {
				echo &quot;Memoria condivisa associata [$shm_id]&lt;br /&gt;\n&quot;;

				// Scrivo la variabile
				if (shm_put_var($shm_id, 1, $value)) {
					echo &quot;Variabile scritta [$value]&lt;br /&gt;\n&quot;;

					// Rilascio il semaforo
					if (sem_release($sem_id)){
						echo &quot;Semaforo rilasciato&lt;br /&gt;\n&quot;;
					} else {
						echo &quot;Errore nel rilascio del semaforo&lt;br /&gt;\n&quot;;
						sem_remove($sem_id);
						shm_remove($shm_id);
					}
					
				} else {
					echo &quot;Errore nella scrittura della variabile&lt;br /&gt;\n&quot;;
					sem_remove($sem_id);
					shm_remove($shm_id);
				}
			} else {
				echo &quot;Errore nell'associazione della memoria condivisa&lt;br /&gt;\n&quot;;
				sem_remove($sem_id);
			}
		} else {
			echo &quot;Errore nell'acquisizione del semaforo&lt;br /&gt;\n&quot;;
			sem_remove($sem_id);
		}
	} else {
		echo &quot;Errore nella creazione del semaforo&lt;br /&gt;\n&quot;;
	}
} else {

?&gt;

&lt;form action='write.php' method='get'&gt;
	&lt;input type='text' name='file' /&gt;&lt;br /&gt;
	&lt;input type='text' name='value' /&gt;&lt;br /&gt;
	&lt;input type='submit' /&gt;
&lt;/form&gt;

&lt;?php
}
?&gt;
</pre>

<p>A questo punto non resta che da implementare una pagina per distruggere l'area di memoria condivisa, in modo da non incappare in problemi di saturazione della memoria.</p> 
<p>Lascio la creazione di tale pagina come esercizio, dato che non trovo più il relativo sorgente <img src='http://gabo.homelinux.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>

<pre class="brush: php;">
/* delete.php */
</pre>

<p>Il codice presentato è un semplice proof of concept, e non è da intendersi valido per un utilizzo in produzione. Mancano tutta una serie di controlli sulla corretta gestione della memoria, sulla validazione del paritario e del necessario timing nel caso in cui si cerchi di accedere ad un semaforo "rosso". Magari in un prossimo post affronterò la questione, per ora devo andarmela a studiare <img src='http://gabo.homelinux.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p> 
<p>Happy coding!</p>]]></content:encoded>
			<wfw:commentRss>http://gabo.homelinux.com/2009/06/shared-memory-in-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Impaginare tabelle con i CSS</title>
		<link>http://gabo.homelinux.com/2009/04/impaginare-tabelle-con-i-css/</link>
		<comments>http://gabo.homelinux.com/2009/04/impaginare-tabelle-con-i-css/#comments</comments>
		<pubDate>Thu, 30 Apr 2009 13:57:47 +0000</pubDate>
		<dc:creator>gabo</dc:creator>
				<category><![CDATA[programmazione]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[tabelle]]></category>

		<guid isPermaLink="false">http://gabo.homelinux.com/?p=330</guid>
		<description><![CDATA[Un tempo i siti venivano impaginati tramite le tabelle, oggi le tabelle le impagini dentro ai siti! Mi sono trovato nelle condizioni di dover scrivere un applicazione web che presenta un gran numero di dati, che per loro stessa natura devono essere disposti all'interno di tabelle. Non sono più avvezzo alle tabelle da quando produco [...]]]></description>
			<content:encoded><![CDATA[<p>Un tempo i siti venivano impaginati tramite le tabelle, oggi le tabelle le impagini dentro ai siti! Mi sono trovato nelle condizioni di dover scrivere un applicazione web che presenta un gran numero di dati, che per loro stessa natura devono essere disposti all'interno di tabelle. Non sono più avvezzo alle tabelle da quando produco siti in XHTML, e mi sono scontrato con tutti i loro limiti e difetti. Ho trovato però un valido alleato: <a href="http://sourceforge.net/projects/openrico/">OpenRico</a>. Si tratta di un framework javascript, che tra le altre cose gestisce le tabelle in un modo che un paio di anni fa sarebbe stato considerato fantascienza.</p>
<p>Ma niente è meglio di un esempio:</p>

		
		<script type='text/javascript'>
	// Carico tutti gli elementi necessari
		Rico.loadModule('LiveGrid','LiveGridMenu','gest.css');
	// var orderGrid,buffer;
	var CustId='1';
	var CustIdCol=7;
	Rico.onLoad( function() {
	// Creo la Classe - classi preesistenti in ricoLiveGridControls.js
		HighlightCellAndLink = Class.create();
	// Dichiaro la classe - si tratta di un misto tra due classi esistenti
		HighlightCellAndLink.prototype = {

			initialize: function(chkcol,chkval,highlightColor,highlightBackground,href,target) {
				this._chkcol=chkcol;
				this._chkval=chkval;
				this._highlightColor=highlightColor;
				this._highlightBackground=highlightBackground;

				this._href=href;
				this._target=target;
				this._anchors=[];
			},
	_create: function(gridCell,windowRow) {
		this._anchors[windowRow]=RicoUtil.createFormField(gridCell,'a',null,this.liveGrid.tableId+'_a_'+this.index+'_'+windowRow);
		if (this._target) this._anchors[windowRow].target=this._target;
		this._clear(gridCell,windowRow);
	},
 _clear: function(gridCell,windowRow) {
	 gridCell.style.color='';
	 gridCell.style.backgroundColor='';
		// 		gridCell.innerHTML='&nbsp;';

	 this._anchors[windowRow].href='';
	 this._anchors[windowRow].innerHTML='';
 },
 _display: function(v,gridCell,windowRow) {
	 var gridval=this.liveGrid.buffer.getWindowValue(windowRow,this._chkcol);
	 var match=(gridval==this._chkval);
	 gridCell.style.color=match ? this._highlightColor : '';
	 gridCell.style.backgroundColor=match ? this._highlightBackground : '';
		//gridCell.innerHTML=this._format(v);

	 this._anchors[windowRow].innerHTML=this._format(v);
	 var getWindowValue=this.liveGrid.buffer.getWindowValue.bind(this.liveGrid.buffer);
	 this._anchors[windowRow].href=this._href.replace(/\{\d+\}/g,
  function ($1) {
	  var colIdx=parseInt($1.substr(1));
	  return getWindowValue(windowRow,colIdx);
  }
		);
 }

		}

	// Carico i dati della tabella dentro al Rico Buffer javascript
		var buffer = new Rico.Buffer.Base($('dataTable').tBodies[0]);
	// Preparo le opzioni
		var grid_options = {
			headingSort: 'hover',
	highlightElem: 'cursorRow',
 FilterLocation: -1,
 visibleRows: 23,
 saveColumnInfo: {width:false, filter:false, sort:false},
 columnSpecs: [

 {height:50, width:113, filterUI:'t^20', control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880')}, // id
 {width:185, filterUI:'t^20', control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880')}, // Rag. sociale
 {width:78, filterUI:'t^20', control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880')}, // tipo lic.
 {width:25, control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880'),ClassName:'centred'}, // n. lic.
 {type:'date', dateFmt:'dd/mm/yyyy', width:75, control:new Rico.TableColumn.HighlightCell( CustIdCol,CustId,'black','#FBC880' )}, // scad. ass.
 {visible:false}, // log id
 {control:new HighlightCellAndLink(CustIdCol,CustId,'black','#FBC880','/','_blank'), type:'date', dateFmt:'dd/mm/yyyy', width:75}, // ultimo agg.
 {width:25, filterUI:'t', control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880'),ClassName:'centred'}, // B
 {width:25, filterUI:'t', control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880'),ClassName:'centred'}, // L
 {type:'date', dateFmt:'dd/mm/yyyy', width:75, control:new Rico.TableColumn.HighlightCell( CustIdCol,CustId,'black','#FBC880' )}, // ultimo int.
 {type:'date', dateFmt:'dd/mm/yyyy', width:75, control:new Rico.TableColumn.HighlightCell( CustIdCol,CustId,'black','#FBC880' )}, // data stipula

 ] };

	// Creo un'istanza della LiveGrid
 var grid = new Rico.LiveGrid('dataTable', buffer, grid_options);
	});
	</script>
			<p class="ricoBookmark"><span id="dataTable_bookmark">&nbsp;</span></p>

			<table id="dataTable" class="ricoLiveGrid">
					<thead>
					<tr>
					<th title='Id Licenza'>id</th>
					<th title='Ragione Sociale'>rag. sociale</th>
					<th title='Tipo Licenza'>tipo lic.</th>
					<th title='Numero Licenze'>n. lic.</th>
					<th title='Scadenza Assistenza'>scad. ass.</th>
					<th>log id</th>
					<!-- utile per il link successivo -->
					<th title='Data Ultimo Aggiornamento'>ultimo agg.</th>
					<th title='Bloccato'>B</th>
					<th title='Numero Licenze'>L</th>
					<th title='Data Ultimo Intervento'>ultimo int.</th>
					<th title='Data Stipula Contratto'>data stipula</th>
					</tr>
					</thead>
					<tbody>
					<tr>
					<td>75164794</td>
					<td>id 460327</td>
					<td>Full</td>
					<td>1</td>
					<td>2008-08-31 00:00:00</td>
					<td>21082</td>
					<td>2008-07-15 09:57:08</td>
					<td>1</td>
					<td>2</td>
					<td>2009-03-09 17:23:30</td>
					<td></td>
					</tr>
					<tr>
					<td>364898682</td>
					<td>id 447571</td>
					<td>Top Class Pack</td>
					<td>1</td>
					<td>2009-04-30 00:00:00</td>
					<td>27254</td>
					<td>2009-04-23 14:41:15</td>
					<td>0</td>
					<td>1</td>
					<td>2009-04-21 11:25:43</td>
					<td></td>
					</tr>
					<tr>
					<td>255706787</td>
					<td>id 201904</td>
					<td>Medium</td>
					<td>1</td>
					<td>2006-06-30 00:00:00</td>
					<td></td>
					<td></td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-08 12:36:05</td>
					<td></td>
					</tr>
					<tr>
					<td>9307861</td>
					<td>id 250671</td>
					<td>Full</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td>18917</td>
					<td>2008-04-16 09:58:16</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-20 10:53:36</td>
					<td></td>
					</tr>
					<tr>
					<td>106170654</td>
					<td>id 964966</td>
					<td>Full</td>
					<td>1</td>
					<td>2008-02-15 00:00:00</td>
					<td>17260</td>
					<td>2008-02-04 12:48:55</td>
					<td>0</td>
					<td>2</td>
					<td>2008-10-10 15:14:08</td>
					<td></td>
					</tr>
					<tr>
					<td>995513917</td>
					<td>id 309631</td>
					<td>Top Pack</td>
					<td>1</td>
					<td>2009-04-23 00:00:00</td>
					<td></td>
					<td></td>
					<td>0</td>
					<td>1</td>
					<td>2009-03-25 17:24:20</td>
					<td></td>
					</tr>
					<tr>
					<td>845306397</td>
					<td>id 593262</td>
					<td>Medium</td>
					<td>1</td>
					<td>2007-04-19 00:00:00</td>
					<td></td>
					<td></td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-22 17:45:27</td>
					<td></td>
					</tr>
					<tr>
					<td>292266845</td>
					<td>id 218200</td>
					<td>Full</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td>19545</td>
					<td>2008-05-13 15:52:04</td>
					<td>0</td>
					<td>2</td>
					<td>2008-05-13 15:15:23</td>
					<td></td>
					</tr>
					<tr>
					<td>191864013</td>
					<td>id 430542</td>
					<td></td>
					<td>1</td>
					<td>2007-09-15 00:00:00</td>
					<td>12225</td>
					<td>2007-06-11 12:09:03</td>
					<td>0</td>
					<td>2</td>
					<td>2009-01-29 09:47:39</td>
					<td></td>
					</tr>
					<tr>
					<td>368316650</td>
					<td>id 70129</td>
					<td>Full</td>
					<td>1</td>
					<td>2008-08-31 00:00:00</td>
					<td>21620</td>
					<td>2008-08-14 20:51:55</td>
					<td>1</td>
					<td>1</td>
					<td>2008-07-29 10:40:55</td>
					<td></td>
					</tr>
					<tr>
					<td>364593506</td>
					<td>id 320556</td>
					<td>Medium</td>
					<td>1</td>
					<td>2006-12-01 00:00:00</td>
					<td></td>
					<td></td>
					<td>0</td>
					<td>2</td>
					<td>2009-03-25 15:37:16</td>
					<td></td>
					</tr>
					<tr>
					<td>192413330</td>
					<td>id 459167</td>
					<td>Medium</td>
					<td>1</td>
					<td>2007-03-15 00:00:00</td>
					<td>9958</td>
					<td>2007-03-14 16:23:51</td>
					<td>1</td>
					<td>2</td>
					<td>2009-04-21 16:20:00</td>
					<td></td>
					</tr>
					<tr>
					<td>82244873</td>
					<td>id 607056</td>
					<td>Top Pack</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td>25340</td>
					<td>2009-02-09 17:45:46</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-09 12:56:50</td>
					<td></td>
					</tr>
					<tr>
					<td>233306884</td>
					<td>id 479065</td>
					<td>Full</td>
					<td>1</td>
					<td>2007-11-30 00:00:00</td>
					<td>15259</td>
					<td>2007-11-05 16:22:47</td>
					<td>0</td>
					<td>1</td>
					<td>2007-11-05 12:52:46</td>
					<td></td>
					</tr>
					<tr>
					<td>563568115</td>
					<td>id 133789</td>
					<td></td>
					<td>1</td>
					<td>2007-04-30 00:00:00</td>
					<td>11795</td>
					<td>2007-05-23 09:46:46</td>
					<td>0</td>
					<td>2</td>
					<td>2008-10-29 17:14:02</td>
					<td></td>
					</tr>
					<tr>
					<td>459747314</td>
					<td>id 723572</td>
					<td>Full</td>
					<td>1</td>
					<td>2008-11-30 00:00:00</td>
					<td>23509</td>
					<td>2008-11-13 19:06:30</td>
					<td>0</td>
					<td>2</td>
					<td>2008-11-13 17:03:34</td>
					<td></td>
					</tr>
					<tr>
					<td>527313232</td>
					<td>id 244507</td>
					<td>Medium</td>
					<td>1</td>
					<td>2007-02-28 00:00:00</td>
					<td>10034</td>
					<td>2007-03-19 10:22:31</td>
					<td>1</td>
					<td>2</td>
					<td>2009-03-23 17:10:21</td>
					<td></td>
					</tr>
					<tr>
					<td>340484619</td>
					<td>id 286438</td>
					<td>Medium</td>
					<td>5</td>
					<td>2007-01-31 00:00:00</td>
					<td>9057</td>
					<td>2007-02-08 17:57:59</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-16 10:31:55</td>
					<td></td>
					</tr>
					<tr>
					<td>192230224</td>
					<td>id 782959</td>
					<td></td>
					<td>1</td>
					<td>2007-06-15 00:00:00</td>
					<td>13979</td>
					<td>2007-09-12 17:18:59</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-17 17:22:14</td>
					<td></td>
					</tr>
					<tr>
					<td>844268799</td>
					<td>id 761414</td>
					<td>Medium</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td></td>
					<td></td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-22 10:10:16</td>
					<td></td>
					</tr>
					<tr>
					<td>277069092</td>
					<td>id 92895</td>
					<td>Full</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td>13357</td>
					<td>2007-08-01 16:07:31</td>
					<td>0</td>
					<td>1</td>
					<td>2009-03-26 12:31:54</td>
					<td></td>
					</tr>
					<tr>
					<td>439849853</td>
					<td>id 242248</td>
					<td>Medium</td>
					<td>1</td>
					<td>2007-09-30 00:00:00</td>
					<td></td>
					<td></td>
					<td>0</td>
					<td>2</td>
					<td>2009-01-29 17:25:09</td>
					<td></td>
					</tr>
					<tr>
					<td>579833</td>
					<td>id 18066</td>
					<td>Full</td>
					<td>1</td>
					<td>2007-11-30 00:00:00</td>
					<td>14971</td>
					<td>2007-10-23 16:40:05</td>
					<td>1</td>
					<td>2</td>
					<td>2008-02-28 11:57:23</td>
					<td></td>
					</tr>
					<tr>
					<td>95977783</td>
					<td>id 322693</td>
					<td>Full</td>
					<td>1</td>
					<td>2008-03-30 00:00:00</td>
					<td>17992</td>
					<td>2008-03-07 09:33:32</td>
					<td>0</td>
					<td>2</td>
					<td>2006-10-09 16:25:34</td>
					<td></td>
					</tr>
					<tr>
					<td>81512451</td>
					<td>id 902222</td>
					<td>Top Pack</td>
					<td>1</td>
					<td>2009-04-30 00:00:00</td>
					<td>27043</td>
					<td>2009-04-16 15:34:02</td>
					<td>0</td>
					<td>1</td>
					<td>2009-04-01 16:31:55</td>
					<td></td>
					</tr>
					<tr>
					<td>281402588</td>
					<td>id 96496</td>
					<td></td>
					<td>1</td>
					<td>2007-06-04 00:00:00</td>
					<td>12434</td>
					<td>2007-06-18 12:56:52</td>
					<td>1</td>
					<td>2</td>
					<td>2008-08-08 11:22:20</td>
					<td></td>
					</tr>
					<tr>
					<td>738616944</td>
					<td>id 589111</td>
					<td>Start</td>
					<td>2</td>
					<td>2006-07-31 00:00:00</td>
					<td>4874</td>
					<td>2006-07-26 09:15:05</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-08 11:09:34</td>
					<td></td>
					</tr>
					<tr>
					<td>964874268</td>
					<td>id 157409</td>
					<td></td>
					<td>1</td>
					<td>2007-03-30 00:00:00</td>
					<td>11816</td>
					<td>2007-05-23 17:00:24</td>
					<td>0</td>
					<td>2</td>
					<td>2009-03-20 10:38:36</td>
					<td></td>
					</tr>
					<tr>
					<td>690643311</td>
					<td>id 422485</td>
					<td>Medium</td>
					<td>1</td>
					<td>2008-10-31 00:00:00</td>
					<td>26357</td>
					<td>2009-03-20 17:33:09</td>
					<td>0</td>
					<td>2</td>
					<td>2008-10-17 11:58:17</td>
					<td></td>
					</tr>
					<tr>
					<td>615142822</td>
					<td>id 599182</td>
					<td>Full</td>
					<td>1</td>
					<td>2008-09-15 00:00:00</td>
					<td>21879</td>
					<td>2008-09-03 10:23:24</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-20 12:45:09</td>
					<td></td>
					</tr>
					<tr>
					<td>156341552</td>
					<td>id 246093</td>
					<td>Medium</td>
					<td>1</td>
					<td>2007-05-16 00:00:00</td>
					<td>11206</td>
					<td>2007-04-27 16:04:04</td>
					<td>0</td>
					<td>2</td>
					<td>2009-02-17 16:05:58</td>
					<td></td>
					</tr>
					<tr>
					<td>200958252</td>
					<td>id 15563</td>
					<td>Medium</td>
					<td>1</td>
					<td>2007-08-10 00:00:00</td>
					<td>13524</td>
					<td>2007-08-14 16:21:18</td>
					<td>0</td>
					<td>2</td>
					<td>2009-01-08 08:32:22</td>
					<td></td>
					</tr>
					<tr>
					<td>854461670</td>
					<td>id 403686</td>
					<td>Full</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td>16131</td>
					<td>2007-12-07 17:43:33</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-23 12:21:27</td>
					<td></td>
					</tr>
					<tr>
					<td>191070556</td>
					<td>id 500305</td>
					<td>Medium</td>
					<td>1</td>
					<td>2006-11-30 00:00:00</td>
					<td>7171</td>
					<td>2006-11-17 11:02:50</td>
					<td>0</td>
					<td>2</td>
					<td>2008-12-19 11:34:49</td>
					<td></td>
					</tr>
					<tr>
					<td>3753662</td>
					<td>id 739014</td>
					<td>Medium</td>
					<td>1</td>
					<td>2006-09-15 00:00:00</td>
					<td>5910</td>
					<td>2006-09-25 18:00:39</td>
					<td>1</td>
					<td>2</td>
					<td>2009-02-25 11:46:33</td>
					<td></td>
					</tr>
					<tr>
					<td>554229736</td>
					<td>id 647156</td>
					<td>Full</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td>15900</td>
					<td>2007-11-29 17:21:53</td>
					<td>0</td>
					<td>1</td>
					<td>2008-06-12 17:13:10</td>
					<td></td>
					</tr>
					<tr>
					<td>322967529</td>
					<td>id 595825</td>
					<td>Medium</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td>27230</td>
					<td>2009-04-23 09:24:18</td>
					<td>0</td>
					<td>2</td>
					<td>2009-03-03 16:13:11</td>
					<td></td>
					</tr>
					<tr>
					<td>759185791</td>
					<td>id 549866</td>
					<td></td>
					<td>1</td>
					<td>2007-05-31 00:00:00</td>
					<td>12205</td>
					<td>2007-06-09 12:51:50</td>
					<td>0</td>
					<td>2</td>
					<td>2008-07-17 09:14:07</td>
					<td></td>
					</tr>
					<tr>
					<td>30853271</td>
					<td>id 817871</td>
					<td>Medium</td>
					<td>1</td>
					<td>2008-04-30 00:00:00</td>
					<td>18968</td>
					<td>2008-04-17 10:28:25</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-23 16:10:41</td>
					<td></td>
					</tr>
					<tr>
					<td>774688721</td>
					<td>id 802185</td>
					<td>Medium</td>
					<td>1</td>
					<td>2010-01-31 00:00:00</td>
					<td></td>
					<td></td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-17 15:18:35</td>
					<td></td>
					</tr>
					<tr>
					<td>846160889</td>
					<td>id 748902</td>
					<td>Medium</td>
					<td>1</td>
					<td>2007-11-30 00:00:00</td>
					<td>7126</td>
					<td>2006-11-16 11:57:18</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-22 15:00:30</td>
					<td></td>
					</tr>
					<tr>
					<td>69488525</td>
					<td>id 497864</td>
					<td>Top Pack</td>
					<td>1</td>
					<td>2009-03-27 00:00:00</td>
					<td>26219</td>
					<td>2009-03-15 15:50:04</td>
					<td>0</td>
					<td>1</td>
					<td>2009-04-20 16:07:29</td>
					<td></td>
					</tr>
					<tr>
					<td>987640381</td>
					<td>id 232666</td>
					<td></td>
					<td>1</td>
					<td>2007-05-10 00:00:00</td>
					<td>11568</td>
					<td>2007-05-14 12:38:33</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-23 15:30:34</td>
					<td></td>
					</tr>
					<tr>
					<td>612335205</td>
					<td>id 230652</td>
					<td>Medium</td>
					<td>1</td>
					<td>2006-09-30 00:00:00</td>
					<td>5448</td>
					<td>2006-09-05 17:55:04</td>
					<td>1</td>
					<td>2</td>
					<td>2008-07-22 10:35:27</td>
					<td></td>
					</tr>
					<tr>
					<td>174041748</td>
					<td>id 612915</td>
					<td>Top Class Pack</td>
					<td>1</td>
					<td>2009-04-23 00:00:00</td>
					<td>26573</td>
					<td>2009-03-27 12:16:30</td>
					<td>0</td>
					<td>1</td>
					<td>2009-03-27 12:15:24</td>
					<td></td>
					</tr>
					<tr>
					<td>871978760</td>
					<td>id 94299</td>
					<td>Medium</td>
					<td>5</td>
					<td>2006-07-15 00:00:00</td>
					<td>4761</td>
					<td>2006-07-19 16:38:39</td>
					<td>0</td>
					<td>2</td>
					<td>2007-01-24 12:00:03</td>
					<td></td>
					</tr>
					<tr>
					<td>624114990</td>
					<td>id 733399</td>
					<td>Full</td>
					<td>1</td>
					<td>2008-09-30 00:00:00</td>
					<td>21892</td>
					<td>2008-09-03 11:29:27</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-23 16:35:21</td>
					<td></td>
					</tr>
					<tr>
					<td>817169190</td>
					<td>id 682556</td>
					<td>Medium</td>
					<td>1</td>
					<td>2007-07-31 00:00:00</td>
					<td>13059</td>
					<td>2007-07-17 14:47:55</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-10 10:58:43</td>
					<td></td>
					</tr>
					<tr>
					<td>56610107</td>
					<td>id 937867</td>
					<td></td>
					<td>1</td>
					<td>2007-06-15 00:00:00</td>
					<td>11833</td>
					<td>2007-05-24 10:40:57</td>
					<td>0</td>
					<td>2</td>
					<td>2008-12-12 08:47:35</td>
					<td></td>
					</tr>
					<tr>
					<td>916656495</td>
					<td>id 89172</td>
					<td>Medium</td>
					<td>1</td>
					<td>2006-12-31 00:00:00</td>
					<td>6285</td>
					<td>2006-10-11 11:46:14</td>
					<td>0</td>
					<td>2</td>
					<td>2007-01-25 16:17:41</td>
					<td></td>
					</tr>
					<tr>
					<td>690277100</td>
					<td>id 70068</td>
					<td>Medium</td>
					<td>1</td>
					<td>2006-07-31 00:00:00</td>
					<td></td>
					<td></td>
					<td>0</td>
					<td>2</td>
					<td>2009-02-18 15:10:49</td>
					<td></td>
					</tr>
					<tr>
					<td>139190673</td>
					<td>id 907898</td>
					<td>Top Class Pack</td>
					<td>1</td>
					<td>2009-03-15 00:00:00</td>
					<td>25409</td>
					<td>2009-02-12 09:22:07</td>
					<td>1</td>
					<td>1</td>
					<td>2009-02-17 09:04:29</td>
					<td></td>
					</tr>
					<tr>
					<td>243865967</td>
					<td>id 473755</td>
					<td>Medium</td>
					<td>1</td>
					<td>2006-12-31 00:00:00</td>
					<td>8022</td>
					<td>2006-12-28 12:39:20</td>
					<td>1</td>
					<td>2</td>
					<td>2009-04-10 12:31:49</td>
					<td></td>
					</tr>
					<tr>
					<td>953521729</td>
					<td>id 232483</td>
					<td>Medium</td>
					<td>5</td>
					<td>2006-09-20 00:00:00</td>
					<td>5858</td>
					<td>2006-09-22 15:59:47</td>
					<td>0</td>
					<td>2</td>
					<td>2009-04-08 11:37:59</td>
					<td></td>
					</tr>
					</tbody></table>
					</code>
					

<p>Ce n'è da sbizzarrirsi, una volta caricati i dati della tabella tramite PHP, AJAX, HTML o XML entra in gioco il javascript, che permette un'infinità di giochetti. In questo esempio ho usato l'ordinamento per colonna, i filtri, l'highlight delle righe ed i link condizionali. Oltre naturalmente alla possibilità di ridimensionare al volo le colonne ed al fatto che la tabella occupa una spazio prefissato. Non ultimo l'header resta fisso durante lo scrolling, risultato non banale se mai avete tentato di fare qualcosa di simile!</p>
<p>Il codice usato è relativamente poco, grazie all'ottimo framework OpenRico, che si appoggia su <a href="http://www.prototypejs.org/">ProtoType</a>. Inizio con l'inizializzazione di ciò che mi serve:</p>

<pre class="brush: jscript;">
// Carico tutti gli elementi necessari
Rico.loadModule('LiveGrid','LiveGridMenu','gest.css');
// var orderGrid,buffer;
var CustId='1';
var CustIdCol=7;
</pre>

<p>Qui c'è la parte più succosa: definisco una classe che in seguito assegnerò alla variabile control, all'interno della definizione delle colonne. Questa classe indica a alla LiveGrid che le colonne interessate dovranno avere un determinato colore di sfondo ed un link condizionale, stabilito sulla base del contenuto di una colonna. Le classi predefinite in OpenRico sono disponibili nel file ricoLiveGridControls.js, e sono un ottimo punto di partenza per svilupparne di proprie.</p>

<pre class="brush: jscript;">
// Creo la Classe - classi preesistenti in ricoLiveGridControls.js
HighlightCellAndLink = Class.create();
// Dichiaro la classe - si tratta di un misto tra due classi esistenti
HighlightCellAndLink.prototype = {

	initialize: function(chkcol,chkval,highlightColor,highlightBackground,href,target) {
		this._chkcol=chkcol;
		this._chkval=chkval;
		this._highlightColor=highlightColor;
		this._highlightBackground=highlightBackground;

		this._href=href;
		this._target=target;
		this._anchors=[];
	},
  _create: function(gridCell,windowRow) {
		this._anchors[windowRow] = RicoUtil.createFormField(gridCell,'a',null,this.liveGrid.tableId+'_a_'+this.index+'_'+windowRow);
		if (this._target) this._anchors[windowRow].target=this._target;
		this._clear(gridCell,windowRow);
  },
  _clear: function(gridCell,windowRow) {
		gridCell.style.color='';
		gridCell.style.backgroundColor='';
	
		this._anchors[windowRow].href='';
		this._anchors[windowRow].innerHTML='';
  },
  _display: function(v,gridCell,windowRow) {
		var gridval=this.liveGrid.buffer.getWindowValue(windowRow,this._chkcol);
		var match=(gridval==this._chkval);
		gridCell.style.color=match ? this._highlightColor : '';
		gridCell.style.backgroundColor=match ? this._highlightBackground : '';
	
		this._anchors[windowRow].innerHTML=this._format(v);
		var getWindowValue=this.liveGrid.buffer.getWindowValue.bind(this.liveGrid.buffer);
		this._anchors[windowRow].href=this._href.replace(/\{\d+\}/g,
		function ($1) {
			var colIdx=parseInt($1.substr(1));
			return getWindowValue(windowRow,colIdx);
		}
	);
  }

}
</pre>

<p>Infine dichiaro alcune variabili ed intervengo sul core della LiveGrid: definisco i parametri di ciascuna colonna.</p>

<pre class="brush: jscript;">
Rico.onLoad( function() {
// Carico i dati della tabella dentro al Rico Buffer javascript
var buffer = new Rico.Buffer.Base($('dataTable').tBodies[0]);
// Preparo le opzioni
var grid_options = {
headingSort: 'hover',
highlightElem: 'cursorRow',
FilterLocation: -1,
visibleRows: 23,
saveColumnInfo: {width:false, filter:false, sort:false},
columnSpecs: [

{
	height:50, 
	width:113,
	filterUI:'t^20',
	control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880')
}, // id
{
	width:185, 
	filterUI:'t^20', 
	control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880')
}, // Rag. sociale
{
	width:78, 
	filterUI:'t^20', 
	control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880')
}, // tipo lic.
{
	width:25, 
	control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880'),
	ClassName:'centred'
}, // n. lic.
{
	type:'date',
	dateFmt:'dd/mm/yyyy',
	width:75, 
	control:new Rico.TableColumn.HighlightCell( CustIdCol,CustId,'black','#FBC880' )
}, // scad. ass.
{
	visible:false
}, // log id
{
	control:new HighlightCellAndLink(CustIdCol,CustId,'black','#FBC880','/','_blank'), 
	type:'date', 
	dateFmt:'dd/mm/yyyy', 
	width:75
}, // ultimo agg.
{
	width:25, 
	filterUI:'t', 
	control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880'),
	ClassName:'centred'
}, // B
{
	width:25, 
	filterUI:'t', 
	control:new Rico.TableColumn.HighlightCell(CustIdCol,CustId,'black','#FBC880'),
	ClassName:'centred'
}, // L
{
	type:'date', 
	dateFmt:'dd/mm/yyyy', 
	width:75, control:new Rico.TableColumn.HighlightCell( CustIdCol,CustId,'black','#FBC880' )
}, // ultimo int.
{
	type:'date', 
	dateFmt:'dd/mm/yyyy', 
	width:75, 
	control:new Rico.TableColumn.HighlightCell( CustIdCol,CustId,'black','#FBC880' )
}, // data stipula

] };

// Creo un'istanza della LiveGrid
var grid = new Rico.LiveGrid('dataTable', buffer, grid_options);
});
</pre>

<p>Il codice completo è disponibile visualizzando il sorgente della pagina, dopo una learning curve un pochino ripida vi troverete a lavorare in modo davvero semplice con questo ottimo prodotto. </p>
<p>Happy coding</p>
]]></content:encoded>
			<wfw:commentRss>http://gabo.homelinux.com/2009/04/impaginare-tabelle-con-i-css/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>phplist e le immagini incluse nei messaggi</title>
		<link>http://gabo.homelinux.com/2009/04/phplist-embedding-images/</link>
		<comments>http://gabo.homelinux.com/2009/04/phplist-embedding-images/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 16:30:39 +0000</pubDate>
		<dc:creator>gabo</dc:creator>
				<category><![CDATA[programmazione]]></category>
		<category><![CDATA[newsletter]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phplist]]></category>

		<guid isPermaLink="false">http://gabo.homelinux.com/?p=292</guid>
		<description><![CDATA[Dalla versione 2.10.8 di phplist (o forse qualcuna prima), vi è la possibilità di inserire immagini all'interno delle nostre mailing, senza dover ricorrere al link esterno (che l'odioso outlook e altri MUA) visualizzano come se si trattasse di errori (per l'utente di medio-basso livello). ]]></description>
			<content:encoded><![CDATA[<p>Dalla versione 2.10.8 di phplist (o forse qualcuna prima), vi è la possibilità di inserire immagini all'interno delle nostre mailing, senza dover ricorrere al link esterno (che l'odioso outlook e altri MUA) visualizzano come se si trattasse di errori (per l'utente di medio-basso livello). Basta aggiungere al file di configurazione </p>

<pre class="brush: php;">
# Aggiunta di Gabo per permettere di inserire le immagini nel corpo del messaggio
define(&quot;EMBEDUPLOADIMAGES&quot;,1);
</pre>

<p>Il problema è che non mi funzionava. Non c'era verso. Allora, armato di santa pazienza, ho messo mano al codice ed ho cercato di capire il motivo. Il problema sta nel fatto che uploadando le immagini, mediante l'FCKEditor, non si possono usare sottodirectory a quella specificata mediante</p>

<pre class="brush: php;">
# If you want to upload images to the FCKeditor, you need to specify the location
# of the directory where the images go. This needs to be writable by the webserver,
# and it needs to be in your public document (website) area
# the directory is relative to the root of PHPlist as set above
# This is a potential security risk, so read README.security for more information
define(&quot;FCKIMAGES_DIR&quot;,&quot;uploadimages&quot;);
</pre>

<p>Dato che io amo le sottodirectory, ma soprattutto perchè gli utenti non avrebbero mai capito il motivo di non poter usare le suddette, ho messo mano al codice ed ho modificato le due funzioni preposte all'arduo compito: filesystem_image_exists e get_filesystem_image, entrambe presenti nel file admin/class.phplistmailer.php</p>
<p>Come prima cosa, però, ho aggiunto anche questa riga al file di configurazione, in modo da poter includere le immagini anche quando si spedisce tramite cronjob e PHP-cli:</p>

<pre class="brush: php;">
//ADDED BY GABO
$phplistRoot = '/home/mysite/public_html';
//END ADDED BY GABO
</pre>

<p>Ecco le funzioni modificate:</p>

<pre class="brush: php;">
## addition for filesystem images - MODIFYED BY GABO
    function filesystem_image_exists($filename) {
      ##  find the image referenced and see if it's on the server

      $elements = parse_url($filename);
      $localfile = basename($elements['path']);

      // search for subdirectory
      $basePath = $GLOBALS['phplistRoot'].$GLOBALS['pageroot'].'/'.FCKIMAGES_DIR;
      $dir = substr($elements['path'],
                    strpos($elements['path'],FCKIMAGES_DIR)+strlen(FCKIMAGES_DIR),
                    strlen($elements['path']) -
                       strpos($elements['path'],FCKIMAGES_DIR) -
                       strlen(FCKIMAGES_DIR)-strlen($localfile));

      return is_file($basePath.$dir.$localfile);
    }

    function get_filesystem_image($filename) {
      ## get the image contents
      $elements = parse_url($filename);
      $localfile = basename($elements['path']);

      $basePath = $GLOBALS['phplistRoot'].$GLOBALS['pageroot'].'/'.FCKIMAGES_DIR;
      $dir = substr($elements['path'],
                    strpos($elements['path'],FCKIMAGES_DIR)+strlen(FCKIMAGES_DIR),
                    strlen($elements['path']) -
                       strpos($elements['path'],FCKIMAGES_DIR) -
                       strlen(FCKIMAGES_DIR)-strlen($localfile));

      if (is_file($basePath.$dir.$localfile)) {
        return base64_encode( file_get_contents($basePath.$dir.$localfile) );
      }
      return 0;
    }
    ## end addition - MODIFYED BY GABO
</pre>

<p>Et voilà, le immagini sono servite. Che poi mandare 6000 email che pesano 500kb sia decisamente peggio di mandarne 6000 che pesano 20Kb è un altro discorso, ma con il management non si discute <img src='http://gabo.homelinux.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://gabo.homelinux.com/2009/04/phplist-embedding-images/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>GDate &#8211; Gestire le date in PHP</title>
		<link>http://gabo.homelinux.com/2009/03/gdate/</link>
		<comments>http://gabo.homelinux.com/2009/03/gdate/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 22:01:03 +0000</pubDate>
		<dc:creator>gabo</dc:creator>
				<category><![CDATA[programmazione]]></category>
		<category><![CDATA[classi]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://gabo.homelinux.com/?p=270</guid>
		<description><![CDATA[GDate, la classe definitiva per la gestione delle date in PHP]]></description>
			<content:encoded><![CDATA[<p>La gestione delle date in PHP, come in ogni altro linguaggio, è una rogna senza fine. Ciascuno le rappresenta come gli pare, ad XML piacciono in un modo, MYSQL se ne inventa un'altro (cambiandolo, tra l'altro, da una versione all'altra), il servizio SOAP a cui mi devo collegare ha un'ulteriore modo di vederle e via discorrendo. Per non parlare dell'internazionalizzazione, gli americani usano aaaa-mm-dd, gli italiani dd-mm-aaaa e chi più ne ha più ne metta!</p>
<p>Ho scritto GDate (GaboDate), una classe PHP5 per la gestione delle date in italiano facilmente estendibile ad altre lingue. Il concetto è semplice: memorizzo la data in un oggetto, e poi la manipolo/rappresento nei vari modi e formati che mi è capitato di dover gestire.</p>
<p>Oltre a gestire date Mysql, XML, Unix Timestamp ed altri, fornisce utilità come settarsi all'<strong>ultimo giorno lavorativo</strong> del mese in corso, calcolare la<strong> distanza tra due date</strong>, settarsi a giorni particolari della settimana o del mese ed altre manipolazioni classiche realtive alle date.</p>
<p>Un esempio è forse la cosa più utile in questo caso. </p>

<pre class="brush: php;">
&lt;?php
require_once 'GDate.php';

$d = new GDate();
$d1 = new GDate();
$d1-&gt;setDateFromXmlDatetime('19810303T06:30:05');

echo &quot;\nNOW IS: \n&quot;;
echo &quot;\nLong date:\t\t&quot; . $d-&gt;getLong(true);
echo &quot;\nShort date:\t\t&quot; . $d-&gt;getShort();
echo &quot;\nMysql TimeStamp:\t&quot; . $d-&gt;getMysqlTimeStamp(true);
echo &quot;\nXML DateTime:\t\t&quot; . $d-&gt;getXmlDatetime(true);
echo &quot;\nUnix TimeStamp:\t\t&quot; . $d-&gt;getUnixTimeStamp(true);
echo &quot;\nIntegerdate:\t\t&quot; . $d-&gt;getIntegerDate(true);

echo &quot;\n&quot;;
echo &quot;\nCOMPARING DATE: \n&quot;;
echo &quot;\nLong date:\t\t&quot; . $d1-&gt;getLong(true);
echo &quot;\nShort date:\t\t&quot; . $d1-&gt;getShort();
echo &quot;\nMysql TimeStamp:\t&quot; . $d1-&gt;getMysqlTimeStamp(true);
echo &quot;\nXML DateTime:\t\t&quot; . $d1-&gt;getXmlDatetime(true);
echo &quot;\nUnix TimeStamp:\t\t&quot; . $d1-&gt;getUnixTimeStamp(true);
echo &quot;\nIntegerdate:\t\t&quot; . $d1-&gt;getIntegerDate(true);

/* DIFFERENZA DATE */
echo &quot;\n\n&quot;;
echo $d-&gt;getShort() .&quot; - &quot; .$d1-&gt;getShort();
echo &quot; =&gt; &quot; . $d1-&gt;compareDate($d);
echo &quot; giorni\n&quot;;

/* ULTIMO GIORNO LAVORATIVO */
echo &quot;\n&quot;;
$d-&gt;setLastWorkDayOfMonth();
echo &quot;L'ultimo giorno lavorativo di &quot; . $d-&gt;getMonthString() .
		&quot; &quot; . $d-&gt;getYear() . &quot; è &quot; . $d-&gt;getdayOfWeekString() .
		&quot; &quot; . $d-&gt;getDay() . &quot;\n&quot;;

$d1-&gt;setLastWorkDayOfMonth();
echo &quot;L'ultimo giorno lavorativo di &quot; . $d1-&gt;getMonthString() .
		&quot; &quot; . $d1-&gt;getYear() . &quot; è &quot; . $d1-&gt;getdayOfWeekString() .
		&quot; &quot; . $d1-&gt;getDay() . &quot;\n&quot;;

$d1-&gt;setDateFromShort('2/2/1992');
$d1-&gt;setLastWorkDayOfMonth();
echo &quot;L'ultimo giorno lavorativo di &quot; . $d1-&gt;getMonthString() .
		&quot; &quot; . $d1-&gt;getYear() . &quot; è &quot; . $d1-&gt;getdayOfWeekString() .
		&quot; &quot; . $d1-&gt;getDay() . &quot;\n&quot;;

/* CHECK LAST WORKING DAY */
echo &quot;\n&quot;;
$d = new GDate();
$d1 = new GDate();

$d1-&gt;setLastWorkDayOfMonth();

$d-&gt;setStartDay();
$d1-&gt;setStartDay();

echo &quot;Oggi:\t\t\t&quot; . $d-&gt;getLong(true);
echo &quot;\n&quot;;
echo &quot;Ultimo lavorativo:\t&quot; . $d1-&gt;getLong(true);
echo &quot;\n&quot;;

/* COMPARE DATE */
if ($d == $d1)
	echo &quot;Oggi è l'ultimo giorno lavorativo del mese\n&quot;;
else
	echo &quot;Oggi NON è l'ultimo giorno lavorativo del mese\n&quot;;

?&gt;
</pre>

<p>Lanciando il file di esempio scaricabile insieme alla classe, si ottiene il seguente output:</p>

<pre>g4b0@slack:~/sys/working/gdate$ php testGDate.php

NOW IS:

Long date:              23/03/2009-20:30:05
Short date:             23/3/2009
Mysql TimeStamp:        2009-03-23 20:30:05
XML DateTime:           20090323T20:30:05
Unix TimeStamp:         1237836605
Integerdate:            20090323

COMPARING DATE:

Long date:              03/03/1981-06:30:05
Short date:             3/3/1981
Mysql TimeStamp:        1981-03-03 06:30:05
XML DateTime:           19810303T06:30:05
Unix TimeStamp:         352445405
Integerdate:            19810303

23/3/2009 - 3/3/1981 => 10247 giorni

L'ultimo giorno lavorativo di Marzo 2009 è Martedì 31
L'ultimo giorno lavorativo di Marzo 1981 è Martedì 31
L'ultimo giorno lavorativo di Febbraio 1992 è Venerdì 28

Oggi:                   24/03/2009-00:00:00
Ultimo lavorativo:      31/03/2009-00:00:00
</pre>

<p>Io la trovo molto comoda, e la uso in svariati progetti. Dopo averci preso un po' la mano semplifica parecchio la vita, e velocizza lo sviluppo software. Ci sarebbero da aggiungere funzionalità varie, come la gestione dei centesimi di secondo, dei millesimi e dei microsecondi. Si potrebbero aggiungere lingue varie. Si potrebbero aggiungere nuove funzionalità.</p>
<p>Scarica <a title="GDate" href="/download/GDate.tar.bz2">GDate</a>.</p>
<p>Questo software è rilasciato sotto licenza GPL, reperibile presso <a title="GPL" href="http://www.gnu.org/copyleft/gpl.html">http://www.gnu.org/copyleft/gpl.html</a></p>]]></content:encoded>
			<wfw:commentRss>http://gabo.homelinux.com/2009/03/gdate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
