17 de dezembro de 2015

Whatsapp fora do ar. Tô nem aí, uso o Telegram mesmo

E a justiça brasileira decide cortar o acesso ao Whatsapp no Brasil. Mas para quê chorar com isso, se existe um aplicativo bem melhor do que o whatsapp para usar. Vamos dar uma olhada na melhor alternativa ao whatsapp no momento. Estou falando do Telegram.  

Já pela sua história, o Telegram nasceu da ideia de um cara que teve que fugir às pressas da Rússia. Segundo relatado na The New York Times


When a SWAT team appeared at Pavel Durov’s door in St. Petersburg, he started thinking about his future in Russia.
He was home alone, and he peered at them through a monitor.
“They had guns and they looked very serious,” said Mr. Durov, once Russia’s biggest celebrity entrepreneur. “They seemed to want to break the door.”


Traduzindo de uma forma BR:

"A polícia tava lá na frente da minha casa querendo entrar na bicuda......"

E foi assim que surgiu o Telegram (depois que o Pavel Durov fugiu da Rússia).

O Telegram já é melhor que  o Whatsapp já pelo fato que não vai transbordar a memória do seu celular gravando todas as imagens de uma maneira bizarra no seu aparelho (deixa tudo espalhado e não adianta remover a conversa, as imagens ficam nele). 

Mas ele é melhor mesmo do que o Whatsapp pelos Stickers existentes: me fala de qual outro aplicativo desse tipo que você pode personalizar com os stickers do Mr. Bean ???





Ah!!! Mas eu não gosto do Mr. Bean. Sou um cara politizado e gosto de discutir sobre política. 

Seus problemas estão resolvidos meu camaradinha. Você pode utilizar os stickers dos políticos brasileiros. 

Não importa se você é mortadela 



coxinha



bolsonarense



marinense



ou tradicionalista



vai sempre ter um sticker que é a sua cara. 







15 de maio de 2013

Artigo Rápido: Como verificar o navegador que está sendo utilizado pelo usuário

Ou no meu caso: "Como verificar se estou utilizando o Internet Explorer (vulgo IE)"

Imagine a seguinte situação: 

"Você quer incluir um arquivo CSS (Cascading Style Sheets) na sua página ou rodar um determinado algoritmo apenas para um determinado tipo de navegador, como por exemplo o IE6."

Aqui neste artigo, vão ser apresentadas algumas opções para resolver este problema: a primeira utilizando, no Zend Framework, o método appendStylesheet do Head Link (já comentado neste artigo); a segunda utilizando diretamente Comentários Condicionais; a terceira utilizando Javascript e a última utilizando apenas PHP


Figura 1: Flash


1ª Utilizando Head Link(*)


Na view basta adicionar o código:


1
2
3
4
5
6
<?php 

// Exemplo de adição de um CSS apenas para o navegador Internet Explorer
$this->headLink()->appendStylesheet('caminho/do/arquivo', 'screen', 'IE');

?>

2ª Utilizando Comentários Condicionais(*)


Basta adicionar o código entre os comentários condicionais, por exemplo:

<!--[if IE]>
<link href="non-ie.css" rel="stylesheet">
<![endif]-->

3ª Utilizando javascript:


1
2
3
4
5

<script type="text/javascript">
   if($.browser.msie){
      alert('Estou utilizando alguma versão do IE. ');
   }
</script>

4ª Utilizando apenas PHP 



1
2
3
4
5
6
7
8
9
<?php 
if(preg_match('/(?i)msie [0-9]*/', $_SERVER['HTTP_USER_AGENT'])){
?>
   <script type="text/javascript">
      alert('Estou utilizando alguma versão do IE. ');
   </script>
<?php
}
?>



(*) Comentários condicionais não são mais reconhecidos no Internet Explorer 10


23 de novembro de 2012

Formulários no Doctrine: Validando a existência do login no Banco de Dados

Ao gerar um formulário para cadastro de usuários em um sistema, usualmente é desejado validar as informações inseridas pelos usuários nos campos do formulário. No caso de um campo que vai ser utilizado na identificação do usuário para este se logar no sistema (login), como por exemplo um apelido (nick) ou um email, deve-se ter a restrição de que nenhum outro usuário já esteja cadastrado com este campo. Um exemplo de duplicação do 'login' ocorre no filme Irmão Gêmeos, onde Julius Benedict (Arnold Schwarzenegger) e Vincent Benedict (Danny DeVito) possuem o mesmo código genético  


Figura 1: exemplo de duplicação de login.  


Neste artigo vai ser apresentado como a classe Zend_Validate_Abstract pode ser estendida para utilizar o Doctrine para validar se o login que está sendo inserido não existe no Banco de Dados. Caso já exista um usuário cadastrado com este login é retornado um código de erro. Além disto, vai ser apresentado um exemplo de como esta classe pode ser utilizado em um formulário de cadastro. 

A seguir é apresentada a classe DoctrineValidateEmail, que estende a Zend_Validate_Abstract e permite a validação do login (neste exemplo básico login = email do usuário). Basicamente nesta classe foi realizada a reimplementação da função isValid que utiliza uma classe DAO (UsuarioDAO) que valida o login passado como parâmetro.


Classe DoctrineValidateEmail


 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
<?php 

class DoctrineValidateEmail extends \Zend_Validate_Abstract{
    
    const NOK = 1;
    
    protected $_messageTemplates = array(
        self::NOK => "%value% já cadastrado"
    );
    
    public function isValid($email){
        
        try{
            $user = UserDAO::getUserByEmail($email);
        }catch(\Doctrine\ORM\NoResultException $e){
            // Email livre para cadastro
            $user = null;
        }
        if($user){
            $this->_error(self::NOK,$email);
            return false;
        }
        return true;
    }
}

A classe UserDAO que interage com o Banco de Dados utilizando o Doctrine é apresentada a seguir. Para simplificar o exemplo é apresentado apenas a implementação do método getUserByEmail utilizado pela DoctrineValidateEmail.


Classe DAO para interação com o Banco de Dados


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php

class UserDAO {
    
    public static function getUserByEmail($email) {
        /**Obtendo o container contendo as operações básicas envolvendo o doctrine. */
        $doctrine_container = \Zend_Registry::get('doctrine');
        $em = $doctrine_container->getEntityManager();
               
        
        $query = $em->createQuery('select s from UserDoctrine s WHERE s.email = ?1');
        $query->setParameter(1, $email);
        
        $user_doctrine = $query->getSingleResult();
        
        return $user_doctrine;        
    } // function
} // class


E finalmente é apresentado como a classe DoctrineValidateEmail implementada pode ser utilizada em um formulário para validar o login que está sendo inserido pelo usuário.


Exemplo de Formulário


 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
<?php

class Cadastro_Form_Cadastro extends Zend_Form
{

    public function init()
    {
        $this->setMethod('post');

        // CSFR (www.frameword.zend.com/manual/en/learning.quickstart.create-form.html)
        $this->addElement('hash', 'csrf', array('ignore' => true));

        // Nome
        $this->addElement(
                'text', 'nome', array(
            'label' => 'Nome:',
            'required' => true,
            'maxlength' => '30',        
            'filters' => array('StringTrim'),
        ));

        // Sobrenome
        $this->addElement(
                'text', 'sobrenome', array(
            'label' => 'Sobrenome:',
            'required' => true,
            'maxlength' => '30',        
            'filters' => array('StringTrim'),
        ));
  
        // Email vai ser utilizado como login
        $email = new Zend_Form_Element_Text('email');
        $email->setLabel('Email:');
        $email->addFilters(array('StringTrim', 'StripTags'));
        $email->addValidator('EmailAddress', TRUE);
        $email->setRequired(true);

        //Adicionando a validação no email                
        $email->addValidator(new DoctrineValidateEmail($email->getValue()));

        $this->addElement($email);

        //Senha        
        $this->addElement(
                'password', 'password', array(
            'label' => 'Senha:',
            'required' => true,
            'maxlength' => '20',        
                )
        );

        $this->addElement(
                'submit', 'submit', array(
            'ignore' => true,
            'label' => 'Cadastrar',
                )
        );
    }
}



1 de setembro de 2012

Herança no Doctrine: Persistindo e recuperando objetos

Em um artigo anterior foi apresentando como a herança pode ser implementada no Doctrine. Neste artigo vamos apresentar como os elementos da herança podem ser persistidos e recuperados do Banco de Dados

Para exemplo didático vamos utilizar novamente o exemplo épico do filme Star Wars (Figura 1), onde existe uma relação de herança entre: DarthVader, Luke Skywalker e Leia Organa.


Figura 1: Exemplo didático de herança. 



As classes que representam cada um dos elementos podem ser visualizadas no post anterior


Para o conjunto de classes do exemplo vamos implementar uma classe DAO (Data Access Object) para interagir com o Banco de Dados. A seguir é apresentado o código da classe DAO:

Classe JediDAO



 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
<?php

class JediDAO {
   
    public static function add($object) {
        /**Obtendo o container contendo as operações básicas envolvendo o doctrine. */
        $doctrine_container = \Zend_Registry::get('doctrine');
        $em = $doctrine_container->getEntityManager();

        if($object->getId()){
            $object = $em->merge($object);
        }else{
            $em->persist($object);
        }
        
        $em->flush();

        return $object;
    }
    
    public static function get($id) {
        /**Obtendo o container contendo as operações básicas envolvendo o doctrine. */
        $doctrine_container = \Zend_Registry::get('doctrine');
        $em = $doctrine_container->getEntityManager();
                       
        $object = $em->getRepository('DarthVader')->find($id);

        return $object;
    } // function
    
    public static function listAll(){
        /**Obtendo o container contendo as operações básicas envolvendo o doctrine. */
        $doctrine_container = \Zend_Registry::get('doctrine');
        $em = $doctrine_container->getEntityManager();
        
        $query = $em->createQuery('select obj from DarthVader obj');
        
        $object_list = $query->getResult();
        
        return $object_list;        
    }
    
} // class

Agora vamos testar os métodos implementados na classe DAO:


 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
<?php 
        //Criando um objeto DarthVader
        $darth_1 = new  DarthVader();
        $darth_1->setAtributoAnakin(1);
        
        //Persistindo o objeto
        JediDAO::add($darth_1);
        
        // Criando um objeto Luke
        $luke_1 = new Luke();
        $luke_1->setAtributoLuke(2);
        
        JediDAO::add($luke_1);
        
        //Criando um objeto Leia
        $leia_1 = new Leia();
        $leia_1->setAtributoLeia(3);
        
        JediDAO::add($leia_1);
        
        // Recuperando o objeto de id = 2
        $jedi_2 = JediDAO::get(2);
        
        /*
          var_dump em $jedi_2 retorna: 
            object(Luke)[198]
              private 'atributo_luke' => int 2
              private 'id' (DarthVader) => int 2
              private 'atributo_anakin' (DarthVader) => null

        */
        
        //Listando todos os objetos jedi's do Banco
        $lista_jedis = JediDAO::listAll();
        
        /*
        var_dump em $lista_jedis retorna um array:

        array (size=3)
        0 => 
            object(DarthVader)[209]
              private 'id' => int 1
              private 'atributo_anakin' => int 1
        1 => 
            object(Luke)[198]
              private 'atributo_luke' => int 2
              private 'id' (DarthVader) => int 2
              private 'atributo_anakin' (DarthVader) => null
        2 => 
            object(Leia)[208]
              private 'atributo_leia' => int 3
              private 'id' (DarthVader) => int 3
              private 'atributo_anakin' (DarthVader) => null
 
        */        


1 de agosto de 2012

Projeto exemplo integrando o Zend Framework e o Doctrine

O início sempre é a parte mais complicada para alguém que está aprendendo um determinado framework, pois ele se depara com uma quantidade grande de novas informações a serem "digeridas".  



Na maioria das vezes falta um projeto básico "Hello World" para apresentar as funcionalidades básicas para o usuário. Algo semelhante ao que ocorre no aprendizado das linguagens de programação.

Em função disto, o ZeDoc foi criado para apresentar um projeto (ou template) exemplo utilizando o Zend Framework em conjunto com o Doctrine, contendo algumas funcionalidades básicas para um projeto, como por exemplo:


Informações mais detalhadas sobre o projeto (como instalar, funcionalidades implementadas) podem ser encontradas em: no site do projeto, aqui mesmo (em futuros artigos) e ali (em futuros artigos).  

25 de julho de 2012

Implementando Herança no Doctrine

Nesse artigo vamos falar um pouco sobre a implementação de Herança no Doctrine. Como exemplo didático de herança, temos a épica relação entre DarthVader,  Luke Skywalker e Leia Organa no filme Star Wars (Figura 1). Em vista disto, vamos utilizar esta relação entre os personagens para ilustrar a implementação da herança no Doctrine


Figura: "I am your father". 

A herança no Doctrine é especificada através dos atributos: 


  • @DiscriminatorColumn: utilizado para indicar qual o elemento da hierarquia (classe) a linha da tabela representa.
  • @DiscriminatorMap: utilizado para identificar quais os valores que existirão na coluna do discriminador e qual classe da hierarquia está mapeado para cada valor.
  • @InheritanceType: representa a estrutura no Banco de Dados que irá armazenar a herança. SINGLE_TABLE indicada que tanto o objeto pai quanto os objetos filhos estarão representados na mesma tabela. JOINED indica que cada classe da hierarquia terá uma tabela própria. 


Por exemplo, tendo o mapa:

@DiscriminatorMap({"father" = "DarthVader", "son" = "Luke", "daughter" = "Leia"})

temos que father representa um objeto da classe DarthVader, já son representa um elemento da classe Luke.


A seguir um exemplo de implementação da herança. São especificadas três classes: DarthVader (classe pai), Luke (classe filho) e Leia (classe filho). 


Classe DarthVader (pai)



 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
<?php

/**
 * @Entity
 * @InheritanceType("SINGLE_TABLE")
 * @Table(name="father")
 * @DiscriminatorColumn(name="discr", type="string")
 * @DiscriminatorMap({"father" = "DarthVader", "son" = "Luke", "daughter" = "Leia"})
 */
class DarthVader{
    
    /**
     * @var integer $id
     * @Column(type="integer")
     * @Id
     * @GeneratedValue(strategy="IDENTITY")
     */
    private $id;
    
    public function setId($id){$this->id = $id;}
    public function getId(){return $this->id;}
    
    /**
     * 
     * @Column(type="integer")
     * 
     */
    private $atributo_anakin;    
    
    public function setAtributoAnakin($atributo){$this->atributo_anakin=$atributo;}
    public function getAtributoAnakin(){return $this->atributo_anakin;}
}


Classe Luke (filho)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?php

/**
 * 
 * @Entity
 * @Table(name="son") 
 */
class Luke extends DarthVader {
    
    /**
     * 
     * @Column(type="integer")
     * 
     */
    private $atributo_luke;    
    
    public function setAtributoLuke($atributo){$this->atributo_luke=$atributo;}
    public function getAtributoLuke(){return $this->atributo_luke;}
    
}


Classe Leia (filho)


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<?php

/**
 * 
 * @Entity
 * @Table(name="daughter") 
 */
class Leia extends DarthVader {
    
    /**
     * 
     * @Column(type="integer")
     * 
     */
    private $atributo_leia;    
    
    public function setAtributoLeia($atributo){$this->atributo_leia=$atributo;}
    public function getAtributoLeia(){return $this->atributo_leia;}
    
    
}


A seguir a estrutura gerada no Banco de Dados para cada tipo de herança (InheritanceType).

JOINED


Figura: Tipo de Herança JOINED



SINGLE_TABLE



Figura: Tipo de Herança SINGLE_TABLE



Num próximo artigo vamos falar como ocorre o processo de persistência dos objetos Doctrine no Banco de Dados.

18 de julho de 2012

Adicionando Javascript nas views do Zend Framework



A inserção de código Javascript nas view do Zend Framework pode ser realizada através da utilização de dois helpers (classes) existentes: HeadScript Helper e InlineScriptHelper. Essas entidades podem ser utilizadas para adicionar diretamente o código javascript ou anexar um arquivo contendo o código javascript



HeadScript é utilizado quando se deseja referenciar o código javascript na marcação (tag) header da página. Para utilização(*) do HeadScript deve-se:

1) No Controller adicionar o endereço do arquivo no HeadScript da view.

  • Exemplo: <?php $this->view->headScript()->appendFile('/js/funcoes.js'); ?>


2) Na view imprimir o conteúdo do HeadScript:

  • Exemplo: <?php echo $this->headScript(); ?>



InlineScript é utilizado quando se deseja referenciar o código javascript na marcação (tag) body da página, ou seja, deseja-se anexar o javascript em uma determinada "posição" da página.  Para utilização(*) do InlineScript deve-se: 


1) No Controller adicionar o endereço do arquivo no InlineScript da view.

  • Exemplo: <?php $this->view->inlineScript()->appendFile('/js/funcoes.js'); ?>


2) Na view imprimir o conteúdo do InlineScript na posição desejada para o código javascript. Geralmente é recomendado imprimir o conteúdo no fim do código da view.

  • Exemplo: <?php echo $this->inlineScript(); ?>


(*) Apenas salientando que os exemplos englobam a inserção de uma referência a um arquivo .js na página. Para inserir diretamente um código javascript  verificar a função appendScript().