Rogério Lino

Web development and tips

HTML5: Websocket

The Websocket Protocol

1
The WebSocket Protocol enables two-way communication between a client running untrusted code in a controlled environment to a remote host that has opted-in to communications from that code. The security model used for this is the origin-based security model commonly used by web browsers. The protocol consists of an opening handshake followed by basic message framing, layered over TCP.  The goal of this technology is to provide a mechanism for browser-based applications that need two-way communication with servers that does not rely on opening multiple HTTP connections (e.g., using XMLHttpRequest or <iframe>s and long polling).

Aproveitando um post sobre PHP Sockets que tinha escrito unindo o estudo sobre Websocket, eu criei um projeto no Github para facilitar o uso de sockets com PHP fornecendo suporte ao Websocket também.

E para visualizar o exemplo basta fazer checkout do projeto, executar o arquivo server.php:

1
$ php server.php

E abrir a página chat.html pelo browser. O funcionamento do exemplo vai depender, além obviamente do suporte à Websocket, do tipo da versão da implementação do browser. Por enquanto a suportada pelo projeto é a HyBi (descrita na RFC 6455).

Extensões Google Chrome

Em 2006 publiquei um post listando algumas extensões que recomendava para o Firefox, o tempo passou e acabei mudando de browser também. E o mais engraçado é que mesmo mudando de browser, as duas extensões que sempre fiz questão de instalar no Firefox, hoje também são pré-requisitos no Chrome. São elas:

Firebug

Firebug Lite is not a substitute for Firebug, or Chrome Developer Tools. It is a tool to be used in conjunction with these tools. Firebug Lite provides the rich visual representation we are used to see in Firebug when it comes to HTML elements, DOM elements, and Box Model shading. It provides also some cool features like inspecting HTML elemements with your mouse, and live editing CSS properties.

Web Developer

The Web Developer extension adds a toolbar button to the browser with various web developer tools. This is the official port of the popular Web Developer extension for Firefox written by the same person.

Além dessas que considero obrigatórias, recomendo também as seguintes extensões:

JSONView

Valida e formata páginas com conteúdo JSON. Excelente extensão.

PerfectPixel

This extension allows developers to put a semi-transparent image overlay over the top of the developed HTML and perform per pixel comparison between them. Analogue of popular Firefox extension PixelPerfect.

Silver Bird (utilizava o Tweetdeck até ser necessária a criação de uma outra conta)

Silver Bird is an awesome Twitter client extension for Google Chrome with lots of features.

Screen Capture by Google

It's easy to use this extension to capture visible content of a tab, a region of a web page, or the whole page as a PNG image.

Window Close Protector

Show a warning dialog when closing a window containing multiple tabs.

PHP: Validate Filters

A partir do PHP 5.2 foi introduzida a função filter_var. Que serve justamente para filtrar uma variável a partir de um filtro especificado.

1
2
mixed filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] )
// Returns the filtered data, or FALSE if the filter fails.

Filtros pré-definidos:

1
2
3
4
5
6
7
8
9
10
11
// email filtering
echo filter_var('email@domain.com', FILTER_VALIDATE_EMAIL); // email@domain.com
echo filter_var('domain.com', FILTER_VALIDATE_EMAIL); // false

// url filtering
echo filter_var('http://rogeriolino.com', FILTER_VALIDATE_URL); // http://rogeriolino.com
echo filter_var('rogeriolino.com', FILTER_VALIDATE_URL); // false

// ip filtering
echo filter_var('127.0.0.1', FILTER_VALIDATE_IP); // 127.0.0.1
echo filter_var('127.0.1', FILTER_VALIDATE_IP); // false

Como a função pode retornar FALSE (caso o filtro falhe) ou o valor filtrado. Podemos utilizar o Not identical operator (!==) para verificar se retorno é realmente FALSE, ou seja, o valor testado não passou pelo filtro.

Colocando em prática a função mais orientação à objetos para criar algumas classes validadoras:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/**
 * Interface Validator 
 */
interface Validator {

    public function isValid($value);

}

/**
 * Abstract class Simple Validator
 */
abstract class SimpleValidator implements Validator {

    protected abstract function defaultFilter();

    public function isValid($value) {
        return filter_var($value, $this->defaultFilter()) !== false;
    }

}

/**
 * Simple Email validator 
 */
class EmailValidator extends SimpleValidator {

    protected function defaultFilter() {
        return FILTER_VALIDATE_EMAIL;
    }

}

/**
 * Simple URL validator 
 */
class UrlValidator extends SimpleValidator {

    protected function defaultFilter() {
        return FILTER_VALIDATE_URL;
    }

}

/**
 * Simple IP Validator 
 */
class IpValidator extends SimpleValidator {

    protected function defaultFilter() {
        return FILTER_VALIDATE_IP;
    }

}

Testando

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// email validating
$validator = new EmailValidator();
echo $validator->isValid('rogeriolino@com'); // false
echo $validator->isValid('contact@rogeriolino.com'); // true
echo $validator->isValid('contact+spam@rogeriolino.com'); // true

// URL validating
$validator = new UrlValidator();
echo $validator->isValid('http://rogeriolino.com'); // true
echo $validator->isValid('http://rogeriolino.com/contact'); // true
echo $validator->isValid('rogeriolino.com/contact'); // false
echo $validator->isValid('https://rogeriolino'); // true
echo $validator->isValid('ftp://rogeriolino.com'); // true

// URL validating
$validator = new IpValidator();
echo $validator->isValid('127.0.0.1'); // true
echo $validator->isValid('127.0.0'); // false
echo $validator->isValid('1050:0000:0000:0000:0005:0600:300c:326b'); // true
echo $validator->isValid('1050:0000:0000:0000:0005:0600'); // false

Para ver outros filtros: http://php.net/manual/filter.filters.validate.php

PHP: Easy SQL Date Time Formatting

SQL to Human:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* 
 * date
 */
$format = 'm/d/Y'; // en-US
// $format = 'd/m/Y'; // pt-BR
$date = '2012-02-01';
echo date($format, strtotime($date));


/* 
 * datetime
 */
$format .= ' H:i:s';
$datetime = '2012-02-01 11:33:59';
echo date($format, strtotime($datetime));

Human to SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/* 
 * date
 */
$sqlFormat = 'Y-m-d';
$date = '02/01/2012';

// en-US
echo date($sqlFormat, strtotime($date));
// pt-BR
echo join('-', array_reverse(explode('/', $date)));


/* 
 * datetime
 */
$sqlFormat = 'Y-m-d H:i:s';

// en-US
$datetime = '02/01/2012 11:33:59';
echo date($sqlFormat, strtotime($datetime));

// pt-BR
$datetime = '01/02/2012 11:33:59';
$datetime = explode(' ', $datetime);
$date = join('-', array_reverse(explode('/', $datetime[0])));
echo $date . ' ' . $datetime[1];

Reference:

strtotime The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.

date Returns a string formatted according to the given format string using the given integer timestamp or the current time if no timestamp is given. In other words, timestamp is optional and defaults to the value of time().

explode Returns an array of strings, each of which is a substring of string formed by splitting it on boundaries formed by the string delimiter.

array_reverse Takes an input array and returns a new array with the order of the elements reversed.

join / implode Join array elements with a glue string.

jQuery: Vertical Scroller Plugin

Hoje criei um novo projeto no Github, para um plugin para jQuery (1.7+) que desenvolvi (estou e estarei desenvolvendo). Trata-se um scroller vertical que pode ser aplicado a qualquer tag block.

1
2
3
4
$('#news').vScroller({
  width: 300,
  height: 400
});

Conforme surgir demanda, necessidade de mais funcionalidades, callbacks, eu irei incrementando o projeto. Embora simples, está funcional, e serve como estudo.

[update 2012-01-24] Features:

  • MouseWheel

  • Drag&Drop;

  • Keys (UP, DOWN, PG_UP, PG_DOWN, HOME, END)

Compatibility (tested):

  • Chrome 12+

  • Firefox 8+

  • Opera 11+

[/update]

Demo: http://dev.rogeriolino.com/js/vscroller.html

Quickpost: Javascript Resource Loader

yepnope is an asynchronous conditional resource loader that’s super-fast, and allows you to load only the scripts that your users need.

Good Things

  • yepnope.js is only 1.6kb - smaller than most and certainly a good size for its functionality set.

  • yepnope.js is called a “resource loader” because it can work with both JavaScript and CSS.

  • yepnope.js has a full test suite in QUnit that you can run in your set of supported browsers to make sure it works. (We run it via TestSwarm in every browser we can get our hands on)

  • yepnope.js fully decouples preloading from execution. This means that you have ultimate control of when your resource is executed and you can change that order on the fly.

  • The yepnope.js api is friendly and encourages logical grouping of resources.

  • yepnope.js is modular. It has a whole system for adding your own functionality and a couple examples of how you might do that. (Prefixes and filters).

  • The yepnope.js api encourages you to only load the resources that you need. This means that even when it’s slower than another script loader, it still can come out on top, because you could avoid an entire resource.

  • yepnope.js is integrated into Modernizr.

  • yepnope.js always executes things in the order they are listed. This is a pro for some, and a con for others. We think it’s a friendly default.

  • yepnope.js has the capability to do resource fallbacks and still download dependent scripts in parallel with the first.

PHP: Manga Framework

Criado o projeto para o framework Manga, no Github (PHP 5.3+).

Entre algumas funcionalidades, destaca-se o seu template engine baseado no Facelets.

Os arquivos de configuração poderão ser escritos em mais de um formato, inicialmente suporte a XML e YAML. Annotations são utilizadas para enxugar esses arquivos de configuração, deixando o código mais intuitivo.

O próximo passo é implementar suporte à IoC, que inicialmente pode ser simulado pelo arquivo de configuração de rotas (com suporte REST).

A intenção não é desenvolver um framework revolucionário, e sim adaptar as ideias e metodologias já utilizadas por outros em um único framework afim de aumentar a produtividade. Servem como inspiração os seguintes frameworks:

Ruby

Java

PHP

CakePHP: Layout Inheritance

Para quem está utilizando o CakePHP ou já utilizou e também sentiu falta de herança nos layouts. Segue abaixo uma dica para ajudar na criações de templates utilizando o CakePHP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
    // sublayout.ctp
    ob_start();
?>
<!-- html content -->
<?php eco $content_for_layout; ?>
<!-- html content -->
<?php

    $content = ob_get_contents();
    ob_end_clean();

    echo $this->renderLayout(
        $content,
        'default' // parent layout
    );
1
2
3
4
5
6
7
8
9
<?php
// controller class
class MyController extends AppController {

    function test() {
        $this->layout = 'sublayout';
    }

}