Rogério Lino

Web development and tips

Novo SGA

novosga

SGA é o acrônimo de Sistema de Gerenciamento de Atendimento, sistema desenvolvido pela Dataprev e liberado como código aberto através da versão SGA Livre. Devido ao desenvolvimento do SGA Livre estar estagnado na mesma versão desde 2009, unindo a burocracia dos responsáveis pela comunidade no [Portal do Software Público](http://softwarepublico.gov.br/) surgiu a necessidade de criar uma nova versão para esse sistema que já roda em diversas localidades do Brasil. A parte web foi totalmente reformulada, deixando mais leve e intuitiva, com uma interface amigável e instalação super fácil. Já no painel foi feitas melhorias para funcionar em monitores widescreen. Outras melhorias e funcionalidades estão previstas e irão ser aplicadas durante o desenvolvimento do projeto.

Visite o site do projeto e confira a versão demo disponível online.

Gostou e quer contribuir com o desenvolvimento? Acesse o projeto no GitHub.

CSS3: Selection Background Color

Com o seletor selection podemos definir a cor do texto e de fundo do texto quando o selecionamos.

The ::-moz-selection (::selection) pseudo-element applies to the portion of a document that has been highlighted (e.g. selected with the mouse) by the user. Gecko/Firefox supports ::-moz-selection, use also ::selection other browsers. The following properties apply to ::-moz-selection: color, background and background-color (background-image is ignored). [http://dochub.io/#css/selection](http://dochub.io/#css/selection)

CSS

1
2
3
4
5
6
7
8
9
10
11
p::selection  { color: #000; }
p::-moz-selection { color: #000; }

p.yellow::selection  { background: yellow; }
p.yellow::-moz-selection { background: yellow; }

p.green::selection { background: #58FF4B; }
p.green::-moz-selection { background: #58FF4B; }

p.pink::selection { background: #E2189C; }
p.pink::-moz-selection { background: #E2189C; }

HTML

1
2
3
4
5
<p class="yellow">Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>

<p class="green">Aliquam erat volutpat. Donec in elit at magna venenatis venenatis...</p>

<p class="pink">Donec interdum placerat urna at aliquet...</p>

Exemplo http://dev.rogeriolino.com/exemplos/css/selection/index.html

jQuery + Modernizr: AccessKey Detection

O código abaixo permite exibir no title e na frente das tags que possuem o atributo accesskey o seu atalho.

Com o uso do CSS é adicionado ao final do conteúdo da tag o seu atalho. E via Javascript esse atalho também é adicionado ao title.

Como esses atalhos variam de acordo com o Browser e o Sistema Operacional, fiz uso do Modernizr + Detectizr para adicionar no body a classes informando o ambiente.

Dependências

1
2
3
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
<script src="https://raw.github.com/barisaydinoglu/Detectizr/master/detectizr.min.js"></script>

CSS

1
2
3
4
5
6
7
8
9
*[accesskey]:after {
    margin-left: 0.3em;
    color: #ccc;
    content: "[Alt + " attr(accesskey) "]";
}

body.firefox *[accesskey]:after { content: "[Alt + Shift + " attr(accesskey) "]"; }
body.firefox.mac *[accesskey]:after { content: "[Ctrl + Opt + " attr(accesskey) "]";  }
body.safari.mac *[accesskey]:after { content: "[Ctrl + " attr(accesskey) "]";  }

Javascript

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
/**
 * Add browser and OS name to body class, and append the shortcut to element title
 * @author rogeriolino
 */
(function($) {
    $(document).ready(function() {
        Modernizr.Detectizr.detect({detectScreen:false});
        var body = $('body')
        body.addClass(Modernizr.Detectizr.device.browser + ' ' + Modernizr.Detectizr.device.os);
        $('*[accesskey]').each(function(i, e) {
            var elem = $(e);
            prefix = 'Alt';
            if (body.hasClass('firefox')) {
                if (body.hasClass('mac')) {
                    prefix = 'Ctrl + Opt';
                } else {
                    prefix = 'Alt + Shift';
                }
            } else if (body.hasClass('safari mac')) {
                prefix = 'Ctrl';
            }
            elem.prop('title', elem.prop('title') + ' [' + prefix + ' + ' + elem.attr('accesskey') + ']');
        });
    });
})(jQuery);

Demo

Clique aqui para visualizar o exemplo no jsFiddle.net

jQuery: Horizontal + Vertical Align

Função jQuery para alinhar horizontalmente e verticalmente o elemento.

1
2
3
4
5
6
7
8
9
jQuery.fn.center = function () {
    this.css("position","absolute");
    this.css({
        top: '50%',
        left: '50%',
        margin: '-' + (this.height() / 2) + 'px 0 0 -' + (this.width() / 2) + 'px'
    });
    return this;
}

Exemplo:

1
2
3
<div id="centered_div">
    <p>My div content here</p>
</div>
1
$('#centered_div').center()

Edit on jsFiddle: http://jsfiddle.net/rc6kS/

Ubuntu: PHP 5.4 + PHP5-FPM/FastCgi on Apache2

Os comandos abaixo que devem ser executados como root.

Passo 1 - Verificando a versão do PHP no repositório

1
apt-cache show php5 | grep Version

Caso a versão mais nova já esteja na 5.4 ou superior, então pule para o próximo passo. Senão execute os comandos abaixo para adicionar o repositório com a versão 5.4.

1
2
3
apt-get install python-software-properties
add-apt-repository ppa:ondrej/php5
apt-get update

Passo 2 - Instalando os pacotes

Execute o commando abaixo para instalar de uma só vez o Apache2 como Worker, o módulo FastCgi e o PHP 5.4 com PHP-FPM.

1
apt-get install apache2-mpm-worker libapache2-mod-fastcgi php5-fpm php5

Habilitando os módulos de requeridos para o próximo passo:

1
a2enmod actions fastcgi alias

Passo 3 - Configurando o Apache2

Editar o arquivo de configuração do módulo fastcgi

1
vim /etc/apache2/mods-enabled/fastcgi.conf

Caso já tenha algumas entradas, comente (adicionando # no início da linha ou simplesmente remova) e adicione as seguintes linhas:

1
2
3
4
AddHandler php5-fcgi .php
Action php5-fcgi /php5-fcgi
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -socket /var/run/php5-fpm.sock -pass-header Authorization

obs: O arquivo /usr/lib/cgi-bin/php5-fcgi realmente não existe, será apenas uma ponte para o PHP-FPM

Passo 4 - Configurando o PHP-FPM

Abra o arquivo de configuração do PHP-FPM

1
vim /etc/php5/fpm/pool.d/www.conf

E procure pela opção listen. Se não estiver como socket, altere conforme abaixo:

1
listen = /var/run/php5-fpm.sock

Essa opção serve para evitar overhead no TCP (caso o socket não esteja configurado)

obs: Repare que tem que ser o mesmo caminho especificado no fastcgi.conf

Passo 5 - Reiniciando e testando

Reiniciando os serviços:

1
2
/etc/init.d/apache2 restart
/etc/init.d/php5-fpm restart

Criando arquivo de teste:

1
2
cd /var/www
echo '<?php phpinfo();' | tee info.php

Depois acesse o arquivo criado via browser: http://nome_servidor/info.php

Confira a versão do PHP descrita no cabeçalho e se o valor do Server API está como FPM/FastCGI.

CSS3: Horizontal Menu

Exemplo de um menu dropdown horizontal, utilizando gradient e transition apenas com CSS3.

CSS

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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
.hmenu {
    height: 40px;
    position: relative;
}

.hmenu, .hmenu ul {
    border-radius: 3px;
}

.hmenu, .hmenu * {
    margin: 0;
    padding: 0;
}

.hmenu li {
    list-style: none;
    position: relative;
    display: inline;
}

.hmenu li {
    list-style: none;
    position: relative;
    float: left;
}

/* all links style */
.hmenu a {
    font-weight: bold;
    font-family: Arial, Verdana, sans-serif;
    font-size: 12px;
    text-decoration: none;
}

/* main link style */
.hmenu>li>a {
    padding: 13px 20px;
    float: left;
}

.hmenu li ul {
    width: 150px;
    position: absolute;
    visibility: hidden;
    opacity: 0;
    /* fading transition */
    transition: opacity .5s ease-in-out;
   -moz-transition: opacity .5s ease-in-out;
   -webkit-transition: opacity .5s ease-in-out;
}

/* first submenu */
.hmenu>li>ul {
    top: 40px;
    left: 0;
    border-top-left-radius: 0;
    border-top-right-radius: 0;
}

.hmenu li:hover>ul {
    visibility: visible;
    opacity: 1;
}

.hmenu li ul ul {
    top: 0px;
    left: 150px;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

.hmenu li ul li {
    width: 150px;
    display: block;
}

/* submenu link style */
.hmenu ul a {
    margin: 3px 2px;
    padding: 8px 15px;
    border-radius: 5px;
    display: block;
}

/* theming */
.hmenu {
    box-shadow: 0px 1px 5px #ccc;
    background: #ffffff; /* Old browsers */
    background: -moz-linear-gradient(top,  #ffffff 0%, #e5e5e5 100%); /* FF3.6+ */
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(100%,#e5e5e5)); /* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,  #ffffff 0%,#e5e5e5 100%); /* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,  #ffffff 0%,#e5e5e5 100%); /* Opera 11.10+ */
    background: -ms-linear-gradient(top,  #ffffff 0%,#e5e5e5 100%); /* IE10+ */
    background: linear-gradient(to bottom,  #ffffff 0%,#e5e5e5 100%); /* W3C */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e5e5e5',GradientType=0 ); /* IE6-9 */
}

.hmenu a {
    color: #999;
}

.hmenu a:hover {
}

.hmenu li:hover>a {
    color: #000;
    text-shadow: 1px 1px 2px #ccc;
}

.hmenu ul {
    background-color: #f1f1f1;
    box-shadow: 0px 1px 5px #bbb;
}

.hmenu ul a:hover {
    background-color: #e1e1e1;
}

.hmenu>li>ul {
    border-top: 2px solid #999;
}

.hmenu li ul ul {
    border-left: 2px solid #999;
}

HTML

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
<ul class="hmenu">
    <li><a href="#">Home</a></li>
    <li>
        <a href="#">Services</a>
        <ul>
            <li><a href="#">Service 1</a></li>
            <li>
                <a href="#">Service 2</a>
                <ul>
                    <li><a href="#">Subservice 1</a></li>
                    <li><a href="#">Subservice 2</a></li>
                    <li><a href="#">Subservice 3</a></li>
                </ul>
            </li>
            <li><a href="#">Service 3</a></li>
            <li><a href="#">Service 4</a></li>
            <li><a href="#">Service 5</a></li>
        </ul>
    </li>
    <li>
        <a href="#">About</a>
        <ul>
            <li><a href="#">Company</a></li>
            <li><a href="#">Contact</a></li>
        </ul>
    </li>
</ul>

Visualizar o menu funcionando

PHP: 5.4 New Features

Segue abaixo algumas das novas funcionalidades da versão 5.4 do PHP. Para ver mais informações, siga os links no final do post.

Trait

Trait (ou mixin em outras linguagens) é um mecanismo que permite que as classes reutilizem métodos de outras classes sem a necessidade de estende-la.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
trait Singleton {
    public static function getInstance() { ... }
}

class A {
    use Singleton;
    // ...
}

class B extends ArrayObject {
    use Singleton;
    // ...
}

// Singleton method is now available for both classes
A::getInstance();
B::getInstance();

Sintaxe curta para definição de Array

Agora é possível instanciar um array de maneira semelhante à outras linguagens de script, como por exemplo, Javascript.

1
2
$a = [1, 2, 3];
$b = ['foo' => 'orange', 'bar' => 'apple'];

Referência direta ao retorno das funções/métodos

Também é possível fazer fazer chamada direta ao retorno das funções, sem que haja necessidade de atribuir o valor a uma variável e só depois fazer a chamada.

1
2
3
4
function fruits() {
    return ['apple', 'banana', 'orange'];
}
echo fruits()[0]; // Outputs: apple

O mesmo serve para chamadas através de novas instâncias:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person {
    private $name;
    public function setName($name) {
        $this->name = $name;
    }
    public function getName() {
        return $this->name;
    }
}
function createPerson() {
    $p = new Person();
    $p->setName('Rogerio');
    return $p;
}

echo (new Person)->setName('Rogerio')->getName(); // Outputs: Rogerio

Método mágico __invoke

Permite chamar um objeto como se fosse uma função

1
2
3
4
5
6
7
8
9
10
11
class MoneyObject {
    private $value;
    function __construct($val) {
        $this->value = $val;
    }
    function __invoke() {
        return sprintf('$%.2f',$this->value);
    }
}
$Money = new MoneyObject(11.02/5*13);
echo $Money(); // Outputs: $28.65

Built-in Web Server (CLI)

CLI server é uma pequena implementação de um Web server que você pode executar via linha de comando.

1
% php -S localhost:8000

Obviamente, não é para ser usado em produção.

Native Session Handler Interface

Ao invés de definir várias funções, você pode criar uma handler para a sua sessão, e apenas informá-lo no session_set_save_handler.

1
2
3
4
5
6
7
8
9
10
SessionHandler implements SessionHandlerInterface {
    public int close ( void )
    public int destroy ( string $sessionid )
    public int gc ( int $maxlifetime )
    public int open ( string $save_path , string $sessionid )
    public string read ( string $sessionid )
    public int write ( string $sessionid , string $sessiondata )
}

session_set_save_handler(new MySessionHandler);

JsonSerialize Interface

Semelhante ao __tostring ao tentar imprimir um objeto, você pode pre-definir o objeto que será serializado para o formato json, através do uso da função json_encode.

1
2
3
4
5
6
7
8
9
10
class Foo implements JsonSerializable {

    private $data = 'Bar';

    public function jsonSerialize() {
        return array('data'=>$this->data);
    }
}

echo json_encode(new Foo); // Outputs: {"data":"Bar"}

Para visualizar as alterações entre as versão 5.3 e 5.4, clique aqui.

Fontes: http://php.net/manual/en/migration54.new-features.php http://css.dzone.com/polls/what-new-feature-php-54 http://www.oracle.com/technetwork/articles/dsl/lerdorf-php54-1564639.html

Development Tools

Iniciei e publiquei um pequeno projeto que reune algumas funcionalidades para auxiliar durante o desenvolvimento. Segue abaixo as funcionalidades que estão disponíveis por enquanto:

  • Crypt: algorítimos de hash como sha1 e md5, e base64 encode/decode

  • Random: geração de senhas (com opções de configuração), CPF e CNPJ, e Lorem Ipsum

  • Converter: conversor de unidades de medida

  • Network: exibe o IP do cliente, geo localização (coordenadas e mapa), e consulta de domínios (whois server)

  • Browser: informações sobre versão, user-agent, resolução e viewport, e as principais funcionalidades do HTML5 e CSS3 que o browser suporta.

  • Javascript: code minifier and optimizer

Como toda a execução é feita no lado do servidor, você pode fazer uma execução ajax do seu site/aplicação para o dev-tools e pegar no response o resultado, sem que haja necessidade de importar novos recursos:

1
2
3
4
5
6
7
GET
>     /ajax/<package>/<method>/?<params>
>     /ajax/crypt/sha1?data=test
>     
>     JSON RESPONSE
>     {"success":true,"data":"a94a8fe5ccb19ba61c4c0873d391e987982fbbd3"}
>     

Conforme eu vá sentindo necessidade de mais funcionalidade ou alguém dê uma sugestão, irei incrementando. Depois criarei um projeto no Github e atualizarei o post com o link.

Android: Futeria App

Há alguns dias publiquei uma app no Google Play: Futeria, versão móvel do site Futeria.net, agregador de notícias dos principais clubes de futebol do Brasil.

Para o desenvolvimento dessa app foi utilizado HTML5 e jQueryMobile para o frontend, e PHP para o backend. E para agilizar o carregamento das pãginas estã sendo utilizado o Manifest App Cache do HTML5. Já para uma próxima versão estará disponível uma página para salvar configurações do usuário, utilizando LocalStorage.

Então, se você é um usuário Android e gostaria de ler as últimas notícias do seu time, instale o Futeria e dê uma feedback sobre bugs e melhorias que podem ser feitas. E muito obrigado!