Development

Changeset 28263

You must first sign up to be able to contribute.

Changeset 28263

Show
Ignore:
Timestamp:
02/25/10 03:00:40 (5 years ago)
Author:
Andreia.Bellini
Message:

corrections: chapter 05 and 08

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • doc/branches/1.4/more-with-symfony/pt/05-Custom-Widgets-and-Validators.markdown

    r27173 r28263  
    1 Widgets e Validators Personalizados 
    2 =================================== 
    3  
    4 * por Thomas Rabaix
    5  
    6 Este capítulo explica como criar um widget e validadores personalizados para uso 
     1Widgets e Validadores Personalizados 
     2==================================== 
     3 
     4*por Thomas Rabaix
     5 
     6Este capítulo explica como criar *widgets* e validadores personalizados para uso 
    77no framework de formulário. Ele irá explicar os detalhes internos de `sfWidgetForm` e 
    8 `sfValidator`, bem como a forma de construir tanto um widget simples quanto um complexo. 
     8`sfValidator`, bem como a forma de construir tanto um *widget* simples quanto um complexo. 
    99 
    1010Por Dentro do Widget e Validator 
     
    2929   pode ser facilmente substituído. 
    3030 
    31 * `render()`: saídas de HTML para o widget. O método tem uma primeiro argumento obrigatório, 
     31* `render()`: saídas de HTML para o widget. O método tem um primeiro argumento obrigatório, 
    3232   o nome do elemento HTML, e um segundo argumento opcional, 
    3333   o valor. 
    3434 
    35 > **NOTE** 
    36 > Um objeto `sfWidgetForm` não sabe nada sobre o seu nome ou o seu valor. 
    37 > O componente é responsável apenas pela prestação do widget. O nome e 
    38 > o valor são geridos por um objeto `sfFormFieldSchema`, que é o link 
    39 > entre os dados e os widgets. 
     35>**NOTE** 
     36>Um objeto `sfWidgetForm` não sabe nada sobre o seu nome ou o seu valor. 
     37>O componente é responsável apenas pela prestação do widget. O nome e 
     38>o valor são geridos por um objeto `sfFormFieldSchema`, que é o link 
     39>entre os dados e os widgets. 
    4040 
    4141### Por Dentro do sfValidatorBase 
     
    4545pois ele verifica se o valor é válido, dependendo das opções fornecidas. 
    4646 
    47 Internamente, o método `clean()` realiza várias acções diferentes: 
     47Internamente, o método `clean()` realiza várias ações diferentes: 
    4848 
    4949* Retira os espaços no início e no final do valor de entrada para valores string (se especificado através da opção `trim`) 
    5050* Verifica se o valor é vazio 
    51 * Chama o método `doclean()` do validador. 
     51* Chama o método `doClean()` do validador. 
    5252 
    5353O método `doClean()` é o método que implementa a lógica principal de validação. 
    54 Não é boa prática para sobrescrever o método `clean()`. Em vez disso, 
    55 sempre execute qualquer lógica personalizada através do método `doClean()`. 
     54Não é uma boa prática sobrescrever o método `clean()`. Em vez disso, 
     55customize a lógica do método `doClean()`. 
    5656 
    5757O validador também pode ser usado como um componente independente para verificar a integridade de entrada. 
     
    7070    } 
    7171 
    72 > **NOTE** 
    73 > Quando um formulário está vinculado aos valores de solicitação, o objeto `sfForm` mantém 
    74 > referências aos valores originais (dirty, "sujos") e os valores validados (clean, "limpos"). 
    75 > Os valores originais são usados quando o formulário é redesenhado, enquanto  
    76 > os valores "cleaned" são utilizados pela aplicação (por exemplo, para salvar o objeto). 
     72>**NOTE** 
     73>Quando um formulário está vinculado aos valores de solicitação, o objeto `sfForm` mantém 
     74>referências aos valores originais (*dirty*, "sujos") e os valores validados (*clean*, "limpos"). 
     75>Os valores originais são usados quando o formulário é redesenhado, enquanto  
     76>os valores *cleaned* são utilizados pela aplicação (por exemplo, para salvar o objeto). 
    7777 
    7878### O atributo `options` 
    7979 
    80 Tanto o `sfWidgetForm` e `sfValidatorBase` objetos têm uma variedade de opções: 
    81 algumas são opcionais, enquanto outras são obrigatórias. Estas opções são definidas 
     80Tanto o objeto `sfWidgetForm` quanto o `sfValidatorBase` têm uma variedade de opções: 
     81algumas opcionais, outras obrigatórias. Estas opções são definidas 
    8282dentro do método `configure()` de cada classe através de: 
    8383 
     
    8686 
    8787Estes dois métodos são muito convenientes pois garantem que os valores de dependência 
    88 são corretamente passados para o validador ou o widget. 
    89  
    90 Construir um Widget e Validator Simples 
     88são passados corretamente para o validador ou o widget. 
     89 
     90Construindo um Widget e Validator Simples 
    9191-------------------------------------- 
    9292 
    9393Esta seção irá explicar como criar um widget simples. Este elemento particular 
    94 será chamado de "Trilean widget". O widget exibirá uma caixa de seleção com três opções: 
     94será chamado de "Trilean" widget. O widget exibirá uma caixa de seleção com três opções: 
    9595`Não`, `Sim` e `Nulo`. 
    9696 
     
    121121          } 
    122122 
    123           $options [] = $this->renderContentTag
     123          $options [] = $this->renderContentTag
    124124            'option', 
    125125            self::escapeOnce($option), 
     
    128128        } 
    129129 
    130         return $ this-> renderContentTag
     130        return $this->renderContentTag
    131131          'select', 
    132132          "\n". implode ("\n", $options). "\n", 
     
    136136    } 
    137137 
    138 O método `configure()` define a lista de valores de opção através da opção `choices`. 
     138O método `configure()` define a lista de valores da opção através da opção `choices`. 
    139139Este array pode ser redefinido (ou seja, para alterar o rótulo associado a cada valor). 
    140140Não há limite para o número de opções que um widget pode definir.  
    141 A classe Widget base, no entanto, declara algumas opções padrão, que funcionam de-facto 
     141A classe base widget, no entanto, declara algumas opções padrões, que funcionam *de-facto* 
    142142como opções reservadas: 
    143143 
     
    209209 
    210210**NOTE** 
    211 > Se `isEmpty()` retorna true, o método `doClean()` método nunca será chamado. 
     211>Se `isEmpty()` retorna true, o método `doClean()` método nunca será chamado. 
    212212 
    213213Embora este widget seja bastante simples, ele apresenta algumas características de base importantes 
     
    220220Nesta seção, vamos construir um widget complexo. Novos métodos serão 
    221221introduzidos e o widget terá alguma interação JavaScript também. 
    222 O widget será chamado de "GMAW": "Google Map Address Widget". 
     222O widget será chamado de "GMAW": "*Google Map Address Widget*". 
    223223 
    224224O que queremos alcançar? O widget deve fornecer uma maneira fácil para o 
     
    355355          $value['latitude'] = isset($value['latitude']) ? $value['latitude'] : ''; $ value [ 'latitude']:''; 
    356356 
    357           / / Define o widget address 
     357          // Define o widget address 
    358358          $address = new sfWidgetFormInputText(array(), $this->getOption('address.options')); 
    359359          $template_vars['{input.search}'] = $address->render($name.'[address]', $value['address']); 
     
    364364          $template_vars['{input.latitude}'] = $hidden->render($name.'[latitude]', $value['latitude']); 
    365365 
    366           / / Mesclarmodelos e variáveis 
     366          // Mescla modelos e variáveis 
    367367          return strtr( 
    368368            $this->getOption('template.html').$this->getOption('template.javascript'), 
     
    388388tratar adequadamente os diferentes elementos. 
    389389 
    390 O método `rende ()` também instancia dois widgets internos: um widget `sfWidgetFormInputText`,  
     390O método `render()` também instancia dois widgets internos: um widget `sfWidgetFormInputText`,  
    391391que é usado para processar o campo `address` e um widget `sfWidgetFormInputHidden`,  
    392392que é usado para processar os campos ocultos. 
     
    433433 
    434434* `init()`: o método em que todas as variáveis são inicializadas e eventos 
    435    inputs 
     435   para diferentes inputs 
    436436 
    437437* `lookupCallback()`: um método *estático* usado pelo método de geocoder 
     
    444444 
    445445Por favor, consulte a documentação do Google map para obter mais detalhes sobre a funcionalidade 
    446 do Google Maps [API](http://code.google.com/apis/maps/). 
     446do Google maps [API](http://code.google.com/apis/maps/). 
    447447 
    448448### Validador `sfValidatorGMapAddress` 
     
    453453os diferentes valores: `latitude`, `longitude` e `address`. A variável `$value`  
    454454deve ser um array, mas como não se deve confiar na entrada do usuário, o validador  
    455 verifica a presença de todas as chaves para que os validadores internos passam valores válidos. 
     455verifica a presença de todas as chaves para que os validadores internos passam 
    456456valores válidos. 
    457457 
     
    461461      protected function doClean($value) 
    462462      { 
    463         if (! if (!is_array($value)) 
     463        if (! if(!is_array($value)) 
    464464        { 
    465465          throw new sfValidatorError($this, 'invalid'); 
     
    489489>Um validador sempre lança uma `excepção` `sfValidatorError` quando um valor não é 
    490490>válido. Por isso, a validação é cercada por um bloco `try/catch`. 
    491 >Neste validador, o validador re-lança uma nova excepção `invalid`, que 
     491>Neste validador, a validação re-lança uma nova excepção `invalid`, que 
    492492>equivale a um erro de validação `invalid` no validador  
    493493>`sfValidatorGMapAddress`. 
     
    495495### Testando 
    496496 
    497 Por que o teste é importante? O validador é a cola entre a entrada do usuário 
    498 e a aplicação. Se o validador é falho, a aplicação é vulnerável. 
     497Por que o teste é importante? O validador é a ponte entre a entrada do usuário 
     498e a aplicação. Se o validador é falho, a aplicação esta vulnerável. 
    499499Felizmente, o symfony vem com o `lime` que é uma biblioteca de testes  
    500500muito fácil de usar. 
     
    542542o validador `sfValidatorGMapAddress` diretamente e testa diferentes valores. 
    543543 
    544 Reflexões Finais 
     544Considerações Finais 
    545545-------------- 
    546546 
    547 O erro mais comum durante a criação de um widget é ser focar excessivamente em 
     547O erro mais comum durante a criação de um *widget* é ser focar excessivamente em 
    548548como as informações serão armazenadas no banco de dados. O framework formulário é 
    549549simplesmente um contêiner de dados e um framework de validação. Portanto, um widget deve 
    550550gerenciar somente a sua informação relacionada. Se os dados forem válidos, em seguida, os diferentes 
    551 valores limpos poderão então ser utilizada pelo model ou no controller. 
     551valores limpos poderão então ser utilizados no modelo ou no controlador. 
  • doc/branches/1.4/more-with-symfony/pt/08-Advanced-Doctrine-Usage.markdown

    r28027 r28263  
    1 Uso Avançado do Doctrine  
    2 ======================== 
    3  
    4 * Por Jonathan H. Wage
    5  
    6 Criando um comportamento para Doctrine 
    7 -------------------------------------- 
    8  
    9 Nesta seção vamos demonstrar como você pode escrever um comportamento usando Doctrine 1.2. 
     1Uso Avançado do Doctrine 
     2======================= 
     3 
     4*Por Jonathan H. Wage
     5 
     6Criando um Comportamento no Doctrine 
     7--------------------------- 
     8 
     9Nesta seção vamos demonstrar como você pode escrever um comportamento (*behavior*) usando Doctrine 1.2. 
    1010Iremos criar um exemplo que lhe permitirá manter facilmente um contador em cache dos relacionamentos 
    11 de modo que você não terá que consultar a contagem a todo momento. 
     11de modo que você não terá que consultar o contador a todo momento. 
    1212 
    1313A funcionalidade é bastante simples. Para todos os relacionamentos que você deseja manter 
    1414um contador, o comportamento irá adicionar uma coluna ao modelo para armazenar a contagem atual. 
    1515 
    16 ### O Schema 
    17  
    18 Aqui está o Schema que você irá utilizar para começar. Mais tarde vamos modificá-lo e adicionar a 
     16### O Esquema 
     17 
     18Aqui está o esquema (*schema*) que você irá utilizar para começar. Mais tarde vamos modificá-lo e adicionar a 
    1919definição do `actAs` para o comportamento que estamos prestes a escrever: 
    2020 
     
    4040          foreignAlias: Posts 
    4141 
    42 Agora podemos criar tudo para este schema: 
    43  
    44     $ php symfony doctrine:build all 
     42Agora podemos criar tudo para este esquema: 
     43 
     44    $ php symfony doctrine:build --all 
    4545 
    4646### O Template 
    4747 
    48 Primeiro, precisamos escrever uma classe de template (modelo) `Doctrine_Template` filha que será 
     48Primeiro, precisamos escrever uma classe filha de `Doctrine_Template` que será 
    4949responsável por adicionar as colunas ao modelo que irá armazenar a contagem. 
    5050 
     
    8080terão os métodos `setTableDefinition()` e `setUp()` invocados. Da mesma forma que você têm 
    8181na classe `BasePost` em `lib/model/doctrine/base/BasePost.class.php`. Isto 
    82 lhe permite adicionar coisas para qualquer modelo de modo plug n' play. Isto pode esta
    83 nas colunas, relacionamentos, ouvintes de eventos, etc 
     82lhe permite adicionar coisas para qualquer modelo de modo *plug n' play*. Isto pode se
     83nas colunas, relacionamentos, ouvintes de eventos (*event listeners*), etc. 
    8484 
    8585Agora que você entende um pouco sobre o que está acontecendo, vamos fazer o 
    86 comportamento `CountCache` realmente fazer alguma coisa
     86comportamento `CountCache` fazer alguma coisa de fato
    8787 
    8888    [php] 
     
    106106          $columnName = $this->_options['relations'][$relation]['columnName']; 
    107107          $relatedTable = $this->_table->getRelation($relation)->getTable(); 
    108           $ this-> _OPTIONS [ 'Relações'] [$ relation] [ 'className'] = $ RelatedTable-> GetOption ( 'nome'); 
     108          $this->_options['relations'][$relation]['className'] = $relatedTable->getOption('name'); 
    109109          $relatedTable->setColumn($columnName, 'integer', null, array('default' => 0)); 
    110110        } 
     
    112112     
    113113 
    114 O código acima irá agora adicionar colunas para manter a contagem do modelo relacionados
     114O código acima irá adicionar colunas para manter a contagem do modelo relacionado
    115115Portanto, no nosso caso, estamos adicionando o comportamento ao modelo `Post` para o relacionamento  
    116 com `Thread` Nós queremos manter o número de posts qualquer instancia de `Thread` 
    117 tem em uma coluna chamada `num_posts`. Então agora modifique o YAML schema para  
     116com `Thread`. Nós queremos manter o número de posts que qualquer instância de `Thread` 
     117tem em uma coluna chamada `num_posts`. portanto modifique o esquema YAML para  
    118118definir as opções adicionais para o comportamento: 
    119119 
     
    130130      # ... 
    131131 
    132 Agora, o modelo `Thread` tem uma coluna `num_posts`que irá manter-se atualizada 
     132Agora o modelo `Thread` possui uma coluna `num_posts`que irá manter-se atualizada 
    133133com o número de posts que cada thread tem. 
    134134 
    135 ### O Ouvinte de Eventos 
    136  
    137 O próximo passo para a construção do comportamento é escrever um ouvinte de evento registrador  
     135### O Ouvinte de Eventos (*Event Listener*) 
     136 
     137O próximo passo para a construção do comportamento é escrever um registrador de ouvintes de evento (*record event listener*) 
    138138que será responsável por manter a contagem atualizada quando inserirmos novos registros, 
    139 excluir um registro ou executar DQL de exclusão de registros em lote: 
     139excluirmos um registro ou executarmos DQL de exclusão de registros em lote: 
    140140 
    141141    [php] 
     
    152152    } 
    153153 
    154 Antes de prosseguirmos, precisamos definir a `classe` CountCacheListener que 
    155 extende `Doctrine_Record_Listener`. Ele aceita uma variedade de opções que são simplesmente 
    156 transmitidos ao ouvinte a partir do modelo: 
     154Antes de prosseguirmos, precisamos definir a classe `CountCacheListener` que 
     155extende `Doctrine_Record_Listener`. Ela aceita uma variedade de opções que são simplesmente 
     156repassadas ao ouvinte a partir do modelo: 
    157157 
    158158    [php] 
     
    196196            ->createQuery() 
    197197            ->Update() 
    198             ->set($options['columnName'], $options['columnName'].' +1
     198            ->set($options['columnName'], $options['columnName'].' +1'
    199199            ->where($relation['local'].' = ?', $invoker->$relation['foreign']) 
    200200            ->execute(); 
     
    204204 
    205205O código acima irá incrementar a contagem em um para todas os relacionamentos configurados 
    206 mediante a emissão de uma instrução DQL UPDATE quando um novo objeto como é inserido abaixo: 
     206mediante a emissão de uma instrução DQL UPDATE quando um novo objeto como é inserido, conforme o exemplo abaixo: 
    207207 
    208208    [php] 
    209209    $post = new Post(); 
    210     $ post-> thread_id = 1; 
     210    $post->thread_id = 1; 
    211211    $post->body = 'corpo da mensagem'; 
    212212    $post->save(); 
    213213 
    214 O `Thread` com o `id` `1` terá a coluna `num_posts` coluna incrementado em `1`. 
     214O `Thread` com o `id` `1` terá a coluna `num_posts` incrementada em `1`. 
    215215 
    216216Agora que o contador está sendo incrementado quando novos objetos são inseridos, nós 
     
    242242 
    243243O método `postDelete()` acima é quase idêntico ao `postInsert`. A 
    244 única diferença é que nós diminuiremos a coluna `num_posts` em 1 ao invés de 
     244única diferença é que nós diminuiremos a coluna `num_posts` em `1` ao invés de 
    245245incrementá-lo. Ele manipularia o seguinte código se fôssemos remover o registro `$post` 
    246246salvo previamente: 
     
    283283    } 
    284284 
    285 O código acima clona a instrução `DQL DELETE` e transformá-lo em um `SELECT` que 
     285O código acima clona a instrução `DQL DELETE` e transformá-a em em um `SELECT` que 
    286286nos permite recuperar os `ID`s que serão excluídos, para que possamos atualizar o contador 
    287287desses registros que foram excluídos. 
    288288 
    289 Agora, temos o seguinte cenário cuidando de que o contador será decrementado 
    290 se tivéssemos de fazer o seguinte: 
     289Agora, temos o seguinte cenário tratado e os contadores serão decrementados 
     290se fizéssemos o seguinte: 
    291291 
    292292    [php] 
     
    307307      ->execute(); 
    308308 
    309 >**NOTA** 
     309>**NOTE** 
    310310>Para que o método `preDqlDelete()` seja invocado você deve habilitar 
    311311>um atributo. Os retornos DQL estão desligados por padrão devido a eles terem um custo 
     
    341341 
    342342Agora tudo está criado e a massa de dados está carregada, por isso vamos executar um teste para ver 
    343 Se os contadores foram mantidas atualizados: 
     343se os contadores foram mantidas atualizados: 
    344344 
    345345    $ php symfony doctrine:dql "FROM Thread t, t.Posts p" 
     
    397397      ->execute(); 
    398398 
    399 Agora nós excluimos todos as mensagens relatadas e o valor de `num_posts` deverá ser zero: 
     399Agora nós excluimos todas as mensagens relacionadas e o valor de `num_posts` deverá ser zero: 
    400400 
    401401    $ php symfony doctrine:dql "FROM Thread t, t.Posts p" 
     
    406406    doctrine - Posts: { } 
    407407 
    408 E é isso! Espero que este artigo seja útil tanto no sentido de que você aprenda 
    409 algo sobre os comportamentos e os comportamentos em si também sejam úteis à você! 
     408E é isso! Espero que este artigo seja útil tanto no sentido de que você aprendeu 
     409algo sobre os comportamentos e que os comportamentos em si também sejam úteis à você! 
    410410 
    411411Usando o Cache de Resultados do Doctrine 
     
    413413 
    414414Em aplicações web de tráfego pesado é comum necessitar de um cache de informações 
    415 para salvar recursos de CPU. Com a última versão do Doctrine 1.2 fizemos um monte de 
     415para poupar recursos de CPU. Com a última versão do Doctrine 1.2 fizemos um monte de 
    416416melhorias no cache de conjunto de resultados que lhe dará muito mais controle sobre 
    417 a remoção de entradas no cache a partir dos controladore de cache. Anteriormente não era possível 
     417a remoção de entradas no cache a partir dos controladores de cache. Anteriormente não era possível 
    418418especificar a chave de cache usado para armazenar a entrada no cache, então você não podia realmente 
    419 identificar a entrada de cache a fim de excluí-lo
     419identificar a entrada de cache a fim de excluí-la
    420420 
    421421Nesta seção, mostraremos um exemplo simples de como você pode utilizar o cacheamento de conjunto de resultados 
    422422para cachear todas as consultas relacionadas a seu usuário, bem como o uso de eventos para se certificar 
    423 de que eles sejam devidamente apurados quando alguns dado for alterado
     423de que eles sejam devidamente limpos quando alguns dadoa forem alterados
    424424 
    425425### Nosso Schema 
     
    461461    } 
    462462 
    463 Mais tarde no artigo você vai precisar adicionar algum código para esta classe para fazer a anotação da mesma. 
     463Mais tarde, no artigo, você vai precisar adicionar algum código a esta classe para fazer a anotação da mesma. 
    464464 
    465465### Configurando o Cache de Resultado 
     
    492492### Consultas de exemplo 
    493493 
    494 Agora imagine que em sua aplicação você tem um grande número de consultas realcioniona ao usuário 
     494Agora imagine que em sua aplicação você tem um grande número de consultas relacionadas ao usuário 
    495495e quer apurá-los sempre que algum dado do usuário for alterado. 
    496496 
     
    508508    $q->useResultCache(true, 3600, 'users_index'); 
    509509 
    510 >**NOTA** 
     510>**NOTE** 
    511511>Observe o terceiro argumento. Esta é a chave que será usada para armazenar a entrada 
    512512> cacheada para os resultados no controlador de cache. Isso nos permite identificar facilmente 
    513513>esta consulta e excluí-la do controlador de cache. 
    514514 
    515 Agora, quando executarmos a consulta quirá irá consultar o banco de dados para buscar os resultados e armazená- 
     515Agora, quando executarmos a consulta que irá consultar o banco de dados para buscar os resultados e armazená- 
    516516los no controlador de cache na chave chamada `users_index` e todas as requisições posteriores 
    517517obterão as informações do controlador de cache em vez de pedir ao banco de dados: 
     
    520520    $users = $q->execute(); 
    521521 
    522 >**NOTA** 
     522>**NOTE** 
    523523>Isso não somente economiza o processamento no servidor de banco de dados, ele também ignora 
    524 > o processo inteiro de hidratação que é como o Doctrine armazena os dados hidratado. Isso significa 
     524> o processo inteiro de hidratação que é como o Doctrine armazena os dados hidratados. Isso significa 
    525525> que irá também aliviar um pouco o processamento do seu servidor web. 
    526526 
     
    549549-lo em um evento. 
    550550 
    551 >**Dica** 
     551>**TIP** 
    552552> Para ter acesso à instância do controlador de cache de resultado você pode recuperá-lo a partir da 
    553553> instância da classe `Doctrine_Manager`. 
     
    582582   passado; 
    583583 
    584 * `deleteByRegex($regex)`: Exclui as entradas de cache que correspondam à 
     584* `deleteByRegularExpression($regex)`: Exclui as entradas de cache que correspondam à 
    585585   expressão regular passada; 
    586586 
     
    611611 
    612612Agora, se fôssemos atualizar um usuário ou inserir um novo ele iria limpar o cache para 
    613 todas as consultas relarionadas ao usuário: 
     613todas as consultas relacionadas ao usuário: 
    614614 
    615615    [php] 
    616616    $user = new User(); 
    617     $user->username = 'jorge'; 
     617    $user->username = 'jwage'; 
    618618    user->password = 'mudeme'; 
    619619    $user->save(); 
     
    625625usar esses recursos para implementar um cacheamento refinado em suas consultas Doctrine. 
    626626 
    627 Criando Hydratador Doctrine 
     627Criando Hidratador Doctrine 
    628628--------------------------- 
    629629 
    630630Uma das principais características do Doctrine é a capacidade de transformar um objeto `Doctrine_Query` 
    631 em várias estruturas de conjunto de resultado. Este é o trabalho dos hidratadores do 
     631em várias estruturas de conjunto de resultados. Este é o trabalho dos hidratadores do 
    632632Doctrine e até a versão 1.2, o hidratadores eram todos codificados rigidamente e não 
    633633eram abertos aos desenvolvedores para serem personalizados. Agora que isto mudou, é possível 
     
    658658    User: 
    659659      user1: 
    660         username: jorge 
     660        username: jwage 
    661661        password: mudeme 
    662662        is_active: 1 
    663663      user2: 
    664         username: jorjao 
     664        username: jonwage 
    665665        password: mudeme 
    666666        is_active: 0 
     
    670670    $ php symfony doctrine:build --all --and-load 
    671671 
    672 ### Escrevendo o Hydratador 
     672### Escrevendo o Hidratador 
    673673 
    674674Para escrever um hidratador tudo o que precisamos fazer é escrever uma nova classe que se estende `Doctrine_Hydrator_Abstract` 
     
    752752    Array 
    753753    ( 
    754         [jorge] => 1 
    755         [jorjao] => 0 
     754        [jwage] => 1 
     755        [jonwage] => 0 
    756756    ) 
    757757 
    758758Bem, é isso! Simplesmente lindo não? Espero que isso seja útil a você e como resultado 
    759 a comunidade terá alguns novos e impressivos hidratadores contribuídos. 
     759a comunidade terá contribuições de alguns novos e expressivos hidratadores.