piątek, 27 lipca 2007

Google Analytics po naszemu

No i kolejna usługa Googla po naszemu. Google Analytics doczekało się języka polskiego, wystarczy wybrać go w opcjach. Screeny i helpik u Tomasza Topy.

czwartek, 26 lipca 2007

Google Gears - brakujący pierwiastek

Interfejs www jest jednym z najwygodniejszych jeżeli chodzi o szybkość projektowania i jego przenośność. Strona stworzona na środowisku konfigurowanym przez samego programistę (lub nie, w każdym razie jednoznacznie sprecyzowanym), wydajność serwerowa ... marzenie. Brakuje jednego małego elementu ... wersji offline. Co teraz? Nasz gigant znowu na miejscu ... oto Google Gears!

O co chodzi?
Co znowu wymyślili chłopaki z Googla? Niby nic rewolucyjnego, wystarczyło wzbogacić przeglądarki o 3 elementy.
  • Serwer Lokalny: służy on do składowania obrazków, css'ów i wszystkiego czego tylko chcesz podczas przebywania w trybie offline.
  • Baza danych: prosta baza SQLite, wysyłania do której można wykonywać prosto z JavaScriptu na stronie.
  • WorkerPool: dodatkowe rozszerzenie JavaScriptu umożliwiające tworzenie wątków dla długo trwających zapytań. Po co? Żeby przeglądarka nie "zamarzła".
Dlaczego to może wypalić? Z powodu prostej instalacji pod Firefoxem i Internet Explorerem. Brak zbędnych zagmatwanych instalatorów na pewno pomoże.

Bezpiecznie panowie (i panie)
Bezpieczeństwo przede wszystkim. Taka przyświeca nam wszystkim zasada. I słusznie! Tutaj też to działa. A przynajmniej w obrębie jednego programisty. Konkrety? Służę, baza stworzona z jednej domeny (przykładowo domena1.pl) może być obsługiwana tylko przez tą jedną domenę. Czyli zła konkurencja z domeny domena2.pl nic nam nie namiesza.

Troszkę kodu
Weźmy na warsztat prościutki system dodawania artykułów. Chcemy tylko mieć dostęp do dodanych artykułów zarówno w wersji online jak i offline. Po stronie serwera jedna baza artykułów, prosty formularz dodawania i strona podziękowania za wpis. Nie będę tego pisał, każdy robił to już tysiące razy. Nie? Szukać w necie ;)

Co jeszcze po stronie serwera? Potrzebujemy plik articles.php generujący nam prostego xml'a. Przykładowy output mógłby wyglądać tak:

<articles>
<article id="1" title="Hate test strings">Test article here bla bla</article>
<article id="2" title="Lorem ipsum forever">
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</article>
</articles>
Teraz plik z dodawaniem artykułów do Google Gears... Dla uproszczenia użyję zapytań Ajaxa używając Prototype. Plik gears_init.js natomiast jest dodawany do zestawu developerskiego Google. Oba zaincludowane w headzie.
 <html>
<head>
<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript" src="prototype.js"></script>
</head>
<body onload="initializedb()">

<table width="100%">
<tr><td width="20%" valign="top">
<table width="100%" id="elArticles">
</table>
</td><td width="80%" valign="top">
<div id="elContent"></div>
</td></tr></table>

<a href="javascript:void sync();">Synchronizuj</a>

<script>
var db;

function sync()
{
new Ajax.Request( 'articles.php', { method: 'get',
onSuccess: function( transport ) {
var articleTags = transport.responseXML.getElementsByTagName( 'article' );

for( var a = 0; a < articleTags.length; a++ ) {
addArticle( parseInt( articleTags[a].getAttribute('id') ),
articleTags[a].getAttribute('title'),
articleTags[a].firstChild.nodeValue );
}
showArticles();
} } );
}

function initializedb() {
if (!window.google || !google.gears)
return;

try {
db = google.gears.factory.create('beta.database', '1.0');
} catch (ex) {
alert('Could not create database: ' + ex.message);
}

if (db) {
db.open('gearsintro');
db.execute('create table if not exists articles' +
' ( article_id int, title varchar(255), content text )');
}
showArticles();
}

function showArticle( id )
{
var rs = db.execute( 'select content from articles where article_id = ?', [ id ] );
var found = 0;
while (rs.isValidRow()) { $('elContent').innerHTML = rs.field(0); rs.next(); }
rs.close();
}

function showArticles()
{
while( $('elArticles').rows.length > 0 )
$('elArticles').deleteRow( -1 );

var rs = db.execute( 'select * from articles' );
while (rs.isValidRow())
{
var elTR = $('elArticles').insertRow( -1 );
var elTD = elTR.insertCell( -1 );
elTD.onmouseover = function() { this.style.background = '#eee'; };
elTD.onmouseout = function() { this.style.background = 'none'; };

elTD.id = rs.field( 0 );
elTD.onmouseup = function() { showArticle( this.id ); };

elTD.appendChild( document.createTextNode( rs.field(1) ) );
rs.next();
}
rs.close();
}

function addArticle( id, title, content )
{
var rs = db.execute( 'select * from articles where article_id = ?', [ id ] );
var found = 0;
while (rs.isValidRow()) { found++; rs.next(); }
rs.close();
if ( found == 0 )
db.execute('insert into articles values (?, ?, ?)', [id, title, content]);
}
</script>
</body>
</html>

Google Gears uruchamiamy z użyciem funkcji initializedb, co otwiera połączenie z bazą i tworzy tablicę artykułów. Ostatnią rzeczą w initialize db jest metoda showArticles, która szuka artykułów w bazie Gears i wyświetla je w tablicy.

Funkcja sync, którą uruchamia się po kliknięciu linka synchronizuj pobiera Ajaxem plik articles.php z xml'em i wywołuje metodę addArticle dla każdego artykułu. Ta z kolei dodaje artykuł do bazy o ile artykuł z takim ID nie istnieje w bazie. Potem po raz kolejny wywoływana jest metoda showArticles.

Tradycyjne podsumowanie

Warto? Hah! Odwieczne pytanie. Oczywiście zależy od aplikacji. Warunkowe użycie (świat to nie Firefox + IE), dodatkowe pisanie, stany offline i online ... to problemy, które dochodzą i tak już zapracowanemu programiście. W każdym razie po raz kolejny Google dało nam znakomite narzędzie, jak je użyjemy ...

wtorek, 17 lipca 2007

Umarł król, niech żyje król

Stało się! Długo oczekiwana wiadomość od grupy PHP doszła 13 lipca. PHP4 nie będzie dalej rozwijane. Mając na uwadze iż PHP5 na dobre zadomowiło się na maszynach hostingowych a PHP6 jest już w produkcji, krok ten był nieunikniony.

Jak wygląda kalendarz? Do końca roku zapewniony jest support dla PHP4, natomiast do 08.08.2008 (ładna data ;) będą wypuszczane łatki krytyczne. Potem? Hulaj hakerska duszo! Pół roku na przesiadkę na PHP5 moim zdaniem to aż za dużo. Lista niekompatybilnych zmian dostępna jest tutaj. Krótka? Oczywiście, wszyscy to powtarzają już od 3 lat ;)

Pisałem o wyborze PHP jako platformy. Problem sie skończył ... teraz jedyną opcją jest PHP5. Do czasu kiedy światło dzienne ujrzy PHP6 i jazda zacznie się od nowa ...

środa, 4 lipca 2007

HTML Purifier - i życie stało się ... bezpieczniejsze

Jaki jest cel odwiecznej ludzkiej złośliwości? ... część znajomych każe mi spytać samego siebie, ale co oni wiedzą ;) Problem złośliwości dla informatyka zaczyna się tam, gdzie pojawia się interakcja z użytkownikiem. Od dawien dawna wiadomo, że najbardziej pracochłonną czynnością jest zabezpieczanie wszystkiego (tak, wszystkiego) przed podłymi, tudzież ciekawskimi, useram. Aby umilić nam web developerom życie, Edward Yang stworzył coś, co nazywa się HTML Purifier.

Jest to biblioteka oferująca filtr, zamieniający wprowadzony ciąg znaków na validujący się kod HTML. Nie tylko usuwa złośliwy kod wprowadzony przez użytkownika (znany jako XSS), ale też zamyka tagi i zapewnia pełną zgodność z W3C.

Osobiście polecam używanie tego rodzaju bibliotek. Uważam tą za dobrze napisaną i wartą uwagi. Jak działa można sprawdzić samemu tutaj.