Tuesday, 21 September 2010

Generatore di Feed RSS/Atom

Una delle funzionalità più utili e ricercate dei siti è la gestione dei feed RSS (2.0). Per implementarla in PHP, utilizziamo la comoda classe FeedWriter di Anis Ahmad e disponibile nel suo sito per il download.



Ci dobbiamo ricordare solo di due cose, per la gestione dei feed in lingua italiana ed in generale per le lingue con caratteri accentati (ASCII code > 127): tutte le occorrenze dei caratteri accentati NON vanno escapate tranne la & commerciale (&), e la tabella codici deve essere sempre lo stesso, e cioè UTF-8. Il Feed RSS è un file XML e dunque le entità HTML supportate sono solo 5 (lt, gt, amp, quote, apos)*.

Bisogna dunque controllare che nella prima riga del feed RSS corrispondente ci sia

<?xml version="1.0" encoding="UTF-8" ?>

Una prima versione del codice, molto banale, potrebbe essere la seguente:

$titolo = str_replace("&", "&amp;", $titolo);

Addendum "Check and Escape".

Una procedura completa, in caso di necessità, per trovare tutti i caratteri maggiori di ASCII(127) in un dato testo con un controllo esadecimale prevede un ciclo di controllo:

// Controlla se c'e' un Ascii > 127
$titolo = $row['titolo'];
        $strl = strlen($titolo);
         for ($i = 0;$i < $strl; $i++)
        {
            $char = '0x' . bin2hex(substr($titolo,$i,1));
            $pos = in_array($char, $arr_hex);
            if ($pos == 1)
            {
                    // Neutralizza carattere Ascii>127 trasformandolo in Html
                    // Esempio: 0xe0 diventa .....
                $titolo = str_replace($char, ' ', $titolo);
            }
        }
      

L'array di cui si parla nel frammento di codice precedente è:

// Ascii Hex > 128 (see http://www.table-ascii.com/)
$arr_hex = array(
"0x80","0x81","0x82","0x83","0x84","0x85","0x86","0x87","0x88","0x89","0x8A",
"0x8B","0x8C","0x8D","0x8E","0x8F",
"0x90","0x91","0x92","0x93","0x94","0x95","0x96","0x97","0x98","0x99","0x9A",
"0x9B","0x9C","0x9D","0x9E","0x9F",
"0xA0","0xA1","0xA2","0xA3","0xA4","0xA5","0xA6","0xA7","0xA8","0xA9","0xAA",
"0xAB","0xAC","0xAD","0xAE","0xAF",
"0xB0","0xB1","0xB2","0xB3","0xB4","0xB5","0xB6","0xB7","0xB8","0xB9","0xBA",
"0xBB","0xBC","0xBD","0xBE","0xBF",
"0xC0","0xC1","0xC2","0xC3","0xC4","0xC5","0xC6","0xC7","0xC8","0xC9","0xCA",
"0xCB","0xCC","0xCD","0xCE","0xCF",
"0xD0","0xD1","0xD2","0xD3","0xD4","0xD5","0xD6","0xD7","0xD8","0xD9","0xDA",
"0xDB","0xDC","0xDD","0xDE","0xDF",
"0xE0","0xE1","0xE2","0xE3","0xE4","0xE5","0xE6","0xE7","0xE8","0xE9","0xEA",
"0xEB","0xEC","0xED","0xEE","0xEF",
"0xF0","0xF1","0xF2","0xF3","0xF4","0xF5","0xF6","0xF7","0xF8","0xF9","0xFA",
"0xFB","0xFC","0xFD","0xFE","0xFF"
);

Nella lingua italiana, in generale, può bastare anche (come workaround) trasformare le accentate in apostrofate, poiché ogni lettera accentata è alla fine della parola:

$accentate = array ("à","è","ì","ò","ù");
$apostrofate = array ("a'","e'","i'","o'","u'");
$titolo = str_replace($accentate, $apostrofate, $row['titolo']);

Per le altre lingue, un ulteriore funzione è quella che prevede di trasformare qualsiasi accentata nella corrispondente parola piana (utile dove le lettere accentate sono in mezzo alla frase):

function replace_accents($str) {
$str = htmlentities($str, ENT_COMPAT, "UTF-8");
$str = preg_replace('/&([a-zA-Z])(uml|acute|grave|circ|tilde);/','$1',$str);
    return html_entity_decode($str);
}

Infine, un ultimo metodo per ottenere un feed accentato consiste nel porre tra CDATA anche il campo titolo (gli altri campi di descrizione sono già in questo contenitore), che corrisponde a trattare come Binario tale dato:

<title><![CDATA[Prova titolo che sarà accentato]]></title>

Il corrispondente feed non sarà però completamente standard.

*
Name Character Unicode code point (decimal) Standard Description
quot " U+0022 (34) XML 1.0 (double) quotation mark
amp & U+0026 (38) XML 1.0 ampersand
apos ' U+0027 (39) XML 1.0 apostrophe (= apostrophe-quote)
lt < U+003C (60) XML 1.0 less-than sign
gt > U+003E (62) XML 1.0 greater-than sign