diff --git a/pt/404.rst b/pt/404.rst index 3d3459dd4d..682e7d9dab 100644 --- a/pt/404.rst +++ b/pt/404.rst @@ -1,7 +1,7 @@ :orphan: True -Página não encontrada -##################### +Não Encontrado +############## -A página que você está procurando não foi encontrada. Tente usar o campo de -busca para localizar o que você procura. +A página que você está procurando não pode ser encontrada. Tente usar a barra de pesquisa para encontrar +o que você está procurando. diff --git a/pt/_static/img/cakefest-2022-banner.png b/pt/_static/img/cakefest-2022-banner.png new file mode 100644 index 0000000000..ce074d1242 Binary files /dev/null and b/pt/_static/img/cakefest-2022-banner.png differ diff --git a/pt/appendices.rst b/pt/appendices.rst index 4e51a999f9..55710fe6a7 100644 --- a/pt/appendices.rst +++ b/pt/appendices.rst @@ -2,15 +2,30 @@ Apêndices ######### Os apêndices contêm informações sobre os novos recursos -introduzidos em cada versão e a forma de executar a migração entre versões. +introduzidos em cada versão e o caminho de migração entre versões. -Guia de Migração para a versão 4.x -================================== +Guias de Migração +================= -.. toctree:: - :maxdepth: 1 +:doc:`appendices/migration-guides` + +Compatibilidade Retroativa com Shim +==================================== + +Se você precisa/quer adicionar o comportamento do 4.x, ou migrar parcialmente em etapas, confira +o `Plugin Shim `__ que pode ajudar a mitigar algumas mudanças que quebram a compatibilidade retroativa. + +Compatibilidade Futura com Shim +================================ + +A compatibilidade futura com shim pode preparar sua aplicação 4.x para a próxima versão principal +(5.x). - appendices/4-0-migration-guide +Se você já quer adicionar o comportamento do 5.x no 4.x, confira o `Plugin Shim +`__. Este plugin tem como objetivo mitigar +algumas quebras de compatibilidade retroativa e ajudar a fazer backport de recursos do 5.x para +4.x. Quanto mais próxima sua aplicação 3.x estiver do 4.x, menor será o diff de +mudanças, e mais suave será a atualização final. Informações Gerais ================== @@ -23,4 +38,4 @@ Informações Gerais .. meta:: :title lang=pt: Apêndices - :keywords lang=pt: guia de migração,como migrar,migração,nova versão,ajuda,glossário,rota de migração,novas funcionalidades + :keywords lang=pt: guia de migração,caminho de migração,novos recursos,glossário diff --git a/pt/appendices/4-0-migration-guide.rst b/pt/appendices/4-0-migration-guide.rst deleted file mode 100644 index 1ac9c3ea33..0000000000 --- a/pt/appendices/4-0-migration-guide.rst +++ /dev/null @@ -1,12 +0,0 @@ -4.0 Migration Guide -################### - -.. note:: - Atualmente, a documentação desta página não é suportada em português. - - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. - - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. diff --git a/pt/appendices/5-0-migration-guide.rst b/pt/appendices/5-0-migration-guide.rst new file mode 100644 index 0000000000..6342ced76d --- /dev/null +++ b/pt/appendices/5-0-migration-guide.rst @@ -0,0 +1,427 @@ +5.0 Guia de Migração +#################### + +O CakePHP 5.0 contém mudanças drásticas e não é compatível com versões anteriores da versão 4.x. +Antes de tentar atualizar para a versão 5.0, atualize primeiro para a 4.5 e resolva +todos os avisos de descontinuação. + +Consulte o :doc:`/appendices/5-0-upgrade-guide` para obter instruções passo a passo +sobre como atualizar para a versão 5.0. + +Recursos obsoletos removidos +============================ + +Todos os métodos, propriedades e funcionalidades que estavam emitindo avisos de descontinuação +a partir da versão 4.5 foram removidos. + +Mudanças Drásticas +================== + +Além da remoção de recursos obsoletos, foram feitas alterações drásticas: + +Global +------ + +- Declarações de tipo foram adicionadas a todos os parâmetros e retornos de funções, sempre que possível. O objetivo é + corresponder às anotações do docblock, mas incluem correções para anotações incorretas. +- Declarações de tipo foram adicionadas a todas as propriedades de classe sempre que possível. + Isso também inclui algumas correções para anotações incorretas. +- As constantes ``SECOND``, ``MINUTE``, ``HOUR``, ``DAY``, ``WEEK``, ``MONTH``, ``YEAR`` foram removidas. +- O uso de ``#[\AllowDynamicProperties]`` foi removido em todos os lugares. Era usado para as seguintes classes: + - ``Command/Command`` + - ``Console/Shell`` + - ``Controller/Component`` + - ``Controller/Controller`` + - ``Mailer/Mailer`` + - ``View/Cell`` + - ``View/Helper`` + - ``View/View`` +- As versões do mecanismo de banco de dados suportado foram atualizadas: + - MySQL (5.7 ou superior) + - MariaDB (10.1 ou superior) + - PostgreSQL (9.6 ou superior) + - Microsoft SQL Server (2012 ou superior) + - SQLite 3 (3.16 ou superior) + +Auth +---- + +- `Auth` foi removido. Em vez disso, use os plugins `cakephp/authentication `__ e + `cakephp/authorization `__. + +Cache +----- + +- O mecanismo ``Wincache`` foi removido. A extensão wincache não é suportada + no PHP 8. + +Collection +---------- + +- ``combine()`` agora lança uma exceção se o caminho da chave ou do grupo não existir ou contiver um valor nulo. + Isso corresponde ao comportamento de ``indexBy()`` e ``groupBy()``. + +Console +------- + +- ``BaseCommand::__construct()`` foi removido. +- ``ConsoleIntegrationTestTrait::useCommandRunner()`` foi removido porque não é mais necessário. +- ``Shell`` foi removido e deve ser substituído por `Command `__ +- ``ConsoleOptionParser::addSubcommand()`` foi removido juntamente com a remoção de + ``Shell``. Subcomandos devem ser substituídos por classes ``Command`` que + implementam ``Command::defaultName()`` para definir o nome do comando necessário. +- ``BaseCommand`` agora emite eventos ``Command.beforeExecute`` e + ``Command.afterExecute`` em torno do método ``execute()`` do comando + sendo invocado pelo framework. + +Connection +---------- + +- ``Connection::prepare()`` foi removido. Você pode usar ``Connection::execute()`` + para executar uma consulta SQL especificando a string SQL, os parâmetros e os tipos em uma única chamada. +- ``Connection::enableQueryLogging()`` foi removido. Se você não habilitou o registro + através da configuração de conexão, poderá posteriormente definir a instância do registrador para o + driver para habilitar o registro de consulta ``$connection->getDriver()->setLogger()``. + +Controller +---------- + +- A assinatura do método ``Controller::__construct()`` foi alterada. + Portanto, você precisa ajustar seu código adequadamente se estiver substituindo o construtor. +- Após o carregamento, os componentes não são mais definidos como propriedades dinâmicas. Em vez disso, + ``Controller`` usa ``__get()`` para fornecer acesso de propriedade aos componentes. Esta + alteração pode impactar aplicativos que usam ``property_exists()`` em componentes. +- O retorno de chamada do evento ``Controller.shutdown`` dos componentes foi renomeado de + ``shutdown`` para ``afterFilter`` para corresponder ao do controller. Isso torna os retornos de chamada mais consistentes. +- ``PaginatorComponent`` foi removido e deve ser substituído chamando ``$this->paginate()`` no seu controller ou + usando ``Cake\Datasource\Paging\NumericPaginator`` diretamente. +- ``RequestHandlerComponent`` foi removido. Consulte o guia + `migração 4.4 `__ para saber como atualizar. +- ``SecurityComponent`` foi removido. Use ``FormProtectionComponent`` para proteção contra adulteração de formulários + ou ``HttpsEnforcerMiddleware`` para impor o uso de HTTPS para solicitações. +- ``Controller::paginate()`` não aceita mais opções de consulta como ``contain`` para + seu argumento ``$settings``. Em vez disso, você deve usar a opção ``finder`` + ``$this->paginate($this->Articles, ['finder' => 'published'])``. Ou você pode + criar a consulta de seleção necessária com antecedência e passá-la para ``paginate()`` + ``$query = $this->Articles->find()->where(['is_published' => true]); $this->paginate($query);``. + +Core +---- + +- A função ``getTypeName()`` foi descontinuada. Em vez disso, use ``get_debug_type()`` do PHP. +- A dependência de ``league/container`` foi atualizada para ``4.x``. Isso + exigirá a adição de dicas de tipo às suas implementações de ``ServiceProvider``. +- ``deprecationWarning()`` agora possui um parâmetro ``$version``. +- A opção de configuração ``App.uploadedFilesAsObjects`` foi removida, + juntamente com o suporte a arrays em formato de upload de arquivos PHP em todo o + framework. +- ``ClassLoader`` foi removido. Em vez disso, use o composer para gerar arquivos de carregamento automático. + +Database +-------- + +- ``DateTimeType`` e ``DateType`` agora sempre retornam objetos imutáveis. + Além disso, a interface para objetos ``Date`` reflete a interface ``ChronosDate``, + que não possui todos os métodos relacionados a tempo presentes no CakePHP 4.x. +- ``DateType::setLocaleFormat()`` não aceita mais um array. +- ``Query`` agora aceita apenas parâmetros ``\Closure`` em vez de ``callable``. Callables podem ser convertidos + em closures usando a nova sintaxe de array de primeira classe do PHP 8.1. +- ``Query::execute()`` não executa mais callbacks do decorador de resultados. Você deve usar ``Query::all()`` em seu lugar. +- ``TableSchemaAwareInterface`` foi removido. +- ``Driver::quote()`` foi removido. Use instruções preparadas em seu lugar. +- ``Query::orderBy()`` foi adicionado para substituir ``Query::order()``. +- ``Query::groupBy()`` foi adicionado para substituir ``Query::group()``. +- ``SqlDialectTrait`` foi removido e toda a sua funcionalidade foi movida + para a própria classe ``Driver``. +- ``CaseExpression`` foi removido e deve ser substituído por + ``QueryExpression::case()`` ou ``CaseStatementExpression`` +- ``Connection::connect()`` foi removido. Use + ``$connection->getDriver()->connect()`` em vez disso. +- ``Connection::disconnect()`` foi removido. Use + ``$connection->getDriver()->disconnect()`` em vez disso. +- ``cake.database.queries`` foi adicionado como alternativa ao escopo ``queriesLog`` +- A capacidade de habilitar/desabilitar o buffer do ResultSet foi removida. Os resultados são sempre armazenados em buffer. + +Datasource +---------- + +- O método ``getAccessible()`` foi adicionado a ``EntityInterface``. Implementações não-ORM + precisam implementar este método agora. +- O método ``aliasField()`` foi adicionado a ``RepositoryInterface``. Implementações não-ORM + precisam implementar este método agora. + +Event +----- + +- Os payloads de eventos devem ser um array. Outros objetos, como ``ArrayAccess``, não são mais convertidos para array e agora gerarão um ``TypeError``. +- Recomenda-se ajustar os manipuladores de eventos para que sejam métodos nulos e usem ``$event->setResult()`` em vez de retornar o resultado. + +Error +----- + +- ``ErrorHandler`` e ``ConsoleErrorHandler`` foram removidos. Consulte o guia + `migração 4.4 `__ para saber como atualizar. +- ``ExceptionRenderer`` foi removido e deve ser substituído por ``WebExceptionRenderer`` +- ``ErrorLoggerInterface::log()`` foi removido e deve ser substituído por ``ErrorLoggerInterface::logException()`` +- ``ErrorLoggerInterface::logMessage()`` foi removido e deve ser substituído por ``ErrorLoggerInterface::logError()`` + +Filesystem +---------- + +- O pacote Filesystem foi removido, e a classe ``Filesystem`` foi movida para o pacote Utility. + +Http +---- + +- ``ServerRequest`` não é mais compatível com ``files`` como arrays. Este + comportamento foi desabilitado por padrão desde a versão 4.1.0. Os dados de ``files`` agora + sempre conterão objetos ``UploadedFileInterfaces``. + +I18n +---- + +- ``FrozenDate`` foi renomeado para `Date` e ``FrozenTime`` foi renomeado para ``DateTime``. +- ``Time`` agora estende ``Cake\Chronos\ChronosTime`` e, portanto, é imutável. +- Objetos ``Date`` não estendem mais ``DateTimeInterface`` - portanto, você não pode compará-los com objetos ``DateTime``. + Consulte a documentação da versão `cakephp/chronos `__ para mais informações. +- ``Date::parseDateTime()`` foi removido. +- ``Date::parseTime()`` foi removido. +- ``Date::setToStringFormat()`` e ``Date::setJsonEncodeFormat()`` não aceitam mais um array. +- ``Date::i18nFormat()`` e ``Date::nice()`` não aceitam mais um parâmetro de fuso horário. +- Arquivos de tradução para plugins com nomes prefixados pelo fornecedor (``FooBar/Awesome``) agora terão esse + prefixo no nome do arquivo, por exemplo, ``foo_bar_awesome.po`` para evitar colisão com um arquivo ``awesome.po`` + de um plugin correspondente (``Awesome``). + +Log +--- + +- A configuração do mecanismo de log agora usa ``null`` em vez de ``false`` para desabilitar escopos. + Portanto, em vez de ``'scopes' => false``, você precisa usar ``'scopes' => null`` na sua configuração de log. + +Mailer +------ + +- ``Email`` foi removido. Em vez disso, use `Mailer `__. +- ``cake.mailer`` foi adicionado como alternativa ao escopo ``email``. + +ORM +--- + +- ``EntityTrait::has()`` agora retorna ``true`` quando um atributo existe e está + definido como ``null``. Em versões anteriores do CakePHP, isso retornava ``false``. + Consulte as notas de lançamento da versão 4.5.0 para saber como adotar esse comportamento na versão 4.x. +- ``EntityTrait::extractOriginal()`` agora retorna apenas campos existentes, semelhante a ``extractOriginalChanged()``. +- Os argumentos do Finder agora precisam ser arrays associativos, como sempre foi esperado. +- ``TranslateBehavior`` agora usa como padrão a estratégia ``ShadowTable``. Se você estiver + usando a estratégia ``Eav``, precisará atualizar sua configuração de comportamento + para manter o comportamento anterior. +- A opção ``allowMultipleNulls`` para a regra ``isUnique`` agora usa como padrão true, correspondendo + ao comportamento original da versão 3.x. +- ``Table::query()`` foi removido em favor de funções específicas do tipo de consulta. +- ``Table::updateQuery()``, ``Table::selectQuery()``, ``Table::insertQuery()`` e + ``Table::deleteQuery()`` foram adicionados e retornam os novos objetos de consulta específicos do tipo abaixo. +- ``SelectQuery``, ``InsertQuery``, ``UpdateQuery`` e ``DeleteQuery`` foram adicionados, + que representam apenas um único tipo de consulta e não permitem alternar entre tipos de consulta nem + chamar funções não relacionadas ao tipo de consulta específico. +- ``Table::_initializeSchema()`` foi removido e deve ser substituído pela chamada de + ``$this->getSchema()`` dentro do método ``initialize()``. +- ``SaveOptionsBuilder`` foi removido. Use um array normal para opções. + +Routing +------- + +- Os métodos estáticos ``connect()``, ``prefix()``, ``scope()`` e ``plugin()`` do ``Router`` foram removidos e + devem ser substituídos chamando suas variantes de método não estático por meio da instância ``RouteBuilder``. +- ``RedirectException`` foi removido. Em vez disso, use ``\Cake\Http\Exception\RedirectException``. + +TestSuite +--------- + +- ``TestSuite`` foi removido. Os usuários devem usar variáveis ​​de ambiente para personalizar + as configurações de teste unitário. +- ``TestListenerTrait`` foi removido. O PHPUnit removeu o suporte para esses ouvintes. + Consulte :doc:`/appendices/phpunit10` +- ``IntegrationTestTrait::configRequest()`` agora mescla a configuração quando chamado várias vezes + em vez de substituir a configuração atual. + +Validation +---------- + +- ``Validation::isEmpty()`` não é mais compatível com arrays + de upload de arquivos. O suporte para arrays de upload de arquivos PHP também foi removido de + ``ServerRequest``, portanto, você não deve ver isso como um problema fora dos testes. +- Anteriormente, a maioria das mensagens de erro de validação de dados era simplesmente ``O valor fornecido é inválido``. + Agora, as mensagens de erro de validação de dados são redigidas com mais precisão. + Por exemplo, ``O valor fornecido deve ser maior ou igual a \`5\```. + +View +---- + +- As opções ``ViewBuilder`` agora são verdadeiramente associativas (chaves de string). +- ``NumberHelper`` e ``TextHelper`` não aceitam mais a configuração ``engine``. +- O parâmetro ``$merge`` do ``ViewBuilder::setHelpers()`` foi removido. Em vez disso, use ``ViewBuilder::addHelpers()``. +- Dentro de ``View::initialize()``, prefira usar ``addHelper()`` em vez de ``loadHelper()``. + Todos os auxiliares configurados serão carregados posteriormente, de qualquer forma. +- ``View\Widget\FileWidget`` não é mais compatível com arrays em formato de upload de arquivos PHP. + Isso está alinhado com as alterações em ``ServerRequest`` e ``Validation``. +- ``FormHelper`` não define mais ``autocomplete=off`` em campos de token CSRF. Esta + foi uma solução alternativa para um bug do Safari que não é mais relevante. + +Deprecations +============ + +A seguir, uma lista de métodos, propriedades e comportamentos obsoletos. +Esses recursos continuarão funcionando na versão 5.x e serão removidos na versão 6.0. + +Database +-------- + +- ``Query::order()`` foi descontinuado. Use ``Query::orderBy()`` em vez disso, agora que + os métodos ``Connection`` não são mais proxy. Isso alinha o nome da função + com a instrução SQL. +- ``Query::group()`` foi descontinuado. Use ``Query::groupBy()`` em vez disso, agora que + os métodos ``Connection`` não são mais proxy. Isso alinha o nome da função + com a instrução SQL. + +ORM +--- + +- Chamar ``Table::find()`` com array de opções está obsoleto. Use + `argumentos nomeados `__ + em vez disso. Por exemplo, em vez de ``find('all', ['conditions' => $array])``, use + ``find('all', conditions: $array)``. Da mesma forma, para opções personalizadas do localizador, em vez + de ``find('list', ['valueField' => 'name'])``, use ``find('list', valueField: 'name')`` + ou múltiplos argumentos nomeados como ``find(type: 'list', valueField: 'name', conditions: $array)``. + +New Features +============ + +Improved type checking +----------------------- + +O CakePHP 5 aproveita o recurso de sistema de tipos expandido disponível no PHP 8.1+. +O CakePHP também utiliza ``assert()`` para fornecer mensagens de erro aprimoradas e maior solidez de tipos. +No modo de produção, você pode configurar o PHP para não gerar código para ``assert()``, +resultando em melhor desempenho da aplicação. Consulte o arquivo +:ref:`symlink-assets` para saber como fazer isso. + +Collection +---------- + +- Adicionado ``unique()``, que filtra valores duplicados especificados pelo retorno de chamada fornecido. +- ``reject()`` agora suporta um retorno de chamada padrão que filtra valores verdadeiros, o que é + o inverso do comportamento padrão de ``filter()``. + +Core +---- + +- O método ``services()`` foi adicionado a ``PluginInterface``. +- ``PluginCollection::addFromConfig()`` foi adicionado para :ref:`simplificar o carregamento de plugins `. + +Database +-------- + +- ``ConnectionManager`` agora suporta funções de conexão de leitura e gravação. As funções podem ser configuradas + com as chaves ``read`` e ``write`` na configuração de conexão que substituem a configuração compartilhada. +- ``Query::all()`` foi adicionado, o que executa callbacks do decorador de resultados e retorna um conjunto de resultados para consultas selecionadas. +- ``Query::comment()`` foi adicionado para adicionar um comentário SQL à consulta executada. Isso facilita a depuração de consultas. +- ``EnumType`` foi adicionado para permitir o mapeamento entre enumerações baseadas em PHP e uma coluna de string ou inteiro. +- ``getMaxAliasLength()`` e ``getConnectionRetries()`` foram adicionados à ``DriverInterface``. +- Os drivers suportados agora adicionam automaticamente o incremento automático apenas às chaves primárias inteiras denominadas "id" em vez + de todas as chaves primárias inteiras. Definir 'autoIncrement' como falso sempre desabilita em todos os drivers suportados. + +Http +---- + +- Adicionado suporte para a interface `PSR-17 `__factorys. + Isso permite que ``cakephp/http`` forneça uma implementação cliente para + bibliotecas que permitem resolução automática de interface, como php-http. +- Adicionados ``CookieCollection::__get()`` e ``CookieCollection::__isset()`` para adicionar + maneiras ergonômicas de acessar cookies sem exceções. + +ORM +--- + +Required Entity Fields +---------------------- + +As entidades têm uma nova funcionalidade de opt-in que permite que as entidades tratem +propriedades de forma mais rigorosa. O novo comportamento é chamado de "campos obrigatórios". Quando +habilitado, o acesso a propriedades não definidas na entidade gerará +exceções. Isso afeta o seguinte uso:: + + $entity->get(); + $entity->has(); + $entity->getOriginal(); + isset($entity->attribute); + $entity->attribute; + +Os campos são considerados definidos se passarem por ``array_key_exists``. Isso inclui +valores nulos. Como esse recurso pode ser trabalhoso de habilitar, ele foi adiado para a versão 5.0. +Gostaríamos de receber seu feedback sobre esse recurso, pois estamos considerando torná-lo +o comportamento padrão no futuro. + +Typed Finder Parameters +----------------------- + +Os localizadores de tabela agora podem ter argumentos digitados, conforme necessário, em vez de uma matriz de opções. +Por exemplo, um localizador para buscar postagens por categoria ou usuário:: + + public function findByCategoryOrUser(SelectQuery $query, array $options) + { + if (isset($options['categoryId'])) { + $query->where(['category_id' => $options['categoryId']]); + } + if (isset($options['userId'])) { + $query->where(['user_id' => $options['userId']]); + } + + return $query; + } + +agora pode ser escrito como:: + + public function findByCategoryOrUser(SelectQuery $query, ?int $categoryId = null, ?int $userId = null) + { + if ($categoryId) { + $query->where(['category_id' => $categoryId]); + } + if ($userId) { + $query->where(['user_id' => $userId]); + } + + return $query; + } + +O localizador pode então ser chamado como ``find('byCategoryOrUser', userId: $somevar)``. +Você pode até incluir argumentos nomeados especiais para definir cláusulas de consulta. +``find('byCategoryOrUser', userId: $somevar, conditions: ['enabled' => true])``. + +Uma alteração semelhante foi aplicada ao método ``RepositoryInterface::get()``:: + + public function view(int $id) + { + $author = $this->Authors->get($id, [ + 'contain' => ['Books'], + 'finder' => 'latest', + ]); + } + +agora pode ser escrito como:: + + public function view(int $id) + { + $author = $this->Authors->get($id, contain: ['Books'], finder: 'latest'); + } + +TestSuite +--------- + +- ``IntegrationTestTrait::requestAsJson()`` foi adicionado para definir cabeçalhos JSON para a próxima solicitação. + +Plugin Installer +---------------- + +- O instalador de plugins foi atualizado para lidar automaticamente com o carregamento automático de classes + para os plugins do seu aplicativo. Assim, você pode remover os mapeamentos de namespace para caminho dos seus + plugins do seu ``composer.json`` e simplesmente executar ``composer dumpautoload``. diff --git a/pt/appendices/5-0-upgrade-guide.rst b/pt/appendices/5-0-upgrade-guide.rst new file mode 100644 index 0000000000..fc14a4a31b --- /dev/null +++ b/pt/appendices/5-0-upgrade-guide.rst @@ -0,0 +1,76 @@ +5.0 Guia de atualização +####################### + +Primeiro, verifique se seu aplicativo está sendo executado na versão mais recente do CakePHP 4.x. + +Corrigir Avisos de Descontinuação +================================= + +Depois que seu aplicativo estiver sendo executado na versão mais recente do CakePHP 4.x, +habilite os avisos de descontinuação em **config/app.php**:: + + 'Error' => [ + 'errorLevel' => E_ALL, + ] + +Agora que você pode ver todos os avisos, certifique-se de que eles sejam corrigidos antes de prosseguir com a atualização. + +Algumas descontinuações potencialmente impactantes que você deve ter certeza de ter abordado +são: + +- ``Table::query()`` foi descontinuado na versão 4.5.0. Em vez disso, use ``selectQuery()``, + ``updateQuery()``, ``insertQuery()`` e ``deleteQuery()``. + +Atualizar para PHP 8.1 +====================== + +Se você não estiver usando **PHP 8.1 ou superior**, será necessário atualizar o PHP antes de atualizar o CakePHP. + +.. note:: + O CakePHP 5.0 requer **no mínimo PHP 8.1**. + +.. _upgrade-tool-use: + +Use a Ferramenta de Atualização +=============================== + +.. note:: + A ferramenta de atualização só funciona em aplicativos que executam a versão mais recente do CakePHP 4.x. + Você não pode executar a ferramenta de atualização após atualizar para o CakePHP 5.0. + +Como o CakePHP 5 utiliza tipos de união e ``mixed``, há muitas +mudanças incompatíveis com versões anteriores relacionadas a assinaturas de métodos e renomeação de arquivos. +Para ajudar a agilizar a correção dessas mudanças tediosas, existe uma ferramenta de CLI de atualização: + +.. code-block:: console + + # Install the upgrade tool + git clone https://github.com/cakephp/upgrade + cd upgrade + git checkout 5.x + composer install --no-dev + +Com a ferramenta de atualização instalada, você pode executá-la em seu aplicativo ou +plugin:: + + bin/cake upgrade rector --rules cakephp50 + bin/cake upgrade rector --rules chronos3 + +Atualizar Dependência do CakePHP +================================ + +Após aplicar as refatorações do rector, você precisa atualizar o CakePHP, seus plugins, o PHPUnit +e talvez outras dependências no seu ``composer.json``. +Este processo depende muito da sua aplicação, por isso recomendamos que você compare o seu +``composer.json`` com o que está presente em `cakephp/app +`__. + +Após as strings de versão serem ajustadas em seu ``composer.json``, execute +``composer update -W`` e verifique sua saída. + +Atualizar arquivos do aplicativo com base no modelo de aplicativo mais recente +============================================================================== + +Em seguida, certifique-se de que o restante do seu aplicativo foi atualizado para se basear na +versão mais recente de `cakephp/app +`__. diff --git a/pt/appendices/5-1-migration-guide.rst b/pt/appendices/5-1-migration-guide.rst new file mode 100644 index 0000000000..dd79c84073 --- /dev/null +++ b/pt/appendices/5-1-migration-guide.rst @@ -0,0 +1,197 @@ +5.1 Guia de Migração +#################### + +A versão 5.1.0 é compatível com a versão 5.0. Ela adiciona novas funcionalidades +e introduz novas descontinuações. Qualquer funcionalidade descontinuada na versão 5.x será +removida na versão 6.0.0. + +Behavior Changes +================ + +- A conexão agora cria drivers de leitura e gravação exclusivos se as chaves ``read`` ou + ``write`` estiverem presentes na configuração, independentemente dos valores. +- O FormHelper não gera mais atributos ``aria-required`` em elementos de entrada + que também possuem o atributo ``required`` definido. O atributo ``aria-required`` + é redundante nesses elementos e gera avisos de validação HTML. Se você + estiver usando o atributo ``aria-required`` em estilização ou script, precisará + atualizar seu aplicativo. +- Adicionar associações com nomes duplicados agora gerará exceções. Você pode + usar ``$table->associations()->has()`` para definir associações condicionalmente, + se necessário. +- Os métodos Text Utility e TextHelper sobre truncamento e comprimento máximo estão usando + um caractere UTF-8 para ``ellipsis`` em vez de caracteres legados ``...``. +- ``TableSchema::setColumnType()`` agora gera uma exceção se a coluna especificada + não existir. +- ``PluginCollection::addPlugin()`` agora gera uma exceção se um plugin com o mesmo + nome já tiver sido adicionado. +- ``TestCase::loadPlugins()`` agora limpará todos os plugins carregados anteriormente. Portanto, + você deve especificar todos os plugins necessários para quaisquer testes subsequentes. +- O algoritmo de hash para configurações de ``Cache`` que usam ``groups``. Quaisquer + chaves terão novos hashes de prefixo de grupo gerados, o que causará + falhas de cache. Considere uma implementação incremental para evitar operar em um cache + totalmente frio. +- ``FormHelper::getFormProtector()`` agora retorna ``null`` além de seus + tipos anteriores. Isso permite que o código de visualização dinâmica seja executado com menos erros e + não deve impactar a maioria dos aplicativos. +- O valor padrão para ``valueSeparator`` em ``Table::findList()`` agora é + um único espaço em vez de ``;``. +- ``ErrorLogger`` agora usa ``Psr\Log\LogTrait``. +- ``Database\QueryCompiler::$_orderedUnion`` foi removido. + +Deprecations +============ + +I18n +---- + +- A chave de configuração de cache ``_cake_core_`` foi renomeada para ``_cake_translations_``. + +Mailer +------ + +- ``Mailer::setMessage()`` está obsoleto. Seu comportamento é pouco intuitivo e seu uso é + muito baixo. + + +New Features +============ + +Cache +----- + +- ``RedisEngine`` agora suporta a opção ``tls`` que permite a conexão ao Redis + por meio de uma conexão TLS. Você pode usar as opções ``ssl_ca``, ``ssl_cert`` e + ``ssl_key`` para definir o contexto TLS para o Redis. + +Command +------- + +- ``bin/cake plugin list`` foi adicionado para listar todos os plugins disponíveis, + sua configuração de carregamento e versão. +- Argumentos opcionais ``Command`` agora podem ter um valor ``default``. +- ``BannerHelper`` foi adicionado. Este auxiliar de comando pode formatar texto como um banner + com fundo colorido e preenchimento. +- Estilos padrão adicionais para ``info.bg``, ``warning.bg``, ``error.bg`` e + ``success.bg`` foram adicionados a ``ConsoleOutput``. + +Console +------- + +- ``Arguments::getBooleanOption()`` e ``Arguments::getMultipleOption()`` foram adicionados. +- ``Arguments::getArgument()`` agora gerará uma exceção se um nome de argumento + desconhecido for fornecido. Isso ajuda a evitar a confusão de nomes de opções/argumentos. + +Controller +---------- + +- Os componentes agora podem usar o contêiner DI para ter dependências resolvidas e + fornecidas como parâmetros do construtor, assim como Controllers e Comandos. + +Core +---- + +- ``PluginConfig`` foi adicionado. Use esta classe para obter todos os plugins disponíveis, suas configurações de carga e versões. +- As funções ``toString``, ``toInt`` e ``toBool`` foram adicionadas. Elas oferecem + uma maneira segura de converter dados de requisição ou outras entradas e retornar ``null`` quando a conversão falha. +- ``pathCombine()`` foi adicionado para ajudar a construir caminhos sem se preocupar com barras duplicadas e finais. +- Um novo hook ``events`` foi adicionado à classe ``BaseApplication``, bem como à classe ``BasePlugin``. Este hook + é a maneira recomendada de registrar ouvintes de eventos globais para sua aplicação. + Consulte :ref:`Registrando Ouvintes ` + +Database +-------- + +- Suporte para os tipos ``point``, ``linestring``, ``polygon`` e ``geometry`` foi + adicionado. Esses tipos são úteis ao trabalhar com coordenadas geoespaciais ou cartesianas. + O suporte ao SQLite usa colunas de texto por baixo dos panos e não possui + funções para manipular dados como valores geoespaciais. +- ``SelectQuery::__debugInfo()`` agora inclui a função de conexão para a qual a consulta + se destina. +- ``SelectQuery::intersect()`` e ``SelectQuery::intersectAll()`` foram adicionados. + Esses métodos permitem que consultas usando as conjunções ``INTERSECT`` e ``INTERSECT ALL`` + sejam expressas. +- Novos recursos de suporte foram adicionados para os recursos ``intersect``, ``intersect-all`` e + ``set-operations-order-by``. +- A capacidade de buscar registros sem buffer, que existia na versão 4.x, foi restaurada. + Os métodos ``SelectQuery::enableBufferedResults()``, ``SelectQuery::disableBufferedResults()`` + e ``SelectQuery::isBufferedResultsEnabled()`` foram adicionados novamente. + +Datasource +---------- + +- Os métodos ``RulesChecker::remove()``, ``removeCreate()``, ``removeUpdate()`` e + ``removeDelete()`` foram adicionados. Esses métodos permitem remover regras + por nome. + +Http +---- + +- ``SecurityHeadersMiddleware::setPermissionsPolicy()`` foi adicionado. Este método + adiciona a capacidade de definir valores de cabeçalho ``permissions-policy``. +- ``Client`` agora emite os eventos ``HttpClient.beforeSend`` e ``HttpClient.afterSend`` + quando as solicitações são enviadas. Você pode usar esses eventos para executar logs, + armazenamento em cache ou coletar telemetria. +- ``Http\Server::terminate()`` foi adicionado. Este método aciona o + evento ``Server.terminate``, que pode ser usado para executar lógica após a resposta + ter sido enviada em ambientes fastcgi. Em outros ambientes, o + evento ``Server.terminate`` é executado *antes* do envio da resposta. + +I18n +---- + +- ``Number::formatter()`` e ``currency()`` agora aceitam a opção ``roundingMode`` + para substituir a forma como o arredondamento é feito. +- As funções ``toDate`` e ``toDateTime`` foram adicionadas. Elas oferecem + uma maneira segura de converter dados de solicitação ou outra entrada e retornar ``null`` quando + a conversão falhar. + +ORM +--- + +- Definindo a opção ``preserveKeys`` em consultas do localizador de associações. Isso pode ser + usado com ``formatResults()`` para substituir os resultados do localizador de associações por um + array associativo. +- Colunas SQLite com nomes contendo ``json`` agora podem ser mapeadas para ``JsonType``. + Este é atualmente um recurso opcional que é habilitado definindo o valor de configuração ``ORM.mapJsonTypeForSqlite`` + como ``true`` em seu aplicativo. + +TestSuite +--------- + +- O CakePHP e o template do aplicativo foram atualizados para usar o PHPUnit ``^10.5.5 || ^11.1.3"``. +- Os métodos ``ConnectionHelper`` agora são todos estáticos. Esta classe não possui estado e + seus métodos foram atualizados para serem estáticos. +- ``LogTestTrait`` foi adicionado. Este novo trait facilita a captura de logs + em seus testes e a realização de asserções sobre a presença ou ausência de mensagens de log. +- ``IntegrationTestTrait::replaceRequest()`` foi adicionado. + +Utility +------- + +- ``Hash::insert()`` e ``Hash::remove()`` agora aceitam objetos ``ArrayAccess`` junto com dados ``array``. + +Validation +---------- + +- ``Validation::enum()`` e ``Validator::enum()`` foram adicionados. Esses métodos de + validação simplificam a validação de valores de enumeração com suporte. +- ``Validation::enumOnly()`` e ``Validation::enumExcept()`` foram adicionados para verificar casos específicos + e simplificar ainda mais a validação de valores de enumeração com suporte. + +View +---- + +- As células de visualização agora emitem eventos em torno de suas ações ``Cell.beforeAction`` e + ``Cell.afterAction``. +- ``NumberHelper::format()`` agora aceita a opção ``roundingMode`` para substituir como + o arredondamento é feito. + +Helpers +------- + +- ``TextHelper::autoLinkUrls()`` possui opções adicionadas para melhorar a impressão do rótulo do link: + * ``stripProtocol``: Remove ``http://`` e ``https://`` do início do link. Padrão desativado. + * ``maxLength``: O comprimento máximo do rótulo do link. Padrão desativado. + * ``ellipsis``: A string a ser anexada ao final do rótulo do link. Padrão para a versão UTF8. +- ``HtmlHelper::meta()`` agora pode criar uma meta tag contendo o token CSRF + atual usando ``meta('csrfToken')``. diff --git a/pt/appendices/5-2-migration-guide.rst b/pt/appendices/5-2-migration-guide.rst new file mode 100644 index 0000000000..fa54745ec6 --- /dev/null +++ b/pt/appendices/5-2-migration-guide.rst @@ -0,0 +1,133 @@ +5.2 Migration Guide +################### + +A versão 5.2.0 é compatível com a versão 5.0. Ela adiciona novas funcionalidades +e introduz novas descontinuações. Qualquer funcionalidade descontinuada na versão 5.x será +removida na versão 6.0.0. + +Behavior Changes +================ + +- ``ValidationSet::add()`` agora gerará erros quando uma regra for adicionada com + um nome já definido. Essa alteração visa evitar que as regras sejam + sobrescritas acidentalmente. +- ``Http\Session`` agora gerará uma exceção quando uma predefinição de sessão inválida for usada. +- ``FormProtectionComponent`` agora gera ``Cake\Controller\Exception\FormProtectionException``. Esta + classe é uma subclasse de ``BadRequestException`` e oferece o benefício de + ser filtrável a partir de registros. +- ``NumericPaginator::paginate()`` agora usa a opção ``finder`` mesmo quando uma instância de ``SelectQuery`` é passada a ela. + +Deprecations +============ + +Console +------- + +- ``Arguments::getMultipleOption()`` está obsoleto. Use ``getArrayOption()`` em seu lugar. + +Datasource +---------- + +- A capacidade de converter uma instância de ``EntityInterface`` para uma string foi descontinuada. + Em vez disso, você deve usar ``json_encode()`` para a entidade. + +- A atribuição em massa de múltiplos campos de entidade usando ``EntityInterface::set()`` foi descontinuada. + Em vez disso, use ``EntityInterface::patch()``. Por exemplo, altere o uso de + ``$entity->set(['field1' => 'value1', 'field2' => 'value2'])`` para + ``$entity->patch(['field1' => 'value1', 'field2' => 'value2'])``. + +Event +----- + +- Retornar valores de ouvintes de eventos/retornos de chamada está obsoleto. Use ``$event->setResult()`` + em vez disso ou ``$event->stopPropogation()`` para simplesmente interromper a propagação do evento. + +View +---- + +- A opção ``errorClass`` de ``FormHelper`` foi descontinuada em favor do uso de + uma string de modelo. Para atualizar, mova sua definição de ``errorClass`` para + um conjunto de modelos. Consulte :ref:`customizing-templates`. + + +New Features +============ + +Console +------- + +- O comando ``cake counter_cache`` foi adicionado. Este comando pode ser usado para + regenerar contadores para modelos que usam ``CounterCacheBehavior``. +- ``ConsoleIntegrationTestTrait::debugOutput()`` facilita a depuração + de testes de integração para comandos de console. +- ``ConsoleInputArgument`` agora suporta a opção ``separator``. Esta opção + permite que argumentos posicionais sejam delimitados com uma sequência de caracteres como + ``,``. O CakePHP dividirá o argumento posicional em um array quando os argumentos + forem analisados. +- ``Arguments::getArrayArgumentAt()`` e ``Arguments::getArrayArgument()`` + foram adicionados. Esses métodos permitem que você leia argumentos posicionais delimitados + por ``separator`` como arrays. +- ``ConsoleInputOption`` agora suporta a opção ``separator``. Esta opção + permite que valores de opção sejam delimitados com uma sequência de caracteres como + ``,``. O CakePHP dividirá o valor da opção em um array quando os argumentos + forem analisados. +- ``Arguments::getArrayArgumentAt()``, ``Arguments::getArrayArgument()`` e ``Arguments::getArrayOption()`` + foram adicionados. Esses métodos permitem que você leia argumentos posicionais delimitados + por ``separator`` como arrays. + +Database +-------- + +- O tipo ``nativeuuid`` foi adicionado. Este tipo permite que colunas ``uuid`` sejam + usadas em conexões MySQL com MariaDB. Em todos os outros drivers, ``nativeuuid`` + é um alias para ``uuid``. +- ``Cake\Database\Type\JsonType::setDecodingOptions()`` foi adicionado. Este método + permite definir o valor para o argumento ``$flags`` de ``json_decode()``. +- ``CounterCacheBehavior::updateCounterCache()`` foi adicionado. Este método permite + atualizar os valores do cache do contador para todos os registros das associações + configuradas. ``CounterCacheCommand`` também foi adicionado para fazer o mesmo através do + console. +- ``Cake\Database\Driver::quote()`` foi adicionado. Este método fornece uma maneira de + citar valores a serem usados ​​em consultas SQL onde instruções preparadas não podem + ser usadas. + +Datasource +---------- + +- As regras de aplicação agora podem usar ``Closure`` para definir a mensagem de validação. + Isso permite criar mensagens de validação dinâmicas com base no estado da entidade + e nas opções da regra de validação. + +Error +----- + +- Exceções personalizadas podem ter lógica específica de tratamento de erros definida em + ``ErrorController``. + +ORM +--- + +- ``CounterCacheBehavior::updateCounterCache()`` foi adicionado. Este método + permite atualizar os valores do cache do contador para todos os registros das associações + configuradas. +- ``BelongsToMany::setJunctionProperty()`` e ``getJunctionProperty()`` foram + adicionados. Esses métodos permitem personalizar a propriedade ``_joinData`` que é + usada para hidratar os registros da tabela de junção. +- ``Table::findOrCreate()`` agora aceita um array como segundo argumento para passar dados diretamente. + +TestSuite +--------- + +- ``TestFixture::$strictFields`` foi adicionado. Habilitar esta propriedade fará com que + os fixtures gerem um erro se a lista de registros de um fixture contiver campos que não + existam no esquema. + +View +---- + +- ``FormHelper::deleteLink()`` foi adicionado como um wrapper conveniente para links de exclusão em + modelos usando o método ``DELETE``. +- ``HtmlHelper::importmap()`` foi adicionado. Este método permite definir + mapas de importação para seus arquivos JavaScript. +- ``FormHelper`` agora usa o modelo ``containerClass`` para aplicar uma classe + à div de controle do formulário. O valor padrão é ``input``. diff --git a/pt/appendices/cakephp-development-process.rst b/pt/appendices/cakephp-development-process.rst index 4dc57c48b9..a6cd6f66ac 100644 --- a/pt/appendices/cakephp-development-process.rst +++ b/pt/appendices/cakephp-development-process.rst @@ -1,53 +1,67 @@ -Processo de desenvolvimento no CakePHP +Processo de Desenvolvimento do CakePHP ###################################### -Aqui tentamos explicar o processo utilizado no desenvolvimento com o framework -CakePHP. Nós dependemos fortemente da interação por tickets e no canal do IRC. -O IRC é o melhor lugar para encontrar membros do -`time de desenvolvimento `_ e discutir -idéias, o ultimo código e fazer comentários gerais. Se algo mais formal tem que -ser proposto ou exite um problema com uma versão, o sistema de tickets é o -melhor lugar para compartilhar seus pensamentos. - -Nós atualmente mantemos 4 versões do CakePHP. - -- **versões tageadas** : Versões tageadas são destinadas para produção onde uma - estabilidade maior é mais importante do que funcionalidades. Questões sobre - versões tageadas serão resolvidas no branch relacionado e serão parte do - próximo release. -- **branch principal** : Esses branches são onde todas as correções são - fundidas. Versões estáveis são rotuladas apartir desses branches. ``master`` é - o principal branch para a versão atual. ``2.x`` é o branch de manutenção para - a versão 2.x. Se você está usando versões estáveis e precisa de correções que - não chegaram em uma versão tageada olhe aqui. -- **desenvolvimento** : O branch de desenvolvimento contém sempre as ultimas - correções e funcionalidades. Eles são nomeados pela versão a qual se destinam, - ex: *3.next*. Uma vez que estas braches estão estáveis elas são fundidas na - branch principal da versão. -- **branches de funcionalidades** : Branches de funcionalidade contém trabalhos - que estão sendo desenvolvidos ou possivelmente instáveis e são recomendadas - apenas para usuários avançados interessados e dispostos a contribuir com a - comunidade. Branches de funcionalidade são nomeadas pela seguinte convenção - *versão-funcionalidade*. Um exemplo seria *3.3-router* Que conteria novas - funcionalidades para o Router na 3.3 - -Esperamos que isso te ajudará a entender que versão é correta pra você. -Uma vez que escolhida a versão você pode se sentir compelido a reportar um erro -ou fazer comentários gerais no código. - -- Se você está usando uma versão estável ou de manutenção, por favor envie - tickets ou discuta conosco no IRC. -- Se você está usando uma branch de desenvolvimento ou funcionalidade, o - primeiro lugar para ir é o IRC. Se você tem um comentário e não consegue - entrar no IRC depois de um ou dois dias, envie um ticket. - -Se você encontrar um problema, a melhor resposta é escrever um teste. O melhor -conselho que podemos oferecer em escrever testes é olhar nos que estão no núcleo -do projeto. - -E sempre, se você tiver alguma questão ou cometários, nos visite no #cakephp no -irc.freenode.net +Os projetos CakePHP seguem amplamente o `semver `__. Isso significa que: + +- As versões são numeradas na forma de **A.B.C** +- Versões **A** são *versões principais*. Elas contêm mudanças incompatíveis e exigirão + quantidades não triviais de trabalho para atualizar de uma versão **A** inferior. +- Versões **A.B** são *versões de funcionalidades*. Cada versão será compatível com versões + anteriores, mas pode introduzir novas depreciações. Se uma mudança incompatível for + absolutamente necessária, será anotada no guia de migração para essa versão. +- Versões **A.B.C** são versões de *correção*. Elas devem ser compatíveis com a versão + de correção anterior. A exceção a esta regra é se um problema de segurança for + descoberto e a única solução for quebrar uma API existente. + +Veja :doc:`/contributing/backwards-compatibility` para o que consideramos ser +compatível com versões anteriores e mudanças incompatíveis. + +Versões Principais +================== + +Versões principais introduzem novos recursos e podem remover funcionalidades depreciadas em +uma versão anterior. Essas versões vivem em branches ``next`` que correspondem ao seu +número de versão, como ``5.next``. Uma vez lançadas, elas são promovidas para ``master`` +e então a branch ``5.next`` é usada para futuras versões de funcionalidades. + +Versões de Funcionalidades +=========================== + +Versões de funcionalidades são onde novos recursos ou extensões para recursos existentes são +entregues. Cada série de versão que recebe atualizações terá uma branch ``next``. Por +exemplo ``4.next``. Se você gostaria de contribuir com um novo recurso, por favor, direcione +para essas branches. + +Versões de Correção +==================== + +Versões de correção corrigem bugs em código/documentação existente e devem sempre ser +compatíveis com versões de correção anteriores da mesma versão de funcionalidade. Essas +versões são criadas a partir das branches estáveis. Branches estáveis são frequentemente nomeadas +após a série de versão, como ``3.x``. + +Cadência de Versões +=================== + +- *Versões Principais* são entregues aproximadamente a cada dois a três anos. Esse prazo + nos força a ser deliberados e cuidadosos com nossas mudanças incompatíveis e dá + tempo para a comunidade acompanhar sem sentir que está sendo deixada para trás. +- *Versões de Funcionalidades* são entregues a cada cinco a oito meses. +- *Versões de Correção* são inicialmente entregues a cada duas semanas. À medida que uma versão de funcionalidade + amadurece, essa cadência relaxa para um cronograma mensal. + +Política de Depreciação +======================== + +Antes que um recurso possa ser removido em uma versão principal, ele precisa ser depreciado. +Quando um comportamento é depreciado na versão **A.x**, ele continuará a funcionar para +o restante de todas as versões **A.x**. Depreciações são geralmente indicadas via +avisos do PHP. Você pode habilitar avisos de depreciação adicionando ``E_USER_DEPRECATED`` ao +valor ``Error.level`` da sua aplicação. + +Uma vez depreciado, o comportamento não é removido até a próxima versão principal. Por +exemplo, comportamento depreciado em ``4.1`` será removido em ``5.0``. .. meta:: - :title lang=pt: Processo de desenvolvimento no CakePHP - :keywords lang=pt: manutenção, interação com a comunidade, comunidade, funcionalidade, versão estável, ticket, funcionalidade avançada, usuários avançados, irc, desenvolvimento, tentativas + :title lang=pt: Processo de Desenvolvimento do CakePHP + :keywords lang=pt: branch de manutenção,interação com a comunidade,recurso da comunidade,recurso necessário,versão estável,sistema de tickets,recurso avançado,usuários avançados,conjunto de recursos,chat irc,ponta de lança,router,novos recursos,membros,tentativa,branches de desenvolvimento,desenvolvimento de branch diff --git a/pt/appendices/glossary.rst b/pt/appendices/glossary.rst index 5559f7e471..2fba249197 100644 --- a/pt/appendices/glossary.rst +++ b/pt/appendices/glossary.rst @@ -1,47 +1,38 @@ Glossário ######### -.. glossary:: - - routing array - Uma série de atributos que são passados para :php:meth:`Router::url()`. - Eles normalmente parecem:: - - ['controller' => 'Posts', 'action' => 'view', 5] - - HTML attributes - Uma série de arrays key => values que são compostos em atributos HTML. Por Exemplo:: - // Tendo isso - ['class' => 'my-class', 'target' => '_blank'] - - // Geraria isto - class="my-class" target="_blank" - - Se uma opção pode ser minimizada ou aceitar seu nome como valor, então ``true`` - pode ser usado:: +.. glossary:: - // Tendo isso - ['checked' => true] + CDN + Content Delivery Network. Um fornecedor de código de terceiros que você + pode pagar para ajudar a distribuir seu conteúdo para centros de dados + em todo o mundo. Isso ajuda a colocar seus ativos estáticos mais próximos + dos usuários distribuídos geograficamente. - // Geraria isto - checked="checked" + columns + Usado no ORM ao se referir às colunas de uma tabela em um banco de dados. - sintaxe plugin - A sintaxe do plugin refere-se ao nome da classe separada por pontos que indica classes:: + CSRF + Cross Site Request Forgery. Impede ataques de repetição, + envios duplos e solicitações forjadas de outros domínios. - // O plugin "DebugKit", e o nome da "Toolbar". - 'DebugKit.Toolbar' + DI Container + Em ``Application::services()`` você pode configurar serviços de aplicação + e suas dependências. Os serviços de aplicação são injetados automaticamente + em ações do Controller e Construtores de Comando. Consulte + :doc:`/development/dependency-injection`. - // O plugin "AcmeCorp/Tools", e o nome da class "Toolbar". - 'AcmeCorp/Tools.Toolbar' + DSN + Nome da Fonte de Dados. Um formato de string de conexão que é formado como um URI. + O CakePHP suporta DSNs para conexões de Cache, Banco de Dados, Log e E-mail. dot notation - A notação de ponto define um caminho do array, separando níveis aninhados com ``.`` + A notação de ponto define um caminho de array, separando os níveis aninhados com ``.`` Por exemplo:: Cache.default.engine - Geraria o seguinte valor:: + Apontaria para o seguinte valor:: [ 'Cache' => [ @@ -51,20 +42,64 @@ Glossário ] ] - CSRF - Cross Site Request Forgery. Impede ataques de repetição, envios duplos e solicitações forjadas de outros domínios. + DRY + Não se repita. É um princípio de desenvolvimento de software que visa + reduzir a repetição de informações de todos os tipos. No CakePHP, o DRY é usado + para permitir que você codifique as coisas uma vez e as reutilize em toda a sua + aplicação. - CDN - Content Delivery Network. Um fornecedor de código de terceiros que você pode pagar para ajudar a distribuir seu conteúdo para centros de dados em todo o mundo. Isso ajuda a colocar seus ativos estáticos mais próximos dos usuários distribuídos geograficamente. + campos + Um termo genérico usado para descrever propriedades de entidades ou colunas + de banco de dados. Frequentemente usado em conjunto com o FormHelper. - routes.php - O arquivo ``config`` diretório que contém configuração de roteamento. Este arquivo está incluído antes de cada solicitação ser processada. Ele deve conectar todas as rotas que seu aplicativo precisa para que as solicitações possam ser encaminhadas para a ação correta do controlador. + attributos HTML + Uma chave de array => valores que são compostos em atributos HTML. Por exemplo:: - DRY - Não se repita. É um princípio de desenvolvimento de software destinado a reduzir a repetição de informações de todos os tipos. No CakePHP DRY é usado para permitir codificar coisas uma vez e reutilizá-las em toda a sua aplicação. + // Considerando + ['class' => 'my-class', 'target' => '_blank'] + + // Geraria + class="my-class" target="_blank" + + Se uma opção puder ser minimizada ou aceitar seu nome como valor, então ``true`` + pode ser usado:: + + // Considerando + ['checked' => true] + + // Geraria + checked="checked" PaaS - Plataforma como um serviço. A plataforma como um provedor de serviços fornecerá recursos baseados em nuvem de hospedagem, banco de dados e armazenamento em cache. Alguns provedores populares incluem Heroku, EngineYard e PagodaBox. + Plataforma como Serviço. Os provedores de Plataforma como Serviço fornecerão + recursos de hospedagem, banco de dados e cache baseados em nuvem. Alguns provedores + populares incluem Heroku, EngineYard e PagodaBox. - DSN - Data Source Name. Um formato de seqüência de conexão que é formado como um URI. O CakePHP suporta DSN para conexões Cache, Database, Log e Email. + propriedades + Usado ao referenciar colunas mapeadas em uma entidade ORM. + + sintaxe de plugin + Sintaxe de plugin refere-se ao nome da classe separado por pontos, indicando que as classes + fazem parte de um plugin:: + + // O plugin é "DebugKit" e o nome da classe é "Toolbar". + 'DebugKit.Toolbar' + + // O plugin é "AcmeCorp/Tools" e o nome da classe é "Toolbar". + 'AcmeCorp/Tools.Toolbar' + + routes.php + Um arquivo no diretório ``config`` que contém a configuração de roteamento. + Este arquivo é incluído antes do processamento de cada solicitação. + Ele deve conectar todas as rotas que sua aplicação precisa para que + as solicitações possam ser roteadas para o controller + ação corretos. + + routing array + Um conjunto de atributos que são passados ​​para :php:meth:`Router::url()`. + Eles normalmente se parecem com:: + + ['controller' => 'Posts', 'action' => 'view', 5] + +.. meta:: + :title lang=pt: Glossário + :keywords lang=pt: atributos HTML, classe de array, controller de array, glossário,target blank, campos, propriedades, colunas, notação de ponto, configuração de roteamento, falsificação, repetição, roteador, sintaxe, configuração, envios \ No newline at end of file diff --git a/pt/appendices/migration-guides.rst b/pt/appendices/migration-guides.rst new file mode 100644 index 0000000000..a898a1241c --- /dev/null +++ b/pt/appendices/migration-guides.rst @@ -0,0 +1,14 @@ +Guias de Migração +################# + +Os guias de migração contêm informações sobre os novos recursos introduzidos em +cada versão e o caminho de migração entre as versões secundárias 5.x. + +.. toctree:: + :maxdepth: 1 + + ./5-0-upgrade-guide + ./5-0-migration-guide + ./5-1-migration-guide + ./5-2-migration-guide + ./phpunit10 diff --git a/pt/appendices/phpunit10.rst b/pt/appendices/phpunit10.rst new file mode 100644 index 0000000000..8c3256460d --- /dev/null +++ b/pt/appendices/phpunit10.rst @@ -0,0 +1,65 @@ +Atualização do PHPUnit 10 +######################### + +Com o CakePHP 5, a versão mínima do PHPUnit mudou de ``^8.5 || ^9.3`` para ``^10.1``. +Isso introduz algumas mudanças significativas tanto no PHPUnit quanto no CakePHP. + +ajustes de phpunit.xml +====================== + +É recomendável deixar o PHPUnit atualizar seu arquivo de configuração por meio do seguinte comando:: + + vendor/bin/phpunit --migrate-configuration + +.. note:: + + Certifique-se de que você já está no PHPUnit 10 via ``vendor/bin/phpunit --version`` antes de executar este comando! + +Com esse comando concluído, seu ``phpunit.xml`` já terá a maioria das alterações recomendadas presentes. + +Novo sistema de eventos +----------------------- + +O PHPUnit 10 removeu o antigo sistema de hooks e introduziu um novo `Sistema de eventos +`_ +que requer que o seguinte código no seu ``phpunit.xml`` seja ajustado de:: + + + + + +para:: + + + + + +``->withConsecutive()`` foi removido +==================================== + +Você pode converter o método removido ``->withConsecutive()`` em uma +solução provisória funcional, como você pode ver aqui:: + + ->withConsecutive(['firstCallArg'], ['secondCallArg']) + +deve ser convertido para:: + + ->with( + ...self::withConsecutive(['firstCallArg'], ['secondCallArg']) + ) + +O método estático ``self::withConsecutive()`` foi adicionado por meio de ``Cake\TestSuite\PHPUnitConsecutiveTrait`` +à classe base ``Cake\TestSuite\TestCase`` para que você não precise adicionar manualmente essa característica às suas classes Testcase. + +os provedores de dados precisam ser estáticos +============================================= + +Se seus casos de teste utilizam o recurso de provedor de dados do PHPUnit, +você precisa ajustar seus provedores de dados para que sejam estáticos:: + + public function myProvider(): array + +deve ser convertido para:: + + public static function myProvider(): array + diff --git a/pt/bake.rst b/pt/bake.rst index 662af4d4eb..34f4920853 100644 --- a/pt/bake.rst +++ b/pt/bake.rst @@ -1,4 +1,4 @@ -Bake Console +Console Bake ############ -Esta página foi `movida `__. +Esta página foi `movida `__. diff --git a/pt/bake/development.rst b/pt/bake/development.rst index ea02f8c8bc..7a7b33232c 100644 --- a/pt/bake/development.rst +++ b/pt/bake/development.rst @@ -1,4 +1,4 @@ Extendendo o Bake ################# -Esta página foi `movida `__. +Esta página foi `movida `__. diff --git a/pt/bake/usage.rst b/pt/bake/usage.rst index 03762dd4c7..be237d2d5c 100644 --- a/pt/bake/usage.rst +++ b/pt/bake/usage.rst @@ -1,4 +1,4 @@ Geração de código com bake ########################## -Esta página foi `movida `__. +Esta página foi `movida `__. diff --git a/pt/chronos.rst b/pt/chronos.rst index 8a552bd6c6..4d3de5c3cc 100644 --- a/pt/chronos.rst +++ b/pt/chronos.rst @@ -1,4 +1,4 @@ Chronos -####### +======= -Esta página foi `movida `__. +Esta página foi `movida `__. diff --git a/pt/console-and-shells.rst b/pt/console-and-shells.rst deleted file mode 100644 index f25b6e8281..0000000000 --- a/pt/console-and-shells.rst +++ /dev/null @@ -1,953 +0,0 @@ -Console e Shells -################ - -.. php:namespace:: Cake\Console - -O CakePHP não oferece um framework apenas para desenvolvimento web, -mas também um framework para criação de aplicações de console. Estas -aplicações são ideais para manipular variadas tarefas em segundo plano como -manutenção e complementação de trabalho fora do ciclo requisição-resposta. -As aplicações de console do CakePHP permitem a vocë reutilizar suas classes -de aplicação a partir da linha de comando. - -O CakePHP traz consigo algumas aplicações de console nativas. Algumas dessas -aplicações são utilizadas em conjunto com outros recursos do CakePHP -(como i18n), e outros de uso geral para aceleração de trabalho. - -O Console do CakePHP -==================== - -Esta seção provê uma introdução à linha de comando do CakePHP. -Ferramentas de console são ideais para uso em cron jobs, ou utilitários -baseados em linha de comando que não precisam ser acessíveis por um navegador -web. - -O PHP provê um cliente CLI que faz interface com o seu -sistema de arquivos e aplicações de forma muito mais suave. O console do CakePHP -provê um framework para criar scripts shell. O console utiliza uma configuração -tipo dispatcher para carregar uma shell ou tarefa, e prover seus parâmetros. - -.. note:: - - Uma linha de comando (CLI) constutuída a partir do PHP deve estar - disponível no sistema se você planeja utilizr o Console. - -Antes de entrar em detalhes, vamos ter certeza de que você pode executar o -console do CakePHP. Primeiro, você vai precisar executar um sistema shell. Os -exemplos apresentados nesta seção serão em bash, mas o Console do CakePHP é -compatível com o Windows também. Este exemplo assume que o usuário está -conectado em um prompt do bash e está atualmente na raiz de uma aplicação -CakePHP. - -Aplicações CakePHP possuem um diretório `Console``` que contém todas as -shells e tarefas para uma aplicação. Ele também vem com um executável:: - - $ cd /path/to/app - $ bin/cake - -Executar o Console sem argumentos produz esta mensagem de ajuda:: - - Welcome to CakePHP v3.0.0 Console - --------------------------------------------------------------- - App : App - Path: /Users/markstory/Sites/cakephp-app/src/ - --------------------------------------------------------------- - Current Paths: - - -app: src - -root: /Users/markstory/Sites/cakephp-app - -core: /Users/markstory/Sites/cakephp-app/vendor/cakephp/cakephp - - Changing Paths: - - Your working path should be the same as your application path. To change your path use the '-app' param. - Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp - - Available Shells: - - [Bake] bake - - [Migrations] migrations - - [CORE] i18n, orm_cache, plugin, server - - [app] behavior_time, console, orm - - To run an app or core command, type cake shell_name [args] - To run a plugin command, type cake Plugin.shell_name [args] - To get help on a specific command, type cake shell_name --help - -A primeira informação impressa refere-se a caminhos. Isso é útil se você estiver -executando o console a partir de diferentes partes do sistema de arquivos. - -Criando uma Shell -================= - -Vamos criar uma shell para utilizar no Console. Para este exemplo, -criaremos uma simples Hello World (Olá Mundo) shell. No diretório -**src/Shell** de sua aplicação crie **HelloShell.php**. Coloque o seguinte -código dentro do arquivo recem criado:: - - namespace App\Shell; - - use Cake\Console\Shell; - - class HelloShell extends Shell - { - public function main() - { - $this->out('Hello world.'); - } - } - -As convenções para as classes de shell são de que o nome da classe deve -corresponder ao nome do arquivo, com o sufixo de Shell. No nosso shell criamos -um método ``main()``. Este método é chamado quando um shell é chamado sem -comandos adicionais. Vamos adicionar alguns comandos daqui a pouco, mas por -agora vamos executar a nossa shell. A partir do diretório da aplicação, -execute:: - - bin/cake hello - -Você deve ver a seguinte saída:: - - Welcome to CakePHP Console - --------------------------------------------------------------- - App : app - Path: /Users/markstory/Sites/cake_dev/src/ - --------------------------------------------------------------- - Hello world. - -Como mencionado antes, o método ``main()`` em shells é um método especial -chamado sempre que não há outros comandos ou argumentos dados para uma shell. -Por nosso método principal não ser muito interessante, vamos adicionar outro -comando que faz algo:: - - namespace App\Shell; - - use Cake\Console\Shell; - - class HelloShell extends Shell - { - public function main() - { - $this->out('Hello world.'); - } - - public function heyThere($name = 'Anonymous') - { - $this->out('Hey there ' . $name); - } - } - -Depois de salvar o arquivo, você deve ser capaz de executar o seguinte comando e -ver o seu nome impresso:: - - bin/cake hello hey_there your-name - -Qualquer método público não prefixado por um ``_`` é permitido para ser chamado -a partir da linha de comando. Como você pode ver, os métodos invocados a partir -da linha de comando são transformados do argumento prefixado para a forma -correta do nome camel-cased (camelizada) -na classe. - -No nosso método ``heyThere()`` podemos ver que os argumentos posicionais são -providos para nossa função ``heyThere()``. Argumentos posicionais também estão -disponívels na propriedade ``args``. Você pode acessar switches ou opções em -aplicações shell, estando disponíveis em ``$this->params``, mas nós iremos -cobrir isso daqui a pouco. - -Quando utilizando um método ``main()`` você não estará liberado para utilizar -argumentos posicionais. Isso se deve ao primeiro argumento posicional ou opção -ser interpretado(a) como o nome do comando. Se você quer utilizar argumentos, -você deve usar métodos diferentes de ``main()``. - -Usando Models em suas shells ----------------------------- - -Você frequentemente precisará acessar a camada lógica de negócios em seus -utilitários shell; O CakePHP faz essa tarefa super fácil. Você pode carregar models em -shells assim como faz em um controller utilizando ``loadModel()``. Os models carregados -são definidos como propriedades anexas à sua shell:: - - namespace App\Shell; - - use Cake\Console\Shell; - - class UserShell extends Shell - { - - public function initialize() - { - parent::initialize(); - $this->loadModel('Users'); - } - - public function show() - { - if (empty($this->args[0])) { - return $this->error('Por favor, indique um nome de usuário.'); - } - $user = $this->Users->findByUsername($this->args[0])->first(); - $this->out(print_r($user, true)); - } - } - -A shell acima, irá preencher um user pelo seu username e exibir a informação -armazenada no banco de dados. - -Tasks de Shell -============== - -Haverão momentos construindo aplicações mais avançadas de console que você vai -querer compor funcionalidades em classes reutilizáveis que podem ser -compartilhadas através de muitas shells. Tasks permitem que você extraia -comandos em classes. Por exemplo, o ``bake`` é feito quase que completamente de -tasks. Você define tasks para uma shell usando a propriedade ``$tasks``:: - - class UserShell extends Shell - { - public $tasks = ['Template']; - } - -Você pode utilizar tasks de plugins utilizando o padrão :term:`sintaxe plugin`. -Tasks são armazenadas sob ``Shell/Task/`` em arquivos nomeados depois de suas -classes. Então se nós estivéssemos criando uma nova task 'FileGenerator', você -deveria criar **src/Shell/Task/FileGeneratorTask.php**. - -Cada task deve ao menos implementar um método ``main()``. O ShellDispatcher, -vai chamar esse método quando a task é invocada. Uma classe task se parece com:: - - namespace App\Shell\Task; - - use Cake\Console\Shell; - - class FileGeneratorTask extends Shell - { - public function main() - { - } - } - -Uma shell também pode prover acesso a suas tasks como propriedades, que fazem -tasks serem ótimas para criar punhados de funcionalidade reutilizáveis similares -a :doc:`/controllers/components`:: - - // Localizado em src/Shell/SeaShell.php - class SeaShell extends Shell - { - // Localizado em src/Shell/Task/SoundTask.php - public $tasks = ['Sound']; - - public function main() - { - $this->Sound->main(); - } - } - -Você também pode acessar tasks diretamente da linha de comando:: - - $ cake sea sound - -.. note:: - - Para acessar tasks diretamente através da linha de comando, a task - **deve** ser incluída na propriedade da classe shell ``$tasks``. - Portanto, esteja ciente que um método chamado "sound" na classe SeaShell - deve sobrescrever a habilidade de acessar a funcionalidade na task - Sound, especificada no array $tasks. - -Carregando Tasks em tempo-real com TaskRegistry ------------------------------------------------ - -Você pode carregar arquivos em tempo-real utilizando o Task registry object. -Você pode carregar tasks que não foram declaradas no $tasks dessa forma:: - - $project = $this->Tasks->load('Project'); - -Carregará e retornará uma instância ProjectTask. Você pode carregar tasks de -plugins usando:: - - $progressBar = $this->Tasks->load('ProgressBar.ProgressBar'); - -.. _invoking-other-shells-from-your-shell: - -Invocando outras Shells a partir da sua Shell -============================================= - -.. php:method:: dispatchShell($args) - -Existem ainda muitos casos onde você vai querer invocar uma shell a partir de -outra. ``Shell::dispatchShell()`` lhe dá a habilidade de chamar outras shells -ao providenciar o ``argv`` para a sub shell. Você pode providenciar argumentos -e opções tanto como variáveis ou como strings:: - - // Como uma string - $this->dispatchShell('schema create Blog --plugin Blog'); - - // Como um array - $this->dispatchShell('schema', 'create', 'Blog', '--plugin', 'Blog'); - -O conteúdo acima mostra como você pode chamar a shell schema para criar o schema -de um plugin de dentro da shell do próprio. - -Recenendo Input de usuários -=========================== - -.. php:method:: in($question, $choices = null, $defaut = null) - -Quando construir aplicações interativas pelo console você irá precisar receber -inputs dos usuários. CakePHP oferece uma forma fácil de fazer isso:: - - // Receber qualquer texto dos usuários. - $color = $this->in('What color do you like?'); - - // Receber uma escolha dos usuários. - $selection = $this->in('Red or Green?', ['R', 'G'], 'R'); - -A validação de seleção é insensitiva a maiúsculas / minúsculas. - -Criando Arquivos -================ - -.. php:method:: createFile($path, $contents) - -Muitas aplicações Shell auxiliam tarefas de desenvolvimento e implementação. -Criar arquivos é frequentemente importante nestes casos de uso. O CakePHP -oferece uma forma fácil de criar um arquivo em um determinado diretório:: - - $this->createFile('bower.json', $stuff); - -Se a Shell for interativa, um alerta vai ser gerado, e o usuário questionado se -ele quer sobreescrever o arquivo caso já exista. Se a propriedade de interação -da shell for ``false``, nenhuma questão será disparada e o arquivo será -simplesmente sobreescrito. - -Saída de dados do Console -========================= - -.. php:method:out($message, $newlines, $level) -.. php:method:err($message, $newlines) - -A classe ``Shell`` oferece alguns métodos para direcionar conteúdo:: - - // Escreve para stdout - $this->out('Normal message'); - - // Escreve para stderr - $this->err('Error message'); - - // Escreve para stderr e para o processo - $this->error('Fatal error'); - -A Shell também inclui métodos para limpar a saída de dados, criando linhas -em branco, ou desenhando uma linha de traços:: - - // Exibe 2 linhas novas - $this->out($this->nl(2)); - - // Limpa a tela do usuário - $this->clear(); - - // Desenha uma linha horizontal - $this->hr(); - -Por último, você pode atualizar a linha atual de texto na tela usando -``_io->overwrite()``:: - - $this->out('Counting down'); - $this->out('10', 0); - for ($i = 9; $i > 0; $i--) { - sleep(1); - $this->_io->overwrite($i, 0, 2); - } - -É importante lembrar, que você não pode sobreescrever texto -uma vez que uma nova linha tenha sido exibida. - -.. _shell-output-level: - -Console Output Levels ---------------------- - -Shells frequentemente precisam de diferentes níveis de verbosidade. Quando -executadas como cron jobs, muitas saídas são desnecessárias. E há ocasiões que -você não estará interessado em tudo que uma shell tenha a dizer. Você pode usar -os níveis de saída para sinalizar saídas apropriadamente. O usuário da shell, -pode então decidir qual nível de detalhe ele está interessado ao sinalizar o -chamado da shell. :php:meth:`Cake\\Console\\Shell::out()` suporta 3 tipos de -saída por padrão. - -* QUIET - Apenas informação absolutamente importante deve ser sinalizada. -* NORMAL - O nível padrão, e uso normal. -* VERBOSE - Sinalize mensagens que podem ser irritantes em demasia para uso - diário, mas informativas para depuração como VERBOSE. - -Você pode sinalizar a saíde da seguinte forma:: - - // Deve aparecer em todos os níveis. - $this->out('Quiet message', 1, Shell::QUIET); - $this->quiet('Quiet message'); - - // Não deve aparecer quando a saída quiet estiver alternado. - $this->out('normal message', 1, Shell::NORMAL); - $this->out('loud message', 1, Shell::VERBOSE); - $this->verbose('Verbose output'); - - // Deve aparecer somente quando a saíde verbose estiver habilitada. - $this->out('extra message', 1, Shell::VERBOSE); - $this->verbose('Verbose output'); - -Você pode controlar o nível de saída das shells, ao usar as opções ``--quiet`` -e ``--verbose``. Estas opções são adicionadas por padrão, e permitem a você -controlar consistentemente níveis de saída dentro das suas shells do CakePHP. - -Estilizando a saída de dados ----------------------------- - -Estilizar a saída de dados é feito ao incluir tags - como no HTML - em sua -saída. O ConsoleOutput irá substituir estas tags com a seqüência correta de -código ansi. Hão diversos estilos nativos, e você pode criar mais. Os nativos -são: - -* ``error`` Mensagens de erro. Texto sublinhado vermelho. -* ``warning`` Mensagens de alerta. Texto amarelo. -* ``info`` Mensagens informativas. Texto ciano. -* ``comment`` Texto adicional. Texto azul. -* ``question`` Texto que é uma questão, adicionado automaticamente pela shell. - -Você pode criar estilos adicionais usando ``$this->stdout->styles()``. Para -declarar um novo estilo de saíde você pode fazer:: - - $this->_io->styles('flashy', ['text' => 'magenta', 'blink' => true]); - -Isso deve então permití-lo usar uma ```` tag na saída de sua shell, e se -as cores ansi estiverem habilitadas, o seguinte pode ser renderizado como texto -magenta piscante ``$this->out('Whoooa Something went wrong');``. -Quando definir estilos você pode usar as seguintes cores para os atributos -``text`` e ``background``: - -* black -* red -* green -* yellow -* blue -* magenta -* cyan -* white - -Você também pode usar as seguintes opções através de valores boleanos, -defini-los com valor positivo os habilita. - -* bold -* underline -* blink -* reverse - -Adicionar um estilo o torna disponível para todas as instâncias do -ConsoleOutput, então você não tem que redeclarar estilos para os objetos stdout -e stderr respectivamente. - -Desabilitando a colorização ---------------------------- - -Mesmo que a colorização seja incrível, haverão ocasiões que você quererá -desabilitá-la, ou forçá-la:: - - $this->_io->outputAs(ConsoleOutput::RAW); - -O citado irá colocar o objeto de saída em modo raw. Em modo raw, -nenhum estilo é aplicado. Existem três modos que você pode usar. - -* ``ConsoleOutput::RAW`` - Saída raw, nenhum estilo ou formatação serão - aplicados. Este é um modo indicado se você estiver exibindo XML ou, quiser - depurar porquê seu estilo não está funcionando. -* ``ConsoleOutput::PLAIN`` - Saída de texto simples, tags conhecidas de estilo - serão removidas da saída. -* ``ConsoleOutput::COLOR`` - Saída onde a cor é removida. - -Por padrão em sistemas \*nix objetos ConsoleOutput padronizam-se a a saída de -cores. Em sistemas Windows, a saída simples é padrão a não ser que a variável de -ambiente ``ANSICON`` esteja presente. - -Opções de configuração e Geração de ajuda -========================================= - -.. php:class:: ConsoleOptionParser - -``ConsoleOptionParser`` oferece uma opção de CLI e analisador de argumentos. - -OptionParsers permitem a você completar dois objetivos ao mesmo tempo. Primeiro, -eles permitem definir opções e argumentos para os seus comandos. Isso permite -separar validação básica de dados e seus comandos do console. Segundo, -permite prover documentação, que é usada para gerar arquivos de ajuda bem -formatados. - -O console framework no CakePHP recebe as opções do seu interpetador shell ao -chamar ``$this->getOptionParser()``. Sobreescrever esse método permite -configurar o OptionParser para definir as entradas aguardadas da sua shell. -Você também pode configurar interpetadores de subcomandos, que permitem ter -diferentes interpretadores para subcomandos e tarefas. -O ConsoleOptionParser implementa uma interface fluida e inclui métodos para -facilmente definir múltiplas opções/argumentos de uma vez:: - - public function getOptionParser() - { - $parser = parent::getOptionParser(); - // Configure parser - return $parser; - } - -Configurando um interpretador de opção com a interface fluida -------------------------------------------------------------- - -Todos os métodos que configuram um interpretador de opções podem ser -encadeados, permitindo definir um interpretador de opções completo em uma -série de chamadas de métodos:: - - public function getOptionParser() - { - $parser = parent::getOptionParser(); - $parser->addArgument('type', [ - 'help' => 'Either a full path or type of class.' - ])->addArgument('className', [ - 'help' => 'A CakePHP core class name (e.g: Component, HtmlHelper).' - ])->addOption('method', [ - 'short' => 'm', - 'help' => __('The specific method you want help on.') - ])->description(__('Lookup doc block comments for classes in CakePHP.')); - - return $parser; - } - -Os métodos que permitem encadeamento são: - -- description() -- epilog() -- command() -- addArgument() -- addArguments() -- addOption() -- addOptions() -- addSubcommand() -- addSubcommands() - -.. php:method:: description($text = null) - -Recebe ou define a descrição para o interpretador de opções. A -descrição é exibida acima da informação do argumento e da opção. Ao -instanciar tanto em array como em string, você pode definir o valor -da descrição. Instanciar sem argumentos vai retornar o valor atual:: - - // Define múltiplas linhas de uma vez - $parser->description(['line one', 'line two']); - - // Lê o valor atual - $parser->description(); - -.. php:method:: epilog($text = null) - -Recebe ou define o epílogo para o interpretador de opções. O epílogo -é exibido depois da informação do argumento e da opção. Ao instanciar -tanto em array como em string, você pode definir o valor do epílogo. -Instanciar sem argumentos vai retornar o valor atual:: - - // Define múltiplas linhas de uma vez - $parser->epilog(['line one', 'line two']); - - // Lê o valor atual - $parser->epilog(); - -Adicionando argumentos ----------------------- - -.. php:method:: addArgument($name, $params = []) - -Argumentos posicionais são frequentemente usados em ferramentas -de linha de comando, e ``ConsoleOptionParser`` permite definir -argumentos bem como torná-los requiríveis. Você pode adicionar -argumentos um por vez com ``$parser->addArgument();`` ou múltiplos -de uma vez com ``$parser->addArguments();``:: - - $parser->addArgument('model', ['help' => 'The model to bake']); - -Você pode usar as seguintes opções ao criar um argumento: - -* ``help`` O texto de ajuda a ser exibido para este argumento. -* ``required`` Se esse parâmetro é requisito. -* ``index`` O índice do argumento, se deixado indefinido, o argumento será - colocado no final dos argumentos. Se você definir o mesmo índice duas vezes, - a primeira opção será sobreescrita. -* ``choices`` Um array de opções válidas para esse argumento. Se deixado vazio, - todos os valores são válidos. Uma exceção será lançada quando parse() - encontrar um valor inválido. - -Argumentos que forem definidos como requisito lançarão uma exceção quando -interpretarem o comando se eles forem omitidos. Então você não tem que lidar -com isso em sua shell. - -.. php:method:: addArguments(array $args) - -Se você tem um array com múltiplos argumentos você pode usar -``$parser->addArguments()`` para adicioná-los de uma vez.:: - - $parser->addArguments([ - 'node' => ['help' => 'The node to create', 'required' => true], - 'parent' => ['help' => 'The parent node', 'required' => true] - ]); - -Assim como todos os métodos de construção no ConsoleOptionParser, addArguments -pode ser usado como parte de um fluido método encadeado. - -Validando argumentos --------------------- - -Ao criar argumentos posicionais, você pode usar a marcação ``required`` para -indicar que um argumento deve estar presente quando uma shell é chamada. -Adicionalmente você pode usar o ``choices`` para forçar um argumento a -ser de uma lista de escolhas válidas:: - - $parser->addArgument('type', [ - 'help' => 'The type of node to interact with.', - 'required' => true, - 'choices' => ['aro', 'aco'] - ]); - -O código acima irá criar um argumento que é requisitado e tem validação -no input. Se o argumento está tanto indefinodo, ou possui um valor -incorreto, uma exceção será lançada e a shell parará. - -Adicionando opções ------------------- - -.. php:method:: addOption($name, $options = []) - -Opções são frequentemente usadas em ferramentas CLI. -``ConsoleOptionParser`` suporta a criação de opções com -verbose e aliases curtas, suprindo padrões e criando ativadores -boleanos. Opções são criadas tanto com -``$parser->addOption()`` ou ``$parser->addOptions()``.:: - - $parser->addOption('connection', [ - 'short' => 'c', - 'help' => 'connection', - 'default' => 'default', - ]); - -O código citado permite a você usar tanto ``cake myshell --connection=other``, -``cake myshell --connection other``, ou ``cake myshell -c other`` -quando invocando a shell. Você também criar ativadores boleanos. Estes -ativadores não consumem valores, e suas presenças apenas os habilitam nos -parâmetros interpretados.:: - - $parser->addOption('no-commit', ['boolean' => true]); - -Com essa opção, ao chamar uma shell como ``cake myshell --no-commit something`` -o parâmetro no-commit deve ter um valor de ``true``, e `something` -deve ser tratado como um argumento posicional. -As opções nativas ``--help``, ``--verbose``, e ``--quiet`` -usam essa funcionalidade. - -Ao criar opções você pode usar os seguintes argumentos para definir -o seu comportamento: - -* ``short`` - A variação de letra única para essa opção, deixe indefinido para - none. -* ``help`` - Texto de ajuda para essa opção. Usado ao gerar ajuda para a opção. -* ``default`` - O valor padrão para essa opção. Se não estiver definido o valor - padrão será ``true``. -* ``boolean`` - A opção não usa valor, é apenas um ativador boleano. Por padrão - ``false``. -* ``choices`` - Um array de escolhas válidas para essa opção. Se deixado vazio, - todos os valores são considerados válidos. Uma exceção será lançada quando - parse() encontrar um valor inválido. - -.. php:method:: addOptions(array $options) - -Se você tem um array com múltiplas opções, você pode usar -``$parser->addOptions()`` para adicioná-las de uma vez.:: - - $parser->addOptions([ - 'node' => ['short' => 'n', 'help' => 'The node to create'], - 'parent' => ['short' => 'p', 'help' => 'The parent node'] - ]); - -Assim como com todos os métodos construtores, no ConsoleOptionParser, addOptions -pode ser usado como parte de um método fluente encadeado. - -Validando opções ----------------- - -Opções podem ser fornecidas com um conjunto de escolhas bem como argumentos -posicionais podem ser. Quando uma opção define escolhas, essas são as únicas -opções válidas para uma opção. Todos os outros valores irão gerar um -``InvalidArgumentException``:: - - $parser->addOption('accept', [ - 'help' => 'What version to accept.', - 'choices' => ['working', 'theirs', 'mine'] - ]); - -Usando opções boleanas ----------------------- - -As opções podem ser definidas como opções boleanas, que são úteis quando você -precisa criar algumas opções de marcação. Como opções com padrões, opções -boleanas sempre irão incluir -se nos parâmetros analisados. Quando as marcações -estão presentes elas são definidas para ``true``, quando elas estão ausentes, -são definidas como ``false``:: - - $parser->addOption('verbose', [ - 'help' => 'Enable verbose output.', - 'boolean' => true - ]); - -A opção seguinte resultaria em ``$this->params['verbose']`` sempre -estando disponível. Isso permite a você omitir verificações ``empty()`` ou -``isset()`` em marcações boleanas:: - - if ($this->params['verbose']) { - // Do something. - } - -Desde que as opções boleanas estejam sempre definidas como ``true`` ou -``false``, você pode omitir métodos de verificação adicionais. - -Adicionando subcomandos ------------------------ - -.. php:method:: addSubcommand($name, $options = []) - -Aplicativos de console são muitas vezes feitas de subcomandos, e esses -subcomandos podem exigir a análise de opções especiais e terem a sua própria -ajuda. Um perfeito exemplo disso é ``bake``. Bake é feita de muitas tarefas -separadas e todas têm a sua própria ajuda e opções. ``ConsoleOptionParser`` -permite definir subcomandos e fornecer comandos analisadores de opção -específica, de modo que a shell sabe como analisar os comandos para as suas -funções:: - - $parser->addSubcommand('model', [ - 'help' => 'Bake a model', - 'parser' => $this->Model->getOptionParser() - ]); - -A descrição acima é um exemplo de como você poderia fornecer ajuda e um -especializado interpretador de opção para a tarefa de uma shell. Ao chamar a -tarefa de ``getOptionParser()`` não temos de duplicar a geração do interpretador -de opção, ou misturar preocupações no nosso shell. Adicionar subcomandos desta -forma tem duas vantagens. Primeiro, ele permite que o seu shell documente -facilmente seus subcomandos na ajuda gerada. Ele também dá fácil acesso ao -subcomando help. Com o subcomando acima criado você poderia chamar -``cake myshell --help`` e ver a lista de subcomandos, e -também executar o ``cake myshell model --help`` para exibir a ajuda -apenas o modelo de tarefa. - -.. note:: - - Uma vez que seu Shell define subcomandos, todos os subcomandos deve ser - explicitamente definidos. - -Ao definir um subcomando, você pode usar as seguintes opções: - -* ``help`` - Texto de ajuda para o subcomando. -* ``parser`` - Um ConsoleOptionParser para o subcomando. Isso permite que você - crie métodos analisadores de opção específios. Quando a ajuda é gerada por um - subcomando, se um analisador está presente ele vai ser usado. Você também - pode fornecer o analisador como uma matriz que seja compatível com - :php:meth:`Cake\\Console\\ConsoleOptionParser::buildFromArray()` - -Adicionar subcomandos pode ser feito como parte de uma cadeia de métodos -fluente. - -Construir uma ConsoleOptionParser de uma matriz ------------------------------------------------ - -.. php:method:: buildFromArray($spec) - -Como mencionado anteriormente, ao criar interpretadores de opção de subcomando, -você pode definir a especificação interpretadora como uma matriz para esse -método. Isso pode ajudar fazer analisadores mais facilmente, já que tudo é um -array:: - - $parser->addSubcommand('check', [ - 'help' => __('Check the permissions between an ACO and ARO.'), - 'parser' => [ - 'description' => [ - __("Use this command to grant ACL permissions. Once executed, the "), - __("ARO specified (and its children, if any) will have ALLOW access "), - __("to the specified ACO action (and the ACO's children, if any).") - ], - 'arguments' => [ - 'aro' => ['help' => __('ARO to check.'), 'required' => true], - 'aco' => ['help' => __('ACO to check.'), 'required' => true], - 'action' => ['help' => __('Action to check')] - ] - ] - ]); - -Dentro da especificação do interpretador, você pode definir as chaves para -``arguments``, ``options``, ``description`` e ``epilog``. Você não pode definir -``subcommands`` dentro de um construtor estilo array. Os valores para os -argumentos e opções, devem seguir o formato que -:php:func:`Cake\\Console\\ConsoleOptionParser::addArguments()` e -:php:func:`Cake\\Console\\ConsoleOptionParser::addOptions()` usam. Você também -pode usar buildFromArray por conta própria, para construir um interpretador de -opção:: - - public function getOptionParser() - { - return ConsoleOptionParser::buildFromArray([ - 'description' => [ - __("Use this command to grant ACL permissions. Once executed, the "), - __("ARO specified (and its children, if any) will have ALLOW access "), - __("to the specified ACO action (and the ACO's children, if any).") - ], - 'arguments' => [ - 'aro' => ['help' => __('ARO to check.'), 'required' => true], - 'aco' => ['help' => __('ACO to check.'), 'required' => true], - 'action' => ['help' => __('Action to check')] - ] - ]); - } - -Recebendo ajuda das Shells --------------------------- - -Com a adição de ConsoleOptionParser receber ajuda de shells é feito -de uma forma consistente e uniforme. Ao usar a opção ``--help`` ou ``-h`` você -pode visualizar a ajuda para qualquer núcleo shell, e qualquer shell que -implementa um ConsoleOptionParser:: - - cake bake --help - cake bake -h - -Ambos devem gerar a ajuda para o bake. Se o shell suporta subcomandos -você pode obter ajuda para estes de uma forma semelhante:: - - cake bake model --help - cake bake model -h - -Isso deve fornecer a você a ajuda específica para a tarefa bake dos models. - -Recebendo ajuda como XML ------------------------- - -Quando a construção de ferramentas automatizadas ou ferramentas de -desenvolvimento que necessitam interagir com shells do CakePHP, é bom ter ajuda -disponível em uma máquina capaz interpretar formatos. O ConsoleOptionParser pode -fornecer ajuda em xml, definindo um argumento adicional:: - - cake bake --help xml - cake bake -h xml - -O trecho acima deve retornar um documento XML com a ajuda gerada, opções, -argumentos e subcomando para o shell selecionado. Um documento XML de amostra -seria algo como: - -.. code-block:: xml - - - - bake fixture - Generate fixtures for use with the test suite. You can use - `bake fixture all` to bake all fixtures. - - Omitting all arguments and options will enter into an interactive - mode. - - - - - - - - - - - - - - - - - - -Roteamento em Shells / CLI -========================== - -Na interface de linha de comando (CLI), especificamente suas shells e tarefas, -``env('HTTP_HOST')`` e outras variáveis de ambiente webbrowser específica, não -estão definidas. - -Se você gerar relatórios ou enviar e-mails que fazem uso de ``Router::url()``, -estes conterão a máquina padrão ``http://localhost/`` e resultando assim em -URLs inválidas. Neste caso, você precisa especificar o domínio manualmente. -Você pode fazer isso usando o valor de configuração ``App.fullBaseUrl`` no seu -bootstrap ou na sua configuração, por exemplo. - -Para enviar e-mails, você deve fornecer a classe CakeEmail com o host que você -deseja enviar o e-mail:: - - $Email = new CakeEmail(); - $Email->domain('www.example.org'); - -Iste afirma que os IDs de mensagens geradas são válidos e adequados para o -domínio a partir do qual os e-mails são enviados. - -Métodos enganchados -=================== - -.. php:method:: initialize() - - Inicializa a Shell para atua como construtor de subclasses e permite - configuração de tarefas antes de desenvolver a execução. - -.. php:method:: startup() - - Inicia-se a Shell e exibe a mensagem de boas-vindas. Permite a verificação - e configuração antes de comandar ou da execução principal. - - Substitua este método se você quiser remover as informações de boas-vindas, - ou outra forma modificar o fluxo de pré-comando. - -Mais tópicos -============ - -.. toctree:: - :maxdepth: 1 - - console-and-shells/helpers - console-and-shells/repl - console-and-shells/cron-jobs - console-and-shells/i18n-shell - console-and-shells/completion-shell - console-and-shells/plugin-shell - console-and-shells/routes-shell - console-and-shells/server-shell - console-and-shells/cache - -.. meta:: - :title lang=pt: Console e Shells - :keywords lang=pt: shell scripts,system shell,classes de aplicação,tarefas background,line script,cron job,request response,system path,acl,novos projetos,shells,parametros,i18n,cakephp,directory,manutenção,ideal,aplicações,mvc diff --git a/pt/console-and-shells/cache.rst b/pt/console-and-shells/cache.rst deleted file mode 100644 index fa0dbbfe56..0000000000 --- a/pt/console-and-shells/cache.rst +++ /dev/null @@ -1,11 +0,0 @@ -Cache Shell -=========== - -Para ajudá-lo a gerenciar melhor os dados armazenados em cache a partir de um ambiente CLI, um comando shell está disponível -para limpar os dados em cache que seu aplicativo possui:: - - // Limpar uma configuração de cache - bin/cake cache clear - - // Limpar todas as configurações de cache - bin/cake cache clear_all diff --git a/pt/console-and-shells/completion-shell.rst b/pt/console-and-shells/completion-shell.rst deleted file mode 100644 index dd2df27659..0000000000 --- a/pt/console-and-shells/completion-shell.rst +++ /dev/null @@ -1,12 +0,0 @@ -Completion Shell -################ - -.. note:: - Atualmente, a documentação desta página não é suportada em português. - - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. - - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. \ No newline at end of file diff --git a/pt/console-and-shells/cron-jobs.rst b/pt/console-and-shells/cron-jobs.rst deleted file mode 100644 index 6bfddc7f86..0000000000 --- a/pt/console-and-shells/cron-jobs.rst +++ /dev/null @@ -1,27 +0,0 @@ -Executando Shells como Cron Jobs -################################ - -Uma coisa comum a fazer com um shell é torná-lo executado como um cronjob para limpar o banco de dados de vez em quando ou -enviar newsletters. Isso é trivial para configurar, por exemplo:: - - */5 * * * * cd /full/path/to/root && bin/cake myshell myparam - # * * * * * comando para executar - # │ │ │ │ │ - # │ │ │ │ │ - # │ │ │ │ \───── day of week (0 - 6) (0 a 6 são de domingo a sábado, ou use os nomes) -   # │   │   │   \────────── mês (1 - 12) -   # │   │   \─────────────── dia do mês (1 - 31) - # │ \──────────────────── hora (0 - 23) - # \───────────────────────── minuto (0 - 59) - -Você pode ver mais informações aqui: https://pt.wikipedia.org/wiki/Crontab - -.. tip:: - - Use ``-q`` (ou `--quiet`) para silenciar qualquer saída para cronjobs. - -.. meta:: - - :Title lang=pt: Executando Shells como cronjobs - :keywords lang=pt: crontab, script bash, crontab - diff --git a/pt/console-and-shells/helpers.rst b/pt/console-and-shells/helpers.rst deleted file mode 100644 index 57a41379ea..0000000000 --- a/pt/console-and-shells/helpers.rst +++ /dev/null @@ -1,12 +0,0 @@ -Shell Helpers -############# - -.. note:: - Atualmente, a documentação desta página não é suportada em português. - - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. - - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. diff --git a/pt/console-and-shells/i18n-shell.rst b/pt/console-and-shells/i18n-shell.rst deleted file mode 100644 index 4b1b80b8fa..0000000000 --- a/pt/console-and-shells/i18n-shell.rst +++ /dev/null @@ -1,12 +0,0 @@ -I18N Shell -########## - -.. note:: - Atualmente, a documentação desta página não é suportada em português. - - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. - - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. \ No newline at end of file diff --git a/pt/console-and-shells/orm-cache.rst b/pt/console-and-shells/orm-cache.rst deleted file mode 100644 index 04fb6b15e7..0000000000 --- a/pt/console-and-shells/orm-cache.rst +++ /dev/null @@ -1,22 +0,0 @@ -ORM Cache Shell -############### - -O OrmCacheShell fornece uma ferramenta CLI simples para gerenciar caches de metadados da sua aplicação. Em situações de -implantação, é útil reconstruir o cache de metadados no local sem limpar os dados de cache existentes. Você pode fazer isso -executando:: - - bin/cake orm_cache build --connection default - -Isso irá reconstruir o cache de metadados para todas as tabelas na conexão ``default``. Se você só precisa reconstruir uma -única tabela, você pode fazer isso fornecendo seu nome:: - - bin/cake orm_cache build --connection default <> - -Além de criar dados em cache, você pode usar o OrmCacheShell para remover metadados em cache também:: - - # Limpar todos os metadados - bin/cake orm_cache clear - - # Limpar uma única tabela de metadados - bin/cake orm_cache clear <> - diff --git a/pt/console-and-shells/plugin-shell.rst b/pt/console-and-shells/plugin-shell.rst deleted file mode 100644 index c180b8307b..0000000000 --- a/pt/console-and-shells/plugin-shell.rst +++ /dev/null @@ -1,18 +0,0 @@ -.. _plugin-shell: - -Plugin Shell -############ - -.. note:: - Atualmente, a documentação desta página não é suportada em português. - - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. - - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. - -.. meta:: - :title lang=pt: Plugin Shell - :keywords lang=pt: api docs,shell,plugin,load,unload diff --git a/pt/console-and-shells/repl.rst b/pt/console-and-shells/repl.rst deleted file mode 100644 index 402bba12b0..0000000000 --- a/pt/console-and-shells/repl.rst +++ /dev/null @@ -1,12 +0,0 @@ -Console Interativo (REPL) -######################### - -.. note:: - Atualmente, a documentação desta página não é suportada em português. - - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. - - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. \ No newline at end of file diff --git a/pt/console-and-shells/routes-shell.rst b/pt/console-and-shells/routes-shell.rst deleted file mode 100644 index 9ee380bc0e..0000000000 --- a/pt/console-and-shells/routes-shell.rst +++ /dev/null @@ -1,12 +0,0 @@ -Routes Shell -############ - -.. note:: - Atualmente, a documentação desta página não é suportada em português. - - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. - - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. diff --git a/pt/console-and-shells/server-shell.rst b/pt/console-and-shells/server-shell.rst deleted file mode 100644 index 7d772f9318..0000000000 --- a/pt/console-and-shells/server-shell.rst +++ /dev/null @@ -1,12 +0,0 @@ -Server Shell -############ - -.. note:: - Atualmente, a documentação desta página não é suportada em português. - - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. - - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. diff --git a/pt/console-commands.rst b/pt/console-commands.rst new file mode 100644 index 0000000000..b48add1941 --- /dev/null +++ b/pt/console-commands.rst @@ -0,0 +1,183 @@ +Console Commands +################ + +.. php:namespace:: Cake\Console + +Além de um framework web, o CakePHP também fornece um framework de console para +criar ferramentas e aplicações de linha de comando. Aplicações de console são ideais para +lidar com uma variedade de tarefas de background e manutenção que aproveitam sua +configuração de aplicação, models, plugins e lógica de domínio existentes. + +O CakePHP fornece várias ferramentas de console para interagir com recursos do CakePHP +como i18n e roteamento que permitem introspectar sua aplicação e +gerar arquivos relacionados. + +O Console do CakePHP +==================== + +O Console do CakePHP usa um sistema tipo dispatcher para carregar comandos, analisar +seus argumentos e invocar o comando correto. Embora os exemplos abaixo usem +bash, o console do CakePHP é compatível com qualquer shell \*nix e windows. + +Uma aplicação CakePHP contém o diretório **src/Command** que contém seus comandos. +Ela também vem com um executável no diretório **bin**: + +.. code-block:: console + + $ cd /path/to/app + $ bin/cake + +.. note:: + + Para Windows, o comando precisa ser ``bin\cake`` (observe a barra invertida). + +Executar o Console sem argumentos listará os comandos disponíveis. Você +pode então executar qualquer um dos comandos listados usando seu nome: + +.. code-block:: console + + # executar comando server + bin/cake server + + # executar comando migrations + bin/cake migrations -h + + # executar bake (com prefixo de plugin) + bin/cake bake.bake -h + +Comandos de plugin podem ser invocados sem um prefixo de plugin se o nome do comando +não sobrepõe um comando da aplicação ou do framework. No caso de dois +plugins fornecerem um comando com o mesmo nome, o primeiro plugin carregado terá +o alias curto. Você sempre pode usar o formato ``plugin.command`` para +referenciar inequivocamente um comando. + +Aplicações de Console +====================== + +Por padrão, o CakePHP descobrirá automaticamente todos os comandos em sua +aplicação e seus plugins. Você pode querer reduzir o número de comandos expostos +ao construir aplicações de console standalone. Você pode usar o hook ``console()`` +da sua ``Application`` para limitar quais comandos são expostos e +renomear comandos que são expostos:: + + // em src/Application.php + namespace App; + + use App\Command\UserCommand; + use App\Command\VersionCommand; + use Cake\Console\CommandCollection; + use Cake\Http\BaseApplication; + + class Application extends BaseApplication + { + public function console(CommandCollection $commands): CommandCollection + { + // Adicionar por nome de classe + $commands->add('user', UserCommand::class); + + // Adicionar instância + $commands->add('version', new VersionCommand()); + + return $commands; + } + } + +No exemplo acima, os únicos comandos disponíveis seriam ``help``, ``version`` +e ``user``. Veja a seção :ref:`plugin-commands` para saber como adicionar comandos em +seus plugins. + +.. note:: + + Ao adicionar múltiplos comandos que usam a mesma classe Command, o comando ``help`` + exibirá a opção mais curta. + +.. _renaming-commands: +.. index:: nested commands, subcommands + +Renomeando Comandos +=================== + +Há casos em que você desejará renomear comandos, para criar comandos aninhados +ou subcomandos. Embora a descoberta automática padrão de comandos não faça +isso, você pode registrar seus comandos para criar qualquer nomenclatura desejada. + +Você pode personalizar os nomes dos comandos definindo cada comando em seu plugin:: + + public function console(CommandCollection $commands): CommandCollection + { + // Adicionar comandos com nomenclatura aninhada + $commands->add('user dump', UserDumpCommand::class); + $commands->add('user:show', UserShowCommand::class); + + // Renomear um comando completamente + $commands->add('lazer', UserDeleteCommand::class); + + return $commands; + } + +Ao sobrescrever o hook ``console()`` em sua aplicação, lembre-se de +chamar ``$commands->autoDiscover()`` para adicionar comandos do CakePHP, sua +aplicação e plugins. + +Se você precisar renomear/remover quaisquer comandos anexados, você pode usar o +evento ``Console.buildCommands`` no gerenciador de eventos da sua aplicação para modificar os +comandos disponíveis. + +Commands +======== + +Veja o capítulo :doc:`/console-commands/commands` sobre como criar seu primeiro +comando. Então aprenda mais sobre comandos: + +.. toctree:: + :maxdepth: 1 + + console-commands/commands + console-commands/input-output + console-commands/option-parsers + console-commands/cron-jobs + +Comandos Fornecidos pelo CakePHP +================================= + +.. toctree:: + :maxdepth: 1 + + console-commands/cache + console-commands/completion + console-commands/counter-cache + console-commands/i18n + console-commands/plugin + console-commands/schema-cache + console-commands/routes + console-commands/server + console-commands/repl + +Roteamento no Ambiente de Console +================================== + +Na interface de linha de comando (CLI), especificamente seus comandos de console, +``env('HTTP_HOST')`` e outras variáveis de ambiente específicas do navegador web não são +definidas. + +Se você gerar relatórios ou enviar e-mails que façam uso de ``Router::url()``, eles +conterão o host padrão ``http://localhost/`` e, portanto, resultarão em +URLs inválidas. Neste caso, você precisa especificar o domínio manualmente. +Você pode fazer isso usando o valor Configure ``App.fullBaseUrl`` do seu +bootstrap ou config, por exemplo. + +Para enviar e-mails, você deve fornecer à classe Email o host que deseja usar para +enviar o e-mail:: + + use Cake\Mailer\Email; + + $email = new Email(); + $email->setDomain('www.example.org'); + +Isso garante que os IDs de mensagem gerados são válidos e se ajustam ao domínio +de onde os e-mails são enviados. + + +.. meta:: + :title lang=pt: Shells, Tasks & Console Tools + :keywords lang=pt: shell scripts,system shell,application classes,background tasks,line script,cron job,request response,system path,acl,new projects,commands,specifics,parameters,i18n,cakephp,directory,maintenance,ideal,applications,mvc diff --git a/pt/console-commands/cache.rst b/pt/console-commands/cache.rst new file mode 100644 index 0000000000..ce307f163e --- /dev/null +++ b/pt/console-commands/cache.rst @@ -0,0 +1,14 @@ +Ferramenta de Cache +################### + +Para ajudá-lo a gerenciar melhor os dados armazenados em cache de um ambiente CLI, um comando de console +está disponível para limpar os dados armazenados em cache do seu aplicativo:: + + // Limpar uma configuração de cache + bin/cake cache clear + + // Limpar todas as configurações de cache + bin/cake cache clear_all + + // Limpar um grupo de cache + bin/cake cache clear_group diff --git a/pt/console-commands/commands.rst b/pt/console-commands/commands.rst new file mode 100644 index 0000000000..4f7321966b --- /dev/null +++ b/pt/console-commands/commands.rst @@ -0,0 +1,573 @@ +Objetos de Comando +################## + +.. php:namespace:: Cake\Console +.. php:class:: Command + +O CakePHP vem com uma série de comandos integrados para acelerar seu +desenvolvimento e automatizar tarefas rotineiras. Você pode usar essas mesmas bibliotecas para +criar comandos para sua aplicação e plugins. + +Criando um Comando +================== + +Vamos criar nosso primeiro Comando. Para este exemplo, criaremos um +comando simples "Olá, mundo". No diretório **src/Command** do seu aplicativo, crie +**HelloCommand.php**. Insira o seguinte código dentro dele:: + + out('Olá, mundo.'); + + return static::CODE_SUCCESS; + } + } + +As classes de comando devem implementar um método ``execute()`` que realiza a maior parte +do seu trabalho. Este método é chamado quando um comando é invocado. Vamos chamar nosso primeiro +diretório de aplicativo de comando, execute: + +.. code-block:: console + + bin/cake hello + +Você deverá ver a seguinte saída:: + + Olá, mundo. + +Nosso método ``execute()`` não é muito interessante, vamos ler algumas entradas da +linha de comando:: + + addArgument('name', [ + 'help' => 'What is your name', + ]); + + return $parser; + } + + public function execute(Arguments $args, ConsoleIo $io): int + { + $name = $args->getArgument('name'); + $io->out("Hello {$name}."); + + return static::CODE_SUCCESS; + } + } + + +Depois de salvar este arquivo, você poderá executar o seguinte comando: + +.. code-block:: console + + bin/cake hello jillian + + # Outputs + Hello jillian + +Alterando o Nome do Comando Padrão +================================== + +O CakePHP usará convenções para gerar o nome que seus comandos usarão na +linha de comando. Se você quiser sobrescrever o nome gerado, implemente o método +``defaultName()`` no seu comando:: + + public static function defaultName(): string + { + return 'oh_hi'; + } + +O comando acima tornaria nosso ``HelloCommand`` acessível por ``cake oh_hi`` em vez de ``cake hello``. + +Definindo Argumentos e Opções +============================= + +Como vimos no último exemplo, podemos usar o método de gancho ``buildOptionParser()`` +para definir argumentos. Também podemos definir opções. Por exemplo, poderíamos +adicionar uma opção ``yell`` ao nosso ``HelloCommand``:: + + // ... + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + { + $parser + ->addArgument('name', [ + 'help' => 'What is your name', + ]) + ->addOption('yell', [ + 'help' => 'Shout the name', + 'boolean' => true, + ]); + + return $parser; + } + + public function execute(Arguments $args, ConsoleIo $io): int + { + $name = $args->getArgument('name'); + if ($args->getOption('yell')) { + $name = mb_strtoupper($name); + } + $io->out("Hello {$name}."); + + return static::CODE_SUCCESS; + } + +Veja a seção :doc:`/console-commands/option-parsers` para mais informações. + +Criando saída +============= + +Os comandos recebem uma instância ``ConsoleIo`` quando executados. Este objeto permite +que você interaja com ``stdout``, ``stderr`` e crie arquivos. Consulte a seção +:doc:`/console-commands/input-output` para obter mais informações. + +Usando Modelos em Comandos +========================== + +Frequentemente, você precisará acessar a lógica de negócios do seu aplicativo em comandos +de console. Você pode carregar modelos em comandos, assim como faria em um controller +usando ``$this->fetchTable()``, já que o comando usa o ``LocatorAwareTrait``:: + + addArgument('name', [ + 'help' => 'Qual o seu nome' + ]); + + return $parser; + } + + public function execute(Arguments $args, ConsoleIo $io): int + { + $name = $args->getArgument('name'); + $user = $this->fetchTable()->findByUsername($name)->first(); + + $io->out(print_r($user, true)); + + return static::CODE_SUCCESS; + } + } + +O comando acima buscará um usuário pelo nome de usuário e exibirá as informações +armazenadas no banco de dados. + +Códigos de Saída e Interrupção da Execução +========================================== + +Quando seus comandos apresentam um erro irrecuperável, você pode usar o método ``abort()`` +para encerrar a execução:: + + // ... + public function execute(Arguments $args, ConsoleIo $io): int + { + $name = $args->getArgument('name'); + if (strlen($name) < 5) { + // Interrompa a execução, envie para stderr e defina o código de saída como 1 + $io->error('O nome deve ter pelo menos 4 caracteres.'); + $this->abort(); + } + + return static::CODE_SUCCESS; + } + +Você também pode usar ``abort()`` no objeto ``$io`` para emitir uma mensagem e código:: + + public function execute(Arguments $args, ConsoleIo $io): int + { + $name = $args->getArgument('name'); + if (strlen($name) < 5) { + // Interrompa a execução, envie para stderr e defina o código de saída como 99 + $io->abort('O nome deve ter pelo menos 4 caracteres.', 99); + } + + return static::CODE_SUCCESS; + } + +Você pode passar qualquer código de saída desejado para ``abort()``. + +.. tip:: + + Evite os códigos de saída 64 a 78, pois eles têm significados específicos descritos por + ``sysexits.h``. Evite códigos de saída acima de 127, pois eles são usados ​​para indicar + a saída do processo por sinal, como SIGKILL ou SIGSEGV. + + Você pode ler mais sobre códigos de saída convencionais na página do manual do sysexit + na maioria dos sistemas Unix (``man sysexits``) ou na página de ajuda ``Códigos de Erro do Sistema`` + no Windows. + +Chamando Outros Comandos +======================== + +Você pode precisar chamar outros comandos a partir do seu comando. Você pode usar +``executeCommand`` para fazer isso:: + + // Você pode passar uma série de opções e argumentos da CLI. + $this->executeCommand(OtherCommand::class, ['--verbose', 'deploy']); + + // Pode passar uma instância do comando se ele tiver argumentos de construtor + $command = new OtherCommand($otherArgs); + $this->executeCommand($command, ['--verbose', 'deploy']); + +.. note:: + + Ao chamar ``executeCommand()`` em um loop, é recomendável passar a instância ``ConsoleIo`` + do comando pai como o terceiro argumento opcional para + evitar um potencial limite de "arquivos abertos" que pode ocorrer em alguns ambientes. + +Descrição do Comando de Configuração +==================================== + +Você pode querer definir uma descrição de comando via:: + + class UserCommand extends Command + { + public static function getDescription(): string + { + return 'Minha descrição personalizada'; + } + } + +Isso mostrará sua descrição no Cake CLI: + +.. code-block:: console + + bin/cake + + App: + - user + └─── Minha descrição personalizada + +Bem como na seção de ajuda do seu comando: + +.. code-block:: console + + cake user --help + Minha descrição personalizada + + Usage: + cake user [-h] [-q] [-v] + +.. _console-integration-testing: + +Comandos de Teste +================= + +Para facilitar o teste de aplicações de console, o CakePHP vem com um trait +``ConsoleIntegrationTestTrait`` que pode ser usado para testar aplicações de console +e validar seus resultados. + +Para começar a testar sua aplicação de console, crie um caso de teste que use o trait +``Cake\TestSuite\ConsoleIntegrationTestTrait``. Este trait contém um método +``exec()`` que é usado para executar seu comando. Você pode passar a mesma string +que usaria na CLI para este método. + +Vamos começar com um comando bem simples, localizado em +**src/Command/UpdateTableCommand.php**:: + + namespace App\Command; + + use Cake\Command\Command; + use Cake\Console\Arguments; + use Cake\Console\ConsoleIo; + use Cake\Console\ConsoleOptionParser; + + class UpdateTableCommand extends Command + { + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + { + $parser->setDescription('Meu aplicativo legal de console'); + + return $parser; + } + } + +Para escrever um teste de integração para este comando, criaríamos um caso de teste em +**tests/TestCase/Command/UpdateTableTest.php** que usa a trait +``Cake\TestSuite\ConsoleIntegrationTestTrait``. Este comando não faz muita coisa no +momento, mas vamos apenas testar se a descrição do nosso comando é exibida em ``stdout``:: + + namespace App\Test\TestCase\Command; + + use Cake\TestSuite\ConsoleIntegrationTestTrait; + use Cake\TestSuite\TestCase; + + class UpdateTableCommandTest extends TestCase + { + use ConsoleIntegrationTestTrait; + + public function testDescriptionOutput() + { + $this->exec('update_table --help'); + $this->assertOutputContains('Meu aplicativo legal de console'); + } + } + +Nosso teste passou! Embora este seja um exemplo bastante trivial, ele mostra que a criação de um +caso de teste de integração para aplicativos de console pode seguir as convenções +da linha de comando. Vamos continuar adicionando mais lógica ao nosso comando:: + + namespace App\Command; + + use Cake\Command\Command; + use Cake\Console\Arguments; + use Cake\Console\ConsoleIo; + use Cake\Console\ConsoleOptionParser; + use Cake\I18n\DateTime; + + class UpdateTableCommand extends Command + { + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + { + $parser + ->setDescription('Meu aplicativo legal de console') + ->addArgument('table', [ + 'help' => 'Tabela para atualizar', + 'required' => true + ]); + + return $parser; + } + + public function execute(Arguments $args, ConsoleIo $io): int + { + $table = $args->getArgument('table'); + $this->fetchTable($table)->updateQuery() + ->set([ + 'modified' => new DateTime() + ]) + ->execute(); + + return static::CODE_SUCCESS; + } + } + +Este é um comando mais completo que possui as opções necessárias e a lógica relevante. +Modifique seu caso de teste para o seguinte trecho de código:: + + namespace Cake\Test\TestCase\Command; + + use Cake\Command\Command; + use Cake\I18n\DateTime; + use Cake\TestSuite\ConsoleIntegrationTestTrait; + use Cake\TestSuite\TestCase; + + class UpdateTableCommandTest extends TestCase + { + use ConsoleIntegrationTestTrait; + + protected $fixtures = [ + // assume que você tem um UsersFixture + 'app.Users', + ]; + + public function testDescriptionOutput() + { + $this->exec('update_table --help'); + $this->assertOutputContains('Meu aplicativo legal de console'); + } + + public function testUpdateModified() + { + $now = new DateTime('2017-01-01 00:00:00'); + DateTime::setTestNow($now); + + $this->loadFixtures('Users'); + + $this->exec('update_table Users'); + $this->assertExitCode(Command::CODE_SUCCESS); + + $user = $this->getTableLocator()->get('Users')->get(1); + $this->assertSame($user->modified->timestamp, $now->timestamp); + + DateTime::setTestNow(null); + } + } + +Como você pode ver no método ``testUpdateModified``, estamos testando se nosso +comando atualiza a tabela que estamos passando como primeiro argumento. Primeiro, +afirmamos que o comando saiu com o código de status correto, ``0``. Em seguida, verificamos +se nosso comando fez seu trabalho, ou seja, atualizou a tabela que fornecemos e definiu +a coluna ``modified`` para a hora atual. + +Lembre-se de que ``exec()`` receberá a mesma string que você digitar na sua CLI, para que você +possa incluir opções e argumentos na sua string de comando. + +Testando Comandos Interativos +----------------------------- + +Consoles costumam ser interativos. Testar comandos interativos com a característica +``Cake\TestSuite\ConsoleIntegrationTestTrait`` requer apenas a passagem das +entradas esperadas como o segundo parâmetro de ``exec()``. Elas devem ser +incluídas como um array na ordem em que você as espera. + +Continuando com nosso comando de exemplo, vamos adicionar uma confirmação interativa. +Atualize a classe de comando para o seguinte:: + + namespace App\Command; + + use Cake\Command\Command; + use Cake\Console\Arguments; + use Cake\Console\ConsoleIo; + use Cake\Console\ConsoleOptionParser; + use Cake\I18n\DateTime; + + class UpdateTableCommand extends Command + { + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + { + $parser + ->setDescription('Meu aplicativo legal de console') + ->addArgument('table', [ + 'help' => 'Tabela para atualizar', + 'required' => true + ]); + + return $parser; + } + + public function execute(Arguments $args, ConsoleIo $io): int + { + $table = $args->getArgument('table'); + if ($io->ask('Tem certeza?', 'n', ['y', 'n']) !== 'y') { + $io->error('Você precisa ter certeza.'); + $this->abort(); + } + $this->fetchTable($table)->updateQuery() + ->set([ + 'modified' => new DateTime() + ]) + ->execute(); + + return static::CODE_SUCCESS; + } + } + +Agora que temos um comando interativo, podemos adicionar um caso de teste que testa +se recebemos a resposta correta e outro que testa se recebemos uma +resposta incorreta. Remova o método ``testUpdateModified`` e adicione os seguintes métodos a +**tests/TestCase/Command/UpdateTableCommandTest.php**:: + + + public function testUpdateModifiedSure() + { + $now = new DateTime('2017-01-01 00:00:00'); + DateTime::setTestNow($now); + + $this->loadFixtures('Users'); + + $this->exec('update_table Users', ['y']); + $this->assertExitCode(Command::CODE_SUCCESS); + + $user = $this->getTableLocator()->get('Users')->get(1); + $this->assertSame($user->modified->timestamp, $now->timestamp); + + DateTime::setTestNow(null); + } + + public function testUpdateModifiedUnsure() + { + $user = $this->getTableLocator()->get('Users')->get(1); + $original = $user->modified->timestamp; + + $this->exec('my_console best_framework', ['n']); + $this->assertExitCode(Command::CODE_ERROR); + $this->assertErrorContains('You need to be sure.'); + + $user = $this->getTableLocator()->get('Users')->get(1); + $this->assertSame($original, $user->timestamp); + } + +No primeiro caso de teste, confirmamos a pergunta e os registros são atualizados. No +segundo teste, não confirmamos e os registros não são atualizados, e podemos verificar se +nossa mensagem de erro foi escrita em ``stderr``. + +Métodos de Asserção +------------------- + +O atributo ``Cake\TestSuite\ConsoleIntegrationTestTrait`` fornece uma série de +métodos de asserção que ajudam a fazer a asserção na saída do console:: + + // afirmar que o comando saiu como sucesso + $this->assertExitSuccess(); + + // afirmar que o comando saiu como um erro + $this->assertExitError(); + + // afirmar que o comando saiu com o código esperado + $this->assertExitCode($expected); + + // afirmar que stdout contém uma string + $this->assertOutputContains($expected); + + // afirmar que stderr contém uma string + $this->assertErrorContains($expected); + + // afirmar que stdout corresponde a uma expressão regular + $this->assertOutputRegExp($expected); + + // afirmar que stderr corresponde a uma expressão regular + $this->assertErrorRegExp($expected); + +Debug Helpers +------------- + +Você pode usar ``debugOutput()`` para gerar o código de saída, stdout e stderr do +último comando executado:: + + $this->exec('update_table Users'); + $this->assertExitCode(Command::CODE_SUCCESS); + $this->debugOutput(); + +.. versionadded:: 4.2.0 + O método ``debugOutput()`` foi adicionado. + + +Retornos de Ciclo de Vida +========================= + +Assim como os Controllers, os Comandos oferecem eventos de ciclo de vida que permitem observar +o framework chamando o código da sua aplicação. Os Comandos possuem: + +- ``Command.beforeExecute`` É chamado antes do método ``execute()`` de um comando. + O evento recebe o parâmetro ``ConsoleArguments`` como ``args``. Este + evento não pode ser interrompido ou ter seu resultado substituído. +- ``Command.afterExecute`` É chamado após o método ``execute()`` de um comando ser + concluído. O evento contém ``ConsoleArguments`` como ``args`` e o resultado + do comando como ``result``. Este evento não pode ser interrompido ou ter seu resultado + substituído. diff --git a/pt/console-commands/completion.rst b/pt/console-commands/completion.rst new file mode 100644 index 0000000000..e95b6e08a6 --- /dev/null +++ b/pt/console-commands/completion.rst @@ -0,0 +1,187 @@ +Ferramenta de Conclusão +####################### + +Trabalhar com o console oferece muitas possibilidades ao desenvolvedor, mas ter +que conhecer e escrever completamente esses comandos pode ser tedioso. Especialmente ao +desenvolver novos shells, onde os comandos diferem a cada minuto de iteração. Os +Shells de Conclusão auxiliam nessa questão, fornecendo uma API para escrever scripts de conclusão +para shells como bash, zsh, fish etc. + +Sub Comandos +============ + +O Shell de Conclusão consiste em vários subcomandos para auxiliar o +desenvolvedor na criação do seu script de conclusão. Cada um para uma etapa diferente no +processo de conclusão automática. + +Comandos +-------- + +Para o primeiro passo, os comandos geram os Comandos Shell disponíveis, incluindo +o nome do plugin, quando aplicável. (Todas as possibilidades retornadas, para este e os outros +subcomandos, são separadas por um espaço.) Por exemplo:: + + bin/cake Completion commands + +Returns:: + + acl api bake command_list conclusão console i18n esquema servidor teste suíte de testes atualização + +Seu script de conclusão pode selecionar os comandos relevantes dessa lista para +continuar. (Para este e os subcomandos seguintes.) + +subComandos +----------- + +Uma vez escolhido o comando preferido, o comando subComandos entra como a segunda +etapa e gera o possível subcomando para o comando shell fornecido. Por +exemplo:: + + bin/cake Completion subcommands bake + +Returns:: + + controller db_config modelo de fixação plugin projeto teste visualização + +opções +------ + +Como a terceira e última opção, são geradas opções para o (sub)comando fornecido, conforme +definido em getOptionParser. (Incluindo as opções padrão herdadas do Shell.) +Por exemplo:: + + bin/cake Completion options bake + +Returns:: + + --help -h --verbose -v --quiet -q --everything --connection -c --force -f --plugin -p --prefix --theme -t + +Você também pode passar um argumento adicional, que é o subcomando do shell: ele irá +exibir as opções específicas deste subcomando. + +Como Habilitar o Preenchimento Automático do Bash para o Console CakePHP +======================================================================== + +Primeiro, certifique-se de que a biblioteca **bash-completion** esteja instalada. Caso contrário, faça isso +com o seguinte comando:: + + apt-get install bash-completion + +Crie um arquivo chamado **cake** em **/etc/bash_completion.d/** e insira o +:ref:`bash-completion-file-content` dentro dele. + +Salve o arquivo e reinicie o console. + +.. note:: + + Se estiver usando o MacOS X, você pode instalar a biblioteca **bash-completion** + usando o **homebrew** com o comando ``brew install bash-completion``. + O diretório de destino para o arquivo **cake** será + **/usr/local/etc/bash_completion.d/**. + +.. _bash-completion-file-content: + +Conteúdo do arquivo Bash Conclusão +---------------------------------- + +Este é o código que você precisa inserir dentro do arquivo **cake** no local correto +para obter o preenchimento automático ao usar o console do CakePHP: + +.. code-block:: bash + + # + # Arquivo de conclusão Bash para console CakePHP + # + + _cake() + { + local cur prev opts cake + COMPREPLY=() + cake="${COMP_WORDS[0]}" + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + if [[ "$cur" == -* ]] ; then + if [[ ${COMP_CWORD} = 1 ]] ; then + opts=$(${cake} Completion options) + elif [[ ${COMP_CWORD} = 2 ]] ; then + opts=$(${cake} Completion options "${COMP_WORDS[1]}") + else + opts=$(${cake} Completion options "${COMP_WORDS[1]}" "${COMP_WORDS[2]}") + fi + + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi + + if [[ ${COMP_CWORD} = 1 ]] ; then + opts=$(${cake} Completion commands) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi + + if [[ ${COMP_CWORD} = 2 ]] ; then + opts=$(${cake} Completion subcommands $prev) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + if [[ $COMPREPLY = "" ]] ; then + _filedir + return 0 + fi + return 0 + fi + + opts=$(${cake} Completion fuzzy "${COMP_WORDS[@]:1}") + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + if [[ $COMPREPLY = "" ]] ; then + _filedir + return 0 + fi + return 0; + } + + complete -F _cake cake bin/cake + +Usando autoconclusão +==================== + +Uma vez habilitado, a autoconclusão pode ser usado da mesma forma que para outros +comandos integrados, usando a tecla **TAB**. +São fornecidos três tipos de autoconclusão. A saída a seguir é de uma instalação recente do CakePHP. + +Comandos +-------- + +Exemplo de saída para comandos de autoconclusão: + +.. code-block:: console + + $ bin/cake + bake i18n schema_cache routes + console migrations plugin server + +Subcommands +----------- + +Exemplo de saída para subcomandos de autoconclusão: + +.. code-block:: console + + $ bin/cake bake + behavior helper command + cell mailer command_helper + component migration template + controller migration_snapshot test + fixture model + form plugin + +Opções +------ + +Exemplo de saída para subcomandos de autoconclusão: + +.. code-block:: console + + $ bin/cake bake - + -c --everything --force --help --plugin -q -t -v + --connection -f -h -p --prefix --quiet --theme --verbose + diff --git a/pt/console-commands/counter-cache.rst b/pt/console-commands/counter-cache.rst new file mode 100644 index 0000000000..e2028ea509 --- /dev/null +++ b/pt/console-commands/counter-cache.rst @@ -0,0 +1,24 @@ +Ferramenta de CounterCache +########################## + +O CounterCacheCommand fornece uma ferramenta CLI para reconstruir os caches de contadores +nos seus modelos de aplicativo e plugin. Ele pode ser usado em operações de manutenção e +recuperação, ou para preencher novos caches de contadores adicionados ao seu +aplicativo. + +.. code-block:: console + + bin/cake counter_cache --assoc Comments Articles + +Isso reconstruiria os contadores relacionados a ``Comentários`` na tabela ``Artigos``. +Para tabelas muito grandes, pode ser necessário reconstruir os contadores em lotes. Você pode usar +as opções ``--limit`` e ``--page`` para reconstruir o estado dos contadores de forma incremental. + +.. code-block:: console + + bin/cake counter_cache --assoc Comments --limit 100 --page 2 Articles + +Quando ``limit`` e ``page`` são usados, os registros serão ordenados pela +chave primária da tabela. + +.. versionadded:: 5.2.0 diff --git a/pt/console-commands/cron-jobs.rst b/pt/console-commands/cron-jobs.rst new file mode 100644 index 0000000000..6dc838ad8f --- /dev/null +++ b/pt/console-commands/cron-jobs.rst @@ -0,0 +1,43 @@ +Executando Shells como Cronjobs +############################### + +Uma coisa comum a se fazer com um shell é executá-lo como um cronjob para +limpar o banco de dados de vez em quando ou enviar newsletters. Isso é +trivial de configurar, por exemplo:: + + */5 * * * * cd /full/path/to/root && bin/cake myshell myparam + # * * * * * comando para executar + # │ │ │ │ │ + # │ │ │ │ │ + # │ │ │ │ \───── dia da semana (0 - 6) (0 a 6 são de domingo a sábado, + # | | | | ou usar nomes) + # │ │ │ \────────── mês (1 - 12) + # │ │ \─────────────── dia do mês (1 - 31) + # │ \──────────────────── hora (0 - 23) + # \───────────────────────── minuto (0 - 59) + +Você pode ver mais informações aqui: https://en.wikipedia.org/wiki/Cron + +.. tip:: + + Use ``-q`` (ou `--quiet`) para silenciar qualquer saída de cronjobs. + +Tarefas Cron em Hospedagem Compartilhada +---------------------------------------- + +Em algumas hospedagens compartilhadas, ``cd /full/path/to/root && bin/cake mycommand myparam`` +pode não funcionar. Em vez disso, você pode usar +``php /full/path/to/root/bin/cake.php mycommand myparam``. + +.. note:: + + register_argc_argv precisa ser ativado incluindo ``register_argc_argv + = 1`` no seu php.ini. Se você não puder alterar register_argc_argv globalmente, + você pode instruir o cron job a usar sua própria configuração + especificando-a com o parâmetro ``-d register_argc_argv=1``. Exemplo: ``php + -d register_argc_argv=1 /full/path/to/root/bin/cake.php myshell + myparam`` + +.. meta:: + :title lang=pt: Executando Shells como cronjobs + :keywords lang=pt: cronjob,bash script,crontab diff --git a/pt/console-commands/i18n.rst b/pt/console-commands/i18n.rst new file mode 100644 index 0000000000..478c5be184 --- /dev/null +++ b/pt/console-commands/i18n.rst @@ -0,0 +1,92 @@ +Ferramenta I18N +############### + +Os recursos i18n do CakePHP usam arquivos `po `_ +como fonte de tradução. Os arquivos PO se integram a ferramentas de tradução comumente usadas, +como `Poedit `_. + +Os comandos i18n fornecem uma maneira rápida de gerar arquivos de modelo PO. +Esses arquivos de modelo podem ser fornecidos aos tradutores para que eles possam traduzir as +strings em sua aplicação. Depois que as traduções forem concluídas, os arquivos POT podem ser +mesclados com as traduções existentes para ajudar a atualizar suas traduções. + +Gerando arquivos POT +==================== + +Arquivos POT podem ser gerados para um aplicativo existente usando o comando ``extract``. +Este comando verificará todo o seu aplicativo em busca de chamadas de função no estilo ``__()`` +e extrairá a string da mensagem. Cada string exclusiva do seu +aplicativo será combinada em um único arquivo POT: + +.. code-block:: console + + bin/cake i18n extract + +O comando acima executará o comando de extração. O resultado deste comando será o +arquivo **resources/locales/default.pot**. Use o arquivo pot como modelo para criar +arquivos po. Se estiver criando arquivos po manualmente a partir do arquivo pot, certifique-se de +definir corretamente a linha de cabeçalho ``Plural-Forms``. + +Gerando arquivos POT para Plugins +--------------------------------- + +Você pode gerar um arquivo POT para um plugin específico usando: + +.. code-block:: console + + bin/cake i18n extract --plugin + +Isso gerará os arquivos POT necessários usados ​​nos plugins. + +Extraindo de várias pastas de uma só vez +---------------------------------------- + +Às vezes, você pode precisar extrair strings de mais de um diretório +do seu aplicativo. Por exemplo, se você estiver definindo algumas strings no diretório +``config`` do seu aplicativo, provavelmente desejará extrair strings +desse diretório, bem como do diretório ``src``. Você pode fazer isso +usando a opção ``--paths``. É necessária uma lista de caminhos absolutos separados por vírgulas +para extrair: + +.. code-block:: console + + bin/cake i18n extract --paths /var/www/app/config,/var/www/app/src + +Excluindo Pastas +---------------- + +Você pode passar uma lista separada por vírgulas de pastas que deseja excluir. +Qualquer caminho que contenha um segmento de caminho com os valores fornecidos será ignorado: + +.. code-block:: console + + bin/cake i18n extract --exclude vendor,tests + +Ignorando Avisos de Substituição para Arquivos POT Existentes +------------------------------------------------------------- + +Ao adicionar ``--overwrite``, o script de shell não irá mais avisá-lo se um arquivo POT +já existir e irá sobrescrever por padrão: + +.. code-block:: console + + bin/cake i18n extract --overwrite + +Extraindo Mensagens das Bibliotecas Principais do CakePHP +--------------------------------------------------------- + +Por padrão, o script de shell de extração perguntará se você deseja extrair +as mensagens usadas nas bibliotecas principais do CakePHP. Defina ``--extract-core`` como sim +ou não para definir o comportamento padrão: + +.. code-block:: console + + bin/cake i18n extract --extract-core yes + + // ou + + bin/cake i18n extract --extract-core no + +.. meta:: + :title lang=pt: ferramenta I18N + :keywords lang=pt: arquivos pot, localidade padrão,ferramentas de tradução,mensagens,app locale,classe php,validação,i18n,translations,comando,modelos diff --git a/pt/console-commands/input-output.rst b/pt/console-commands/input-output.rst new file mode 100644 index 0000000000..8350692178 --- /dev/null +++ b/pt/console-commands/input-output.rst @@ -0,0 +1,375 @@ +Entrada/Saída de Comandos +######################### + +.. php:namespace:: Cake\Console +.. php:class:: ConsoleIo + +O CakePHP fornece o objeto ``ConsoleIo`` para comandos, permitindo que eles +leiam a entrada do usuário de forma interativa e exibam informações para o usuário. + +.. _command-helpers: + +Helpers de Comandos +=================== + +Os Helpers de Comandos podem ser acessados e usados a partir de qualquer comando:: + + // Output some data as a table. + $io->helper('Table')->output($data); + + // Get a helper from a plugin. + $io->helper('Plugin.HelperName')->output($data); + +Você também pode obter instâncias de helpers e chamar quaisquer métodos públicos neles:: + + // Get and use the Progress Helper. + $progress = $io->helper('Progress'); + $progress->increment(10); + $progress->draw(); + +Criando Helpers +=============== + +Embora o CakePHP venha com alguns helpers de comando, você pode criar mais em sua +aplicação ou plugins. Como exemplo, vamos criar um helper simples para gerar +cabeçalhos elegantes. Primeiro crie o arquivo **src/Command/Helper/HeadingHelper.php** e coloque +o seguinte nele:: + + _io->out($marker . ' ' . $args[0] . ' ' . $marker); + } + } + +Podemos então usar este novo helper em um de nossos comandos shell chamando-o:: + + // With ### on either side + $this->helper('Heading')->output(['It works!']); + + // With ~~~~ on either side + $this->helper('Heading')->output(['It works!', '~', 4]); + +Os Helpers geralmente implementam o método ``output()`` que recebe um array de +parâmetros. No entanto, como os Console Helpers são classes comuns, eles podem +implementar métodos adicionais que aceitam qualquer forma de argumentos. + +.. note:: + Os Helpers também podem estar em ``src/Shell/Helper`` para compatibilidade com versões anteriores. + +Helpers Integrados +================== + +Helper Table +------------ + +O TableHelper ajuda a criar tabelas ASCII art bem formatadas. Usá-lo é +bastante simples:: + + $data = [ + ['Header 1', 'Header', 'Long Header'], + ['short', 'Longish thing', 'short'], + ['Longer thing', 'short', 'Longest Value'], + ]; + $io->helper('Table')->output($data); + + // Outputs + +--------------+---------------+---------------+ + | Header 1 | Header | Long Header | + +--------------+---------------+---------------+ + | short | Longish thing | short | + | Longer thing | short | Longest Value | + +--------------+---------------+---------------+ + +Você pode usar a tag de formatação ```` em tabelas para alinhar +o conteúdo à direita:: + + $data = [ + ['Name', 'Total Price'], + ['Cake Mix', '1.50'], + ]; + $io->helper('Table')->output($data); + + // Outputs + +----------+-------------+ + | Name 1 | Total Price | + +----------+-------------+ + | Cake Mix | 1.50 | + +----------+-------------+ + +Helper Progress +--------------- + +O ProgressHelper pode ser usado de duas maneiras diferentes. O modo simples permite que você +forneça um callback que é invocado até que o progresso esteja completo:: + + $io->helper('Progress')->output(['callback' => function ($progress) { + // Do work here. + $progress->increment(20); + $progress->draw(); + }]); + +Você pode controlar a barra de progresso melhor fornecendo opções adicionais: + +- ``total`` O número total de itens na barra de progresso. Padrão + é 100. +- ``width`` A largura da barra de progresso. Padrão é 80. +- ``callback`` O callback que será chamado em um loop para avançar a + barra de progresso. + +Um exemplo de todas as opções em uso seria:: + + $io->helper('Progress')->output([ + 'total' => 10, + 'width' => 20, + 'callback' => function ($progress) { + $progress->increment(2); + $progress->draw(); + } + ]); + +O helper de progresso também pode ser usado manualmente para incrementar e re-renderizar a +barra de progresso conforme necessário:: + + $progress = $io->helper('Progress'); + $progress->init([ + 'total' => 10, + 'width' => 20, + ]); + + $progress->increment(4); + $progress->draw(); + +Helper Banner +------------- + +O ``BannerHelper`` pode ser usado para formatar uma ou mais linhas de texto em +um banner com plano de fundo e preenchimento horizontal:: + + $io->helper('Banner') + ->withPadding(5) + ->withStyle('success.bg') + ->output(['Work complete']); + +.. versionadded:: 5.1.0 + O ``BannerHelper`` foi adicionado na versão 5.1 + +Obtendo Entrada do Usuário +=========================== + +.. php:method:: ask($question, $choices = null, $default = null) + +Ao construir aplicações de console interativas, você precisará obter entrada do usuário. +O CakePHP fornece uma forma de fazer isso:: + + // Get arbitrary text from the user. + $color = $io->ask('What color do you like?'); + + // Get a choice from the user. + $selection = $io->askChoice('Red or Green?', ['R', 'G'], 'R'); + +A validação de seleção não diferencia maiúsculas de minúsculas. + +Criando Arquivos +================ + +.. php:method:: createFile($path, $contents) + +Criar arquivos é frequentemente uma parte importante de muitos comandos de console que ajudam +a automatizar o desenvolvimento e implantação. O método ``createFile()`` oferece uma +interface simples para criar arquivos com confirmação interativa:: + + // Create a file with confirmation on overwrite + $io->createFile('bower.json', $stuff); + + // Force overwriting without asking + $io->createFile('bower.json', $stuff, true); + +Criando Saída +============= + +.. php:method:out($message, $newlines, $level) +.. php:method:err($message, $newlines) + +Escrever para ``stdout`` e ``stderr`` é outra operação comum no CakePHP:: + + // Write to stdout + $io->out('Normal message'); + + // Write to stderr + $io->err('Error message'); + +Além dos métodos de saída convencionais, o CakePHP fornece métodos wrapper que +estilizam a saída com cores ANSI apropriadas:: + + // Green text on stdout + $io->success('Success message'); + + // Cyan text on stdout + $io->info('Informational text'); + + // Blue text on stdout + $io->comment('Additional context'); + + // Red text on stderr + $io->error('Error text'); + + // Yellow text on stderr + $io->warning('Warning text'); + +A formatação de cores será automaticamente desabilitada se ``posix_isatty`` retornar +true, ou se a variável de ambiente ``NO_COLOR`` estiver definida. + +O ``ConsoleIo`` fornece dois métodos de conveniência relacionados ao nível de saída:: + + // Would only appear when verbose output is enabled (-v) + $io->verbose('Verbose message'); + + // Would appear at all levels. + $io->quiet('Quiet message'); + +Você também pode criar linhas em branco ou desenhar linhas de traços:: + + // Output 2 newlines + $io->out($io->nl(2)); + + // Draw a horizontal line + $io->hr(); + +Por fim, você pode atualizar a linha atual de texto na tela:: + + $io->out('Counting down'); + $io->out('10', 0); + for ($i = 9; $i > 0; $i--) { + sleep(1); + $io->overwrite($i, 0, 2); + } + +.. note:: + É importante lembrar que você não pode sobrescrever texto + uma vez que uma nova linha tenha sido exibida. + +.. _shell-output-level: + +Níveis de Saída +=============== + +As aplicações de console frequentemente precisam de diferentes níveis de verbosidade. Por exemplo, quando +executado como um cron job, a maior parte da saída é desnecessária. Você pode usar níveis de saída para +marcar a saída adequadamente. O usuário do shell pode então decidir qual nível de +detalhe lhe interessa configurando a flag correta ao chamar o +comando. Existem 3 níveis: + +* ``QUIET`` - Apenas informações absolutamente importantes devem ser marcadas para saída + silenciosa. +* ``NORMAL`` - O nível padrão e uso normal. +* ``VERBOSE`` - Marque mensagens que podem ser muito ruidosas para uso diário, mas + úteis para depuração como ``VERBOSE``. + +Você pode marcar a saída da seguinte forma:: + + // Would appear at all levels. + $io->out('Quiet message', 1, ConsoleIo::QUIET); + $io->quiet('Quiet message'); + + // Would not appear when quiet output is toggled. + $io->out('normal message', 1, ConsoleIo::NORMAL); + $io->out('loud message', 1, ConsoleIo::VERBOSE); + $io->verbose('Verbose output'); + + // Would only appear when verbose output is enabled. + $io->out('extra message', 1, ConsoleIo::VERBOSE); + $io->verbose('Verbose output'); + +Você pode controlar o nível de saída dos comandos usando as opções ``--quiet`` e +``--verbose``. Essas opções são adicionadas por padrão e permitem que você +controle consistentemente os níveis de saída dentro dos seus comandos CakePHP. + +As opções ``--quiet`` e ``--verbose`` também controlam como os dados de log são +exibidos em stdout/stderr. Normalmente, mensagens de log de nível info e superior são exibidas em +stdout/stderr. Quando ``--verbose`` é usado, logs de depuração serão exibidos em stdout. +Quando ``--quiet`` é usado, apenas mensagens de log de warning e superior serão exibidas em +stderr. + +Estilizando a Saída +=================== + +A estilização da saída é feita incluindo tags - assim como HTML - em sua saída. +Essas tags serão substituídas pela sequência de código ansi correta, ou +removidas se você estiver em um console que não suporta códigos ansi. Existem +vários estilos integrados, e você pode criar mais. Os integrados são + +* ``success`` Mensagens de sucesso. Texto verde. +* ``error`` Mensagens de erro. Texto vermelho. +* ``warning`` Mensagens de aviso. Texto amarelo. +* ``info`` Mensagens informativas. Texto ciano. +* ``comment`` Texto adicional. Texto azul. +* ``question`` Texto que é uma pergunta, adicionado automaticamente pelo shell. +* ``info.bg`` Fundo branco com texto ciano. +* ``warning.bg`` Fundo amarelo com texto preto. +* ``error.bg`` Fundo vermelho com texto preto. +* ``success.bg`` Fundo verde com texto preto. + +Você pode criar estilos adicionais usando ``$io->setStyle()``. Para declarar um +novo estilo de saída, você pode fazer:: + + $io->setStyle('flashy', ['text' => 'magenta', 'blink' => true]); + +Isso permitiria que você usasse uma tag ```` em sua saída de shell, e se +as cores ansi estiverem habilitadas, o seguinte seria renderizado como texto magenta +piscando ``$this->out('Whoooa Something went wrong');``. Ao +definir estilos, você pode usar as seguintes cores para os atributos ``text`` e +``background``: + +* black +* blue +* cyan +* green +* magenta +* red +* white +* yellow + +Você também pode usar as seguintes opções como switches booleanos, definindo-os para um +valor verdadeiro os habilita. + +* blink +* bold +* reverse +* underline + +Adicionar um estilo o torna disponível em todas as instâncias de ConsoleOutput também, +então você não precisa redeclarar estilos para os objetos stdout e stderr. + +.. versionchanged:: 5.1.0 + Os estilos ``info.bg``, ``warning.bg``, ``error.bg`` e ``success.bg`` foram adicionados. + +Desativando a Colorização +========================== + +Embora a colorização seja interessante, pode haver momentos em que você queira desativá-la +ou forçar sua ativação:: + + $io->outputAs(ConsoleOutput::RAW); + +O exemplo acima colocará o objeto de saída no modo de saída bruta. No modo de saída bruta, +nenhuma estilização é feita. Existem três modos que você pode usar. + +* ``ConsoleOutput::COLOR`` - Saída com códigos de escape de cor no lugar. +* ``ConsoleOutput::PLAIN`` - Saída de texto simples, tags de estilo conhecidas serão + removidas da saída. +* ``ConsoleOutput::RAW`` - Saída bruta, nenhuma estilização ou formatação será feita. + Este é um bom modo para usar se você estiver gerando XML ou quiser depurar por que + sua estilização não está funcionando. + +Por padrão, em sistemas \*nix, os objetos ConsoleOutput usam saída colorida por padrão. +Em sistemas Windows, a saída simples é o padrão, a menos que a variável de +ambiente ``ANSICON`` esteja presente. diff --git a/pt/console-commands/option-parsers.rst b/pt/console-commands/option-parsers.rst new file mode 100644 index 0000000000..740f037e04 --- /dev/null +++ b/pt/console-commands/option-parsers.rst @@ -0,0 +1,367 @@ +Analisadores de Opções +###################### + +.. php:namespace:: Cake\Console +.. php:class:: ConsoleOptionParser + +As aplicações de console normalmente recebem opções e argumentos como a principal forma de +obter informações do terminal para seus comandos. + +Definindo um OptionParser +========================= + +Os Comandos e Shells fornecem um método hook ``buildOptionParser($parser)`` que +você pode usar para definir as opções e argumentos para seus comandos:: + + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + { + // Define your options and arguments. + + // Return the completed parser + return $parser; + } + +As classes Shell usam o método hook ``getOptionParser()`` para definir seu +analisador de opções:: + + public function getOptionParser() + { + // Get an empty parser from the framework. + $parser = parent::getOptionParser(); + + // Define your options and arguments. + + // Return the completed parser + return $parser; + } + + +Usando Argumentos +================= + +.. php:method:: addArgument($name, $params = []) + +Os argumentos posicionais são frequentemente usados em ferramentas de linha de comando, +e o ``ConsoleOptionParser`` permite que você defina argumentos +posicionais e também os torne obrigatórios. Você pode adicionar argumentos +um de cada vez com ``$parser->addArgument();`` ou múltiplos de uma vez +com ``$parser->addArguments();``:: + + $parser->addArgument('model', ['help' => 'The model to bake']); + +Você pode usar as seguintes opções ao criar um argumento: + +* ``help`` O texto de ajuda a ser exibido para este argumento. +* ``required`` Se este parâmetro é obrigatório. +* ``index`` O índice para o argumento, se deixado indefinido o argumento será colocado + no final dos argumentos. Se você definir o mesmo índice duas vezes, a + primeira opção será sobrescrita. +* ``choices`` Um array de escolhas válidas para este argumento. Se deixado vazio, todos + os valores são válidos. Uma exceção será lançada quando parse() encontrar um + valor inválido. +* ``separator`` Uma sequência de caracteres que separa argumentos que devem ser + analisados em um array. + +Argumentos que foram marcados como obrigatórios lançarão uma exceção ao +analisar o comando se tiverem sido omitidos. Portanto, você não precisa +lidar com isso em seu shell. + +.. versionadded:: 5.2.0 + A opção ``separator`` foi adicionada. + +Adicionando Múltiplos Argumentos +--------------------------------- + +.. php:method:: addArguments(array $args) + +Se você tiver um array com múltiplos argumentos, pode usar +``$parser->addArguments()`` para adicionar múltiplos argumentos de uma vez. :: + + $parser->addArguments([ + 'node' => ['help' => 'The node to create', 'required' => true], + 'parent' => ['help' => 'The parent node', 'required' => true], + ]); + +Como todos os métodos de construção do ConsoleOptionParser, addArguments +pode ser usado como parte de uma cadeia de métodos fluente. + +Validando Argumentos +-------------------- + +Ao criar argumentos posicionais, você pode usar a flag ``required`` para +indicar que um argumento deve estar presente quando um shell é chamado. +Adicionalmente, você pode usar ``choices`` para forçar um argumento a ser de uma lista de +escolhas válidas:: + + $parser->addArgument('type', [ + 'help' => 'The type of node to interact with.', + 'required' => true, + 'choices' => ['aro', 'aco'], + ]); + +O exemplo acima criará um argumento que é obrigatório e tem validação na +entrada. Se o argumento estiver ausente ou tiver um valor incorreto, uma exceção +será lançada e o shell será interrompido. + +Usando Opções +============= + +.. php:method:: addOption($name, array $options = []) + +As opções ou flags são usadas em ferramentas de linha de comando para fornecer argumentos chave/valor +não ordenados para seus comandos. As opções podem definir aliases detalhados e curtos. +Elas podem aceitar um valor (por exemplo, ``--connection=default``) ou serem opções booleanas +(por exemplo, ``--verbose``). As opções são definidas com o método ``addOption()``:: + + $parser->addOption('connection', [ + 'short' => 'c', + 'help' => 'connection', + 'default' => 'default', + ]); + +O exemplo acima permitiria que você usasse ``cake myshell --connection=other``, +``cake myshell --connection other``, ou ``cake myshell -c other`` +ao invocar o shell. + +As chaves booleanas não aceitam ou consomem valores, e sua presença apenas +as habilita nos parâmetros analisados:: + + $parser->addOption('no-commit', ['boolean' => true]); + +Esta opção, quando usada como ``cake mycommand --no-commit something``, teria +um valor de ``true``, e 'something' seria tratado como um argumento +posicional. + +Ao criar opções, você pode usar as seguintes opções para definir o comportamento +da opção: + +* ``short`` - A variante de letra única para esta opção, deixe indefinido para + nenhuma. +* ``help`` - Texto de ajuda para esta opção. Usado ao gerar ajuda para a + opção. +* ``default`` - O valor padrão para esta opção. Se não definido, o padrão + será ``true``. +* ``boolean`` - A opção não usa valor, é apenas uma chave booleana. + Padrão é ``false``. +* ``multiple`` - A opção pode ser fornecida múltiplas vezes. A opção analisada + será um array de valores quando esta opção estiver habilitada. +* ``separator`` - Uma sequência de caracteres pela qual o valor da opção é dividido em um + array. +* ``choices`` - Um array de escolhas válidas para esta opção. Se deixado vazio, todos + os valores são válidos. Uma exceção será lançada quando parse() encontrar um + valor inválido. + + +.. versionadded:: 5.2.0 + A opção ``separator`` foi adicionada. + +Adicionando Múltiplas Opções +----------------------------- + +.. php:method:: addOptions(array $options) + +Se você tiver um array com múltiplas opções, pode usar ``$parser->addOptions()`` +para adicionar múltiplas opções de uma vez. :: + + $parser->addOptions([ + 'node' => ['short' => 'n', 'help' => 'The node to create'], + 'parent' => ['short' => 'p', 'help' => 'The parent node'], + ]); + +Como todos os métodos de construção do ConsoleOptionParser, addOptions pode ser usado +como parte de uma cadeia de métodos fluente. + +Validando Opções +---------------- + +As opções podem ser fornecidas com um conjunto de escolhas, assim como os argumentos posicionais +podem ser. Quando uma opção tem escolhas definidas, essas são as únicas escolhas válidas +para uma opção. Todos os outros valores lançarão uma ``InvalidArgumentException``:: + + $parser->addOption('accept', [ + 'help' => 'What version to accept.', + 'choices' => ['working', 'theirs', 'mine'], + ]); + +Usando Opções Booleanas +----------------------- + +As opções podem ser definidas como opções booleanas, que são úteis quando você precisa +criar algumas opções de flag. Como opções com padrões, as opções booleanas sempre +se incluem nos parâmetros analisados. Quando as flags estão presentes, elas +são definidas como ``true``, quando estão ausentes são definidas como ``false``:: + + $parser->addOption('verbose', [ + 'help' => 'Enable verbose output.', + 'boolean' => true + ]); + +A opção seguinte sempre terá um valor no parâmetro analisado. Quando não +incluída, seu valor padrão seria ``false``, e quando definida será +``true``. + +Construindo um ConsoleOptionParser a partir de um Array +-------------------------------------------------------- + +.. php:method:: buildFromArray($spec) + +Os analisadores de opções também podem ser definidos como arrays. Dentro do array, você pode definir +chaves para ``arguments``, ``options``, ``description`` e ``epilog``. Os valores +para argumentos e opções devem seguir o formato que +:php:func:`Cake\\Console\\ConsoleOptionParser::addArguments()` e +:php:func:`Cake\\Console\\ConsoleOptionParser::addOptions()` usam. Você também pode +usar ``buildFromArray`` por conta própria para construir um analisador de opções:: + + public function getOptionParser() + { + return ConsoleOptionParser::buildFromArray([ + 'description' => [ + __("Use this command to grant ACL permissions. Once executed, the "), + __("ARO specified (and its children, if any) will have ALLOW access "), + __("to the specified ACO action (and the ACO's children, if any).") + ], + 'arguments' => [ + 'aro' => ['help' => __('ARO to check.'), 'required' => true], + 'aco' => ['help' => __('ACO to check.'), 'required' => true], + 'action' => ['help' => __('Action to check')], + ], + ]); + } + +Mesclando Analisadores de Opções +--------------------------------- + +.. php:method:: merge($spec) + +Ao construir um comando de grupo, você pode querer combinar vários analisadores para +isso:: + + $parser->merge($anotherParser); + +Note que a ordem dos argumentos para cada analisador deve ser a mesma, e que +as opções também devem ser compatíveis para funcionar. Portanto, não use chaves para coisas +diferentes. + +Obtendo Ajuda dos Shells +========================= + +Ao definir suas opções e argumentos com o analisador de opções, o CakePHP pode +gerar automaticamente informações de ajuda rudimentares e adicionar ``--help`` e +``-h`` a cada um dos seus comandos. Usar uma dessas opções permitirá que você +veja o conteúdo de ajuda gerado: + +.. code-block:: console + + bin/cake bake --help + bin/cake bake -h + +Ambos gerariam a ajuda para bake. Você também pode obter ajuda para comandos +aninhados: + +.. code-block:: console + + bin/cake bake model --help + bin/cake bake model -h + +O exemplo acima obteria a ajuda específica para o comando model do bake. + +Obtendo Ajuda como XML +---------------------- + +Ao construir ferramentas automatizadas ou ferramentas de desenvolvimento que precisam interagir com +comandos shell do CakePHP, é bom ter ajuda disponível em um formato analisável por máquina. +Ao fornecer a opção ``xml`` ao solicitar ajuda, você pode ter o conteúdo de ajuda +retornado como XML: + +.. code-block:: console + + cake bake --help xml + cake bake -h xml + +O exemplo acima retornaria um documento XML com a ajuda gerada, opções e +argumentos para o shell selecionado. Um documento XML de exemplo +seria parecido com: + +.. code-block:: xml + + + + bake fixture + Generate fixtures for use with the test suite. You can use + `bake fixture all` to bake all fixtures. + + Omitting all arguments and options will enter into an interactive + mode. + + + + + + + + + + + + + + + + + +Personalizando a Saída de Ajuda +================================ + +Você pode enriquecer ainda mais o conteúdo de ajuda gerado adicionando uma descrição e +epílogo. + +Definir a Descrição +------------------- + +.. php:method:: setDescription($text) + +A descrição é exibida acima das informações de argumento e opção. Ao passar +um array ou uma string, você pode definir o valor da descrição:: + + // Set multiple lines at once + $parser->setDescription(['line one', 'line two']); + + // Read the current value + $parser->getDescription(); + +Definir o Epílogo +----------------- + +.. php:method:: setEpilog($text) + +Obtém ou define o epílogo para o analisador de opções. O epílogo é exibido após as +informações de argumento e opção. Ao passar um array ou uma string, você +pode definir o valor do epílogo:: + + // Set multiple lines at once + $parser->setEpilog(['line one', 'line two']); + + // Read the current value + $parser->getEpilog(); diff --git a/pt/console-commands/plugin.rst b/pt/console-commands/plugin.rst new file mode 100644 index 0000000000..163b3eb661 --- /dev/null +++ b/pt/console-commands/plugin.rst @@ -0,0 +1,65 @@ +.. _plugin-shell: + +Ferramenta de Plugin +#################### + +A ferramenta de plugin permite carregar e descarregar plugins via prompt de comando. +Se você precisar de ajuda, execute: + +.. code-block:: console + + bin/cake plugin --help + +Carregando Plugins +------------------ + +Através da tarefa ``Load`` você pode carregar plugins em seu +**config/bootstrap.php**. Você pode fazer isso executando: + +.. code-block:: console + + bin/cake plugin load MyPlugin + +Isso adicionará o seguinte ao seu **src/Application.php**:: + + // In the bootstrap method add: + $this->addPlugin('MyPlugin'); + + +Descarregando Plugins +--------------------- + +Você pode descarregar um plugin especificando seu nome: + +.. code-block:: console + + bin/cake plugin unload MyPlugin + +Isso removerá a linha ``$this->addPlugin('MyPlugin',...)`` de +**src/Application.php**. + +Assets de Plugin +---------------- + +O CakePHP por padrão serve assets de plugins usando o middleware ``AssetMiddleware``. +Embora isso seja conveniente, é recomendado criar um link simbólico / copiar +os assets do plugin para o webroot da aplicação para que eles possam ser servidos diretamente pelo +servidor web sem invocar o PHP. Você pode fazer isso executando: + +.. code-block:: console + + bin/cake plugin assets symlink + +Executar o comando acima criará links simbólicos de todos os assets de plugins no webroot da aplicação. +No Windows, que não suporta links simbólicos, os assets serão copiados nas +respectivas pastas em vez de serem vinculados simbolicamente. + +Você pode criar links simbólicos de assets de um plugin específico especificando seu nome: + +.. code-block:: console + + bin/cake plugin assets symlink MyPlugin + +.. meta:: + :title lang=en: Plugin tool + :keywords lang=en: plugin,assets,tool,load,unload diff --git a/pt/console-commands/repl.rst b/pt/console-commands/repl.rst new file mode 100644 index 0000000000..d1a560e9ca --- /dev/null +++ b/pt/console-commands/repl.rst @@ -0,0 +1,50 @@ +Console Interativo (REPL) +######################### + +O CakePHP oferece o +`plugin REPL(Read Eval Print Loop) `__ para permitir +que você explore o CakePHP e sua aplicação em um console interativo. + +.. note:: + + O plugin era incluído no esqueleto da aplicação CakePHP antes da versão 4.3. + +Você pode iniciar o console interativo usando: + +.. code-block:: console + + bin/cake console + +Isso inicializará sua aplicação e iniciará um console interativo. Neste +ponto você pode interagir com o código da sua aplicação e executar consultas usando os +models da sua aplicação: + +.. code-block:: console + + bin/cake console + + >>> $articles = Cake\Datasource\FactoryLocator::get('Table')->get('Articles'); + // object(Cake\ORM\Table)( + // + // ) + >>> $articles->find()->all(); + +Como sua aplicação foi inicializada, você também pode testar o roteamento usando o +REPL:: + + >>> Cake\Routing\Router::parse('/articles/view/1'); + // [ + // 'controller' => 'Articles', + // 'action' => 'view', + // 'pass' => [ + // 0 => '1' + // ], + // 'plugin' => NULL + // ] + +Você também pode testar a geração de URLs:: + + >>> Cake\Routing\Router::url(['controller' => 'Articles', 'action' => 'edit', 99]); + // '/articles/edit/99' + +Para sair do REPL você pode usar ``CTRL-C`` ou digitando ``exit``. diff --git a/pt/console-commands/routes.rst b/pt/console-commands/routes.rst new file mode 100644 index 0000000000..ec7e00b6e7 --- /dev/null +++ b/pt/console-commands/routes.rst @@ -0,0 +1,40 @@ +Ferramenta de Rotas +################### + +A ferramenta de rotas fornece uma interface CLI simples de usar para testar e depurar +rotas. Você pode usá-la para testar como as rotas são analisadas e quais URLs os parâmetros de +roteamento irão gerar. + +Obtendo uma Lista de todas as Rotas +------------------------------------ + +.. code-block:: console + + bin/cake routes + +Testando a Análise de URL +------------------------- + +Você pode ver rapidamente como uma URL será analisada usando o método ``check``: + +.. code-block:: console + + bin/cake routes check /articles/edit/1 + +Se sua rota contiver parâmetros de query string, lembre-se de colocar a URL +entre aspas: + +.. code-block:: console + + bin/cake routes check "/articles/?page=1&sort=title&direction=desc" + +Testando a Geração de URL +------------------------- + +Você pode ver a URL que um :term:`routing array` irá gerar usando o +método ``generate``: + +.. code-block:: console + + bin/cake routes generate controller:Articles action:edit 1 + diff --git a/pt/console-commands/schema-cache.rst b/pt/console-commands/schema-cache.rst new file mode 100644 index 0000000000..8dcd65219f --- /dev/null +++ b/pt/console-commands/schema-cache.rst @@ -0,0 +1,30 @@ +Ferramenta de Cache de Schema +############################## + +O SchemaCacheCommand fornece uma ferramenta CLI simples para gerenciar os +caches de metadados da sua aplicação. Em situações de implantação, é útil reconstruir o cache de metadados +no local sem limpar os dados de cache existentes. Você pode fazer isso +executando: + +.. code-block:: console + + bin/cake schema_cache build --connection default + +Isso reconstruirá o cache de metadados para todas as tabelas na conexão ``default``. +Se você precisar reconstruir apenas uma única tabela, pode fazer isso +fornecendo seu nome: + +.. code-block:: console + + bin/cake schema_cache build --connection default articles + +Além de construir dados em cache, você pode usar o SchemaCacheShell para remover +metadados em cache também: + +.. code-block:: console + + # Clear all metadata + bin/cake schema_cache clear + + # Clear a single table + bin/cake schema_cache clear articles diff --git a/pt/console-commands/server.rst b/pt/console-commands/server.rst new file mode 100644 index 0000000000..e381a33bba --- /dev/null +++ b/pt/console-commands/server.rst @@ -0,0 +1,30 @@ +Ferramenta de Servidor +###################### + +O ``ServerCommand`` permite que você inicie um servidor web simples usando o servidor web +integrado do PHP. Embora este servidor *não* seja destinado ao uso em produção, ele pode +ser útil no desenvolvimento quando você quiser testar rapidamente uma ideia e não quiser +gastar tempo configurando o Apache ou Nginx. Você pode iniciar o comando do servidor com: + +.. code-block:: console + + bin/cake server + +Você deve ver o servidor inicializar e se conectar à porta 8765. Você pode visitar o +servidor CLI visitando ``http://localhost:8765`` +em seu navegador web. Você pode fechar o servidor pressionando ``CTRL-C`` em seu +terminal. + +.. note:: + + Tente ``bin/cake server -H 0.0.0.0`` se o servidor estiver inacessível de outros hosts. + +Alterando a Porta e o Document Root +==================================== + +Você pode personalizar a porta e o document root usando opções: + +.. code-block:: console + + bin/cake server --port 8080 --document_root path/to/app + diff --git a/pt/contents.rst b/pt/contents.rst index c2cbcf258f..bb083ce654 100644 --- a/pt/contents.rst +++ b/pt/contents.rst @@ -11,9 +11,10 @@ Conteúdo intro quickstart - appendices/4-0-migration-guide + appendices/migration-guides tutorials-and-examples contributing + release-policy .. toctree:: :caption: Começando @@ -21,6 +22,7 @@ Conteúdo installation development/configuration development/application + development/dependency-injection development/routing controllers/request-response controllers/middleware @@ -29,11 +31,10 @@ Conteúdo orm .. toctree:: - :caption: Using CakePHP + :caption: Usando o CakePHP - controllers/components/authentication core-libraries/caching - console-and-shells + console-commands development/debugging deployment core-libraries/email @@ -42,7 +43,7 @@ Conteúdo core-libraries/internationalization-and-localization core-libraries/logging core-libraries/form - controllers/components/pagination + controllers/pagination plugins development/rest security @@ -55,27 +56,32 @@ Conteúdo core-libraries/app core-libraries/collections - core-libraries/file-folder core-libraries/hash core-libraries/httpclient core-libraries/inflector core-libraries/number + core-libraries/plugin core-libraries/registry-objects core-libraries/text core-libraries/time core-libraries/xml .. toctree:: - :caption: Plugins - - Bake - chronos - Debug Kit - Migrations - Elasticsearch + :caption: Plugins e Pacotes + + standalone-packages + Authentication + Authorization + Bake + Debug Kit + Migrations + Elasticsearch + Phinx + Chronos + Queue .. toctree:: - :caption: Diversos + :caption: Outros core-libraries/global-constants-and-functions appendices @@ -85,15 +91,16 @@ Conteúdo topics chronos + debug-kit + elasticsearch bake bake/development bake/usage - debug-kit - elasticsearch migrations + phinx .. todolist:: .. meta:: :title lang=pt: Conteúdo - :keywords lang=pt: bibliotecas do core,busca,filtro,índice,shells,deployment,apêndices,glossário,models,lib + :keywords lang=pt: bibliotecas do core,busca,comandos,deployment,apêndices,glossário,models diff --git a/pt/contributing.rst b/pt/contributing.rst index 8518ed5340..53c053a283 100644 --- a/pt/contributing.rst +++ b/pt/contributing.rst @@ -1,8 +1,8 @@ Contribuindo ############ -Existem várias maneiras de contribuir com o CakePHP. -As seções abaixo irão abordar essas formas de contribuição: +Existem várias maneiras de você contribuir para o CakePHP. As seguintes seções +cobrem as várias maneiras de você contribuir para o CakePHP: .. toctree:: :maxdepth: 1 @@ -15,4 +15,4 @@ As seções abaixo irão abordar essas formas de contribuição: .. meta:: :title lang=pt: Contribuindo - :keywords lang=pt: contribuindo,open source,ajudando,documentação,doc,docs + :keywords lang=pt: convenções de codificação,documentação,maxdepth diff --git a/pt/contributing/backwards-compatibility.rst b/pt/contributing/backwards-compatibility.rst index dfe9b248ab..d3880e18f1 100644 --- a/pt/contributing/backwards-compatibility.rst +++ b/pt/contributing/backwards-compatibility.rst @@ -1,123 +1,120 @@ -Guia de retrocompatibilidade -############################ - -Garantir que você possa atualizar suas aplicações facilmente é importante para -nós. Por esse motivo, apenas quebramos compatibilidade nos *major releases*. -Você deve estar familiarizado com -`versionamento semântico `_, orientação usada em -todos os projetos do CakePHP. Resumindo, significa que apenas *major releases* -(tais como 2.0, 3.0, 4.0) podem quebrar retrocompatibilidades. *Minor releases* -(tais como 2.1, 3.1, 4.1) podem introduzir novos recursos, mas não podem quebrar -retrocompatibilidades. *Releases* de correção de *bugs* (tais como 2.1.2, 3.0.1) -não incluem novos recursos, são destinados apenas à correção de erros e melhora -de desempenho. +Guia de Compatibilidade com Versões Anteriores +############################################## + +Garantir que você possa atualizar suas aplicações de forma fácil e suave é importante +para nós. É por isso que só quebramos a compatibilidade em marcos de lançamentos principais. +Você pode estar familiarizado com `versionamento semântico `_, que é +a diretriz geral que usamos em todos os projetos CakePHP. Resumindo, versionamento +semântico significa que apenas lançamentos principais (como 2.0, 3.0, 4.0) podem quebrar +a compatibilidade com versões anteriores. Lançamentos menores (como 2.1, 3.1, 3.2) podem introduzir novos +recursos, mas não têm permissão para quebrar a compatibilidade. Lançamentos de correção de bugs (como 2.1.2, +3.0.1) não adicionam novos recursos, mas corrigem bugs ou melhoram apenas o desempenho. .. note:: - O CakePHP começou a seguir o versionamento semântico na versão 2.0.0. Essas - regras não se aplicam às versões 1.x. + Depreciações são removidas com a próxima versão principal do framework. + É aconselhável que você se adapte às depreciações conforme são introduzidas para + garantir que futuras atualizações sejam mais fáceis. -Para esclarecer que mudanças você pode esperar em cada ciclo de *release*, nós -temos mais informações detalhadas para desenvolvedores usando o CakePHP, e para -desenvolvedores trabalhando Não CakePHP que ajudam a definir espectativas do que -pode ser feito em *minor releases*. *Major releases* podem ter tantas quebras -quanto forem necessárias. +Para esclarecer quais mudanças você pode esperar em cada nível de lançamento, temos +informações mais detalhadas para desenvolvedores usando CakePHP e para desenvolvedores trabalhando no +CakePHP que ajudam a definir expectativas do que pode ser feito em lançamentos menores. Lançamentos principais +podem ter tantas mudanças quebradas quanto necessário. -Guia de migração -================ +Guias de Migração +================= -Para cada *major* ou *minor releases*, a equipe do CakePHP vai disponibilizar -um guia de migração. Esses guias explicam os novos recursos e qualquer quebra -de compatibilidade. Eles podem ser encontrados na seção :doc:`/appendices` do -manual. +Para cada lançamento principal e menor, a equipe CakePHP fornecerá um guia de migração. +Esses guias explicam os novos recursos e quaisquer mudanças quebradas que estão +em cada lançamento. Eles podem ser encontrados na seção :doc:`/appendices` do +cookbook. -Usando o CakePHP -================ +Usando CakePHP +============== -Se você está construindo sua aplicação com o CakePHP, as orientações a seguir -vão demonstrar a estabilidade que você pode esperar. +Se você está construindo sua aplicação com CakePHP, as seguintes diretrizes +explicam a estabilidade que você pode esperar. Interfaces ---------- -Com exceção dos *major releases*, interfaces oferecidas pelo CakePHP **não** -irão ter alterações em qualquer método. Novos métodos podem ser incluídos, mas -nenhum método existente será alterado. +Fora de lançamentos principais, interfaces fornecidas pelo CakePHP **não** terão nenhum +método existente alterado. Novos métodos podem ser adicionados, mas nenhum método existente será +alterado. Classes ------- -Classes oferecidas pelo CakePHP podem ser construidas e ter seus métodos -públicos e propriedades usados Não código da aplicação e com exceção de -*major releases* a retrocompatibilidade é garantida. +Classes fornecidas pelo CakePHP podem ser construídas e ter seus métodos públicos e +propriedades usadas por código de aplicação e fora de lançamentos principais a +compatibilidade com versões anteriores é garantida. .. note:: - Algumas classes Não CakePHP são marcadas com a *tag* da documentação da API - ``@internal``. Essas classes **não** são estáveis e não tem garantias de - retrocompatibilidade. + Algumas classes no CakePHP são marcadas com a tag de documentação API ``@internal``. Essas + classes **não** são estáveis e não têm nenhuma promessa de compatibilidade com versões anteriores. -Em *minor releases*, novos métodos podem ser adicionados a classes, e métodos -existentes podem passar a receber novos argumentos. Qualquer novo argumento vai -ter valores padrões, mas se você sobrescrever métodos com uma assinatura -diferente, é possível que você receba erros fatais. Métodos que recebem novos -argumentos serão documentados Não guia de migração correspondente ao *release*. +Em lançamentos menores, novos métodos podem ser adicionados a classes, e métodos existentes podem +ter novos argumentos adicionados. Quaisquer novos argumentos terão valores padrão, mas se +você substituiu métodos com uma assinatura diferente, pode ver erros fatais. +Métodos que tiverem novos argumentos adicionados serão documentados no guia de migração +para aquele lançamento. -A tabela a seguir descreve quais casos de uso e que tipo de compatibilidade -você pode esperar do CakePHP. +A tabela a seguir descreve vários casos de uso e qual compatibilidade você pode +esperar do CakePHP: +-------------------------------+--------------------------+ -| Se você... | Retrocompatibilidade? | +| Se você... | Compatibilidade? | +===============================+==========================+ -| Typehint referente à classe | Sim | +| Typehint contra a classe | Sim | +-------------------------------+--------------------------+ -| Criar uma nova instância | Sim | +| Cria uma nova instância | Sim | +-------------------------------+--------------------------+ -| Estender a classe | Sim | +| Estende a classe | Sim | +-------------------------------+--------------------------+ -| Acessar uma propriedade | Sim | -| pública | | +| Acessa uma propriedade pública| Sim | +-------------------------------+--------------------------+ -| Chamar um método público | Sim | +| Chama um método público | Sim | +-------------------------------+--------------------------+ -| **Estender uma classe e...** | +| **Estende uma classe e...** | +-------------------------------+--------------------------+ -| Sobrescrever uma | Sim | -| propriedade pública | | +| Substitui uma propriedade | Sim | +| pública | | +-------------------------------+--------------------------+ -| Acessar uma propriedade | Não [1]_ | +| Acessa uma propriedade | Não [1]_ | | protegida | | +-------------------------------+--------------------------+ -| Sobrescrever uma | Não [1]_ | -| propriedade protegida | | +| Substitui uma propriedade | Não [1]_ | +| protegida | | +-------------------------------+--------------------------+ -| Sobrescrever um método | Não [1]_ | +| Substitui um método protegido | Não [1]_ | +-------------------------------+--------------------------+ -| Chamar um método protegido | Não [1]_ | +| Chama um método protegido | Não [1]_ | +-------------------------------+--------------------------+ -| Adicionar uma propriedade | Não | +| Adiciona uma propriedade | Não | | pública | | +-------------------------------+--------------------------+ -| Adicionar um método público | Não | +| Adiciona um método público | Não | +-------------------------------+--------------------------+ -| Adicionar um argumento | Não [1]_ | -| a um método sobrescrito | | +| Adiciona um argumento a um | Não [1]_ | +| método substituído | | +-------------------------------+--------------------------+ -| Adicinar um valor padrão | Sim | -| a um argumento de método | | -| existente | | +| Adiciona um valor de argumento| Sim | +| padrão a um argumento de | | +| método existente | | +-------------------------------+--------------------------+ Trabalhando no CakePHP ====================== -Se você está ajudando a fazer o CakePHP ainda melhor, por favor, siga as -orientações a seguir quando estiver adicionando/alterando funcionalidades: +Se você está ajudando a tornar o CakePHP ainda melhor, por favor, mantenha as seguintes diretrizes +em mente ao adicionar/alterar funcionalidades: -Em um *minor release* você pode: +Em um lançamento menor você pode: +-------------------------------+--------------------------+ -| Em um *minor release* você pode... | +| Em um lançamento menor você | +| pode... | | +===============================+==========================+ | **Classes** | +-------------------------------+--------------------------+ @@ -125,20 +122,21 @@ Em um *minor release* você pode: +-------------------------------+--------------------------+ | Remover uma interface | Não | +-------------------------------+--------------------------+ -| Remover um trait | Não | +| Remover uma trait | Não | +-------------------------------+--------------------------+ | Tornar final | Não | +-------------------------------+--------------------------+ -| Tornar abstract | Não | +| Tornar abstrata | Não | +-------------------------------+--------------------------+ -| Trocar o nome | Sim [2]_ | +| Mudar nome | Sim [2]_ | +-------------------------------+--------------------------+ -| **Properties** | +| **Propriedades** | +-------------------------------+--------------------------+ | Adicionar uma propriedade | Sim | | pública | | +-------------------------------+--------------------------+ -| Remove a public property | Não | +| Remover uma propriedade | Não | +| pública | | +-------------------------------+--------------------------+ | Adicionar uma propriedade | Sim | | protegida | | @@ -152,9 +150,9 @@ Em um *minor release* você pode: +-------------------------------+--------------------------+ | Remover um método público | Não | +-------------------------------+--------------------------+ -| Adicionar um método público | Sim | +| Adicionar um método protegido | Sim | +-------------------------------+--------------------------+ -| Mover para uma classe parente | Sim | +| Mover para classe pai | Sim | +-------------------------------+--------------------------+ | Remover um método protegido | Sim [3]_ | +-------------------------------+--------------------------+ @@ -166,17 +164,52 @@ Em um *minor release* você pode: | com valor padrão | | +-------------------------------+--------------------------+ | Adicionar um novo argumento | Não | -| a um método existente. | | +| obrigatório a um método | | +| existente | | +-------------------------------+--------------------------+ | Remover um valor padrão de | Não | | um argumento existente | | +-------------------------------+--------------------------+ +| Mudar tipo de método para void| Sim | ++-------------------------------+--------------------------+ + +.. [1] Seu código *pode* ser quebrado por lançamentos menores. Verifique o guia de migração + para detalhes. +.. [2] Você pode mudar um nome de classe/método desde que o nome antigo permaneça + disponível. Isso geralmente é evitado a menos que a renomeação tenha benefício + significativo. +.. [3] Evite sempre que possível. Quaisquer remoções precisam ser documentadas no + guia de migração. + +Depreciações +============ + +Em cada lançamento menor, recursos podem ser depreciados. Se recursos forem depreciados, +documentação da API e avisos em tempo de execução serão adicionados. Erros em tempo de execução ajudam você +a localizar código que precisa ser atualizado antes de quebrar. Se você deseja desabilitar +avisos em tempo de execução, pode fazê-lo usando o valor de configuração ``Error.errorLevel``:: + + // em config/app.php + // ... + 'Error' => [ + 'errorLevel' => E_ALL ^ E_USER_DEPRECATED, + ] + // ... + +Isso desabilitará avisos de depreciação em tempo de execução. + +.. _experimental-features: + +Recursos Experimentais +====================== + +Recursos experimentais **não estão incluídos** nas promessas de compatibilidade com versões anteriores +acima. Recursos experimentais podem ter mudanças quebradas feitas em lançamentos menores +enquanto permanecerem experimentais. Recursos experimentais podem ser identificados pelo +aviso no livro e pelo uso de ``@experimental`` na documentação +da API. -.. [1] Seu código *pode* ser quebrado por *minor releases*. Verifique o guia de - migração para mais detalhes. -.. [2] Você pode mudar o nome de uma classe/método desde que o nome antigo - permaneça disponível. Isso normalmente é evitado, a não ser que a - renomeação traga algum benefício significante. -.. [3] Evite sempre que possível. Qualquer remoção precisa ser documentada - no guia de migração. +Recursos experimentais são destinados a ajudar a coletar feedback sobre como um recurso +funciona antes de se tornar estável. Uma vez que as interfaces e comportamento tenham sido verificados +com a comunidade, as flags experimentais serão removidas. diff --git a/pt/contributing/cakephp-coding-conventions.rst b/pt/contributing/cakephp-coding-conventions.rst index eab94b75c0..9cb363433d 100644 --- a/pt/contributing/cakephp-coding-conventions.rst +++ b/pt/contributing/cakephp-coding-conventions.rst @@ -1,30 +1,42 @@ -Padrões de codificação +Padrões de Codificação ###################### -Desenvolvedores do CakePHP deverão usar o `guia de codificação -PSR-12 `_ em adição às regras apresentadas -a seguir e definidas como padrão. +Os desenvolvedores do CakePHP utilizarão o `guia de estilo de codificação PSR-12 +`_ além das seguintes regras como +padrões de codificação. -É recomendado que outros desenvolvedores que optem pelo CakePHP sigam os mesmos +É recomendado que outros desenvolvedores de CakeIngredients sigam os mesmos padrões. Você pode usar o `CakePHP Code Sniffer -`_ para verificar se o seu -código segue os padrões estabelecidos. +`_ para verificar se seu código +segue os padrões exigidos. -Adicionando novos recursos -========================== +Adicionando Novos Recursos +=========================== + +Nenhum novo recurso deve ser adicionado sem ter seus próprios testes – que +devem ser aprovados antes de serem enviados ao repositório. + +Configuração da IDE +=================== + +Por favor, certifique-se de que sua IDE está configurada para "aparar à direita" os espaços em branco. +Não deve haver espaços em branco no final de cada linha. + +A maioria das IDEs modernas também suporta um arquivo ``.editorconfig``. O esqueleto +da aplicação CakePHP vem com ele por padrão. Ele já contém os padrões de boas práticas. -Nenhum novo recurso deve ser adicionado sem que tenha seus próprios testes -definidos, que por sua vez, devem estar passando antes que o novo recurso seja -enviado para o repositório. +Recomendamos usar o plugin `IdeHelper `_ se você +deseja maximizar a compatibilidade da IDE. Ele ajudará a manter as anotações atualizadas, o que fará +a IDE entender completamente como todas as classes funcionam juntas e fornece melhor dicas de tipo e auto-completar. Indentação ========== Quatro espaços serão usados para indentação. -Então, teremos uma estrutura similar a:: +Portanto, a indentação deve parecer assim:: // nível base // nível 1 @@ -35,30 +47,29 @@ Então, teremos uma estrutura similar a:: Ou:: $booleanVariable = true; - $stringVariable = 'jacaré'; + $stringVariable = 'moose'; if ($booleanVariable) { - echo 'Valor booleano é true'; - if ($stringVariable === 'jacaré') { - echo 'Nós encontramos um jacaré'; + echo 'Boolean value is true'; + if ($stringVariable === 'moose') { + echo 'We have encountered a moose'; } } -Em situações onde você estiver usando uma função em mais de uma linha, siga -as seguintes orientações: +Nos casos em que você está usando uma chamada de função de várias linhas, use as seguintes +diretrizes: -* O parêntese de abertura de uma função multi-linha deve ser o último conteúdo - da linha. -* Apenas um argumento é permitido por linha em uma função multi-linha. -* O parêntese de fechamento de uma função multi-linha deve ter uma linha - reservada para sí. +* O parêntese de abertura de uma chamada de função de várias linhas deve ser o último conteúdo na + linha. +* Apenas um argumento é permitido por linha em uma chamada de função de várias linhas. +* O parêntese de fechamento de uma chamada de função de várias linhas deve estar em uma linha separada. -Um exemplo, ao invés de usar a seguinte formatação:: +Como exemplo, em vez de usar a seguinte formatação:: $matches = array_intersect_key($this->_listeners, array_flip(preg_grep($matchPattern, array_keys($this->_listeners), 0))); -Use esta:: +Use isto em vez disso:: $matches = array_intersect_key( $this->_listeners, @@ -67,118 +78,114 @@ Use esta:: ) ); -Comprimento da linha +Comprimento da Linha ==================== -É recomendado manter as linhas próximas de 100 caracteres no comprimento para -melhor leitura do código. As linhas não devem ser mais longas que 120 -caracteres. +É recomendado manter as linhas com aproximadamente 100 caracteres para melhor +legibilidade do código. Um limite de 80 ou 120 caracteres torna necessário +distribuir lógica ou expressões complexas por função, bem como dar funções +e objetos nomes mais curtos e expressivos. As linhas não devem ter +mais de 120 caracteres. -Resumindo: +Em resumo: -* 100 caracteres é o limite recomendado. -* 120 caracteres é o limite máximo. +* 100 caracteres é o limite suave. +* 120 caracteres é o limite rígido. -Estruturas de controle -====================== +Estruturas de Controle +======================= -Estruturas de controle são por exemplo, "``if``", "``for``", "``foreach``", -"``while``", "``switch``", etc. A baixo, um exemplo com "``if``":: +Estruturas de controle são, por exemplo, "``if``", "``for``", "``foreach``", +"``while``", "``switch``" etc. Abaixo, um exemplo com "``if``":: if ((expr_1) || (expr_2)) { - // ação_1; + // action_1; } elseif (!(expr_3) && (expr_4)) { - // ação_2; + // action_2; } else { - // ação_padrão; + // default_action; } -* Nas estruturas de controle deve existir 1 (um) espaço antes do primeiro - parêntese e 1 (um) espaço entre o último parêntese e a chave de abertura. -* Sempre use chaves nas estruturas de controle, mesmo que não sejam - necessárias. Elas melhorar a leitura do código e tendem a causar menos erros - lógicos. -* A abertura da chave deve ser posicionada na mesma linha que a estrutura de - controle. A chave de fechamento deve ser colocada em uma nova linha e ter o - mesmo nível de indentação que a estrutura de controle. O conteúdo de dentro - das chaves deve começar em uma nova linha e receber um novo nível de - indentação. -* Atribuições em linha não devem ser usadas dentro de estruturas de controle. +* Nas estruturas de controle deve haver 1 (um) espaço antes do primeiro + parêntese e 1 (um) espaço entre o último parêntese e o colchete de abertura. +* Sempre use chaves nas estruturas de controle, mesmo que não sejam necessárias. + Elas aumentam a legibilidade do código e dão menos erros lógicos. +* As chaves de abertura devem ser colocadas na mesma linha que a estrutura de + controle. As chaves de fechamento devem ser colocadas em novas linhas e devem + ter o mesmo nível de indentação que a estrutura de controle. A declaração + incluída nas chaves deve começar em uma nova linha, e o código contido + nela deve ganhar um novo nível de indentação. +* Atribuições inline não devem ser usadas dentro das estruturas de controle. :: // errado = sem chaves, declaração mal posicionada - if (expr) declaração; + if (expr) statement; // errado = sem chaves if (expr) - declaração; + statement; - // certo + // bom if (expr) { - declaração; + statement; } - // errado = atribuição em linha + // errado = atribuição inline if ($variable = Class::function()) { - declaração; + statement; } - // certo + // bom $variable = Class::function(); if ($variable) { - declaração; + statement; } -Operadores ternários --------------------- +Operador Ternário +----------------- -Operadores ternários são admissíveis quando toda a operação ternária se encaixa -em uma única linha. Já operações mais longas devem ser divididas em -declarações ``if else``. Operadores ternários nunca devem ser aninhados. -Opcionalmente parênteses podem ser usados ao redor da verificação de condição -ternária para esclarecer a operação:: +Operadores ternários são permitidos quando toda a operação ternária cabe em uma +linha. Ternários mais longos devem ser divididos em instruções ``if else``. Operadores +ternários nunca devem ser aninhados. Opcionalmente, parênteses podem ser usados ao redor +da verificação de condição do ternário para maior clareza:: // Bom, simples e legível $variable = isset($options['variable']) ? $options['variable'] : true; - // Aninhamento é ruim + // Ternários aninhados são ruins $variable = isset($options['variable']) ? isset($options['othervar']) ? true : false : false; -Arquivos de template +Arquivos de Template -------------------- -Em arquivos de *template* (arquivos .php) os desenvolvedores devem usar -estruturas de controle por palavra-chave. A legibilidade em arquivos de -*template* complexos é muito melhor dessa forma. As estruturas de controle -podem tanto estar contidas em grandes blocos de código PHP, ou ainda em *tags* -PHP separadas:: +Em arquivos de template, os desenvolvedores devem usar estruturas de controle com palavras-chave. +Estruturas de controle com palavras-chave são mais fáceis de ler em arquivos de template complexos. Estruturas de +controle podem estar contidas em um bloco PHP maior ou em tags PHP separadas:: Você é o usuário administrador.

'; + echo '

You are the admin user.

'; endif; ?> -

A seguinte estrutura também é aceitável:

+

The following is also acceptable:

-

Você é o usuário administrador.

+

You are the admin user.

Comparação ========== -Sempre tente ser o mais rigoroso possível. Se uma comparação deliberadamente não -é estrita, pode ser inteligente comentar sobre isso para evitar confusões -geradas por falta de informação. +Sempre tente ser o mais estrito possível. Se um teste não estrito for deliberado, +pode ser prudente comentá-lo como tal para evitar confundi-lo com um erro. -Para testar se uma variável é nula, é recomendado usar uma verificação -estrita:: +Para testar se uma variável é null, é recomendado usar uma verificação estrita:: if ($value === null) { // ... } -O valor a ser verificado deve ser posto do lado direito:: +O valor a ser verificado deve ser colocado no lado direito:: // não recomendado if (null === $this->foo()) { @@ -190,35 +197,33 @@ O valor a ser verificado deve ser posto do lado direito:: // ... } -Chamadas de função +Chamadas de Função ================== -Funções devem ser chamadas sem espaço entre o nome da função e o parêntese -de abertura. Deve haver um espaço entre cada parâmetro de uma chamada de -função:: +Funções devem ser chamadas sem espaço entre o nome da função e o +parêntese de abertura. Deve haver um espaço entre cada parâmetro de uma chamada de função:: $var = foo($bar, $bar2, $bar3); -Como você pode ver a cima, deve haver um espaço em ambos os lados do sinal de -igual (=). +Como você pode ver acima, deve haver um espaço em ambos os lados do sinal de igual (=). -Definição de método -=================== +Definição de Método +==================== Exemplo de uma definição de método:: public function someFunction($arg1, $arg2 = '') { if (expr) { - declaração; + statement; } return $var; } -Parâmetros com um valor padrão, devem ser posicionados por último na definição -de uma função. Tente fazer suas funções retornarem algo, pelo menos ``true`` ou -``false``, assim pode-se determinar se a chamada de função foi bem-sucedida:: +Parâmetros com um valor padrão devem ser colocados por último na definição da função. +Tente fazer suas funções retornarem algo, pelo menos ``true`` ou ``false``, para que +se possa determinar se a chamada da função foi bem-sucedida:: public function connection($dns, $persistent = false) { @@ -235,80 +240,103 @@ de uma função. Tente fazer suas funções retornarem algo, pelo menos ``true`` return true; } -Existem espaços em ambos os lados dos sinais de igual. +Há espaços em ambos os lados do sinal de igual. -Declaração de tipo ------------------- +Retorno Antecipado +================== + +Tente evitar aninhamento desnecessário retornando antecipadamente:: + + public function run(array $data) + { + ... + if (!$success) { + return false; + } + + ... + } + + public function check(array $data) + { + ... + if (!$success) { + throw new RuntimeException(/* ... */); + } + + ... + } + +Isso ajuda a manter a lógica sequencial, o que melhora a legibilidade. + +Tipagem +------- -Argumentos que esperam objetos, *arrays* ou *callbacks* (válidos) podem ser -declarados por tipo. -Nós apenas declaramos métodos públicos, porém, o uso da declaração por tipo não -é livre de custos:: +Argumentos que esperam objetos, arrays ou callbacks (callable) podem ter tipo definido. +No entanto, apenas tipamos métodos públicos, pois a tipagem não é sem custo:: /** - * Descrição do método. + * Some method description. * - * @param \Cake\ORM\Table $table A classe Table a ser usada. - * @param array $array Algum valor em formato array. - * @param callable $callback Algum callback. - * @param bool $boolean Algum valor booleano. + * @param \Cake\ORM\Table $table The table class to use. + * @param array $array Some array value. + * @param callable $callback Some callback. + * @param bool $boolean Some boolean value. */ public function foo(Table $table, array $array, callable $callback, $boolean) { } -Aqui ``$table`` deve ser uma instância de ``\Cake\ORM\Table``, ``$array`` deve -ser um ``array`` e ``$callback`` deve ser do tipo ``callable`` (um *callback* -válido). +Aqui ``$table`` deve ser uma instância de ``\Cake\ORM\Table``, ``$array`` deve ser +um ``array`` e ``$callback`` deve ser do tipo ``callable`` (um callback válido). -Perceba que se você quiser permitir ``$array`` ser também uma instância de -``\ArrayObject`` você não deve declará-lo, pois ``array`` aceita apenas o tipo +Note que se você quiser permitir que ``$array`` também seja uma instância de +``\ArrayObject``, você não deve definir o tipo como ``array``, pois aceita apenas o tipo primitivo:: /** - * Descrição do método. + * Some method description. * - * @param array|\ArrayObject $array Algum valor em formato array. + * @param array|\ArrayObject $array Some array value. */ public function foo($array) { } -Funções anônimas (Closures) ---------------------------- +Funções Anônimas (Closures) +---------------------------- -Para se definir funções anônimas, segue-se o estilo de codificação `PSR-12 -`_, onde elas são declaradas com um espaço -depois da palavra-chave `function`, e um espaço antes e depois da palavra-chave -`use`:: +Definir funções anônimas segue o `guia de estilo de codificação PSR-12 +`_, onde são +declaradas com um espaço após a palavra-chave `function` e um espaço antes e depois +da palavra-chave `use`:: $closure = function ($arg1, $arg2) use ($var1, $var2) { - // código + // code }; -Encadeamento de métodos -======================= +Encadeamento de Métodos +======================== -Encadeamento de métodos deve ter múltiplos métodos distribuidos em linhas -separadas e indentados com quatro espaços:: +O encadeamento de métodos deve ter vários métodos distribuídos em linhas separadas e +indentados com quatro espaços:: - $email->from('foo@exemplo.com') - ->to('bar@exemplo.com') - ->subject('Uma mensagem legal') + $email->from('foo@example.com') + ->to('bar@example.com') + ->subject('A great message') ->send(); -Comentando código +Comentando Código ================= -Todos os comentários devem ser escritos em inglês, e devem de forma clara -descrever o bloco de código comentado. +Todos os comentários devem ser escritos em inglês e devem descrever de forma clara +o bloco de código comentado. -Comentários podem incluir as seguintes *tags* do -`phpDocumentor `_: +Os comentários podem incluir as seguintes tags do `phpDocumentor `_: * `@deprecated `_ - Usando o formato ``@version ``, onde ``version`` e - ``description`` são obrigatórios. + Usando o formato ``@version ``, onde ``version`` + e ``description`` são obrigatórios. Version refere-se àquela em que foi descontinuado. * `@example `_ * `@ignore `_ * `@internal `_ @@ -317,22 +345,22 @@ Comentários podem incluir as seguintes *tags* do * `@since `_ * `@version `_ -*Tags* PhpDoc são muito semelhantes a *tags* JavaDoc no Java. *Tags* são apenas -processadas se forem a primeira coisa numa linha de DocBlock, por exemplo:: +As tags PhpDoc são muito parecidas com as tags JavaDoc em Java. As tags só são processadas se +forem a primeira coisa em uma linha DocBlock, por exemplo:: /** - * Exemplo de tag. + * Tag example. * - * @author essa tag é analisada, mas essa versão é ignorada - * @version 1.0 essa tag também é analisada + * @author this tag is parsed, but this @version is ignored + * @version 1.0 this tag is also parsed */ :: /** - * Exemplo de tags phpDoc em linha. + * Example of inline phpDoc tags. * - * Essa função cria planos com foo() para conquistar o mundo. + * This function works hard with foo() to rule the world. * * @return void */ @@ -341,7 +369,7 @@ processadas se forem a primeira coisa numa linha de DocBlock, por exemplo:: } /** - * Função foo. + * Foo function. * * @return void */ @@ -349,50 +377,50 @@ processadas se forem a primeira coisa numa linha de DocBlock, por exemplo:: { } -Blocos de comentários, com a exceção do primeiro bloco em um arquivo, devem -sempre ser precedidos por uma nova linha. +Blocos de comentários, com exceção do primeiro bloco em um arquivo, devem sempre +ser precedidos por uma nova linha. -Tipos de variáveis +Tipos de Variáveis ------------------ -Tipos de variáveis para serem usadas em DocBlocks: +Tipos de variáveis para uso em DocBlocks: -Tipo - Descrição +Type + Description mixed - Uma variável com múltiplos tipos ou tipo indefinido. + Uma variável com tipo indefinido (ou múltiplo). int - Variável de tipo *int* (número inteiro). + Variável do tipo inteiro (número inteiro). float - Variável de tipo *float* (número decimal). + Tipo float (número com ponto decimal). bool - Variável de tipo *bool* (lógico, verdadeiro ou falso). + Tipo lógico (true ou false). string - Variável de tipo *string* (qualquer valor dentro de " " ou ' '). + Tipo string (qualquer valor entre " " ou ' '). null - Variável de tipo *null*. Normalmente usada em conjunto com outro tipo. + Tipo null. Geralmente usado em conjunto com outro tipo. array - Variável de tipo *array*. + Tipo array. object - Variável de tipo *object*. Um nome específico de classe deve ser usado, se - possível. + Tipo objeto. Um nome de classe específico deve ser usado se possível. resource - Variável de tipo *resource* (retornado de mysql\_connect() por exemplo). - Lembre-se que quando você especificar o tipo como *mixed*, você deve indicar - se o mesmo é desconhecido, ou quais os tipos possíveis. + Tipo resource (retornado por exemplo por mysql\_connect()). + Lembre-se de que quando você especifica o tipo como mixed, deve indicar + se é desconhecido ou quais são os tipos possíveis. callable - Variável de tipo função. + Função callable. -Você também pode combinar tipos usando o caractere de barra vertical:: +Você também pode combinar tipos usando o caractere pipe:: int|bool -Para mais de dois tipos é melhor usar ``mixed``. +Para mais de dois tipos, geralmente é melhor usar apenas ``mixed``. -Ao retornar o próprio objeto, e.g. para encadeamento, use ``$this`` ao invés:: +Ao retornar o próprio objeto (por exemplo, para encadeamento), deve-se usar ``$this`` +em vez disso:: /** - * Função Foo. + * Foo function. * * @return $this */ @@ -401,56 +429,52 @@ Ao retornar o próprio objeto, e.g. para encadeamento, use ``$this`` ao invés:: return $this; } -Incluindo arquivos +Incluindo Arquivos ================== -``include``, ``require``, ``include_once`` e ``require_once`` não tem +``include``, ``require``, ``include_once`` e ``require_once`` não têm parênteses:: - // errado = com parênteses + // errado = parênteses require_once('ClassFileName.php'); require_once ($class); - // certo = sem parênteses + // bom = sem parênteses require_once 'ClassFileName.php'; require_once $class; -Ao incluir arquivos com classes ou bibliotecas, use sempre e apenas a função -`require\_once `_. +Ao incluir arquivos com classes ou bibliotecas, use apenas e sempre a +função `require\_once `_. -Tags do PHP -=========== +Tags PHP +======== -Use sempre *tags* longas (````) ao invés de *tags* curtas (````). -O *short echo* deve ser usado em arquivos de template (**.php**) quando -apropriado. +Sempre use tags longas (````) em vez de tags curtas (````). O echo +curto deve ser usado em arquivos de template quando apropriado. -Short Echo +Echo Curto ---------- -O *short echo* deve ser usado em arquivos de template no lugar de -`` - // certo = sem ponto-e-virgula, com espaços + // bom = espaços, sem ponto e vírgula -A partir do PHP 5.4 a *tag short echo* (```_ * FTP: `ftp://ftp.example.com `_ -O nome de domínio "example.com" foi reservado para isso (see :rfc:`2606`), sendo -recomendado o seu uso em documentações como exemplos. +O nome de domínio "example.com" foi reservado para isso (veja :rfc:`2606`) e +é recomendado para uso em documentação ou como exemplos. Arquivos -------- -Nomes de arquivos que não contém classes devem ser em caixa baixa e sublinhados, +Nomes de arquivos que não contêm classes devem estar em letras minúsculas e sublinhados, por exemplo:: long_file_name.php -Moldagem de tipos +Conversão de Tipo ----------------- -Para moldagem usamos: +Para conversão de tipo usamos: -Tipo - Descrição +Type + Description (bool) - Converte para *boolean*. + Converter para boolean. (int) - Converte para *integer*. + Converter para integer. (float) - Converte para *float*. + Converter para float. (string) - Converte para *string*. + Converter para string. (array) - Converte para *array*. + Converter para array. (object) - Converte para *object*. + Converter para object. -Por favor use ``(int)$var`` ao invés de ``intval($var)`` e ``(float)$var`` ao -invés de ``floatval($var)`` quando aplicável. +Por favor, use ``(int)$var`` em vez de ``intval($var)`` e ``(float)$var`` em vez +de ``floatval($var)`` quando aplicável. -Constante ---------- +Constantes +---------- -Constantes devem ser definidas em caixa alta:: +Constantes devem ser definidas em letras maiúsculas:: define('CONSTANT', 1); -Se o nome de uma constante consiste de múltiplas palavras, eles devem ser -separados por um *underscore*, por exemplo:: +Se um nome de constante consiste em várias palavras, elas devem ser separadas por um +caractere de sublinhado, por exemplo:: define('LONG_NAMED_CONSTANT', 2); -Cuidados usando empty()/isset() -=============================== +Enums +----- + +Casos de Enum são definidos no estilo ``CamelCase``:: + + enum ArticleStatus: string + { + case Published = 'Y'; + case NotPublishedYet = 'N'; + } + +Cuidado ao usar empty()/isset() +================================ -Apesar de ``empty()`` ser uma função simples de ser usada, pode mascarar erros e -causar efeitos não intencionais quando ``'0'`` e ``0`` são retornados. Quando -variáveis ou propriedades já estão definidas, o uso de ``empty()`` não é -recomendado. Ao trabalhar com variáveis, é melhor confiar em coerção de tipo -com booleanos ao invés de ``empty()``:: +Embora ``empty()`` frequentemente pareça correto de usar, pode mascarar erros +e causar efeitos não intencionais quando ``'0'`` e ``0`` são fornecidos. Quando variáveis ou +propriedades já estão definidas, o uso de ``empty()`` não é recomendado. +Ao trabalhar com variáveis, é melhor confiar na coerção de tipo para boolean +em vez de ``empty()``:: function manipulate($var) { @@ -575,7 +591,7 @@ com booleanos ao invés de ``empty()``:: // ... } - // Recomendado, use coerção de tipo booleano + // Use coerção de tipo boolean if (!$var) { // ... } @@ -584,16 +600,16 @@ com booleanos ao invés de ``empty()``:: } } -Ao lidar com propriedades definidas, você deve favorecer verificações por -``null`` sobre verificações por ``empty()``/``isset()``:: +Ao lidar com propriedades definidas, você deve favorecer verificações de ``null`` em vez de +verificações ``empty()``/``isset()``:: class Thing { - private $property; // Definida + private $property; // Defined public function readProperty() { - // Não recomendado já que a propriedade está definida na classe + // Não recomendado pois a propriedade está definida na classe if (!isset($this->property)) { // ... } @@ -604,13 +620,13 @@ Ao lidar com propriedades definidas, você deve favorecer verificações por } } -Ao trabalhar com *arrays*, é melhor mesclar valores padronizados ao usar -verificações por ``empty()``. Assim, você se assegura que as chaves necessárias -estão definidas:: +Ao trabalhar com arrays, é melhor mesclar em padrões do que usar +verificações ``empty()``. Ao mesclar em padrões, você pode garantir que as chaves necessárias +estejam definidas:: function doWork(array $array) { - // Mescla valores para remover a necessidade de verificações via empty. + // Mesclar padrões para remover a necessidade de verificações empty. $array += [ 'key' => null, ]; @@ -627,5 +643,5 @@ estão definidas:: } .. meta:: - :title lang=pt: Padrões de codificação - :keywords lang=pt: indentação,comprimento,linha,funções,classes,métodos,variáveis,propriedades,arquivos,tipos,visibilidade,inclusão,operadores ternários,template,estruturas de controle + :title lang=pt: Padrões de Codificação + :keywords lang=pt: chaves,nível de indentação,erros lógicos,estruturas de controle,estrutura de controle,expr,padrões de codificação,parêntese,foreach,legibilidade,moose,novos recursos,repositório,desenvolvedores diff --git a/pt/contributing/code.rst b/pt/contributing/code.rst index 3cbc818f7d..65a7d0df4a 100644 --- a/pt/contributing/code.rst +++ b/pt/contributing/code.rst @@ -13,7 +13,7 @@ ambiente. Você vai precisar do seguinte *software*: * Git * PHP |minphpversion| ou maior -* PHPUnit 3.7.0 ou maior +* PHPUnit 5.7.0 ou maior Defina suas informações de usuário com seu nome e endereço de email:: @@ -129,12 +129,12 @@ Ao fazer *pull requests* você deve ter certeza que selecionou o *branch* corret atual, escolhe o *branch* **master** como seu alvo. * Se sua alteração for uma **feature**, então você deve escolher o *branch* referente ao próximo número de versão. Por exemplo, se o *branch* atual - estável for ``3.2.10``, o *branch* a receber novas funcionalidades será o - ``3.next``. + estável for ``4.0.0``, o *branch* a receber novas funcionalidades será o + ``4.next``. * Se sua alteração quebra funcionalidades existentes, ou API's, então você deverá escolher o próximo *major release*. Por exemplo, se o branch estável - atual for ``3.2.2``, então a versão na qual o comportamento pode ser quebrado - será na versão ``4.x``. + atual for ``4.0.0``, então a versão na qual o comportamento pode ser quebrado + será na versão ``5.x``. .. note:: diff --git a/pt/contributing/documentation.rst b/pt/contributing/documentation.rst index 08e8d46da8..b4e338483e 100644 --- a/pt/contributing/documentation.rst +++ b/pt/contributing/documentation.rst @@ -10,8 +10,7 @@ direita em qualquer página vai direcioná-lo para o editor online do Github. A documentação do CakePHP é `continuamente integrada `_, -sendo assim, você pode checar o status de -`várias builds `_ no servidor Jenkins a qualquer momento. +e implantada após cada pull request ser mesclada. Traduções ========= @@ -53,8 +52,8 @@ Por exemplo, se um novo arquivo é criado em **en/file.rst**, nós devemos: elementos ``toc-tree``. A nota a seguir será adicionada até que alguém traduza o arquivo:: - File Title - ########## + Título do Arquivo + ################# .. note:: Atualmente, a documentação desta página não é suportada em português. @@ -70,9 +69,8 @@ Por exemplo, se um novo arquivo é criado em **en/file.rst**, nós devemos: .. toctree:: :maxdepth: 1 - toc-file-x - toc-file-y - toc-file-z + one-toc-file + other-toc-file .. meta:: :title lang=pt: Título do arquivo diff --git a/pt/contributing/tickets.rst b/pt/contributing/tickets.rst index 80388ce0d7..8b29448252 100644 --- a/pt/contributing/tickets.rst +++ b/pt/contributing/tickets.rst @@ -20,10 +20,10 @@ ajudam a criar relatórios de erro melhores: seja corrigido. * **Faça**: Dê o máximo de detalhes sobre o seu ambiente: (SO, versão do PHP, versão do CakePHP). -* **Não faça**: Não use o sistema de *tickets* para sanar dúvidas. O canal de - IRC #cakephp na `Freenode `__ possui muitos - desenvolvedores dispníveis para ajudar a responder suas dúvidas. Também dê uma - olhada no `Stack Overflow `__. +* **Não faça**: Por favor, não use o sistema de *tickets* para fazer perguntas de suporte. Tanto o canal de suporte no + `CakePHP Slack workspace `__ quanto o canal IRC #cakephp no `Freenode `__ têm muitos + desenvolvedores disponíveis para ajudar a responder às suas perguntas. Consulte também o + `Stack Overflow `__ ou o `fórum oficial do CakePHP `__. Reportando problemas de segurança ================================= diff --git a/pt/controllers.rst b/pt/controllers.rst index 82d330f0b3..dea61932df 100644 --- a/pt/controllers.rst +++ b/pt/controllers.rst @@ -1,49 +1,47 @@ -Controllers (Controladores) -########################### +Controllers +########### .. php:namespace:: Cake\Controller .. php:class:: Controller -Os controllers (controladores) correspondem ao 'C' no padrão MVC. Após o roteamento ter sido -aplicado e o controller correto encontrado, a ação do controller é chamada. Seu -controller deve lidar com a interpretação dos dados de uma requisição, -certificando-se que os models corretos são chamados e a resposta ou view -esperada seja exibida. Os controllers podem ser vistos como intermediários entre -a camada Model e View. Você vai querer manter seus controllers magros e seus -Models gordos. Isso lhe ajudará a reutilizar seu código e testá-los mais -facilmente. - -Mais comumente, controllers são usados para gerenciar a lógica de um único -model. Por exemplo, se você está construindo um site para uma padaria online, -você pode ter um ``RecipesController`` e um ``IngredientsController`` -gerenciando suas receitas e seus ingredientes. No CakePHP, controllers são -nomeados de acordo com o model que manipulam. É também absolutamente possível -ter controllers que usam mais de um model. - -Os controllers da sua aplicação são classes que estendem a classe -``AppController``, a qual por sua vez estende a classe do core -:php:class:`Controller`. A classe ``AppController`` pode ser definida em -**src/Controller/AppController.php** e deve conter métodos que são -compartilhados entre todos os controllers de sua aplicação. - -Os controllers fornecem uma série de métodos que lidam com requisições. Estas -são chamados de *actions*. Por padrão, todos os métodos públicos em -um controller são uma action e acessíveis por uma URL. Uma action é responsável -por interpretar a requisição e criar a resposta. Normalmente as respostas são -na forma de uma view renderizada, mas também existem outras formas de criar -respostas. +Controllers são o 'C' no MVC. Após o roteamento ser aplicado e o controller +correto ser encontrado, a action do seu controller é chamada. Seu controller +deve manipular a interpretação dos dados da requisição, garantindo que os models +corretos sejam chamados e a resposta ou view correta seja renderizada. Controllers podem ser +pensados como camada intermediária entre o Model e a View. Você deve manter seus +controllers magros e seus models gordos. Isso ajudará você a reutilizar +seu código e tornará seu código mais fácil de testar. + +Comumente, um controller é usado para gerenciar a lógica em torno de um único model. Por +exemplo, se você estivesse construindo um site para uma padaria online, você pode ter um +RecipesController gerenciando suas receitas e um IngredientsController gerenciando seus +ingredientes. No entanto, também é possível ter controllers trabalhando com mais de +um model. No CakePHP, um controller é nomeado após o model primário que ele +manipula. + +Os controllers da sua aplicação estendem a classe ``AppController``, que por sua vez +estende a classe :php:class:`Controller` do núcleo. A classe ``AppController`` +pode ser definida em **src/Controller/AppController.php** e deve +conter métodos que são compartilhados entre todos os controllers da sua aplicação. + +Controllers fornecem vários métodos que manipulam requisições. Estes são chamados +*actions*. Por padrão, cada método público em +um controller é uma action e está acessível a partir de uma URL. Uma action é responsável +por interpretar a requisição e criar a resposta. Normalmente as respostas estão +na forma de uma view renderizada, mas existem outras formas de criar respostas +também. .. _app-controller: O App Controller ================ -Como mencionado anteriormente, a classe ``AppController`` é a mãe de todos os -outros controllers da sua aplicação. A própria ``AppController`` é estendida da +Como mencionado na introdução, a classe ``AppController`` é a classe pai +de todos os controllers da sua aplicação. ``AppController`` por si só estende a classe :php:class:`Cake\\Controller\\Controller` incluída no CakePHP. -Assim sendo, ``AppController`` é definida em -**src/Controller/AppController.php** como a seguir:: +``AppController`` é definida em **src/Controller/AppController.php** como +segue:: namespace App\Controller; @@ -53,15 +51,14 @@ Assim sendo, ``AppController`` é definida em { } -Os atributos e métodos criados em seu ``AppController`` vão estar disponíveis -para todos os controllers que a extendam. Components (sobre os quais você irá -aprender mais tarde) são a melhor alternativa para códigos usados por -muitos (mas não necessariamente em todos) controllers. +Atributos e métodos de controller criados no seu ``AppController`` estarão +disponíveis em todos os controllers que a estendem. Components (que você +aprenderá mais tarde) são melhor utilizados para código que é usado em muitos (mas não +necessariamente todos) controllers. -Você pode usar seu ``AppController`` para carregar components que serão usados -em cada controller de sua aplicação. O CakePHP oferece um método -``initialize()`` que é invocado ao final do construtor do controller para esse -tipo de uso:: +Você pode usar seu ``AppController`` para carregar components que serão usados em todos os +controllers da sua aplicação. CakePHP fornece um método ``initialize()`` que é +invocado no final do construtor de um Controller para este tipo de uso:: namespace App\Controller; @@ -69,146 +66,152 @@ tipo de uso:: class AppController extends Controller { - - public function initialize() + public function initialize(): void { - // Sempre habilite o CSRF component. - $this->loadComponent('Csrf'); + // Sempre habilita o component FormProtection. + $this->loadComponent('FormProtection'); } - } -Em adição ao método ``initialize()``, a antiga propriedade ``$components`` -também vai permitir você declarar quais components devem ser carregados. -Enquanto heranças objeto-orientadas normais são enquadradas, os components e -helpers usados por um controller são especialmente tratados. Nestes casos, os -valores de propriedade do ``AppController`` são mesclados com arrays de classes -controller filhas. Os valores na classe filha irão sempre sobre-escrever aqueles -na ``AppController``. - -Fluxo de requisições -==================== - -Quando uma requisição é feita para uma aplicação CakePHP, a classe -:php:class:`Cake\\Routing\\Router` e a classe -:php:class:`Cake\\Routing\\Dispatcher` usam :ref:`routes-configuration` para -encontrar e criar a instância correta do controller. Os dados da requisição são -encapsulados em um objeto de requisição. O CakePHP coloca todas as informações -importantes de uma requisição na propriedade ``$this->request``. Veja a seção -:ref:`cake-request` para mais informações sobre o objeto de requisição do -CakePHP. - -Métodos (actions) de controllers -================================ - -Actions de controllers são responsáveis por converter os parâmetros de -requisição em uma resposta para o navegador/usuário que fez a requisição. O -CakePHP usa convenções para automatizar este processo e remove alguns códigos -clichês que você teria que escrever de qualquer forma. - -Por convenção, o CakePHP renderiza uma view com uma versão flexionada do nome -da action. Retornando ao nosso exemplo da padaria online, nosso -``RecipesController`` poderia abrigar as actions ``view()``, ``share()`` e -``search()``. O controller seria encontrado em -**src/Controller/RecipesController.php** contendo:: +Fluxo de Requisição +=================== + +Quando uma requisição é feita para uma aplicação CakePHP, as classes +:php:class:`Cake\\Routing\\Router` e :php:class:`Cake\\Routing\\Dispatcher` +do CakePHP usam :ref:`routes-configuration` para encontrar e criar a +instância correta do controller. Os dados da requisição são encapsulados em um objeto de requisição. +CakePHP coloca todas as informações importantes da requisição na propriedade ``$this->request``. +Veja a seção sobre :ref:`cake-request` para mais informações sobre o +objeto de requisição do CakePHP. + +Controller Actions +================== + +Actions de controller são responsáveis por converter os parâmetros da requisição em uma +resposta para o navegador/usuário fazendo a requisição. CakePHP usa convenções para +automatizar este processo e remover algum código boilerplate que você de outra forma precisaria +escrever. + +Por convenção, CakePHP renderiza uma view com uma versão inflectada do nome da action. +Retornando ao nosso exemplo de padaria online, nosso RecipesController pode conter as +actions ``view()``, ``share()`` e ``search()``. O controller seria encontrado +em **src/Controller/RecipesController.php** e conteria:: // src/Controller/RecipesController.php class RecipesController extends AppController { - function view($id) + public function view($id) { - // A lógica da action vai aqui. + // Lógica da action vai aqui. } - function share($customerId, $recipeId) + public function share($customerId, $recipeId) { - // A lógica da action vai aqui. + // Lógica da action vai aqui. } - function search($query) + public function search($query) { - // A lógica da action vai aqui. + // Lógica da action vai aqui. } } -Os arquivos de template para estas actions seriam -**templates/Recipes/view.php**, **templates/Recipes/share.php** e -**templates/Recipes/search.php**. A nomenclatura convencional para arquivos -view é a versão lowercased (minúscula) e underscored (sem sublinhado) do nome -da action. +Os arquivos de template para essas actions seriam **templates/Recipes/view.php**, +**templates/Recipes/share.php** e **templates/Recipes/search.php**. O +nome convencional do arquivo de view é a versão em minúsculas e sublinhadas do +nome da action. -Actions dos controllers geralmente usam ``Controller::set()`` para criar um -contexto que a ``View`` usa para renderizar a camada view. Devido às convenções -que o CakePHP usa, você não precisa criar e renderizar as views manualmente. Ao -invés, uma vez que uma action de controller é completada, o CakePHP irá -manipular a renderização e devolver a view. +Actions de controller geralmente usam +``Controller::set()`` para criar um contexto que +``View`` usa para renderizar a camada de view. Por causa das convenções que o +CakePHP usa, você não precisa criar e renderizar a view manualmente. Em vez disso, +uma vez que uma action de controller tenha sido concluída, CakePHP manipulará a renderização e +entrega da View. -Se por alguma razão você quiser pular o comportamento padrão, você pode retornar -um objeto :php:class:`Cake\\Network\\Response` a partir da action com a resposta -definida. +Se por alguma razão você gostaria de pular o comportamento padrão, pode retornar um +objeto :php:class:`Cake\\Http\\Response` da action com a resposta totalmente +criada. -Para que você possa utilizar um controller de forma eficiente em sua própria -aplicação, nós iremos cobrir alguns dos atributos e métodos oferecidos pelo -controller do core do CakePHP. +Para que você use um controller efetivamente na sua própria aplicação, cobriremos +alguns dos atributos e métodos principais fornecidos pelos controllers do CakePHP. -Interagindo com views ---------------------- +Interagindo com Views +===================== -Os controllers interagem com as views de diversas maneiras. Primeiro eles -são capazes de passar dados para as views usando ``Controller::set()``. Você -também pode decidir no seu controller qual arquivo view deve ser renderizado -através do controller. +Controllers interagem com views de várias maneiras. Primeiro, eles +são capazes de passar dados para as views, usando ``Controller::set()``. Você também pode +decidir qual classe de view usar e qual arquivo de view deve ser +renderizado a partir do controller. .. _setting-view_variables: -Definindo variáveis para a view -------------------------------- +Definindo Variáveis de View +--------------------------- .. php:method:: set(string $var, mixed $value) O método ``Controller::set()`` é a principal maneira de enviar dados do seu -controller para a sua view. Após ter usado o método ``Controller::set()``, a -variável pode ser acessada em sua view:: +controller para sua view. Uma vez que você tenha usado ``Controller::set()``, a variável +pode ser acessada na sua view:: - // Primeiro você passa os dados do controller: + // Primeiro você passa dados do controller: $this->set('color', 'pink'); // Então, na view, você pode utilizar os dados: ?> - Você selecionou a cobertura para o bolo. + You have selected icing for the cake. -O método ``Controller::set()`` também aceita um array associativo como primeiro -parâmetro. Isto pode oferecer uma forma rápida para atribuir uma série de -informações para a view:: +O método ``Controller::set()`` também aceita um +array associativo como seu primeiro parâmetro. Isso pode frequentemente ser uma maneira rápida de +atribuir um conjunto de informações para a view:: $data = [ 'color' => 'pink', 'type' => 'sugar', - 'base_price' => 23.95 + 'base_price' => 23.95, ]; - // Faça $color, $type, e $base_price - // disponíveis na view: + // Torna $color, $type e $base_price + // disponíveis para a view: $this->set($data); -Renderizando uma view +Tenha em mente que variáveis de view são compartilhadas entre todas as partes renderizadas pela sua view. +Elas estarão disponíveis em todas as partes da view: o template, o layout e +todos os elementos dentro dos dois primeiros. + +Definindo Opções de View +------------------------ + +Se você quiser customizar a classe de view, caminhos de layout/template, helpers ou o +tema que será usado ao renderizar a view, você pode usar o +método ``viewBuilder()`` para obter um builder. Este builder pode ser usado para definir +propriedades da view antes de ser criada:: + + $this->viewBuilder() + ->addHelper('MyCustom') + ->setTheme('Modern') + ->setClassName('Modern.Admin'); + +O exemplo acima mostra como você pode carregar helpers customizados, definir o tema e usar uma +classe de view customizada. + +Renderizando uma View --------------------- .. php:method:: render(string $view, string $layout) -O método ``Controller::render()`` é chamado automaticamente no fim de cada ação -requisitada de um controller. Este método executa toda a lógica da view -(usando os dados que você passou usando o método ``Controller::set()``), coloca -a view em ``View::$layout``, e serve de volta para o usuário final. +O método ``Controller::render()`` é automaticamente chamado no final de cada action de +controller requisitada. Este método executa toda a lógica de view (usando os dados +que você submeteu usando o método ``Controller::set()``), coloca a view dentro do seu +``View::$layout`` e a serve de volta para o usuário final. -O arquivo view usado pelo método ``Controller::render()`` é determinado por -convenção. Se a action ``search()`` do controller ``RecipesController`` é -requisitada, o arquivo view encontrado em **templates/Recipes/search.php** -será renderizado:: +O arquivo de view padrão usado pelo render é determinado por convenção. +Se a action ``search()`` do RecipesController for requisitada, +o arquivo de view em **templates/Recipes/search.php** será renderizado:: namespace App\Controller; @@ -217,35 +220,33 @@ será renderizado:: // ... public function search() { - // Render the view in templates/Recipes/search.php - $this->render(); + // Renderiza a view em templates/Recipes/search.php + return $this->render(); } // ... } -Embora o CakePHP irá chamar o método ``Controller::render()`` automaticamente -(ao menos que você altere o atributo ``$this->autoRender`` para ``false``) após -cada action, você pode usá-lo para especificar um arquivo view alternativo -especificando o nome do arquivo view como primeiro parâmetro do método -``Controller::render()``. +Embora o CakePHP vá chamá-lo automaticamente após a lógica de cada action +(a menos que você tenha chamado ``$this->disableAutoRender()``), você pode usá-lo para especificar +um arquivo de view alternativo especificando um nome de arquivo de view como primeiro argumento do +método ``Controller::render()``. -Se o parâmetro ``$view`` começar com '/', é assumido ser um arquivo view -ou elemento relativo ao diretório ``/src/Template``. Isto -permite a renderização direta de elementos, muito útil em chamadas AJAX:: +Se ``$view`` começa com '/', assume-se que é um arquivo de view ou +elemento relativo à pasta **templates**. Isso permite +renderização direta de elementos, muito útil em chamadas AJAX:: // Renderiza o elemento em templates/element/ajaxreturn.php $this->render('/element/ajaxreturn'); -O segundo parâmetro ``$layout`` do ``Controller::render()`` permite que você -especifique o layout pelo qual a view é renderizada. +O segundo parâmetro ``$layout`` de ``Controller::render()`` permite que você especifique o layout +com o qual a view é renderizada. -Renderizando uma view específica -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Renderizando um Template Específico +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Em seu controller você pode querer renderizar uma view diferente do que a -convencional. Você pode fazer isso chamando o método -``Controller::render()`` diretamente. Uma vez chamado o método -``Controller::render()``, o CakePHP não tentará renderizar novamente a view:: +No seu controller, você pode querer renderizar uma view diferente da +convencional. Você pode fazer isso chamando ``Controller::render()`` diretamente. Uma vez que você +tenha chamado ``Controller::render()``, CakePHP não tentará re-renderizar a view:: namespace App\Controller; @@ -257,10 +258,10 @@ convencional. Você pode fazer isso chamando o método } } -Isto renderizaria o arquivo **templates/Posts/custom_file.php** ao invés de -**templates/Posts/my_action.php** +Isso renderizaria **templates/Posts/custom_file.php** em vez de +**templates/Posts/my_action.php**. -Você também pode renderizar views de plugins utilizando a seguinte sintaxe: +Você também pode renderizar views dentro de plugins usando a seguinte sintaxe: ``$this->render('PluginName.PluginController/custom_file')``. Por exemplo:: @@ -268,68 +269,142 @@ Por exemplo:: class PostsController extends AppController { - public function my_action() + public function myAction() { $this->render('Users.UserDetails/custom_file'); } } -Isto renderizaria **plugins/Users/templates/UserDetails/custom_file.php** +Isso renderizaria **plugins/Users/templates/UserDetails/custom_file.php** -Redirecionando para outras páginas -================================== +.. _controller-viewclasses: -.. php:method:: redirect(string|array $url, integer $status) +Negociação de Tipo de Conteúdo +============================== + +.. php:method:: addViewClasses() -O método de controle de fluxo que você vai usar na majoritariamente é -``Controller::redirect()``. Este método recebe seu primeiro parâmetro na forma -de uma URL relativa do CakePHP. Quando um usuário executar um pedido com êxito, -você pode querer redirecioná-lo para uma tela de recepção. :: +Controllers podem definir uma lista de classes de view que eles suportam. Após a +action do controller estar completa, CakePHP usará a lista de view para executar +negociação de tipo de conteúdo com :ref:`file-extensions` ou cabeçalhos ``Accept``. +Isso permite que sua aplicação reutilize a mesma action de controller para +renderizar uma view HTML ou renderizar uma resposta JSON ou XML. Para definir a lista de +classes de view suportadas por um controller, use o método ``addViewClasses()``:: - public function place_order() + namespace App\Controller; + + use Cake\View\JsonView; + use Cake\View\XmlView; + + class PostsController extends AppController { - // Logic for finalizing order goes here - if ($success) { - return $this->redirect( - ['controller' => 'Orders', 'action' => 'thanks'] - ); + public function initialize(): void + { + parent::initialize(); + + $this->addViewClasses([JsonView::class, XmlView::class]); } + } + +A classe ``View`` da aplicação é automaticamente usada como fallback quando nenhuma +outra view pode ser selecionada com base no cabeçalho ``Accept`` da requisição ou extensão de roteamento. +Se sua aplicação suporta apenas tipos de conteúdo para actions específicas, +você pode chamar ``addClasses()`` dentro da sua action também:: + + public function export(): void + { + // Use uma view CSV customizada para exportação de dados. + $this->addViewClasses([CsvView::class]); - return $this->redirect( - ['controller' => 'Orders', 'action' => 'confirm'] - ); + // Resto do código da action } -Este método irá retornar a instância da resposta com cabeçalhos apropriados -definidos. Você deve retornar a instância da resposta da sua action para -prevenir renderização de view e deixar o dispatcher controlar o redirecionamento -corrente. +Se dentro das actions do seu controller você precisar processar a requisição ou carregar dados +de forma diferente com base no tipo de conteúdo, você pode usar +:ref:`check-the-request`:: -Você também pode usar uma URL relativa ou absoluta como o parâmetro $url:: + // Em uma action de controller - return $this->redirect('/orders/thanks'); + // Carrega dados adicionais ao preparar respostas JSON + if ($this->request->is('json')) { + $query->contain('Authors'); + } - return $this->redirect('http://www.example.com'); +Caso sua aplicação precise de lógica mais complexa para decidir quais classes de view usar, +então você pode sobrescrever o método ``Controller::viewClasses()`` e retornar +um array de classes de view conforme necessário. + +.. note:: + Classes de view devem implementar o método hook estático ``contentType()`` para + participar da negociação de tipo de conteúdo. + +Fallbacks de Negociação de Tipo de Conteúdo +=========================================== + +Se nenhuma View puder ser correspondida com as preferências de tipo de conteúdo da requisição, CakePHP +usará a classe ``View`` base. Se você quiser exigir negociação de tipo de conteúdo, +pode usar a ``NegotiationRequiredView`` que define um código de status ``406``:: + + public function initialize(): void + { + parent::initialize(); -Você também pode passar dados para a action:: + // Exige negociação de cabeçalho Accept ou retorna uma resposta 406. + $this->addViewClasses([JsonView::class, NegotiationRequiredView::class]); + } - return $this->redirect(['action' => 'edit', $id]); +Você pode usar o valor de tipo de conteúdo ``TYPE_MATCH_ALL`` para construir sua própria lógica de fallback +de view:: -O segundo parâmetro passado no ``Controller::redirect()`` permite a você definir -um código de status HTTP para acompanhar o redirecionamento. Você pode querer -usar o código 301 (movido permanentemente) ou 303 (veja outro), dependendo -da natureza do redirecionamento. + namespace App\View; -Se você precisa redirecionar o usuário de volta para a página que fez a -requisição, você pode usar:: + use Cake\View\View; - $this->redirect($this->referer()); + class CustomFallbackView extends View + { + public static function contentType(): string + { + return static::TYPE_MATCH_ALL; + } -Um exemplo usando seqüências de consulta e hash pareceria com:: + } + +É importante lembrar que views match-all são aplicadas apenas *após* +a negociação de tipo de conteúdo ser tentada. + +Usando AjaxView +=============== + +Em aplicações que usam clientes hypermedia ou AJAX, você frequentemente precisa renderizar +conteúdos de view sem o layout envolvente. Você pode usar a ``AjaxView`` que é +fornecida com o esqueleto da aplicação:: + + // Em uma action de controller, ou em beforeRender. + if ($this->request->is('ajax')) { + $this->viewBuilder()->setClassName('Ajax'); + } + +``AjaxView`` responderá como ``text/html`` e usará o layout ``ajax``. +Geralmente este layout é mínimo ou contém marcação específica do cliente. Isso +substitui o uso de ``RequestHandlerComponent`` automaticamente usando a +``AjaxView`` no 4.x. + +Redirecionando para Outras Páginas +================================== + +.. php:method:: redirect(string|array $url, integer $status) + +O método ``redirect()`` adiciona um cabeçalho ``Location`` e define o código de status de +uma resposta e a retorna. Você deve retornar a resposta criada por +``redirect()`` para que o CakePHP envie o redirecionamento em vez de completar a +action do controller e renderizar uma view. + +Você pode redirecionar usando valores de :term:`routing array`:: return $this->redirect([ 'controller' => 'Orders', 'action' => 'confirm', + $order->id, '?' => [ 'product' => 'pizza', 'quantity' => 5 @@ -337,168 +412,210 @@ Um exemplo usando seqüências de consulta e hash pareceria com:: '#' => 'top' ]); -A URL gerada seria:: +Ou usando uma URL relativa ou absoluta:: - http://www.example.com/orders/confirm?product=pizza&quantity=5#top + return $this->redirect('/orders/confirm'); -Redirecionando para outra action no mesmo Controller ----------------------------------------------------- + return $this->redirect('http://www.example.com'); -.. php:method:: setAction($action, $args...) +Ou para a página referenciadora:: -Se você precisar redirecionar a atual action para uma diferente no *mesmo* -controller, você pode usar ``Controller::setAction()`` para atualizar o objeto -da requisição, modificar o template da view que será renderizado e redirecionar -a execução para a action especificada:: + return $this->redirect($this->referer()); - // De uma action delete, você pode renderizar uma página - // de índice atualizada. - $this->setAction('index'); +Usando o segundo parâmetro você pode definir um código de status para seu redirecionamento:: -Carregando models adicionais -============================ + // Faz um 301 (movido permanentemente) + return $this->redirect('/order/confirm', 301); -.. php:method:: loadModel(string $modelClass, string $type) + // Faz um 303 (veja outro) + return $this->redirect('/order/confirm', 303); -O método ``loadModel`` vem a calhar quando você precisa usar um model que -não é padrão do controller ou o seu model não está associado com -este.:: +Veja a seção :ref:`redirect-component-events` para como redirecionar a partir de +um manipulador de ciclo de vida. - // Em um método do controller. - $this->loadModel('Articles'); - $recentArticles = $this->Articles->find('all', [ - 'limit' => 5, - 'order' => 'Articles.created DESC' - ]); +Carregando Tables/Models Adicionais +=================================== -Se você está usando um provedor de tabelas que não os da ORM nativa você pode -ligar este sistema de tabelas aos controllers do CakePHP conectando seus -métodos de factory:: +.. php:method:: fetchTable(string $alias, array $config = []) - // Em um método do controller. - $this->modelFactory( - 'ElasticIndex', - ['ElasticIndexes', 'factory'] - ); +O método ``fetchTable()`` é útil quando você precisa usar uma table ORM que não é +a padrão do controller:: -Depois de registrar uma tabela factory, você pode usar o ``loadModel`` para -carregar instâncias:: + // Em um método de controller. + $recentArticles = $this->fetchTable('Articles')->find('all', + limit: 5, + order: 'Articles.created DESC' + ) + ->all(); - // Em um método do controller - $this->loadModel('Locations', 'ElasticIndex'); +.. php:method:: fetchModel(string|null $modelClass = null, string|null $modelType = null) -.. note:: +O método ``fetchModel()`` é útil para carregar models não-ORM ou tables ORM que +não são as padrões do controller:: - O TableRegistry da ORM nativa é conectado por padrão como o provedor de - 'Tabelas'. + // ModelAwareTrait precisa ser explicitamente adicionado ao seu controller primeiro para fetchModel() funcionar. + use ModelAwareTrait; -Paginando um model + // Obtém um model ElasticSearch + $articles = $this->fetchModel('Articles', 'Elastic'); + + // Obtém um model webservices + $github = $this->fetchModel('GitHub', 'Webservice'); + + // Se você pular o 2º argumento, por padrão tentará carregar uma table ORM. + $authors = $this->fetchModel('Authors'); + +.. versionadded:: 4.5.0 + +Paginando um Model ================== .. php:method:: paginate() -Este método é usado para fazer a paginação dos resultados retornados por -seus models. Você pode especificar o tamanho da página (quantos resultados -serão retornados), as condições de busca e outros parâmetros. Veja a seção -:doc:`pagination ` para mais detalhes -sobre como usar o método ``paginate()`` +Este método é usado para paginar resultados obtidos pelos seus models. +Você pode especificar tamanhos de página, condições de busca do model e mais. Veja a +seção de :doc:`pagination ` para mais detalhes sobre +como usar ``paginate()``. -O atributo paginate lhe oferece uma forma fácil de customizar como -``paginate()`` se comporta:: +O atributo ``$paginate`` oferece uma maneira de customizar como ``paginate()`` +se comporta:: class ArticlesController extends AppController { - public $paginate = [ + protected array $paginate = [ 'Articles' => [ - 'conditions' => ['published' => 1] - ] + 'conditions' => ['published' => 1], + ], ]; } -Configurando components para carregar +Configurando Components para Carregar ===================================== .. php:method:: loadComponent($name, $config = []) -Em seu método ``initialize()`` do controller você pode definir qualquer -component que quiser carregado, e qualquer configuração de dados para eles:: +No método ``initialize()`` do seu Controller você pode definir quaisquer components que +deseja carregar e quaisquer dados de configuração para eles:: - public function intialize() + public function initialize(): void { parent::initialize(); - $this->loadComponent('Csrf'); + $this->loadComponent('Flash'); $this->loadComponent('Comments', Configure::read('Comments')); } -.. php:attr:: components +.. _controller-life-cycle: -A propriedade ``$components`` em seus controllers permitem a você configurar -components. Components configurados e suas dependências serão criados pelo -CakePHP para você. Leia a seção :ref:`configuring-components` para mais -informações. Como mencionado anteriormente, a propriedade ``$components`` será -mesclada com a propriedade definida em cada classe parente do seu controller. +Callbacks do Ciclo de Vida da Requisição +======================================== -Configurando helpers para carregar -================================== +Controllers do CakePHP disparam vários eventos/callbacks que você pode usar para inserir +lógica em torno do ciclo de vida da requisição: -.. php:attr:: helpers +Lista de Eventos +---------------- -Vamos observar como dizer ao controller do CakePHP que você planeja usar -classes MVC adicionais:: +* ``Controller.initialize`` +* ``Controller.startup`` +* ``Controller.beforeRedirect`` +* ``Controller.beforeRender`` +* ``Controller.shutdown`` - class RecipesController extends AppController - { - public $helpers = ['Form']; - } +Métodos Callback de Controller +------------------------------ -Cada uma dessas variáveis são mescladas com seus valores herdados, -portanto não é necessário (por exemplo) redeclarar o ``FormHelper``, -ou qualquer coisa declarada em seu ``AppController``. +Por padrão, os seguintes métodos callback são conectados aos eventos relacionados se os +métodos forem implementados pelos seus controllers -.. _controller-life-cycle: +.. php:method:: beforeFilter(EventInterface $event) + + Chamado durante o evento ``Controller.initialize`` que ocorre antes de toda + action no controller. É um lugar útil para verificar uma sessão ativa + ou inspecionar permissões de usuário. -Ciclo de vida de callbacks em uma requisição -============================================ + .. note:: -Os controllers do CakePHP vêm equipados com callbacks que você pode usar para -inserir lógicas em torno do ciclo de vida de uma requisição: + O método beforeFilter() será chamado para actions inexistentes. -.. php:method:: beforeFilter(Event $event) + Retornar uma resposta de um método ``beforeFilter`` não impedirá outros + ouvintes do mesmo evento de serem chamados. Você deve explicitamente + :ref:`parar o evento `. - Este método é executado antes de cada ação dos controllers. - É um ótimo lugar para verificar se há uma sessão ativa ou inspecionar as - permissões de um usuário. +.. php:method:: beforeRender(EventInterface $event) - .. note:: + Chamado durante o evento ``Controller.beforeRender`` que ocorre após + a lógica da action do controller, mas antes da view ser renderizada. Este callback não é + usado frequentemente, mas pode ser necessário se você estiver chamando + :php:meth:`Cake\\Controller\\Controller::render()` manualmente antes do fim + de uma action específica. + +.. php:method:: afterFilter(EventInterface $event) - O método beforeFilter() será chamado para ações ausêntes. + Chamado durante o evento ``Controller.shutdown`` que é disparado após + toda action de controller e após a renderização estar completa. Este é o último + método de controller a ser executado. -.. php:method:: beforeRender(Event $event) +Além dos callbacks de ciclo de vida de controller, :doc:`/controllers/components` +também fornecem um conjunto similar de callbacks. - Chamada após a lógica da action de um controller, mas antes da view ser - renderizada. Esse callback não é usado frequentemente, mas pode ser - necessário se você estiver chamando - :php:meth:`~Cake\\Controller\\Controller::render()` manualmente antes do - final de uma determinada action. +Lembre-se de chamar os callbacks do ``AppController`` dentro dos callbacks de controllers filhos +para melhores resultados:: -.. php:method:: afterFilter() + //use Cake\Event\EventInterface; + public function beforeFilter(EventInterface $event): void + { + parent::beforeFilter($event); + } - Chamada após cada ação dos controllers, e após a completa renderização da - view. Este é o último método executado do controller. +.. _controller-middleware: -Em adição ao ciclo de vida dos callbacks do controller, -:doc:`/controllers/components` também oferece um conjunto de callbacks -similares. +Usando Redirecionamentos em Eventos de Controller +================================================= -Lembre de chamar os callbacks do ``AppController`` em conjunto com os callbacks -dos controllers para melhores resultados:: +Para redirecionar a partir de um método callback de controller você pode usar o seguinte:: - public function beforeFilter(Event $event) + public function beforeFilter(EventInterface $event): void { - parent::beforeFilter($event); + if (...) { + $event->setResult($this->redirect('/')); + + return; + } + + ... + } + +Ao definir um redirecionamento como resultado de evento, você permite que o CakePHP saiba que você não quer que nenhum outro +callback de component seja executado e que o controller não deve manipular a action +mais adiante. + +A partir da versão 4.1.0 você também pode lançar uma ``RedirectException`` para sinalizar um redirecionamento. + +Controller Middleware +===================== + +.. php:method:: middleware($middleware, array $options = []) + +:doc:`Middleware ` pode ser definido globalmente, em +um escopo de roteamento ou dentro de um controller. Para definir middleware para um controller específico, +use o método ``middleware()`` do método ``initialize()`` +do seu controller:: + + public function initialize(): void + { + parent::initialize(); + + $this->middleware(function ($request, $handler) { + // Lógica do middleware. + + // Certifique-se de retornar uma resposta ou chamar handle() + return $handler->handle($request); + }); } -Mais sobre controllers +Middleware definido por um controller será chamado **antes** dos métodos ``beforeFilter()`` e de action serem chamados. + +Mais sobre Controllers ====================== .. toctree:: diff --git a/pt/controllers/components.rst b/pt/controllers/components.rst index 43609cb2ed..c7f6383963 100644 --- a/pt/controllers/components.rst +++ b/pt/controllers/components.rst @@ -1,128 +1,128 @@ Componentes ########### -Componentes são pacotes de lógica compartilhados entre controladores. O CakePHP -vem com um conjunto fantástico de componentes principais que você pode usar para -ajudar em várias tarefas comuns. Você também pode criar seus próprios componentes. -Se você deseja copiar e colar coisas entre controladores, considere criar seu próprio -componente para conter a funcionalidade. A criação de componentes mantém o código do -controlador limpo e permite reutilizar o código entre diferentes controladores. +Componentes são pacotes de lógica compartilhados entre controllers. +O CakePHP vem com um conjunto fantástico de componentes principais que você pode usar para auxiliar em +várias tarefas comuns. Você também pode criar seus próprios componentes. Se você +quiser copiar e colar coisas entre controllers, deve +considerar criar seu próprio componente para conter a funcionalidade. Criar +componentes mantém o código do controller limpo e permite que você reutilize código entre +diferentes controllers. -Para mais informações sobre os componentes incluídos no CakePHP, consulte o -capítulo para cada componente: +Para mais informações sobre os componentes incluídos no CakePHP, confira o +capítulo de cada componente: .. toctree:: :maxdepth: 1 - /controllers/components/authentication /controllers/components/flash - /controllers/components/security - /controllers/components/pagination - /controllers/components/request-handling + /controllers/components/form-protection + /controllers/components/check-http-cache .. _configuring-components: Configurando Componentes ======================== -Muitos dos componentes principais requerem configuração. Alguns exemplos de componentes -que requerem configuração são :doc:`/controllers/components/security` e -:doc:`/controllers/components/request-handling`. A configuração desses componentes e dos -componentes em geral é geralmente feita via ``loadComponent()`` no método ``initialize()`` -do seu Controlador ou através do array ``$components``:: +Muitos dos componentes principais exigem configuração. Um exemplo seria +o :doc:`/controllers/components/form-protection`. A configuração desses componentes, +e de componentes em geral, geralmente é feita via ``loadComponent()`` no método ``initialize()`` do seu +Controller ou via array ``$components``:: class PostsController extends AppController { public function initialize(): void { parent::initialize(); - $this->loadComponent('RequestHandler', [ - 'viewClassMap' => ['json' => 'AppJsonView'], + $this->loadComponent('FormProtection', [ + 'unlockedActions' => ['index'], ]); - $this->loadComponent('Security', ['blackholeCallback' => 'blackhole']); + $this->loadComponent('Flash'); } - } -Você pode configurar componentes em tempo de execução usando o método ``setConfig()``. -Muitas vezes, isso é feito no método ``beforeFilter()`` do seu controlador. O exemplo acima -também pode ser expresso como:: +Você pode configurar componentes em tempo de execução usando o método ``setConfig()``. Frequentemente, +isso é feito no método ``beforeFilter()`` do seu controller. O exemplo acima +também poderia ser expresso como:: - public function beforeFilter(EventInterface $event) + public function beforeFilter(EventInterface $event): void { - $this->RequestHandler->setConfig('viewClassMap', ['rss' => 'MyRssView']); + $this->FormProtection->setConfig('unlockedActions', ['index']); } -Como os auxiliares, os componentes implementam os métodos ``getConfig()`` e -``setConfig()`` para ler e gravar dados de configuração:: +Assim como os helpers, os componentes implementam os métodos ``getConfig()`` e ``setConfig()`` +para ler e escrever dados de configuração:: - // Leia os dados de configuração. - $this->RequestHandler->getConfig('viewClassMap'); + // Ler dados de configuração. + $this->FormProtection->getConfig('unlockedActions'); // Definir configuração - $this->Csrf->setConfig('cookieName', 'token'); + $this->Flash->setConfig('key', 'myFlash'); -Assim como os auxiliares, os componentes mesclam automaticamente sua propriedade -``$ _defaultConfig`` com a configuração do construtor para criar a propriedade -``$_config`` que pode ser acessada com ``getConfig()`` e ``setConfig()``. +Assim como os auxiliares, os componentes mesclarão automaticamente sua propriedade ``$_defaultConfig`` +com a configuração do construtor para criar a propriedade ``$_config`` +que pode ser acessada com ``getConfig()`` e ``setConfig()``. -Alias em Componentes +Aliasing Componentes -------------------- -Uma configuração comum a ser usada é a opção ``className``, que permite o alias -de componentes. Esse recurso é útil quando você deseja substituir ``$this->Auth`` -ou outra referência de componente comum por uma implementação personalizada:: +Uma configuração comum é a opção ``className``, que permite +criar alias para componentes. Este recurso é útil quando você deseja +substituir ``$this->Flash`` ou outra referência comum a Componentes por uma +implementação personalizada:: // src/Controller/PostsController.php class PostsController extends AppController { public function initialize(): void { - $this->loadComponent('Auth', [ - 'className' => 'MyAuth' + $this->loadComponent('Flash', [ + 'className' => 'MyFlash', ]); } } - // src/Controller/Component/MyAuthComponent.php - use Cake\Controller\Component\AuthComponent; + // src/Controller/Component/MyFlashComponent.php + use Cake\Controller\Component\FlashComponent; - class MyAuthComponent extends AuthComponent + class MyFlashComponent extends FlashComponent { - // Adicione seu código para substituir o principal AuthComponent + // Adicione seu código para substituir o FlashComponent principal } -O exemplo acima seria *alias* ``MyAuthComponent`` para ``$this->Auth`` em seus controladores. +O comando acima seria um *alias* de ``MyFlashComponent`` para ``$this->Flash`` em seus +controllers. .. note:: - O alias de um componente substitui essa instância em qualquer lugar em que esse componente - seja usado, inclusive dentro de outros componentes. + Criar um alias para um componente substitui essa instância em qualquer lugar em + que o componente seja usado, inclusive dentro de outros componentes. -Carregando Componentes em Tempo Real +Carregando Componentes em Rempo Real ------------------------------------ -Você pode não precisar de todos os seus componentes disponíveis em todas as ações do controlador. +Você pode não precisar de todos os seus componentes disponíveis em todas as ações do controller. Em situações como essa, você pode carregar um componente em tempo de execução usando o método -``loadComponent()`` no seu controlador:: +``loadComponent()`` no seu controller: - // Em um método do controlador + // Na ação do controller $this->loadComponent('OneTimer'); $time = $this->OneTimer->getTime(); .. note:: - Lembre-se de que os componentes carregados em tempo real não terão retornos de chamada perdidos. - Se você confiar nos retornos de chamada ``beforeFilter`` ou ``startup`` que estão sendo chamados, - pode ser necessário chamá-los manualmente, dependendo de quando você carregar o componente. + Lembre-se de que os componentes carregados em tempo real não terão chamadas de retorno de chamada + perdidas. Se você depender da chamada dos retornos de chamada ``beforeFilter`` ou ``startup`` + , poderá ser necessário chamá-los manualmente, dependendo de quando + você carregar seu componente. Usando Componentes ================== -Depois de incluir alguns componentes no seu controlador, usá-los é bastante simples. -Cada componente usado é exposto como uma propriedade no seu controlador. Se você -carregou a classe :php:class:`Cake\\Controller\\Component\\FlashComponent` no seu -controlador, é possível acessá-lo da seguinte maneira:: +Depois de incluir alguns componentes no seu controller, usá-los é bem +simples. Cada componente usado é exposto como uma propriedade no seu controller. Se +você tivesse carregado a :php:class:`Cake\\Controller\\Component\\FlashComponent` +no seu controller, você poderia acessá-lo assim:: class PostsController extends AppController { @@ -135,7 +135,7 @@ controlador, é possível acessá-lo da seguinte maneira:: public function delete() { if ($this->Post->delete($this->request->getData('Post.id')) { - $this->Flash->success('Post deleted.'); + $this->Flash->success('Post deletado.'); return $this->redirect(['action' => 'index']); } @@ -143,22 +143,25 @@ controlador, é possível acessá-lo da seguinte maneira:: .. note:: - Como os Modelos e os Componentes são adicionados aos Controladores - como propriedades, eles compartilham o mesmo 'namespace'. Certifique-se - de não dar o mesmo nome a um componente de um modelo. + Como Modelos e Componentes são adicionados aos Controllers como + propriedades, eles compartilham o mesmo "namespace". Certifique-se de não dar a um + componente e a um modelo o mesmo nome. + +.. versionchanged:: 5.1.0 + Os componentes podem usar :doc:`/development/dependency-injection` para receber serviços. .. _creating-a-component: Criando um Componente ===================== -Suponha que nosso aplicativo precise executar uma operação matemática complexa -em muitas partes diferentes do aplicativo. Poderíamos criar um componente para -hospedar essa lógica compartilhada para uso em muitos controladores diferentes. +Suponha que nossa aplicação precise realizar uma operação matemática complexa em +várias partes diferentes da aplicação. Poderíamos criar um componente para abrigar +essa lógica compartilhada para uso em diversos controllers. -O primeiro passo é criar um novo arquivo e classe de componente. Crie o arquivo em -**src/Controller/Component/MathComponent.php**. A estrutura básica do componente -será semelhante a isso:: +O primeiro passo é criar um novo arquivo de componente e uma nova classe. Crie o arquivo em +**src/Controller/Component/MathComponent.php**. A estrutura básica do +componente seria algo como isto:: namespace App\Controller\Component; @@ -174,52 +177,74 @@ será semelhante a isso:: .. note:: - Todos os componentes devem estender :php:class:`Cake\\Controller\\Component`. - Não fazer isso acionará uma exceção. + Todos os componentes devem estender :php:class:`Cake\\Controller\\Component`. Caso contrário, + uma exceção será acionada. + +Os componentes podem usar :doc:`/development/dependency-injection` para receber serviços +como parâmetros do construtor:: + + namespace App\Controller\Component; + + use Cake\Controller\Component; + use App\Service\UserService; + + class SsoComponent extends Component + { + public function __construct( + ComponentRegistry $registry, + array $config = [], + UserService $users + ) { + parent::__construct($registry, $config); + $this->users = $users; + } + } + +.. versionadded: 5.1.0 + Foi adicionado suporte ao contêiner DI para componentes. -Incluindo seu Componente em seus Controladores ----------------------------------------------- +Incluindo seu Componente no seu Controller +------------------------------------------ -Depois que nosso componente é concluído, podemos usá-lo nos controladores -do aplicativo carregando-o durante o método ``initialize()`` do controlador. -Uma vez carregado, o controlador receberá um novo atributo com o nome do componente, -através do qual podemos acessar uma instância dele:: +Assim que nosso componente estiver pronto, podemos usá-lo nos controllers +da aplicação, carregando-o durante o método ``initialize()`` do controllers. +Uma vez carregado, o controllers receberá um novo atributo com o nome do +componente, por meio do qual podemos acessar uma instância dele:: // Em um controlador // Disponibilize o novo componente em $this->Math, - // bem como o padrão $this->Csrf + // assim como o $this->Flash padrão public function initialize(): void { parent::initialize(); $this->loadComponent('Math'); - $this->loadComponent('Csrf'); + $this->loadComponent('Flash'); } -Ao incluir componentes em um controlador, você também pode declarar -um conjunto de parâmetros que serão passados para o construtor do componente. -Esses parâmetros podem ser manipulados pelo componente:: +Ao incluir Componentes em um Controller, você também pode declarar um +conjunto de parâmetros que serão passados ​​ao construtor +do Componente. Esses parâmetros podem então ser manipulados +pelo Componente:: - // Em seu controlador + // No seu controller. public function initialize(): void { parent::initialize(); $this->loadComponent('Math', [ 'precision' => 2, - 'randomGenerator' => 'srand' + 'randomGenerator' => 'srand', ]); - $this->loadComponent('Csrf'); + $this->loadComponent('Flash'); } -O exemplo acima passaria um array contendo precision e randomGenerator -para ``MathComponent::initialize()`` no parâmetro ``$config``. +O exemplo acima passaria o array contendo precision e randomGenerator para +``MathComponent::initialize()`` no parâmetro ``$config``. -Usando Outros Componentes em seu Componente +Usando Outros Componentes no seu Componente ------------------------------------------- -Às vezes, um de seus componentes pode precisar usar outro componente. -Nesse caso, você pode incluir outros componentes no seu componente -exatamente da mesma maneira que os inclui nos controladores - usando o -atributo ``$components``:: +Às vezes, um dos seus componentes pode precisar usar outro componente. +Você pode carregar outros componentes adicionando-os à propriedade `$components`:: // src/Controller/Component/CustomComponent.php namespace App\Controller\Component; @@ -229,9 +254,9 @@ atributo ``$components``:: class CustomComponent extends Component { // O outro componente que seu componente usa - public $components = ['Existing']; + protected array $components = ['Existing']; - // Execute qualquer outra configuração adicional para o seu componente. + // Execute qualquer outra configuração adicional para seu componente. public function initialize(array $config): void { $this->Existing->foo(); @@ -250,7 +275,6 @@ atributo ``$components``:: class ExistingComponent extends Component { - public function foo() { // ... @@ -259,54 +283,89 @@ atributo ``$components``:: .. note:: - Ao contrário de um componente incluído em um controlador, + Ao contrário de um componente incluído em um controller, nenhum retorno de chamada será acionado no componente de um componente. -Acessando o Controlador de um Componente ----------------------------------------- +Acessando um Componente de Controller +------------------------------------- -De dentro de um componente, você pode acessar o controlador atual através do +De dentro de um Componente, você pode acessar o controller atual por meio do registro:: - $controller = $this->_registry->getController(); - -Você pode acessar o controlador em qualquer método de retorno de chamada do objeto de -evento:: - - $controller = $event->getSubject(); + $controller = $this->getController(); -Callback de Componentes -======================= +Retornos de Chamada de Componentes +================================== -Os componentes também oferecem alguns retornos de chamada do ciclo de vida da solicitação que -permitem aumentar o ciclo da solicitação. +Os componentes também oferecem alguns retornos de chamada do ciclo de vida da +solicitação que lhes permitem aumentar o ciclo da solicitação. .. php:method:: beforeFilter(EventInterface $event) - É chamado antes do método beforeFilter do controlador, - mas *após* o método initialize() do controlador. + É chamado antes do método + beforeFilter() do controller, mas *depois* do método initialize() do controller. .. php:method:: startup(EventInterface $event) - É chamado após o método beforeFilter do controlador, - mas antes que o controlador execute o manipulador de ações atual. + É chamado após o método beforeFilter() do controller, + mas antes que o controller execute o manipulador de ação + atual. .. php:method:: beforeRender(EventInterface $event) - É chamado após o controlador executar a lógica da ação solicitada, - mas antes de o controlador renderizar visualizações e layout. + É chamado após o controller executar a lógica da ação solicitada, + mas antes do controller renderizar as visualizações e o layout. -.. php:method:: shutdown(EventInterface $event) +.. php:method:: afterFilter(EventInterface $event) - É chamado antes que a saída seja enviada ao navegador. + É chamado durante o evento ``Controller.shutdown``, antes da saída ser enviada ao navegador. .. php:method:: beforeRedirect(EventInterface $event, $url, Response $response) - É chamado quando o método de redirecionamento do controlador é chamado, - mas antes de qualquer ação adicional. Se esse método retornar ``false``, - o controlador não continuará redirecionando a solicitação. Os parâmetros - $url e $response permitem inspecionar e modificar o local ou qualquer outro - cabeçalho na resposta. + É invocado quando o método de redirecionamento + do controller é chamado, mas antes de qualquer ação adicional. Se este método + retornar ``false``, o controller não continuará redirecionando a + solicitação. Os parâmetros $url e $response permitem que você inspecione e modifique + a localização ou quaisquer outros cabeçalhos na resposta. + +.. _redirect-component-events: + +Usando Redirecionamentos em Eventos de Componentes +================================================== + +Para redirecionar de dentro de um método de retorno de chamada de componente, você pode usar o seguinte:: + + public function beforeFilter(EventInterface $event): void + { + if (...) { + $event->setResult($this->getController()->redirect('/')); + + return; + } + + ... + } + +Ao definir um redirecionamento como resultado do evento, você informa ao CakePHP que não deseja que nenhum outro +retorno de chamada de componente seja executado e que o controller não deve mais manipular a ação. +A partir da versão 4.1.0, você pode lançar uma ``RedirectException`` para sinalizar +um redirecionamento:: + + use Cake\Http\Exception\RedirectException; + use Cake\Routing\Router; + + public function beforeFilter(EventInterface $event): void + { + throw new RedirectException(Router::url('/')) + } + +Gerar uma exceção interromperá todos os outros ouvintes de eventos e criará uma nova +resposta que não retém ou herda nenhum dos cabeçalhos da resposta atual. +Ao gerar uma ``RedirectException``, você pode incluir cabeçalhos adicionais:: + + throw new RedirectException(Router::url('/'), 302, [ + 'Header-Key' => 'value', + ]); .. meta:: :title lang=pt: Componentes diff --git a/pt/controllers/components/authentication.rst b/pt/controllers/components/authentication.rst deleted file mode 100644 index 2e9eb11b09..0000000000 --- a/pt/controllers/components/authentication.rst +++ /dev/null @@ -1,1082 +0,0 @@ -AuthComponent -############## - -.. php:class:: AuthComponent(ComponentCollection $collection, array $config = []) - -Identificar, autenticar e autorizar usuários é uma parte comum de -quase todos os aplicativos da web. No CakePHP, o AuthComponent fornece -uma maneira conectável de executar essas tarefas. AuthComponent permite -combinar objetos de autenticação e objetos de autorização para criar maneiras -flexíveis de identificar e verificar a autorização do usuário. - -.. deprecated:: 4.0.0 - O AuthComponent está obsoleto a partir da versão 4.0.0 e será - substituído pelos plugins `authorization `__ e `authentication `__ . - -.. _authentication-objects: - -Sugestão de Leitura Antes de Continuar -====================================== - -A configuração da autenticação requer várias etapas, incluindo a definição de uma -tabela de usuários, a criação de um modelo, controlador e visualizações, etc. - -Tudo isso é abordado passo a passo em :doc:`CMS Tutorial `. - -Se você está procurando soluções de autenticação e/ou autorização existentes para o CakePHP, -consulte a seção `Authentication and Authorization `_ da lista Awesome CakePHP. - -Autenticação -============ - -Autenticação é o processo de identificar usuários pelas credenciais fornecidas -e garantir que os usuários sejam quem eles dizem que são. Geralmente, isso é -feito através de um nome de usuário e senha, que são verificados em uma lista -conhecida de usuários. No CakePHP, existem várias maneiras internas de autenticar -usuários armazenados no seu aplicativo. - -* ``FormAuthenticate`` permite autenticar usuários com base nos dados do formulário POST. - Geralmente, este é um formulário de login no qual os usuários inserem informações. -* ``BasicAuthenticate`` permite autenticar usuários usando a autenticação HTTP básica. -* ``DigestAuthenticate`` permite autenticar usuários usando o Diges Autenticação HTTP. - -Por padrão, ``AuthComponent`` usa ``FormAuthenticate``. - -Escolhendo um Tipo de Autenticação ----------------------------------- - -Geralmente, você deseja oferecer autenticação baseada em formulário. É o mais fácil para os -usuários que usam um navegador da web. Se você estiver criando uma API ou serviço da web, -convém considerar a autenticação básica ou digerir a autenticação. As principais diferenças -entre Digest e autenticação básica estão relacionadas principalmente à maneira como as senhas -são tratadas. Na autenticação básica, o nome de usuário e a senha são transmitidos como texto -sem formatação para o servidor. Isso torna a autenticação básica inadequada para aplicativos -sem SSL, pois você acabaria expondo senhas confidenciais. A autenticação Digest usa um hash de -resumo do nome de usuário, senha e alguns outros detalhes. Isso torna a autenticação Digest mais -apropriada para aplicativos sem criptografia SSL. - -Você também pode usar sistemas de autenticação como o OpenID também; no entanto, o OpenID -não faz parte do núcleo do CakePHP. - -Configurando Manipuladores de Autenticação ------------------------------------------- - -Você configura manipuladores de autenticação usando a configuração ``authenticate``. -Você pode configurar um ou muitos manipuladores para autenticação. O uso de vários manipuladores -permite oferecer suporte a diferentes maneiras de efetuar logon nos usuários. Ao efetuar logon -nos usuários, os manipuladores de autenticação são verificados na ordem em que são declarados. -Quando um manipulador conseguir identificar o usuário, nenhum outro manipulador será verificado. -Por outro lado, você pode interromper toda a autenticação lançando uma exceção. Você precisará -capturar todas as exceções lançadas e manipulá-las conforme necessário. - -Você pode configurar manipuladores de autenticação nos métodos ``beforeFilter()`` ou -``initialize()`` do seu controlador. Você pode passar informações de configuração para -cada objeto de autenticação usando uma matriz:: - - // Configuração simples - $this->Auth->setConfig('authenticate', ['Form']); - - // Passando as configurações - $this->Auth->setConfig('authenticate', [ - 'Basic' => ['userModel' => 'Members'], - 'Form' => ['userModel' => 'Members'] - ]); - -No segundo exemplo, você notará que tivemos que declarar a chave -``userModel`` duas vezes. Para ajudá-lo a manter seu código DRY, você pode usar a -chave ``all``. Essa chave especial permite definir configurações que são passadas -para todos os objetos anexados. A chave ``all`` também é exposta como ``AuthComponent::ALL``:: - - // Passando configurações usando 'all' - $this->Auth->setConfig('authenticate', [ - AuthComponent::ALL => ['userModel' => 'Members'], - 'Basic', - 'Form' - ]); - -No exemplo acima, ``Form`` e ``Basic`` obterão as configurações -definido para a chave 'all'. Quaisquer configurações passadas para -um objeto de autenticação específico substituirão a chave correspondente -na chave 'all'. Os objetos de autenticação principal suportam as seguintes -chaves de configuração. - -- ``fields`` Os campos a serem usados para identificar um usuário. Você pode usar as chaves - ``username`` e ``password`` para especificar seus campos de nome de usuário e senha, respectivamente. -- ``userModel`` O nome do modelo da tabela users; o padrão é Users. -- ``finder`` O método finder a ser usado para buscar um registro do usuário. O padrão é 'all'. -- ``passwordHasher`` Classe de hasher de senha; O padrão é ``Default``. - -Para configurar campos diferentes para o usuário no seu método ``initialize()``:: - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Auth', [ - 'authenticate' => [ - 'Form' => [ - 'fields' => ['username' => 'email', 'password' => 'passwd'] - ] - ] - ]); - } - -Não coloque outras chaves de configuração ``Auth``, como ``authError``, ``loginAction``, etc., -dentro do elemento ``authenticate`` ou ``Form``. Eles devem estar no mesmo nível da chave de -autenticação. A configuração acima com outro exemplo de configuração para autenticação deve -se parecer com:: - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Auth', [ - 'loginAction' => [ - 'controller' => 'Users', - 'action' => 'login', - 'plugin' => 'Users' - ], - 'authError' => 'Did you really think you are allowed to see that?', - 'authenticate' => [ - 'Form' => [ - 'fields' => ['username' => 'email'] - ] - ], - 'storage' => 'Session' - ]); - } - -Além da configuração comum, a autenticação básica suporta as seguintes chaves: - -- ``realm`` O domínio a ser autenticado. O padrão é ``env('SERVER_NAME')``. - -Além da configuração comum, a autenticação Digest suporta as seguintes -chaves: - -- ``realm`` Para autenticação de domínio. O padrão é o nome do servidor. -- ``nonce`` Um nonce usado para autenticação. O padrão é ``uniqid()``. -- ``qop`` O padrão é auth; nenhum outro valor é suportado no momento. -- ``opaque`` Uma sequência que deve ser retornada inalterada pelos clientes. O padrão é ``md5($config['realm']))``. - -.. note:: - Para encontrar o registro do usuário, o banco de dados é consultado apenas - usando o nome de usuário. A verificação da senha é feita em PHP. Isso é necessário - porque algoritmos de hash como bcrypt (que é usado por padrão) geram um novo hash a - cada vez, mesmo para a mesma string e você não pode simplesmente fazer uma comparação - simples de strings no SQL para verificar se a senha corresponde. - -Personalizando a Consulta de Localização ----------------------------------------- - -Você pode personalizar a consulta usada para buscar o registro do usuário usando a opção -``finder`` na opção de autenticação da classe:: - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Auth', [ - 'authenticate' => [ - 'Form' => [ - 'finder' => 'auth' - ] - ], - ]); - } - -Isso exigirá que seu ``UsersTable`` tenha o método localizador ``findAuth()``. -No exemplo mostrado abaixo, a consulta é modificada para buscar apenas os campos -obrigatórios e adicionar uma condição. Você deve garantir que você selecione os -campos necessários para autenticar um usuário, como ``username`` e ``password``:: - - public function findAuth(\Cake\ORM\Query $query, array $options) - { - $query - ->select(['id', 'username', 'password']) - ->where(['Users.active' => 1]); - - return $query; - } - -Identificando Usuários e Efetuando Login ----------------------------------------- - -.. php:method:: identify() - -Você precisa chamar manualmente ``$this->Auth->identity()`` para -identificar o usuário usando as credenciais fornecidas na solicitação. -Em seguida, use ``$this->Auth->setUser()`` para conectar o usuário, -ou seja, salve as informações do usuário na sessão. - -Ao autenticar usuários, os objetos de autenticação anexados são verificados -na ordem em que estão. Depois que um dos objetos pode identificar o -usuário, nenhum outro objeto é verificado. Uma função de login como exemplo para -trabalhar com um formulário de login pode se parecer com:: - - public function login() - { - if ($this->request->is('post')) { - $user = $this->Auth->identify(); - if ($user) { - $this->Auth->setUser($user); - - return $this->redirect($this->Auth->redirectUrl()); - } else { - $this->Flash->error(__('Username or password is incorrect')); - } - } - } - -O código acima tentará primeiro identificar um usuário usando os dados do POST. -Se for bem-sucedido, definimos as informações do usuário para a sessão, para que -elas persistam nas solicitações e, em seguida, redirecionamos para a última página -que eles estavam visitando ou para uma URL especificada na configuração ``loginRedirect``. -Se o logon não for bem-sucedido, uma mensagem flash será definida. - -.. warning:: - - ``$this->Auth->setUser($data)`` registrará o usuário com todos os dados - passados para o método. Na verdade, ele não verifica as credenciais em - uma classe de autenticação. - -Redirecionando Usuários após o Login ------------------------------------- - -.. php:method:: redirectUrl - -Depois de fazer o login de um usuário, você geralmente desejará redirecioná-lo -de volta para onde eles vieram. Passe um URL para definir o destino ao qual um -usuário deve ser redirecionado após o login. - -Se nenhum parâmetro for passado, a URL retornada usará as seguintes regras: - -- Retorna a URL normalizada do valor da string de consulta ``redirect``, - se estiver presente e no mesmo domínio em que o aplicativo atual estiver sendo executado. -- Se não houver um valor de string/sessão de consulta e houver uma configuração com - ``loginRedirect``, o valor ``loginRedirect`` será retornado. -- Se não houver valor de redirecionamento e nenhum ``loginRedirect``, ``/`` será retornado. - -Criando Sistemas de Autenticação sem Estado -------------------------------------------- - -Basic e Digest são esquemas de autenticação sem estado e não requerem um POST -ou um formulário inicial. Se você estiver usando apenas autenticadores basic/digest, -não precisará de uma ação de login no seu controlador. A autenticação sem estado -verificará novamente as credenciais do usuário em cada solicitação, isso cria uma -pequena quantidade de sobrecarga adicional, mas permite que os clientes efetuem login -sem usar cookies e torna o AuthComponent mais adequado para a criação de APIs. - -Para autenticadores sem estado, a configuração `` storage`` deve ser definida como -``Memory`` para que o AuthComponent não use uma sessão para armazenar o registro do -usuário. Você também pode querer configurar config ``unauthorizedRedirect`` para -``false``, para que AuthComponent gere uma ``ForbiddenException`` em vez do comportamento -padrão de redirecionar para o referenciador. - -A opção ``unauthorizedRedirect`` se aplica apenas a usuários autenticados. Quando um usuário -ainda não está autenticado e você não deseja que ele seja redirecionado, será necessário -carregar um ou mais autenticadores sem estado, como ``Basic`` ou ``Digest``. - -Objetos de autenticação podem implementar um método ``getUser()`` que pode ser usado para -oferecer suporte a sistemas de login de usuário que não dependem de cookies. Um método -getUser típico examina a solicitação/ambiente e usa as informações para confirmar a -identidade do usuário. A autenticação HTTP Basic, por exemplo, usa ``$_SERVER['PHP_AUTH_USER']`` -e ``$_SERVER['PHP_AUTH_PW']`` para os campos de nome de usuário e senha. - -.. note:: - - Caso a autenticação não funcione como o esperado, verifique se as consultas são executadas - (consulte ``BaseAuthenticate::_query($username)``). Caso nenhuma consulta seja executada, - verifique se ``$_SERVER['PHP_AUTH_USER']`` e ``$_SERVER['PHP_AUTH_PW']`` são preenchidos - pelo servidor web. Se você estiver usando o Apache com FastCGI-PHP, poderá ser necessário - adicionar esta linha ao seu arquivo **.htaccess** no webroot:: - - RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] - -Em cada solicitação, esses valores, ``PHP_AUTH_USER`` e ``PHP_AUTH_PW``, são usados -para identificar novamente o usuário e garantir que ele seja o usuário válido. Assim -como no método ``authenticate()`` do objeto de autenticação, o método ``getUser()`` -deve retornar uma matriz de informações do usuário sobre o sucesso ou ``false`` em -caso de falha. :: - - public function getUser(ServerRequest $request) - { - $username = env('PHP_AUTH_USER'); - $pass = env('PHP_AUTH_PW'); - - if (empty($username) || empty($pass)) { - return false; - } - - return $this->_findUser($username, $pass); - } - -A seguir, é apresentado como você pode implementar o método getUser para -autenticação HTTP básica. O método ``_findUser()`` faz parte de ``BaseAuthenticate`` -e identifica um usuário com base em um nome de usuário e senha. - -.. _basic-authentication: - -Usando Autenticação Básica --------------------------- - -A autenticação básica permite criar uma autenticação sem estado que pode -ser usada em aplicativos de intranet ou em cenários simples da API. As -credenciais de autenticação básica serão verificadas novamente em cada solicitação. - -.. warning:: - A autenticação básica transmite credenciais em texto sem formatação. - Você deve usar HTTPS ao usar a autenticação básica. - -Para usar a autenticação básica, você precisará configurar o AuthComponent:: - - $this->loadComponent('Auth', [ - 'authenticate' => [ - 'Basic' => [ - 'fields' => ['username' => 'username', 'password' => 'api_key'], - 'userModel' => 'Users' - ], - ], - 'storage' => 'Memory', - 'unauthorizedRedirect' => false - ]); - -Aqui, usamos o nome de usuário + chave da API como nossos campos e usamos o modelo Usuários. - -Criando Chaves de API para Autenticação Básica -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Como o HTTP básico envia credenciais em texto sem formatação, não é aconselhável -que os usuários enviem sua senha de login. Em vez disso, geralmente é usada uma -chave de API. Você pode gerar esses tokens de API aleatoriamente usando bibliotecas -do CakePHP:: - - namespace App\Model\Table; - - use Cake\Auth\DefaultPasswordHasher; - use Cake\Utility\Text; - use Cake\Event\EventInterface; - use Cake\ORM\Table; - use Cake\Utility\Security; - - class UsersTable extends Table - { - public function beforeSave(EventInterface $event) - { - $entity = $event->getData('entity'); - - if ($entity->isNew()) { - $hasher = new DefaultPasswordHasher(); - - // Gera uma API 'token' - $entity->api_key_plain = Security::hash(Security::randomBytes(32), 'sha256', false); - - // Criptografe o token para que BasicAuthenticate - // possa verificá-lo durante o login. - $entity->api_key = $hasher->hash($entity->api_key_plain); - } - - return true; - } - } - -O exemplo acima gera um hash aleatório para cada usuário conforme eles são salvos. -O código acima assume que você tem duas colunas ``api_key`` - para armazenar a chave -da API hash e ``api_key_plain`` - para a versão em texto sem formatação da chave da -API, para que possamos exibi-la ao usuário posteriormente. Usar uma chave em vez de -uma senha significa que, mesmo em HTTP simples, seus usuários podem usar um token simples -em vez da senha original. Também é aconselhável incluir lógica que permita que as chaves -da API sejam regeneradas a pedido de um usuário. - -Usando Autenticação Digest --------------------------- - -A autenticação Digest oferece um modelo de segurança aprimorado em relação à -autenticação básica, pois as credenciais do usuário nunca são enviadas no cabeçalho -da solicitação. Em vez disso, um hash é enviado. - -Para usar a autenticação Digest, você precisará configurar o ``AuthComponent``:: - - $this->loadComponent('Auth', [ - 'authenticate' => [ - 'Digest' => [ - 'fields' => ['username' => 'username', 'password' => 'digest_hash'], - 'userModel' => 'Users' - ], - ], - 'storage' => 'Memory', - 'unauthorizedRedirect' => false - ]); - -Aqui, estamos usando o nome de usuário + digest_hash como nossos campos e também -usamos o modelo Users. - -Hashing de Senhas para Autenticação Digest -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Como a autenticação Digest requer um hash de senha no formato definido pelo -RFC, para hash corretamente uma senha para uso com a autenticação Digest, -você deve usar a função de hash de senha especial em ``DigestAuthenticate``. -Se você combinar a autenticação digest com outras estratégias de autenticação, -também é recomendável que você armazene a senha digest em uma coluna separada, -a partir do hash da senha normal:: - - namespace App\Model\Table; - - use Cake\Auth\DigestAuthenticate; - use Cake\Event\EventInterface; - use Cake\ORM\Table; - - class UsersTable extends Table - { - public function beforeSave(EventInterface $event) - { - $entity = $event->getData('entity'); - - // Fazendo a senha para autenticação digest - $entity->digest_hash = DigestAuthenticate::password( - $entity->username, - $entity->plain_password, - env('SERVER_NAME') - ); - - return true; - } - } - -As senhas para autenticação Digest precisam de um pouco mais de informações do -que outros hashes de senha, com base no RFC para autenticação Digest. - -.. note:: - - O terceiro parâmetro de ``DigestAuthenticate::password()`` deve - corresponder ao valor de configuração 'realm' definido quando - DigestAuthentication foi configurado em ``AuthComponent::$authenticate``. - O padrão é ``env('SCRIPT_NAME')``. Você pode usar uma string estática se - desejar hashes consistentes em vários ambientes. - -Criando Objetos de Autenticação Personalizados ----------------------------------------------- - -Como os objetos de autenticação são conectáveis, você pode criar objetos -de autenticação personalizados em seu aplicativo ou plug-in. Se, por exemplo, -você desejasse criar um objeto de autenticação OpenID. Em **src/Auth/OpenidAuthenticate.php**, -você pode colocar o seguinte:: - - namespace App\Auth; - - use Cake\Auth\BaseAuthenticate; - use Cake\Http\ServerRequest; - use Cake\Http\Response; - - class OpenidAuthenticate extends BaseAuthenticate - { - public function authenticate(ServerRequest $request, Response $response) - { - // Faça coisas para o OpenID aqui. - // Retorne uma matriz do usuário se eles puderem autenticar o usuário, - // retorne false se não. - } - } - -Os objetos de autenticação devem retornar ``false`` se não puderem identificar -o usuário e uma matriz de informações do usuário, se puderem. Não é necessário -que você estenda ``BaseAuthenticate``, apenas que seu objeto de autenticação -implemente ``Cake\Event\EventListenerInterface``. A classe ``BaseAuthenticate`` -fornece vários métodos úteis que são comumente usados. Você também pode implementar -um método ``getUser()`` se o seu objeto de autenticação precisar suportar -autenticação sem estado ou sem cookie. Consulte as seções sobre autenticação -básica e digest abaixo para obter mais informações. - -``AuthComponent`` dispara dois eventos, ``Auth.afterIdentify`` e ``Auth.logout``, -depois que um usuário é identificado e antes que o usuário seja desconectado, -respectivamente. Você pode definir funções de retorno de chamada para esses eventos -retornando uma matriz de mapeamento do método ``managedEvents()`` da sua classe de -autenticação:: - - public function implementedEvents() - { - return [ - 'Auth.afterIdentify' => 'afterIdentify', - 'Auth.logout' => 'logout' - ]; - } - -Usando Objetos de Autenticação Personalizados ---------------------------------------------- - -Depois de criar seus objetos de autenticação personalizados, você pode usá-los -incluindo-os na matriz de autenticação do ``AuthComponent``:: - - $this->Auth->setConfig('authenticate', [ - 'Openid', // app authentication object. - 'AuthBag.Openid', // plugin authentication object. - ]); - -.. note:: - Observe que, ao usar notação simples, não há palavra 'Authenticate' ao iniciar o - objeto de autenticação. Em vez disso, se você estiver usando namespace, precisará - definir o namespace completo da classe, incluindo a palavra 'Authenticate'. - -Manipulando Solicitações Não Autenticadas ------------------------------------------ - -Quando um usuário não autenticado tenta acessar uma página protegida primeiro, -o método ``unauthenticated()`` do último autenticador da cadeia é chamado. -O objeto de autenticação pode lidar com o envio de resposta ou redirecionamento -retornando um objeto de resposta para indicar que nenhuma ação adicional é necessária. -Devido a isso, é importante a ordem na qual você especifica o provedor de autenticação -na configuração ``authenticate``. - -Se o autenticador retornar nulo, ``AuthComponent`` redirecionará o usuário para a -ação de login. Se for uma solicitação AJAX e a configuração ``ajaxLogin`` for -especificada, esse elemento será renderizado, caso contrário, um código de status -HTTP 403 será retornado. - -Exibindo Mensagens Flash Relacionadas à Autenticação ----------------------------------------------------- - -Para exibir as mensagens de erro da sessão que o Auth gera, você precisa -adicionar o seguinte código ao seu layout. Adicione as duas linhas a seguir -ao arquivo **templates/layout/default.php** na seção body:: - - echo $this->Flash->render(); - -Você pode personalizar as mensagens de erro e as configurações do flash que o -``AuthComponent`` usa. Usando a configuração ``flash``, você pode configurar -os parâmetros que o ``AuthComponent`` usa para definir mensagens em flash. -As chaves disponíveis são - -- ``key`` - A chave a ser usada é padronizada como 'default'. -- ``element`` - O nome do elemento a ser usado para renderização, o padrão é null. -- ``params`` - A matriz de parâmetros adicionais a serem usados, o padrão é ``[]``. - -Além das configurações de mensagens flash, você pode personalizar outras -mensagens de erro que o ``AuthComponent`` usa. Nas configurações ``beforeFilter()`` -do seu controlador ou componente, você pode usar ``authError`` para personalizar -o erro usado quando a autorização falha:: - - $this->Auth->setConfig('authError', "Woopsie, you are not authorized to access this area."); - -Às vezes, você deseja exibir o erro de autorização somente após o usuário já estar conectado. -Você pode suprimir esta mensagem definindo seu valor como booleano ``false``. - -Nas configurações ``beforeFilter()`` ou no componente do seu controlador:: - - if (!$this->Auth->user()) { - $this->Auth->setConfig('authError', false); - } - -.. _hashing-passwords: - -Hashing de Senhas ------------------ - -Você é responsável por fazer o hash das senhas antes que elas persistam no -banco de dados, a maneira mais fácil é usar uma função setter na sua entidade -User:: - - namespace App\Model\Entity; - - use Cake\Auth\DefaultPasswordHasher; - use Cake\ORM\Entity; - - class User extends Entity - { - - // ... - - protected function _setPassword($password) - { - if (strlen($password) > 0) { - return (new DefaultPasswordHasher)->hash($password); - } - } - - // ... - } - -``AuthComponent`` é configurado por padrão para usar o ``DefaultPasswordHasher`` -ao validar credenciais do usuário, portanto, nenhuma configuração adicional é -necessária para autenticar usuários. - -``AuthComponent`` é configurado como padrão para usar o ``DefaultPasswordHasher`` -para validar credenciais do usuário, portanto, nenhuma configuração adicional é -necessária para autenticação de usuários. - -O ``DefaultPasswordHasher`` usa o algoritmo de hash bcrypt internamente, que é -uma das soluções mais fortes de hash de senha usadas no setor. Embora seja -recomendável usar essa classe de hasher de senha, pode ser que você esteja -gerenciando um banco de dados de usuários cuja senha foi usada um tipo de hash diferente. - -Criando Classes Personalizadas de Hasher de Senha -------------------------------------------------- - -Para usar um hasher de senha diferente, você precisa criar a classe em -**src/Auth/LegacyPasswordHasher.php** e implementar os métodos ``hash()`` -e ``check()``. Esta classe precisa estender a classe ``AbstractPasswordHasher``:: - - namespace App\Auth; - - use Cake\Auth\AbstractPasswordHasher; - - class LegacyPasswordHasher extends AbstractPasswordHasher - { - - public function hash($password) - { - return sha1($password); - } - - public function check($password, $hashedPassword) - { - return sha1($password) === $hashedPassword; - } - } - -Em seguida, você deve configurar o ``AuthComponent`` para usar o seu hasher de senha -customizado:: - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Auth', [ - 'authenticate' => [ - 'Form' => [ - 'passwordHasher' => [ - 'className' => 'Legacy', - ] - ] - ] - ]); - } - -Oferecer suporte a sistemas legados é uma boa idéia, mas é ainda melhor manter seu -banco de dados com os mais recentes avanços de segurança. A seção a seguir explica -como migrar de um algoritmo de hash para o padrão do CakePHP. - -Alterando Algoritmos de Hash ----------------------------- - -O CakePHP fornece uma maneira limpa de migrar as senhas de seus usuários de um -algoritmo para outro, isso é alcançado através da classe ``FallbackPasswordHasher``. -Supondo que você esteja migrando seu aplicativo do CakePHP 2.x que usa hashes de -senha ``sha1``, você pode configurar o ``AuthComponent`` da seguinte forma:: - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Auth', [ - 'authenticate' => [ - 'Form' => [ - 'passwordHasher' => [ - 'className' => 'Fallback', - 'hashers' => [ - 'Default', - 'Weak' => ['hashType' => 'sha1'] - ] - ] - ] - ] - ]); - } - -O primeiro nome que aparece na chave ``hashers`` indica qual das classes é a -preferida, mas retornará para as outras na lista se a verificação não tiver êxito. - -Ao usar o ``WeakPasswordHasher``, você precisará definir o ``Security.salt`` -para configurar o valor para garantir que as senhas sejam transformadas. - -Para atualizar as senhas de usuários antigos rapidamente, você pode alterar -a função de login de acordo:: - - public function login() - { - if ($this->request->is('post')) { - $user = $this->Auth->identify(); - if ($user) { - $this->Auth->setUser($user); - if ($this->Auth->authenticationProvider()->needsPasswordRehash()) { - $user = $this->Users->get($this->Auth->user('id')); - $user->password = $this->request->getData('password'); - $this->Users->save($user); - } - - return $this->redirect($this->Auth->redirectUrl()); - } - ... - } - } - -Como você pode ver, estamos apenas definindo a senha simples novamente, -para que a função setter na entidade faça hash na senha, como mostrado no -exemplo anterior, e salve a entidade. - -Logon Manual de Usuários ------------------------- - -.. php:method:: setUser(array $user) - -Às vezes, surge a necessidade de fazer o login manual de um usuário, como -logo após ele se registrar no seu aplicativo. Você pode fazer isso chamando -``$this->Auth->setUser()`` com os dados do usuário que deseja 'logar':: - - public function register() - { - $user = $this->Users->newEntity($this->request->getData()); - if ($this->Users->save($user)) { - $this->Auth->setUser($user->toArray()); - - return $this->redirect([ - 'controller' => 'Users', - 'action' => 'home' - ]); - } - } - -.. warning:: - - Certifique-se de adicionar manualmente o novo ID do usuário à matriz - passada para o método ``setUser()``. Caso contrário, você não terá o ID - do usuário disponível. - -Acessando o Usuário Conectado ------------------------------ - -.. php:method:: user($key = null) - -Depois que um usuário está logado, muitas vezes você precisará de algumas -informações específicas sobre o usuário atual. Você pode acessar o usuário -conectado no momento usando ``AuthComponent::user()``:: - - // De dentro de um controlador ou outro componente. - $this->Auth->user('id'); - -Se o usuário atual não estiver conectado ou a chave não existir, o valor nulo -será retornado. - -Logout de Usuários ------------------- - -.. php:method:: logout() - -Eventualmente, você desejará uma maneira rápida de autenticar alguém e redirecioná-lo -para onde ele precisa ir. Esse método também é útil se você deseja fornecer um link -'Desconectar-se' dentro da área de um membro do seu aplicativo:: - - public function logout() - { - return $this->redirect($this->Auth->logout()); - } - -É difícil realizar logoff de usuários que efetuaram logon com autenticação -Digest ou Basic para todos os clientes. A maioria dos navegadores retém -credenciais pelo período em que ainda estão abertos. Alguns clientes podem -ser forçados a sair, enviando um código de status 401. Alterar o domínio de -autenticação é outra solução que funciona para alguns clientes. - -Decidindo Quando Executar a Autenticação ----------------------------------------- - -Em alguns casos, você pode querer usar ``$this->Auth->user()`` no método -``beforeFilter()``. Isso é possível usando a chave de configuração ``checkAuthIn``. -As alterações a seguir, para o qual as verificações de autenticação -inicial devem ser feitas:: - - // Configure AuthComponent para autenticar em initialize () - $this->Auth->setConfig('checkAuthIn', 'Controller.initialize'); - -O valor padrão para ``checkAuthIn`` é ``'Controller.startup'``, mas usando a -autenticação inicial ``'Controller.initialize'`` é feita antes do método ``beforeFilter()``. - -.. _authorization-objects: - -Autorização -=========== - -Autorização é o processo de garantir que um usuário identificado/autenticado -tenha permissão para acessar os recursos que está solicitando. Se ativado, o -``AuthComponent`` pode verificar automaticamente os manipuladores de autorização -e garantir que os usuários conectados tenham permissão para acessar os recursos -que estão solicitando. Existem vários manipuladores de autorização internos e você -pode criar personalizações para o seu aplicativo ou como parte de um plug-in. - -- ``ControllerAuthorize`` Chama ``isAuthorized()`` no controlador ativo e - usa o retorno para autorizar um usuário. Geralmente, é a maneira mais - simples de autorizar usuários. - -.. note:: - - O adaptador ``ActionsAuthorize`` e ``CrudAuthorize`` disponível no CakePHP 2.x - foram agora movidos para um plugin separado `cakephp/acl `_. - -Configurando Manipuladores de Autorização ------------------------------------------ - -Você configura manipuladores de autorização usando a chave de configuração -``authorize``. Você pode configurar um ou muitos manipuladores para autorização. -O uso de vários manipuladores permite oferecer suporte a diferentes maneiras de -verificar a autorização. Quando os manipuladores de autorização são verificados, -eles serão chamados na ordem em que são declarados. Os manipuladores devem retornar -``false``, se não conseguirem verificar a autorização ou se a verificação falhar. -Os manipuladores devem retornar ``true`` se puderem verificar a autorização com -êxito. Os manipuladores serão chamados em sequência até que um passe. Se todas as -verificações falharem, o usuário será redirecionado para a página de onde veio. Além -disso, você pode interromper toda a autorização lançando uma exceção. Você precisará -capturar todas as exceções lançadas e lidar com elas. - -Você pode configurar manipuladores de autorização nos métodos ``beforeFilter()`` ou -``initialize()`` do seu controlador. Você pode passar informações de configuração -para cada objeto de autorização, usando uma matriz:: - - // Configuração básica - $this->Auth->setConfig('authorize', ['Controller']); - - // Passando configurações - $this->Auth->setConfig('authorize', [ - 'Actions' => ['actionPath' => 'controllers/'], - 'Controller' - ]); - -Assim como ``authenticate``, ``authorize``, ajuda a manter seu código DRY, -usando a chave ``all``. Essa chave especial permite definir configurações -que são passadas para todos os objetos anexados. A chave ``all`` também é -exposta como ``AuthComponent::ALL``:: - - // Passando as configurações usando 'all' - $this->Auth->setConfig('authorize', [ - AuthComponent::ALL => ['actionPath' => 'controllers/'], - 'Actions', - 'Controller' - ]); - -No exemplo acima, as ações ``Actions`` e `` Controller`` receberão as -configurações definidas para a chave 'all'. Quaisquer configurações -passadas para um objeto de autorização específico substituirão a chave -correspondente na chave 'all'. - -Se um usuário autenticado tentar acessar uma URL que ele não está autorizado -a acessar, ele será redirecionado de volta ao referenciador. Se você não desejar -esse redirecionamento (principalmente necessário ao usar o adaptador de autenticação -sem estado), defina a opção de configuração ``unauthorizedRedirect`` para ``false``. -Isso faz com que o ``AuthComponent`` gere uma ``ForbiddenException`` em vez de redirecionar. - -Criando Objetos de Autorização Personalizados ---------------------------------------------- - -Como os objetos de autorização são conectáveis, você pode criar objetos -de autorização personalizados em seu aplicativo ou plug-in. Se, por exemplo, -você desejasse criar um objeto de autorização LDAP. Em **src/Auth/LdapAuthorize.php**, -você pode colocar o seguinte:: - - namespace App\Auth; - - use Cake\Auth\BaseAuthorize; - use Cake\Http\ServerRequest; - - class LdapAuthorize extends BaseAuthorize - { - public function authorize($user, ServerRequest $request) - { - // Faça coisas para o LDAP aqui. - } - } - -Os objetos de autorização devem retornar ``false`` se o acesso do usuário -for negado ou se o objeto não puder executar uma verificação. Se o objeto -puder verificar o acesso do usuário, ``true`` deve ser retornado. Não é -necessário que você estenda ``BaseAuthorize``, apenas que seu objeto de -autorização implemente um método ``authorize()``. A classe ``BaseAuthorize`` -fornece vários métodos úteis que são comumente usados. - -Usando Objetos de Autorização Personalizados -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Depois de criar seu objeto de autorização personalizado, você pode usá-lo -incluindo-o na matriz de autorização do ``AuthComponent``:: - - $this->Auth->setConfig('authorize', [ - 'Ldap', // objeto de autorização do aplicativo. - 'AuthBag.Combo', // plugin autoriza objeto. - ]); - -Usando Sem Autorização ----------------------- - -Se você não quiser usar nenhum dos objetos de autorização internos e quiser -lidar com coisas totalmente fora de ``AuthComponent``, poderá definir -``$this->Auth->setConfig('authorize', false);``. Por padrão, ``AuthComponent`` -começa com ``authorize`` definido como ``false``. Se você não usar um esquema -de autorização, verifique você mesmo a autorização no ``beforeFilter()`` do -seu controlador ou com outro componente. - -Tornando Métodos Públicos -------------------------- - -.. php:method:: allow($actions = null) - -Muitas vezes, há ações do controlador que você deseja manter totalmente -públicas ou que não exigem que os usuários façam login. ``AuthComponent`` -é pessimista no padrão para negar acesso. Você pode marcar métodos como métodos -públicos usando ``AuthComponent::allow()``. Ao marcar ações como públicas, o -``AuthComponent`` não procurará um usuário conectado nem autorizará a verificação -de objetos:: - - // Permitir todas as ações - $this->Auth->allow(); - - // Permitir apenas a ação index. - $this->Auth->allow('index'); - - // Permitir apenas as ações de view e index. - $this->Auth->allow(['view', 'index']); - -Ao chamá-lo de vazio, você permite que todas as ações sejam públicas. Para uma única -ação, você pode fornecer o nome da ação como uma sequência. Caso contrário, use uma matriz. - -.. note:: - - Você não deve adicionar a ação "login" do seu ``UsersController`` na lista de permissões. - Fazer isso causaria problemas com o funcionamento normal de ``AuthComponent``. - -Fazendo Métodos Exigir Autorização ----------------------------------- - -.. php:method:: deny($actions = null) - -Por padrão, todas as ações requerem autorização. No entanto, depois de tornar -os métodos públicos, você deseje revogar o acesso público. -Você pode fazer isso usando ``AuthComponent::deny()``:: - - // Negar todas as ações. - $this->Auth->deny(); - - // Negar uma ação - $this->Auth->deny('add'); - - // Nega um grupo de ações. - $this->Auth->deny(['add', 'edit']); - -Ao chamá-lo de vazio, você nega todas as ações. Para um único método, -você pode fornecer o nome da ação como uma sequência. Caso contrário, use uma matriz. - -Usando ControllerAuthorize --------------------------- - -ControllerAuthorize permite manipular verificações de autorização em um -retorno de chamada do controlador. Isso é ideal quando você possui uma -autorização muito simples ou precisa usar uma combinação de modelos e -componentes para fazer sua autorização e não deseja criar um objeto de -autorização personalizado. - -O retorno de chamada é sempre chamado de ``isAuthorized()`` e deve -retornar um valor booleano para permitir ou não ao usuário acessar -recursos na solicitação. O retorno de chamada é passado ao usuário -ativo para que possa ser verificado:: - - class AppController extends Controller - { - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Auth', [ - 'authorize' => 'Controller', - ]); - } - - public function isAuthorized($user = null) - { - // Qualquer usuário registrado pode acessar funções públicas - if (!$this->request->getParam('prefix')) { - return true; - } - - // Somente administradores podem acessar funções administrativas - if ($this->request->getParam('prefix') === 'admin') { - return (bool)($user['role'] === 'admin'); - } - - // Negação padrão - return false; - } - } - -O retorno de chamada acima forneceria um sistema de autorização muito simples, -no qual apenas usuários com role = admin poderiam acessar ações que estavam no -prefixo do administrador. - -Opções de configuração -====================== - -Todas as configurações a seguir podem ser definidas no método ``initialize()`` do seu -controlador ou usando ``$this->Auth->setConfig()`` no seu ``beforeFilter()``: - -ajaxLogin - O nome de um elemento de exibição opcional a ser renderizado quando uma - solicitação AJAX é feita com uma sessão inválida ou expirada. -allowedActions - Ações do controlador para as quais a validação do usuário não é necessária. -authenticate - Defina como uma matriz de objetos de autenticação que você deseja - usar ao fazer logon de usuários. Existem vários objetos de autenticação - principais; veja a seção :ref:`authentication-objects`. -authError - Erro para exibir quando o usuário tenta acessar um objeto ou ação ao qual não tem acesso. - - Você pode impedir que a mensagem authError seja exibida definindo esse valor como - booleano ``false``. -authorize - Defina como uma matriz de objetos de Autorização que você deseja - usar ao autorizar usuários em cada solicitação; veja a seção :ref:`authorization-objects`. -flash - Configurações a serem usadas quando o Auth precisar enviar - uma mensagem flash com ``FlashComponent::set()``. - - As chaves disponíveis são: - - ``element`` - O elemento a ser usado; o padrão é 'default'. - - ``key`` - A chave para usar; o padrão é 'auth'. - - ``params`` - A matriz de parâmetros adicionais a serem usados; o padrão é '[]'. -loginAction - Uma URL (definida como uma sequência ou matriz) para a ação do controlador - que lida com logins. O padrão é ``/users/login``. -loginRedirect - A URL (definida como uma sequência ou matriz) para os usuários da - ação do controlador deve ser redirecionada após o login. Esse valor - será ignorado se o usuário tiver um valor ``Auth.redirect`` em sua sessão. -logoutRedirect - A ação padrão a ser redirecionada após o logout do usuário. Enquanto - ``AuthComponent`` não lida com o redirecionamento pós-logout, uma URL - de redirecionamento será retornada de :php:meth:`AuthComponent::logout()`. - O padrão é ``loginAction``. -unauthorizedRedirect - Controla a manipulação do acesso não autorizado. Por padrão, o usuário não - autorizado é redirecionado para o URL do referenciador ``loginAction`` - ou '/'. Se definido como ``false``, uma exceção ForbiddenException é - lançada em vez de redirecionar. -storage - Classe de armazenamento a ser usada para o registro persistente do usuário. - Ao usar o autenticador sem estado, defina-o como ``Memory``. O padrão é ``Session``. - Você pode passar as opções de configuração para a classe de armazenamento usando o - formato de matriz. Por ex. Para usar uma chave de sessão personalizada, - você pode definir ``storage`` como ``['className' => 'Session', 'key' => 'Auth.Admin']``. -checkAuthIn - Nome do evento no qual as verificações de autenticação iniciais devem ser - feitas. O padrão é ``Controller.startup``. Você pode configurá-lo para - ``Controller.initialize`` se você quiser que a verificação seja feita antes - que o método ``beforeFilter()`` do controlador seja executado. - -Você pode obter os valores atuais da configuração chamando ``$this->Auth->getConfig()``:: -apenas a opção de configuração:: - - $this->Auth->getConfig('loginAction'); - - $this->redirect($this->Auth->getConfig('loginAction')); - -Isso é útil se você deseja redirecionar um usuário para a rota ``login``, por exemplo. -Sem um parâmetro, a configuração completa será retornada. - -Testando Ações Protegidas por AuthComponent -=========================================== - -Veja a seção :ref:`testing-authentication` para obter dicas sobre como testar -ações do controlador protegidas por ``AuthComponent``. - -.. meta:: - :title lang=pt: Autenticação - :keywords lang=pt: manipuladores de autenticação, array php, autenticação básica, aplicativo da web, maneiras diferentes, credenciais, exceções, cakephp, logging diff --git a/pt/controllers/components/check-http-cache.rst b/pt/controllers/components/check-http-cache.rst new file mode 100644 index 0000000000..d4fd94360e --- /dev/null +++ b/pt/controllers/components/check-http-cache.rst @@ -0,0 +1,31 @@ +Checando o Cache HTTP +===================== + +.. php:class:: CheckHttpCacheComponent(ComponentCollection $collection, array $config = []) + +O modelo de validação de cache HTTP é um dos processos usados ​​por gateways de cache, +também conhecidos como proxies reversos, para determinar se eles podem fornecer uma cópia armazenada de +uma resposta ao cliente. Com esse modelo, você economiza principalmente largura de banda, mas, quando +usado corretamente, também pode economizar algum processamento de CPU, reduzindo +os tempos de resposta:: + + // No Controller + public function initialize(): void + { + parent::initialize(); + + $this->addComponent('CheckHttpCache'); + } + +Habilitar o ``CheckHttpCacheComponent`` no seu controlador ativa automaticamente uma verificação +``beforeRender``. Essa verificação compara os cabeçalhos de cache definidos no objeto de resposta +com os cabeçalhos de cache enviados na solicitação para determinar se a resposta não foi modificada +desde a última vez que o cliente a solicitou. Os seguintes cabeçalhos de solicitação são usados: + +* ``If-None-Match`` é comparado com o cabeçalho ``Etag`` da resposta. +* ``If-Modified-Since`` é comparado com o cabeçalho ``Last-Modified`` da resposta. + +Se os cabeçalhos de resposta corresponderem aos critérios do cabeçalho da solicitação, a renderização da visualização será +ignorada. Isso evita que seu aplicativo gere uma visualização, economizando largura de banda e +tempo. Quando os cabeçalhos de resposta correspondem, uma resposta vazia é retornada com um código de status ``304 +Not Modified``. diff --git a/pt/controllers/components/flash.rst b/pt/controllers/components/flash.rst index e231b0552f..fe0bee6bf4 100644 --- a/pt/controllers/components/flash.rst +++ b/pt/controllers/components/flash.rst @@ -5,21 +5,21 @@ Flash .. php:class:: FlashComponent(ComponentCollection $collection, array $config = []) -O FlashComponent fornece uma maneira de definir as mensagens de notificação únicas -a serem exibidas após o processamento de um formulário ou o reconhecimento de dados. -CakePHP refere-se a essas mensagens como "mensagens flash". O FlashComponent grava -mensagens flash em ``$_SESSION``, para serem renderizadas em uma View usando +FlashComponent fornece uma maneira de definir mensagens de notificação únicas a serem +exibidas após processar um formulário ou reconhecer dados. O CakePHP se refere a essas +mensagens como "mensagens flash". FlashComponent grava mensagens flash em +``$_SESSION``, para serem renderizadas em uma View usando :doc:`FlashHelper `. -Configurando Mensagens em Flash -=============================== +Definindo Mensagens Flash +========================== -O FlashComponent fornece duas maneiras de definir mensagens em flash: seu método -mágico ``__call()`` e seu método ``set()``. Para fornecer detalhes ao seu aplicativo, -o método mágico ``__call()`` do FlashComponent permite que você use um nome de método -que mapeie para um elemento localizado no diretório **templates/element/flash**. Por -convenção, os métodos camelcased serão mapeados para o nome do elemento em minúsculas -e sublinhado:: +FlashComponent fornece duas maneiras de definir mensagens flash: seu método mágico ``__call()`` +e seu método ``set()``. Para fornecer verbosidade à sua aplicação, +o método mágico ``__call()`` do FlashComponent permite que você use um nome de método que +mapeia para um elemento localizado no diretório **templates/element/flash**. +Por convenção, métodos camelcased serão mapeados para o nome do elemento +em letras minúsculas e com underscores:: // Usa templates/element/flash/success.php $this->Flash->success('This was successful'); @@ -27,75 +27,76 @@ e sublinhado:: // Usa templates/element/flash/great_success.php $this->Flash->greatSuccess('This was greatly successful'); -Como alternativa, para definir uma mensagem de texto sem processar um elemento, -você pode usar o método ``set()``:: +Alternativamente, para definir uma mensagem de texto simples sem renderizar um elemento, você pode +usar o método ``set()``:: $this->Flash->set('This is a message'); -Mensagens em Flash são anexadas a uma matriz internamente. Chamadas sucessivas -para ``set()`` ou ``__call()`` com a mesma chave anexarão as mensagens em -``$_SESSION``. Se você deseja sobrescrever as mensagens existentes ao definir -uma mensagem flash, defina a opção ``clear`` como ``true`` ao configurar o -componente. +Mensagens flash são anexadas a um array internamente. Chamadas sucessivas a +``set()`` ou ``__call()`` com a mesma chave irão anexar as mensagens em +``$_SESSION``. Se você quiser sobrescrever mensagens existentes ao definir uma mensagem +flash, defina a opção ``clear`` como ``true`` ao configurar o Component. -Os métodos ``__call()`` e ``set()`` do FlashComponent recebem opcionalmente um -segundo parâmetro, uma matriz de opções: +Os métodos ``__call()`` e ``set()`` do FlashComponent opcionalmente aceitam um segundo +parâmetro, um array de opções: -* ``key`` O padrão é 'flash'. A chave da matriz encontrada sob a chave ``Flash`` na sessão. -* ``element`` O padrão é ``null``, mas será automaticamente definido ao usar o método mágico - ``__call()``. O nome do elemento a ser usado para renderização. -* ``params`` Uma matriz opcional de chaves/valores para disponibilizar como variáveis dentro de um elemento. -* ``clear`` espera um ``bool`` e permite excluir todas as mensagens da pilha atual e iniciar uma nova. +* ``key`` Padrão é 'flash'. A chave do array encontrada sob a chave ``Flash`` na + sessão. +* ``element`` Padrão é ``null``, mas será automaticamente definido ao usar o + método mágico ``__call()``. O nome do elemento a ser usado para renderização. +* ``params`` Um array opcional de chaves/valores para disponibilizar como variáveis + dentro de um elemento. +* ``clear`` espera um ``bool`` e permite que você exclua todas as mensagens na + pilha atual e inicie uma nova. Um exemplo de uso dessas opções:: - // Em seu Controller + // In your Controller $this->Flash->success('The user has been saved', [ 'key' => 'positive', 'clear' => true, 'params' => [ 'name' => $user->name, - 'email' => $user->email - ] + 'email' => $user->email, + ], ]); - // Em sua View + // In your View Flash->render('positive') ?> - +
: , .
-Observe que o parâmetro ``element`` sempre será substituído ao usar +Note que o parâmetro ``element`` sempre será sobrescrito ao usar +``__call()``. Para recuperar um elemento específico de um plugin, você deve +definir o parâmetro ``plugin``. Por exemplo:: -Observe que o parâmetro ``element`` sempre será substituído ao usar ``__call()``. -Para recuperar um elemento específico de um plugin, você deve definir o parâmetro -``plugin``. Por exemplo:: - - // Em seu Controller + // In your Controller $this->Flash->warning('My message', ['plugin' => 'PluginName']); -O código acima usará o elemento **warning.php** em -**plugins/PluginName/templates/element/flash** para renderizar a mensagem flash. +O código acima usará o elemento **warning.php** sob +**plugins/PluginName/templates/element/flash** para renderizar a mensagem +flash. .. note:: - Por padrão, o CakePHP escapa o conteúdo das mensagens em flash para evitar - scripts entre sites. Os dados do usuário em suas mensagens flash serão codificados - em HTML e seguros para serem impressos. Se você deseja incluir HTML em suas mensagens - em flash, é necessário passar a opção ``escape`` e ajustar seus modelos de mensagens - em flash para permitir desativar a fuga quando a opção de escape é aprovada. + Por padrão, o CakePHP escapa o conteúdo em mensagens flash para prevenir cross + site scripting. Dados do usuário em suas mensagens flash serão codificados em HTML e + seguros para serem impressos. Se você quiser incluir HTML em suas mensagens flash, você + precisa passar a opção ``escape`` e ajustar seus templates de mensagens flash + para permitir desabilitar o escape quando a opção escape for passada. -HTML Em Mensagens Flash -======================= +HTML em Mensagens Flash +======================== É possível gerar HTML em mensagens flash usando a chave de opção ``'escape'``:: $this->Flash->info(sprintf('%s %s', h($highlight), h($message)), ['escape' => false]); -Certifique-se de escapar da entrada manualmente, então. No exemplo acima, ``$highlights`` e -``$message`` são entradas não HTML e, portanto, escapam. +Certifique-se de escapar a entrada manualmente. No exemplo acima, +``$highlight`` e ``$message`` são entradas não-HTML e, portanto, escapadas. -Para obter mais informações sobre como renderizar suas mensagens em flash, consulte a +Para mais informações sobre renderização de suas mensagens flash, consulte a seção :doc:`FlashHelper `. diff --git a/pt/controllers/components/form-protection.rst b/pt/controllers/components/form-protection.rst new file mode 100644 index 0000000000..cce5608cbb --- /dev/null +++ b/pt/controllers/components/form-protection.rst @@ -0,0 +1,167 @@ +Componente FormProtection +########################## + +.. php:class:: FormProtection(ComponentCollection $collection, array $config = []) + +O componente FormProtection fornece proteção contra adulteração de dados de formulário. + +Como todos os componentes, ele é configurado por meio de diversos parâmetros configuráveis. +Todas essas propriedades podem ser definidas diretamente ou por meio de métodos setter +de mesmo nome nos métodos ``initialize()`` ou ``beforeFilter()`` do seu controller. + +Se você estiver usando outros componentes que processam dados de formulário em seus retornos +de chamada ``startup()``, certifique-se de colocar o componente FormProtection antes desses +componentes no seu método ``initialize()``. + +.. note:: + + Ao usar o Componente FormProtection, você **deve** usar o FormHelper para criar + seus formulários. Além disso, você **não** deve substituir nenhum dos atributos "name" + dos campos. O Componente FormProtection procura por certos indicadores que são + criados e gerenciados pelo FormHelper (especialmente aqueles criados em + :php:meth:`~Cake\\View\\Helper\\FormHelper::create()` e + :php:meth:`~Cake\\View\\Helper\\FormHelper::end()`). Alterar dinamicamente + os campos enviados em uma solicitação POST, como desabilitar, excluir + ou criar novos campos via JavaScript, provavelmente causará falha na validação do token + do formulário. + +Prevenção de adulteração de formulários +======================================= + +Por padrão, o ``FormProtectionComponent`` impede que os usuários alterem +formulários de maneiras específicas. Isso impedirá o seguinte: + +* A ação do formulário (URL) não pode ser modificada. +* Campos desconhecidos não podem ser adicionados ao formulário. +* Campos não podem ser removidos do formulário. +* Valores em entradas ocultas não podem ser modificados. + +A prevenção desses tipos de adulteração é realizada trabalhando com o ``FormHelper`` +e rastreando quais campos estão em um formulário. Os valores dos campos ocultos também são +rastreados. Todos esses dados são combinados e transformados em um hash, e os campos de token ocultos +são inseridos automaticamente nos formulários. Quando um formulário é enviado, +o ``FormProtectionComponent`` usará os dados POST para construir a mesma estrutura +e comparar o hash. + +.. note:: + + O FormProtectionComponent **não** impedirá que opções selecionadas sejam + adicionadas/alteradas. Também não impedirá que opções de rádio sejam adicionadas/alteradas. + +Uso +=== + +A configuração do componente de proteção de formulário geralmente é feita nos +callbacks ``initialize()`` ou ``beforeFilter()`` do controller. + +As opções disponíveis são: + +validate + Defina como ``false`` para pular completamente a validação de solicitações POST + , essencialmente desativando a validação do formulário. + +unlockedFields + Defina uma lista de campos de formulário a serem excluídos da validação POST. Os campos podem ser + desbloqueados no Componente ou com + :php:meth:`FormHelper::unlockField()`. Campos que foram desbloqueados + não precisam fazer parte do POST e campos desbloqueados ocultos não têm + seus valores verificados. + +unlockedActions + Ações a serem excluídas das verificações de validação POST. + +validationFailureCallback + Callback para chamar em caso de falha de validação. Deve ser um Closure válido. + Não definido por padrão, caso em que uma exceção é lançada em caso de falha de validação. + +Desabilitando verificações de adulteração de formulários +======================================================== + +:: + + namespace App\Controller; + + use App\Controller\AppController; + use Cake\Event\EventInterface; + + class WidgetsController extends AppController + { + public function initialize(): void + { + parent::initialize(); + + $this->loadComponent('FormProtection'); + } + + public function beforeFilter(EventInterface $event): void + { + parent::beforeFilter($event); + + if ($this->request->getParam('prefix') === 'Admin') { + $this->FormProtection->setConfig('validate', false); + } + } + } + +O exemplo acima desabilitaria a prevenção de adulteração de formulários para rotas +prefixadas pelo administrador. + +Desabilitando a adulteração de formulários para ações específicas +================================================================= + +Pode haver casos em que você queira desabilitar a prevenção de adulteração de formulário para uma +ação (por exemplo, solicitações AJAX). Você pode "desbloquear" essas ações listando-as em +``$this->FormProtection->setConfig('unlockedActions', ['edit']);`` no seu ``beforeFilter()``:: + + namespace App\Controller; + + use App\Controller\AppController; + use Cake\Event\EventInterface; + + class WidgetController extends AppController + { + public function initialize(): void + { + parent::initialize(); + $this->loadComponent('FormProtection'); + } + + public function beforeFilter(EventInterface $event): void + { + parent::beforeFilter($event); + + $this->FormProtection->setConfig('unlockedActions', ['edit']); + } + } + +Este exemplo desabilitaria todas as verificações de segurança para a ação de edição. + +Lidando com falhas de validação por meio de retornos de chamada +=============================================================== + +Se a validação da proteção do formulário falhar, resultará em um erro 400 por padrão. +Você pode configurar esse comportamento definindo a opção de configuração ``validationFailureCallback`` +para uma função de retorno de chamada no controller. + +Ao configurar um método de retorno de chamada, você pode personalizar como o processo de tratamento de falhas +funciona:: + + use Cake\Controller\Exception\FormProtectionException; + + public function beforeFilter(EventInterface $event): void + { + parent::beforeFilter($event); + + $this->FormProtection->setConfig( + 'validationFailureCallback', + // Antes do uso do 5.2 Cake\Http\Exception\BadRequestException. + function (FormProtectionException $exception) { + // Você pode retornar uma instância de resposta ou lançar a exceção + // recebida como argumento. + } + ); + } + +.. meta:: + :title lang=pt: FormProtection + :keywords lang=pt: parâmetros configuráveis,form protection component,configuração de parâmetros,recursos de proteção,segurança mais apertada,php class,meth,array,submissão,security class,disable security,unlockActions diff --git a/pt/controllers/components/pagination.rst b/pt/controllers/components/pagination.rst deleted file mode 100644 index 82e735c141..0000000000 --- a/pt/controllers/components/pagination.rst +++ /dev/null @@ -1,332 +0,0 @@ -Pagination -########## - -.. php:namespace:: Cake\Controller\Component - -.. php:class:: PaginatorComponent - -Um dos principais obstáculos da criação de aplicativos Web flexíveis e fáceis de usar -é o design de uma interface de usuário intuitiva. Muitos aplicativos tendem a crescer -em tamanho e complexidade rapidamente, e designers e programadores acham que não conseguem -lidar com a exibição de centenas ou milhares de registros. A refatoração leva tempo, e o -desempenho e a satisfação do usuário podem sofrer. - -A exibição de um número razoável de registros por página sempre foi uma parte crítica -de todos os aplicativos e usada para causar muitas dores de cabeça aos desenvolvedores. -O CakePHP facilita a carga para o desenvolvedor, fornecendo uma maneira rápida e fácil -de paginar os dados. - -A paginação no CakePHP é oferecida por um componente no controlador, para facilitar a -criação de consultas paginadas. A View :php:class:`~Cake\\View\\Helper\\PaginatorHelper` -é usada para simplificar a geração de links e botões de paginação. - -Usando Controller::paginate() -============================= - -No controlador, começamos definindo as condições de consulta padrão que a paginação usará -na variável do controlador ``$paginate``. Essas condições servem como base para suas -consultas de paginação. Eles são aumentados pelos parâmetros ``sort``, ``direction``, -``limit`` e ``page`` transmitidos a partir da URL. É importante notar que a chave ``order`` -deve ser definida em uma estrutura de matriz como abaixo:: - - class ArticlesController extends AppController - { - public $paginate = [ - 'limit' => 25, - 'order' => [ - 'Articles.title' => 'asc' - ] - ]; - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Paginator'); - } - } - -Você também pode incluir qualquer uma das opções suportadas -por :php:meth:`~Cake\\ORM\\Table::find()`, como ``fields``:: - - class ArticlesController extends AppController - { - public $paginate = [ - 'fields' => ['Articles.id', 'Articles.created'], - 'limit' => 25, - 'order' => [ - 'Articles.title' => 'asc' - ] - ]; - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Paginator'); - } - } - -Enquanto você pode passar a maioria das opções de consulta da propriedade -paginate, geralmente é mais fácil e simples agrupar suas opções de paginação -em :ref:`custom-find-methods`. Você pode definir o uso da paginação do -localizador, definindo a opção ``finder``:: - - class ArticlesController extends AppController - { - public $paginate = [ - 'finder' => 'published', - ]; - } - -Como os métodos localizadores personalizados também podem receber opções, é assim -que você passa as opções para um método find personalizado dentro da propriedade -paginate:: - - class ArticlesController extends AppController - { - // encontrar artigos por tag - public function tags() - { - $tags = $this->request->getParam('pass'); - - $customFinderOptions = [ - 'tags' => $tags - ]; - // o método find personalizado é chamado findTagged dentro de ArticlesTable.php, - // e deve ter se parecer com: public function findTagged(Query $query, array $options) { - // portanto, você usa tags como a chave - $this->paginate = [ - 'finder' => [ - 'tagged' => $customFinderOptions - ] - ]; - $articles = $this->paginate($this->Articles); - $this->set(compact('articles', 'tags')); - } - } - -Além de definir valores gerais de paginação, você pode definir mais de um -conjunto de padrões de paginação no controlador, basta nomear as chaves da -matriz após o modelo que deseja configurar:: - - class ArticlesController extends AppController - { - public $paginate = [ - 'Articles' => [], - 'Authors' => [], - ]; - } - -Os valores das chaves ``Articles`` e ``Authors`` podem conter todas as propriedades -que um modelo/chave menos a matriz ``$paginate``. - -Depois de definida a propriedade ``$paginate``, podemos usar o método :php:meth:`~Cake\\Controller\\Controller::paginate()` -para criar os dados de paginação e adicionar o ``PaginatorHelper `` se ainda não foi adicionado. -O método paginado do controlador retornará o conjunto de resultados da consulta paginada e -definirá os metadados de paginação para a solicitação. Você pode acessar os metadados da -paginação em ``$this->request->getParam('paging')``. Um exemplo mais completo do uso de -``paginate()`` seria:: - - class ArticlesController extends AppController - { - public function index() - { - $this->set('articles', $this->paginate()); - } - } - -Por padrão, o método ``paginate()`` usará o modelo padrão para -um controlador. Você também pode passar a consulta resultante de um método find:: - - public function index() - { - $query = $this->Articles->find('popular')->where(['author_id' => 1]); - $this->set('articles', $this->paginate($query)); - } - -Se você quiser paginar um modelo diferente, poderá fornecer uma consulta para ele, -sendo o próprio objeto de tabela ou seu nome:: - - // Usando a query. - $comments = $this->paginate($commentsTable->find()); - - // Usando o nome do modelo. - $comments = $this->paginate('Comments'); - - // Usando um objeto de tabela. - $comments = $this->paginate($commentTable); - -Usando o Paginator Diretamente -============================== - -Se você precisar paginar os dados de outro componente, poderá usar o PaginatorComponent -diretamente. O PaginatorComponent possui uma API semelhante ao método do controlador:: - - $articles = $this->Paginator->paginate($articleTable->find(), $config); - - // Ou - $articles = $this->Paginator->paginate($articleTable, $config); - -O primeiro parâmetro deve ser o objeto de consulta de um objeto de localização na tabela -do qual você deseja paginar os resultados. Opcionalmente, você pode passar o objeto de -tabela e permitir que a consulta seja construída para você. O segundo parâmetro deve ser -a matriz de configurações a serem usadas para paginação. Essa matriz deve ter a mesma estrutura -que a propriedade ``$paginate`` em um controlador. Ao paginar um objeto ``Query``, a opção -``finder`` será ignorada. Supõe-se que você esteja passando a consulta que deseja paginar. - -.. _paginating-multiple-queries: - -Paginando Múltiplas Queries -=========================== - -Você pode paginar vários modelos em uma única ação do controlador, usando a opção -``scope`` na propriedade ``$paginate`` do controlador e na chamada para o -método ``paginate()``:: - - // Propriedade Paginar - public $paginate = [ - 'Articles' => ['scope' => 'article'], - 'Tags' => ['scope' => 'tag'] - ]; - - // Em um método do controlador - $articles = $this->paginate($this->Articles, ['scope' => 'article']); - $tags = $this->paginate($this->Tags, ['scope' => 'tag']); - $this->set(compact('articles', 'tags')); - -A opção ``scope`` resultará na ``PaginatorComponent`` procurando nos parâmetros da -string de consulta com escopo definido. Por exemplo, o URL a seguir pode ser usado -para paginar tags e artigos ao mesmo tempo:: - - /dashboard?article[page]=1&tag[page]=3 - -Veja a seção `paginator-helper-multiple` para saber como gerar elementos HTML -com escopo e URLs para paginação. - -Paginando o Mesmo Modelo Várias Vezes -------------------------------------- - -Para paginar o mesmo modelo várias vezes em uma única ação do controlador, é -necessário definir um alias para o modelo. Consulte `table-registry-usage` -para obter detalhes adicionais sobre como usar o registro da tabela:: - - // Em um método do controlador - $this->paginate = [ - 'ArticlesTable' => [ - 'scope' => 'published_articles', - 'limit' => 10, - 'order' => [ - 'id' => 'desc', - ], - ], - 'UnpublishedArticlesTable' => [ - 'scope' => 'unpublished_articles', - 'limit' => 10, - 'order' => [ - 'id' => 'desc', - ], - ], - ]; - - // Registre um objeto de tabela adicional para permitir a diferenciação no componente de paginação - TableRegistry::getTableLocator()->setConfig('UnpublishedArticles', [ - 'className' => 'App\Model\Table\ArticlesTable', - 'table' => 'articles', - 'entityClass' => 'App\Model\Entity\Article', - ]); - - $publishedArticles = $this->paginate( - $this->Articles->find('all', [ - 'scope' => 'published_articles' - ])->where(['published' => true]) - ); - - $unpublishedArticles = $this->paginate( - TableRegistry::getTableLocator()->get('UnpublishedArticles')->find('all', [ - 'scope' => 'unpublished_articles' - ])->where(['published' => false]) - ); - -.. _control-which-fields-used-for-ordering: - -Controlar Quais Campos Usados para Ordenamento -============================================== - -Por padrão, a classificação pode ser feita em qualquer coluna não virtual que uma -tabela tenha. Às vezes, isso é indesejável, pois permite que os usuários classifiquem -em colunas não indexadas que podem ser caras de solicitar. Você pode definir a lista de -permissões dos campos que podem ser classificados usando a opção ``sortableFields``. Essa -opção é necessária quando você deseja classificar os dados associados ou os campos computados -que podem fazer parte da sua consulta de paginação:: - - public $paginate = [ - 'sortableFields' => [ - 'id', 'title', 'Users.username', 'created' - ] - ]; - -Quaisquer solicitações que tentem classificar campos que não estão na lista de permissões serão ignoradas. - -Limitar o Número Máximo de Linhas por Página -============================================ - -O número de resultados que são buscados por página é exposto ao usuário como o -parâmetro ``limit``. Geralmente, é indesejável permitir que os usuários busquem -todas as linhas em um conjunto paginado. A opção ``maxLimit`` afirma que ninguém -pode definir esse limite muito alto do lado de fora. Por padrão, o CakePHP limita -o número máximo de linhas que podem ser buscadas para 100. Se esse padrão não for -apropriado para a sua aplicação, você poderá ajustá-lo como parte das opções de paginação, -por exemplo, reduzindo-o para ``10``:: - - public $paginate = [ - // Outras chaves aqui. - 'maxLimit' => 10 - ]; - -Se o parâmetro de limite da solicitação for maior que esse valor, -ele será reduzido ao valor ``maxLimit``. - -Juntando Associações Adicionais -=============================== - -Associações adicionais podem ser carregadas na tabela paginada usando o -parâmetro ``contains``:: - - public function index() - { - $this->paginate = [ - 'contain' => ['Authors', 'Comments'] - ]; - - $this->set('articles', $this->paginate($this->Articles)); - } - -Solicitações de Página Fora do Intervalo -======================================== - -O PaginatorComponent lançará uma ``NotFoundException`` ao tentar acessar uma página -inexistente, ou seja, o número da página solicitada é maior que a contagem total de páginas. - -Portanto, você pode permitir que a página de erro normal seja renderizada ou usar um -bloco try catch e executar a ação apropriada quando um ``NotFoundException`` for capturado:: - - use Cake\Http\Exception\NotFoundException; - - public function index() - { - try { - $this->paginate(); - } catch (NotFoundException $e) { - // Faça algo aqui como redirecionar para a primeira ou a última página. - // $this->request->getParam('paging') fornecerá as informações necessárias. - } - } - -Paginação na View -================= - -Verifique a documentação :php:class:`~Cake\\View\\Helper\\PaginatorHelper` -para saber como criar links para navegação de paginação. - -.. meta:: - :title lang=pt: Paginação - :keywords lang=pt: matriz de pedidos, condições de consulta, classe php, aplicativos web, dores de cabeça, obstáculos, complexidade, programadores, parâmetros, paginar, designers, cakephp, satisfação, desenvolvedores diff --git a/pt/controllers/components/request-handling.rst b/pt/controllers/components/request-handling.rst deleted file mode 100644 index 5adebed49b..0000000000 --- a/pt/controllers/components/request-handling.rst +++ /dev/null @@ -1,274 +0,0 @@ -Request Handler (Tratamento de Requisições) -########################################### - -.. php:class:: RequestHandlerComponent(ComponentCollection $collection, array $config = []) - -O componente Request Handler é usado no CakePHP para obter informações adicionais -sobre as solicitações HTTP feitas para sua aplicação. Você pode usá-lo para ver quais -tipos de conteúdo os clientes preferem, analisar automaticamente a entrada da solicitação, -definir como os tipos de conteúdo são mapeados para exibir classes ou caminhos de modelo. - -Por padrão, o RequestHandler detectará automaticamente solicitações AJAX com base no -cabeçalho HTTP ``X-Requested-With`` que muitas bibliotecas JavaScript usam. Quando usado -em conjunto com :php:meth:`Cake\\Routing\\Router::extensions()`, o RequestHandler muda -automaticamente os arquivos de layout e modelo para aqueles que correspondem aos tipos -de mídia não HTML. Além disso, se existir um auxiliar com o mesmo nome que a extensão -solicitada, ele será adicionado à matriz Auxiliar de Controladores. Por fim, se os -dados XML/JSON forem enviados para seus controladores, eles serão analisados em -uma matriz atribuída a ``$this->request->getData()`` e, e pode ser acessado como -faria com os dados POST padrão. Para fazer uso do RequestHandler, ele deve ser incluído no -seu método ``initialize()``:: - - class WidgetsController extends AppController - { - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('RequestHandler'); - } - - // Resto do controller - } - -Obtenção de Informações de Solicitação -====================================== - -O manipulador de solicitações possui vários métodos que fornecem informações sobre o -cliente e sua solicitação. - -.. php:method:: accepts($type = null) - - $type pode ser uma string, uma matriz ou nulo. Se uma string, ``accept()`` - retornará ``true`` se o cliente aceitar o tipo de conteúdo. Se uma matriz - for especificada, ``accept()`` retorna ``true`` se qualquer um dos tipos de - conteúdo for aceito pelo cliente. Se null, retorna uma matriz dos tipos de - conteúdo que o cliente aceita. Por exemplo:: - - class ArticlesController extends AppController - { - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('RequestHandler'); - } - - public function beforeFilter(EventInterface $event) - { - if ($this->RequestHandler->accepts('html')) { - // Execute o código apenas se o cliente aceitar uma resposta - // HTML (text/html). - } elseif ($this->RequestHandler->accepts('xml')) { - // Executar código somente XML - } - if ($this->RequestHandler->accepts(['xml', 'rss', 'atom'])) { - // Executa se o cliente aceita qualquer um dos itens acima: XML, RSS - // ou Atom. - } - } - } - -Outros métodos de detecção de 'type' de solicitação incluem: - -.. php:method:: isXml() - - Retorna ``true`` se a solicitação atual aceitar XML como resposta. - -.. php:method:: isRss() - - Retorna ``true`` se a solicitação atual aceitar RSS como resposta. - -.. php:method:: isAtom() - - Retorna ``true`` se a chamada atual aceitar uma resposta Atom, caso contrário, false. - -.. php:method:: isMobile() - - Retorna ``true`` se a sequência do agente do usuário corresponder a um - navegador da Web móvel ou se o cliente aceitar conteúdo WAP. As sequências - suportadas do Mobile User Agent são: - - - Android - - AvantGo - - BlackBerry - - DoCoMo - - Fennec - - iPad - - iPhone - - iPod - - J2ME - - MIDP - - NetFront - - Nokia - - Opera Mini - - Opera Mobi - - PalmOS - - PalmSource - - portalmmm - - Plucker - - ReqwirelessWeb - - SonyEricsson - - Symbian - - UP.Browser - - webOS - - Windows CE - - Windows Phone OS - - Xiino - -.. php:method:: isWap() - - Retorna ``true`` se o cliente aceitar conteúdo WAP. - -Todos os métodos de detecção de solicitação acima podem ser usados de -maneira semelhante para filtrar a funcionalidade destinada a tipos de -conteúdo específicos. Por exemplo, ao responder a solicitações AJAX, -geralmente você deseja desativar o cache do navegador e alterar o nível -de depuração. No entanto, você deseja permitir o armazenamento em cache -para solicitações não-AJAX. O seguinte exemplo faria isso:: - - if ($this->request->is('ajax')) { - $this->response->disableCache(); - } - // Continua ação do controlador - -Decodificação Automática de Dados de Solicitação -================================================ - -Adicione um decodificador de dados de solicitação. O manipulador deve conter -um retorno de chamada e quaisquer argumentos adicionais para o retorno de -chamada. O retorno de chamada deve retornar uma matriz de dados contidos na -entrada da solicitação. Por exemplo, adicionar um manipulador de CSV pode -parecer:: - - class ArticlesController extends AppController - { - public function initialize(): void - { - parent::initialize(); - $parser = function ($data) { - $rows = str_getcsv($data, "\n"); - foreach ($rows as &$row) { - $row = str_getcsv($row, ','); - } - - return $rows; - }; - $this->loadComponent('RequestHandler', [ - 'inputTypeMap' => [ - 'csv' => [$parser] - ] - ]); - } - } - -Você pode usar qualquer `callable `_ para a função -de manipulação. Você também pode passar argumentos adicionais para o retorno de -chamada, isso é útil para retornos de chamada como ``json_decode``:: - - $this->RequestHandler->setConfig('inputTypeMap.json', ['json_decode', true]); - -O exemplo acima tornará ``$this->request->getData()`` uma matriz dos dados de entrada JSON, -sem o ``true`` adicional, você obteria um conjunto de objetos ``stdClass``. - -.. versionchanged:: 3.6.0 - Você deve preferir usar :ref:`body-parser-middleware` em vez de - RequestHandlerComponent. - -VerificandoPreferências de Tipo de Conteúdo -=========================================== - -.. php:method:: prefers($type = null) - -Determina quais tipos de conteúdo o cliente prefere. Se nenhum parâmetro -for fornecido, o tipo de conteúdo mais provável será retornado. Se $type -for uma matriz, o primeiro tipo aceito pelo cliente será retornado. A -preferência é determinada principalmente pela extensão do arquivo analisada -pelo roteador, se houver, e por uma lista de tipos de conteúdo em ``HTTP_ACCEPT``:: - - $this->RequestHandler->prefers('json'); - -Respondendo a Solicitações -========================== - -.. php:method:: renderAs($controller, $type) - -Altere o modo de renderização de um controlador para o tipo especificado. -Também anexará o auxiliar apropriado à matriz auxiliar do controlador, se -disponível e ainda não estiver na matriz:: - - // Force o controlador a renderizar uma resposta xml. - $this->RequestHandler->renderAs($this, 'xml'); - -Este método também tentará adicionar um auxiliar que corresponda ao seu tipo de -conteúdo atual. Por exemplo, se você renderizar como ``rss``, o ``RssHelper`` -será adicionado. - -.. php:method:: respondAs($type, $options) - -Define o cabeçalho da resposta com base nos nomes do mapa do tipo de conteúdo. -Este método permite definir várias propriedades de resposta de uma só vez:: - - $this->RequestHandler->respondAs('xml', [ - // Força o download - 'attachment' => true, - 'charset' => 'UTF-8' - ]); - -.. php:method:: responseType() - -Retorna o tipo de resposta atual com o Cabeçalho do tipo de conteúdo ou nulo se -ainda não tiver sido definido. - -Aproveitando a Validação de Cache HTTP -====================================== - -O modelo de validação de cache HTTP é um dos processos usados para gateways de cache, -também conhecidos como proxies reversos, para determinar se eles podem servir uma cópia -armazenada de uma resposta ao cliente. Sob esse modelo, você economiza principalmente -largura de banda, mas, quando usado corretamente. Também é possível economizar algum -processamento da CPU, reduzindo assim os tempos de resposta. - -A ativação do RequestHandlerComponent no seu controlador ativa automaticamente uma -verificação feita antes de renderizar a exibição. Essa verificação compara o objeto de -resposta com a solicitação original para determinar se a resposta não foi modificada -desde a última vez que o cliente solicitou. - -Se a resposta for avaliada como não modificada, o processo de renderização da visualização -será interrompido, economizando tempo de processamento, economizando largura de banda e nenhum -conteúdo será retornado ao cliente. O código de status da resposta é então definido como ``304 Not Modified``. - -Você pode desativar essa verificação automática definindo a configuração ``checkHttpCache`` -como ``false``:: - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('RequestHandler', [ - 'checkHttpCache' => false - ]); - } - -Usando ViewClasses Customizadas -=============================== - -Ao usar o JsonView/XmlView, você pode substituir a serialização padrão por uma -classe View personalizada ou adicionar classes View para outros tipos. - -Você pode mapear tipos novos e existentes para suas classes personalizadas. Você -também pode definir isso automaticamente usando a configuração ``viewClassMap``:: - - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('RequestHandler', [ - 'viewClassMap' => [ - 'json' => 'ApiKit.MyJson', - 'xml' => 'ApiKit.MyXml', - 'csv' => 'ApiKit.Csv' - ] - ]); - } - -.. meta:: - :title lang=pt: Request Handling - :keywords lang=pt: componente manipulador, bibliotecas javascript, componentes públicos, retornos nulos, dados do modelo, dados de solicitação, tipos de conteúdo, extensões de arquivo, ajax, meth, tipo de conteúdo, matriz, conjunção, cakephp, insight, php diff --git a/pt/controllers/components/security.rst b/pt/controllers/components/security.rst deleted file mode 100644 index a66821ebc0..0000000000 --- a/pt/controllers/components/security.rst +++ /dev/null @@ -1,253 +0,0 @@ -Security (Segurança) -#################### - -.. php:class:: SecurityComponent(ComponentCollection $collection, array $config = []) - -O componente de segurança cria uma maneira fácil de integrar maior segurança ao -seu aplicativo. Ele fornece métodos para várias tarefas, como: - -* Restringindo quais métodos HTTP seu aplicativo aceita. -* Proteção contra violação de formulário -* Exigindo que o SSL seja usado. -* Limitar a comunicação entre controladores. - -Como todos os componentes, ele é ajustado através de vários parâmetros configuráveis. -Todas essas propriedades podem ser definidas diretamente ou através de métodos setter -com o mesmo nome no ``beforeFilter()`` do seu controlador. - -Ao usar o componente de segurança, você obtém automaticamente proteção -contra violação de formulários. Os campos de token oculto são inseridos -automaticamente nos formulários e verificados pelo componente Security. - -Se você estiver usando os recursos de proteção de formulário do componente -Security e outros componentes que processam dados do formulário em seus -retornos de chamada ``startup()``, certifique-se de colocar o Componente -de Segurança antes desses componentes no método ``initialize()``. - -.. note:: - - Ao usar o componente de segurança, você deve usar o FormHelper para criar seus - formulários. Além disso, você não deve substituir nenhum dos atributos "name" dos - campos. O componente de segurança procura determinados indicadores criados e - gerenciados pelo FormHelper (especialmente aqueles criados em - :php:meth:`~Cake\\View\\Helper\\FormHelper::create()` e :php:meth:`~Cake\\View\\Helper\\FormHelper::end()`). - Alterar dinamicamente os campos que são enviados em uma solicitação POST (por exemplo, - desativar, excluir ou criar novos campos via JavaScript) provavelmente fará com - que a solicitação seja enviada como retorno a um blackhole. - - Você sempre deve verificar o método HTTP que está sendo usado antes da execução - para evitar efeitos colaterais. Você deve :ref:`check the HTTP method ` - ou usar :php:meth:`Cake\\Http\\ServerRequest::allowMethod()` para garantir que - o método HTTP correto seja usado. - -Como Lidar com Retornos de Chamada Blackhole -============================================ - -.. php:method:: blackHole(Controller $controller, string $error = '', ?SecurityException $exception = null) - -Se uma ação for restringida pelo Componente de Segurança, ela será 'ocultada em preto' -como uma solicitação inválida que resultará em um erro 400 por padrão. Você pode configurar -esse comportamento definindo a opção de configuração ``blackHoleCallback`` como uma função -de retorno de chamada no controlador. - -Ao configurar um método de retorno de chamada, você pode personalizar como o processo do -blackhole funciona:: - - public function beforeFilter(EventInterface $event) - { - parent::beforeFilter($event); - - $this->Security->setConfig('blackHoleCallback', 'blackhole'); - } - - public function blackhole($type, SecurityException $exception) - { - if ($exception->getMessage() === 'Request is not SSL and the action is required to be secure') { - // Reescreva a mensagem de exceção com uma sequência traduzível. - $exception->setMessage(__('Please access the requested page through HTTPS')); - } - - // Lance novamente a exceção reformulada condicionalmente. - throw $exception; - - // Como alternativa, lide com o erro, ex.: defina uma mensagem flash e - // redirecione para a versão HTTPS da página solicitada. - } - -O parâmetro ``$type`` pode ter os seguintes valores: - -* 'auth' Indica um erro de validação do formulário ou um erro de incompatibilidade de controlador/ação. -* 'secure' Indica uma falha de restrição do método SSL. - -Restringir Ações ao SSL -======================= - -.. php:method:: requireSecure() - - Define as ações que requerem uma solicitação protegida por SSL. - Leva qualquer número de argumentos. Pode ser chamado sem argumentos - para forçar todas as ações a exigir um SSL protegido. - -.. php:method:: requireAuth() - - Define as ações que requerem um token válido gerado pelo Componente de segurança. - Leva qualquer número de argumentos. Pode ser chamado sem argumentos para forçar - todas as ações a exigir uma autenticação válida. - -Restringindo a Comunicação entre Controladores -============================================== - -allowedControllers - Uma lista de controladores que podem enviar solicitações para esse controlador. - Isso pode ser usado para controlar solicitações entre controladores. -allowedActions - Uma lista de ações que têm permissão para enviar solicitações para as ações deste controlador. - Isso pode ser usado para controlar solicitações entre controladores. - -Essas opções de configuração permitem restringir a comunicação entre controladores. - -Prevenção de Adulteração de Formulários -======================================= - -Por padrão, o ``SecurityComponent`` impede que os usuários adulterem formulários de -maneiras específicas. O `` SecurityComponent`` impedirá o seguinte: - -* Campos desconhecidos não podem ser adicionados ao formulário. -* Os campos não podem ser removidos do formulário. -* Os valores nas entradas ocultas não podem ser modificados. - -A prevenção desses tipos de adulteração é realizada trabalhando com o ``FormHelper`` e -rastreando quais campos estão em um formulário. Os valores para campos ocultos também -são rastreados. Todos esses dados são combinados e transformados em um hash. Quando um -formulário é enviado, o ``SecurityComponent`` usará os dados do POST para criar a mesma -estrutura e comparar o hash. - -.. note:: - - O SecurityComponent **não** impede que as opções selecionadas sejam adicionadas/alteradas. - Nem impedirá que as opções de rádio sejam adicionadas/alteradas. - -unlockedFields - Defina para uma lista de campos de formulário a serem excluídos da validação - do POST. Os campos podem ser desbloqueados no Component ou com :php:meth:`FormHelper::unlockField()`. - Os campos que foram desbloqueados não precisam fazer parte do POST e os - campos desbloqueados ocultos não têm seus valores verificados. - -validatePost - Defina como ``false`` para ignorar completamente a validação - de solicitações POST, essencialmente desativando a validação de formulário. - -Uso -=== - -Geralmente, o uso do componente de segurança é feito no ``beforeFilter()`` do -controlador. Você especificaria as restrições de segurança que deseja e o -Componente de Segurança as aplicará em sua inicialização:: - - namespace App\Controller; - - use App\Controller\AppController; - use Cake\Event\EventInterface; - - class WidgetsController extends AppController - { - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Security'); - } - - public function beforeFilter(EventInterface $event) - { - parent::beforeFilter($event); - - if ($this->request->getParam('admin')) { - $this->Security->requireSecure(); - } - } - } - -O exemplo acima forçaria todas as ações que tinham roteamento de -administrador a exigir solicitações SSL seguras:: - - namespace App\Controller; - - use App\Controller\AppController; - use Cake\Event\EventInterface; - - class WidgetsController extends AppController - { - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Security', ['blackHoleCallback' => 'forceSSL']); - } - - public function beforeFilter(EventInterface $event) - { - parent::beforeFilter($event); - - if ($this->request->getParam('admin')) { - $this->Security->requireSecure(); - } - } - - public function forceSSL($error = '', SecurityException $exception = null) - { - if ($exception instanceof SecurityException && $exception->getType() === 'secure') { - return $this->redirect('https://' . env('SERVER_NAME') . Router::url($this->request->getRequestTarget())); - } - - throw $exception; - } - } - -Este exemplo forçaria todas as ações que tinham roteamento de administrador a -exigir solicitações SSL seguras. Quando a solicitação é ocultada em preto, ele -chama o retorno de chamada ``forceSSL()``, que redirecionará solicitações não -seguras para proteger solicitações automaticamente. - -.. _security-csrf: - -Proteção CSRF -============= - -CSRF ou falsificação de solicitação entre sites é uma vulnerabilidade comum em -aplicativos da web. Ele permite que um invasor capture e reproduza uma solicitação -anterior e, às vezes, envie solicitações de dados usando tags ou recursos de imagem -em outros domínios. Para habilitar os recursos de proteção CSRF, use :ref:`csrf-middleware`. - -Desabilitando o Componente de Segurança para Ações Específicas -============================================================== - -Pode haver casos em que você deseja desativar todas as verificações de -segurança de uma ação (por exemplo, solicitações AJAX). Você pode "desbloquear" -essas ações listando-as em ``$this->Security->unlockedActions`` em seu ``beforeFilter()``. -A propriedade ``unlockedActions`` **não** afeta outros recursos do ``SecurityComponent``:: - - namespace App\Controller; - - use App\Controller\AppController; - use Cake\Event\EventInterface; - - class WidgetController extends AppController - { - public function initialize(): void - { - parent::initialize(); - $this->loadComponent('Security'); - } - - public function beforeFilter(EventInterface $event) - { - parent::beforeFilter($event); - - $this->Security->setConfig('unlockedActions', ['edit']); - } - } - -Este exemplo desabilitaria todas as verificações de segurança da ação de edição. - -.. meta:: - :title lang=pt: Segurança - :keywords lang=pt: parâmetros configuráveis, componente de segurança, parâmetros de configuração, solicitação inválida, recursos de proteção, segurança mais rígida, holing, classe php, meth, erro 404, período de inatividade, csrf, matriz, envio, classe de segurança, desativar segurança, unlockActions diff --git a/pt/controllers/middleware.rst b/pt/controllers/middleware.rst index 373154ac60..cc6d1d74c8 100644 --- a/pt/controllers/middleware.rst +++ b/pt/controllers/middleware.rst @@ -25,30 +25,36 @@ resposta PSR-7. O CakePHP também suporta o padrão PSR-15 para manipuladores de servidor, para que você possa usar qualquer middleware compatível com PSR-15 disponível em `The Packagist `_. -Middleware em CakePHP +Middleware no CakePHP ===================== O CakePHP fornece vários middlewares para lidar com tarefas comuns em aplicativos da web: -* ``Cake\Error\Middleware\ErrorHandlerMiddleware`` intercepta exceções do middleware - empacotado e renderiza uma página de erro usando o manipulador de - exceção :doc:`/development/errors`. -* ``Cake\Routing\AssetMiddleware`` verifica se a solicitação está se referindo a um tema ou - arquivo estático do plug-in, como CSS, JavaScript ou arquivo de imagem armazenado na pasta - raiz da web de um plug-in ou na pasta correspondente a um Tema. -* ``Cake\Routing\Middleware\RoutingMiddleware`` usa o ``Router`` para analisar a URL - recebida e atribuir parâmetros de roteamento à solicitação. -* ``Cake\I18n\Middleware\LocaleSelectorMiddleware`` habilita a troca automática de idioma no - cabeçalho ``Accept-Language`` enviado pelo navegador. -* ``Cake\Http\Middleware\SecurityHeadersMiddleware`` facilita adicionar cabeçalhos relacionados - à segurança como ``X-Frame-Options`` às respostas. -* ``Cake\Http\Middleware\EncryptedCookieMiddleware`` oferece a capacidade de manipular cookies - criptografados, caso você precise manipular cookies com dados ofuscados. -* ``Cake\Http\Middleware\CsrfProtectionMiddleware`` adiciona proteção CSRF ao seu aplicativo. -* ``Cake\Http\Middleware\BodyParserMiddleware`` permite decodificar JSON, XML e outros corpos - de solicitação codificados com base no cabeçalho ``Content-Type``. -* ``Cake\Http\Middleware\CspMiddleware`` simplifica a adição de cabeçalhos de política de - segurança de conteúdo ao seu aplicativo. +* ``Cake\Error\Middleware\ErrorHandlerMiddleware`` captura exceções do middleware encapsulado e renderiza + uma página de erro usando o manipulador de exceções :doc:`/development/errors`. +* ``Cake\Routing\AssetMiddleware`` verifica se a solicitação está se referindo a um + arquivo de recursos de tema ou plugin, como um arquivo CSS, JavaScript ou de imagem armazenado + na pasta webroot de um plugin ou na pasta correspondente de um tema. +* ``Cake\Routing\Middleware\RoutingMiddleware`` usa o ``Router`` para analisar a + URL de entrada e atribuir parâmetros de roteamento à solicitação. +* ``Cake\I18n\Middleware\LocaleSelectorMiddleware`` permite a troca automática de idioma + a partir do cabeçalho ``Accept-Language`` enviado pelo navegador. +* ``Cake\Http\Middleware\EncryptedCookieMiddleware`` permite que você + manipule cookies criptografados caso precise manipular cookies com + dados ofuscados. +* ``Cake\Http\Middleware\BodyParserMiddleware`` permite decodificar JSON, XML + e outros corpos de solicitação codificados com base no cabeçalho ``Content-Type``. +* :doc:`Cake\Http\Middleware\HttpsEnforcerMiddleware ` + requer o uso de HTTPS. +* :doc:`Cake\Http\Middleware\CsrfProtectionMiddleware ` adiciona + proteção CSRF baseada em cookie de envio duplo ao seu aplicativo. +* :doc:`Cake\Http\Middleware\SessionCsrfProtectionMiddleware ` + adiciona proteção CSRF baseada em sessão ao seu aplicativo. +* :doc:`Cake\Http\Middleware\CspMiddleware ` + simplifica a adição de cabeçalhos Content-Security-Policy ao seu aplicativo. +* :doc:`Cake\Http\Middleware\SecurityHeadersMiddleware ` + possibilita a adição de cabeçalhos relacionados à segurança, como ``X-Frame-Options``, a + respostas. .. _using-middleware: @@ -72,12 +78,18 @@ middleware:: class Application extends BaseApplication { - public function middleware(MiddlewareQueue $middlwareQueue): MiddlewareQueue + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { - // Vincule o manipulador de erros à fila do middleware. + // Vincule o handler de erros à fila do middleware. $middlewareQueue->add(new ErrorHandlerMiddleware(Configure::read('Error'), $this)); - return $middlwareQueue; + // Adicionar middleware por nome de classe. + // A partir da versão 4.5.0, o middleware de nome de classe é resolvido opcionalmente + // usando o contêiner DI. Se a classe não for encontrada no + // contêiner, uma instância será criada pela fila de middleware. + $middlewareQueue->add(UserRateLimiting::class); + + return $middlewareQueue; } } @@ -111,9 +123,9 @@ Além de adicionar ao final do ``MiddlewareQueue``, você pode executar várias $layer ); -Além de aplicar o middleware a todo o aplicativo, você pode aplicar o -middleware a conjuntos específicos de rotas usando -:ref:`Scope Middleware `. +Se o seu middleware for aplicável apenas a um subconjunto de rotas ou controllers +individuais, você pode usar :ref:`Middleware com escopo de rota `, +ou :ref:`Middleware do controller `. Adicionando Middleware a partir de Plugins ------------------------------------------ @@ -218,81 +230,16 @@ aplicativo:: Roteamento de Middleware ======================== -O middleware de roteamento é responsável por aplicar as rotas no seu aplicativo e -resolver o: plug-in, o controlador e a ação que uma solicitação está pedindo. -Ele pode armazenar em cache a coleção de rotas usada no seu aplicativo para aumentar o -tempo de inicialização. Para habilitar o cache de rotas em, forneça o -:ref:`cache configuration ` desejado como um parâmetro:: +O middleware de roteamento é responsável por aplicar as rotas da sua aplicação e +resolver o plugin, o controller e a ação para a qual uma solicitação será enviada:: - // Em Application.php - public function middleware(MiddlewareQueue $middlwareQueue): MiddlewareQueue + // In Application.php + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { // ... - $middlwareQueue->add(new RoutingMiddleware($this, 'routing')); + $middlewareQueue->add(new RoutingMiddleware($this)); } -O exemplo acima usaria o mecanismo de cache ``routing`` para armazenar a coleção -de rotas gerada. - -.. _security-header-middleware: - -Middleware de Cabeçalho de Segurança -==================================== - -A camada ``Security Headers Middleware`` facilita a aplicação de cabeçalhos -relacionados à segurança em seu aplicativo. Depois de configurado, o middleware -pode aplicar os seguintes cabeçalhos às respostas: - -* ``X-Content-Type-Options`` -* ``X-Download-Options`` -* ``X-Frame-Options`` -* ``X-Permitted-Cross-Domain-Policies`` -* ``Referrer-Policy`` - -Esse middleware é configurado usando uma interface simples antes de ser aplicado à -pilha de middleware do seu aplicativo:: - - use Cake\Http\Middleware\SecurityHeadersMiddleware; - - $securityHeaders = new SecurityHeadersMiddleware(); - $securityHeaders - ->setCrossDomainPolicy() - ->setReferrerPolicy() - ->setXFrameOptions() - ->setXssProtection() - ->noOpen() - ->noSniff(); - - $middlwareQueue->add($securityHeaders); - -Middleware do Cabeçalho da Política de Segurança de Conteúdo -============================================================ - -O ``CspMiddleware`` facilita a adição de cabeçalhos referente a política de segurança de -conteúdo em seu aplicativo. Antes de usá-lo, você deve instalar o ``paragonie/csp-builder``: - -.. code-block::bash - - composer require paragonie/csp-builder - -Você pode configurar o middleware usando uma matriz ou passando um -objeto ``CSPBuilder`` integrado:: - - use Cake\Http\Middleware\CspMiddleware; - - $csp = new CspMiddleware([ - 'script-src' => [ - 'allow' => [ - 'https://www.google-analytics.com', - ], - 'self' => true, - 'unsafe-inline' => false, - 'unsafe-eval' => false, - ], - ]); - - $middlewareQueue->add($csp); - .. _encrypted-cookie-middleware: Middleware de Cookie Criptografado @@ -321,100 +268,6 @@ OpenSSL usando AES:: Os algoritmos de criptografia e o estilo de preenchimento usados pelo middleware do cookie são compatíveis com o ``CookieComponent`` de versões anteriores do CakePHP. -.. _csrf-middleware: - -Falsificação de Solicitação entre Sites (CSRF) Middleware -========================================================= - -A proteção CSRF pode ser aplicada a todo o aplicativo ou a escopos de roteamento específicos. - -.. note:: - - Você não pode usar as duas abordagens a seguir juntas; deve escolher apenas uma. - Se você usar as duas abordagens juntas, ocorrerá um erro de incompatibilidade de - token CSRF em cada solicitação `PUT` e` POST` - -Ao aplicar o ``CsrfProtectionMiddleware`` à pilha de middleware do Aplicativo, -você protege todas as ações no aplicativo:: - - // Em src/Application.php - use Cake\Http\Middleware\CsrfProtectionMiddleware; - - public function middleware($middlwareQueue) { - $options = [ - // ... - ]; - $csrf = new CsrfProtectionMiddleware($options); - - $middlwareQueue->add($csrf); - - return $middlwareQueue; - } - -Ao aplicar o ``CsrfProtectionMiddleware`` aos escopos de roteamento, você pode -incluir ou excluir grupos de rotas específicos:: - - // Em src/Application.php - use Cake\Http\Middleware\CsrfProtectionMiddleware; - - public function routes($routes) { - $options = [ - // ... - ]; - $routes->registerMiddleware('csrf', new CsrfProtectionMiddleware($options)); - parent::routes($routes); - } - - // Em config/routes.php - Router::scope('/', function (RouteBuilder $routes) { - $routes->applyMiddleware('csrf'); - }); - - -As opções podem ser passadas para o construtor do middleware. -As opções de configuração disponíveis são: - -- ``cookieName`` O nome do cookie a ser enviado. O padrão é `` csrfToken``. -- ``expiry`` Quanto tempo o token CSRF deve durar. O padrão é a sessão do navegador. -- ``secure`` Se o cookie será ou não definido com o sinalizador Secure. Isso é, -   o cookie será definido apenas em uma conexão HTTPS e qualquer tentativa no - HTTP normal falhará. O padrão é ``false``. -- ``httpOnly`` Se o cookie será ou não definido com o sinalizador HttpOnly. O padrão é ``false``. -- ``field`` O campo do formulário a ser verificado. O padrão é ``_csrfToken``. - Alterar isso também exigirá a configuração do FormHelper. - -Quando ativado, você pode acessar o token CSRF atual no objeto de solicitação:: - - $token = $this->request->getParam('_csrfToken'); - -.. note:: - - Você deve aplicar o middleware de proteção CSRF apenas para URLs que manipulam solicitações - com estado usando cookies/sessão. Solicitações sem estado, por ex. ao desenvolver uma API, - não são afetados pelo CSRF; portanto, o middleware não precisa ser aplicado a essas URLs. - -Integração com FormHelper -------------------------- - -O ``CsrfProtectionMiddleware`` se integra perfeitamente ao ``FormHelper``. Cada vez -que você cria um formulário com ``FormHelper``, ele insere um campo oculto que contém o token CSRF. - -.. note:: - - Ao usar a proteção CSRF, você sempre deve iniciar seus formulários com o ``FormHelper``. - Caso contrário, será necessário criar manualmente entradas ocultas em cada um dos seus formulários. - -Solicitações de Proteção CSRF e AJAX ------------------------------------- - -Além de solicitar parâmetros de dados, os tokens CSRF podem ser enviados por meio -de um cabeçalho especial ``X-CSRF-Token``. O uso de um cabeçalho geralmente facilita -a integração de um token CSRF com aplicativos pesados de JavaScript ou endpoints de API -baseados em XML/JSON. - -O token CSRF pode ser obtido através do cookie ``csrfToken``. - - .. _body-parser-middleware: Body Parser Middleware diff --git a/pt/controllers/pages-controller.rst b/pt/controllers/pages-controller.rst index 3c52c960dd..717310a9d3 100644 --- a/pt/controllers/pages-controller.rst +++ b/pt/controllers/pages-controller.rst @@ -1,17 +1,17 @@ O Pages Controller ################## -CakePHP é distribuído com o controller **PagesController.php**. Esse controller -é simples, seu uso é opcional e normalmente direcionado a prover páginas -estáticas. A homepage que você vê logo depois de instalar o CakePHP utiliza esse -controller e o arquivo da view fica em **templates/Pages/home.php**. Se você -criar o arquivo **templates/Pages/about.php**, você poderá acessá-lo em -**http://example.com/pages/about**. Fique a vontade para alterar esse controller -para atender suas necessacidades ou mesmo excluí-lo. +A aplicação skeleton oficial do CakePHP vem com um controller padrão **PagesController.php**. +Este é um controller simples e opcional para servir conteúdo estático. A página inicial +que você vê após a instalação é gerada usando este controller e o arquivo de view +**templates/Pages/home.php**. Se você criar o arquivo de view +**templates/Pages/about_us.php**, você pode acessá-lo usando a URL +**http://example.com/pages/about_us**. Você é livre para modificar o Pages +Controller para atender às suas necessidades. -Quando você cria sua aplicação pelo Composer, o ``PagesController`` vai ser -criado na pasta **src/Controller/**. +Quando você "bake" uma aplicação usando o Composer, o Pages Controller é criado na sua +pasta **src/Controller/**. .. meta:: - :title lang=pt: O Controlador Pages - :keywords lang=pt: pages controller,default controller,cakephp,ships,php,home page,página estática + :title lang=en: The Pages Controller + :keywords lang=en: pages controller,default controller,cakephp,ships,php,file folder,home page diff --git a/pt/controllers/pagination.rst b/pt/controllers/pagination.rst new file mode 100644 index 0000000000..eac526b647 --- /dev/null +++ b/pt/controllers/pagination.rst @@ -0,0 +1,296 @@ +Paginação +########## + +Um dos principais obstáculos na criação de aplicações web flexíveis e amigáveis +é o design de uma interface de usuário intuitiva. Muitas aplicações tendem a +crescer rapidamente em tamanho e complexidade, e designers e programadores acabam +descobrindo que não conseguem lidar com a exibição de centenas ou milhares de registros. +A refatoração leva tempo, e o desempenho e a satisfação do usuário podem sofrer. + +Exibir um número razoável de registros por página sempre foi uma parte crítica +de todas as aplicações e costumava causar muitas dores de cabeça para os desenvolvedores. +O CakePHP alivia o fardo do desenvolvedor fornecendo uma maneira concisa de +paginar dados. + +A paginação nos controllers do CakePHP é feita através do método ``paginate()``. Você +então usa :php:class:`~Cake\\View\\Helper\\PaginatorHelper` nos seus view templates +para gerar controles de paginação. + +Uso Básico +=========== + +Você pode chamar ``paginate()`` usando uma instância de tabela ORM ou objeto ``Query``:: + + public function index() + { + // Paginar a tabela ORM. + $this->set('articles', $this->paginate($this->Articles)); + + // Paginar uma query select + $query = $this->Articles->find('published')->contain('Comments'); + $this->set('articles', $this->paginate($query)); + } + +Uso Avançado +============== + +Casos de uso mais complexos são suportados através da configuração da propriedade +``$paginate`` do controller ou como argumento ``$settings`` para ``paginate()``. Essas +condições servem como base para suas queries de paginação. Elas são aumentadas +pelos parâmetros ``sort``, ``direction``, ``limit`` e ``page`` passados +da URL:: + + class ArticlesController extends AppController + { + protected array $paginate = [ + 'limit' => 25, + 'order' => [ + 'Articles.title' => 'asc', + ], + ]; + } + +.. tip:: + As opções padrão de ``order`` devem ser definidas como um array. + +Você também pode usar :ref:`custom-find-methods` na paginação usando a opção ``finder``:: + + class ArticlesController extends AppController + { + protected array $paginate = [ + 'finder' => 'published', + ]; + } + +Nota: Isso funciona apenas com Table como entrada de string em ``$this->paginate('MyTable')``. Depois de usar ``$this->MyTable->find()`` como entrada para ``paginate()``, você deve usar diretamente esse objeto Query. + +Se o seu método finder requer opções adicionais, você pode passá-las +como valores para o finder:: + + class ArticlesController extends AppController + { + // encontrar artigos por tag + public function tags() + { + $tags = $this->request->getParam('pass'); + + $customFinderOptions = [ + 'tags' => $tags + ]; + // Estamos usando o argumento $settings para paginate() aqui. + // Mas a mesma estrutura poderia ser usada em $this->paginate + // + // Nosso finder customizado é chamado findTagged dentro de ArticlesTable.php + // que é por isso que estamos usando `tagged` como chave. + // Nosso finder deve ser assim: + // public function findTagged(Query $query, array $tagged = []) + $settings = [ + 'finder' => [ + 'tagged' => $customFinderOptions + ] + ]; + $articles = $this->paginate($this->Articles, $settings); + $this->set(compact('articles', 'tags')); + } + } + +Além de definir valores gerais de paginação, você pode definir mais de um +conjunto de padrões de paginação no controller. O nome de cada model pode ser usado +como uma chave na propriedade ``$paginate``:: + + class ArticlesController extends AppController + { + protected array $paginate = [ + 'Articles' => [], + 'Authors' => [], + ]; + } + +Os valores das chaves ``Articles`` e ``Authors`` podem conter todas as chaves +que um array ``$paginate`` básico conteria. + +``Controller::paginate()`` retorna uma instância de ``Cake\Datasource\Paging\PaginatedResultSet`` +que implementa a ``Cake\Datasource\Paging\PaginatedInterface``. + +Este objeto contém os registros paginados e os parâmetros de paginação. + +Paginação Simples +================= + +Por padrão, ``Controller::paginate()`` usa a classe ``Cake\Datasource\Paging\NumericPaginator`` +que faz uma query ``COUNT()`` para calcular o tamanho do conjunto de resultados para +que os links de número de página possam ser renderizados. Em conjuntos de dados muito grandes, essa query de contagem +pode ser muito cara. Em situações onde você quer mostrar apenas os links 'Próximo' e 'Anterior', +você pode usar o paginador 'simple' que não faz uma query de contagem:: + + class ArticlesController extends AppController + { + protected array $paginate = [ + 'className' => 'Simple', // Ou use Cake\Datasource\Paging\SimplePaginator::class FQCN + ]; + } + +Ao usar o ``SimplePaginator``, você não será capaz de gerar números de +página, dados de contador, links para a última página ou controles de contagem total de registros. + +.. _paginating-multiple-queries: + +Paginando Múltiplas Queries +=========================== + +Você pode paginar múltiplos models em uma única ação de controller, usando a +opção ``scope`` tanto na propriedade ``$paginate`` do controller quanto na +chamada ao método ``paginate()``:: + + // Propriedade Paginate + protected array $paginate = [ + 'Articles' => ['scope' => 'article'], + 'Tags' => ['scope' => 'tag'] + ]; + + // Em uma ação do controller + $articles = $this->paginate($this->Articles, ['scope' => 'article']); + $tags = $this->paginate($this->Tags, ['scope' => 'tag']); + $this->set(compact('articles', 'tags')); + +A opção ``scope`` fará com que o paginador procure por +parâmetros de query string com escopo. Por exemplo, a seguinte URL poderia ser usada para +paginar tags e artigos ao mesmo tempo:: + + /dashboard?article[page]=1&tag[page]=3 + +Veja a seção :ref:`paginator-helper-multiple` para saber como gerar elementos HTML +e URLs com escopo para paginação. + +Paginando o Mesmo Model várias vezes +------------------------------------ + +Para paginar o mesmo model várias vezes dentro de uma única ação do controller você +precisa definir um alias para o model.:: + + // Em uma ação do controller + $this->paginate = [ + 'Articles' => [ + 'scope' => 'published_articles', + 'limit' => 10, + 'order' => [ + 'id' => 'desc', + ], + ], + 'UnpublishedArticles' => [ + 'scope' => 'unpublished_articles', + 'limit' => 10, + 'order' => [ + 'id' => 'desc', + ], + ], + ]; + + $publishedArticles = $this->paginate( + $this->Articles->find('all', scope: 'published_articles') + ->where(['published' => true]) + ); + + // Carregar um objeto de tabela adicional para permitir a diferenciação no paginador + $unpublishedArticlesTable = $this->fetchTable('UnpublishedArticles', [ + 'className' => 'App\Model\Table\ArticlesTable', + 'table' => 'articles', + 'entityClass' => 'App\Model\Entity\Article', + ]); + + $unpublishedArticles = $this->paginate( + $unpublishedArticlesTable->find('all', scope: 'unpublished_articles') + ->where(['published' => false]) + ); + +.. _control-which-fields-used-for-ordering: + +Controlar quais Campos são Usados para Ordenação +================================================ + +Por padrão, a ordenação pode ser feita em qualquer coluna não virtual que uma tabela tenha. Isso às vezes +é indesejável, pois permite que os usuários ordenem por colunas não indexadas que podem +ser caras para ordenar. Você pode definir a lista de campos permitidos que podem ser ordenados +usando a opção ``sortableFields``. Esta opção é necessária quando você deseja +ordenar por quaisquer dados associados ou campos computados que possam fazer parte da sua +query de paginação:: + + protected array $paginate = [ + 'sortableFields' => [ + 'id', 'title', 'Users.username', 'created', + ], + ]; + +Quaisquer requisições que tentem ordenar por campos que não estão na lista permitida serão +ignoradas. + +Limitar o Número Máximo de Linhas por Página +============================================ + +O número de resultados que são buscados por página é exposto ao usuário como o +parâmetro ``limit``. Geralmente é indesejável permitir que os usuários busquem todas +as linhas em um conjunto paginado. A opção ``maxLimit`` garante que ninguém possa definir +esse limite muito alto de fora. Por padrão, o CakePHP limita o número máximo +de linhas que podem ser buscadas para 100. Se esse padrão não for apropriado +para sua aplicação, você pode ajustá-lo como parte das opções de paginação, por +exemplo, reduzindo-o para ``10``:: + + protected array $paginate = [ + // Outras chaves aqui. + 'maxLimit' => 10 + ]; + +Se o parâmetro limit da requisição for maior que este valor, ele será reduzido para +o valor ``maxLimit``. + +Requisições de Página Fora do Intervalo +======================================= + +``Controller::paginate()`` lançará uma ``NotFoundException`` ao tentar +acessar uma página inexistente, ou seja, o número da página solicitado é maior que a +contagem total de páginas. + +Então você pode deixar a página de erro normal ser renderizada ou usar um bloco try catch +e tomar a ação apropriada quando uma ``NotFoundException`` for capturada:: + + use Cake\Http\Exception\NotFoundException; + + public function index() + { + try { + $this->paginate(); + } catch (NotFoundException $e) { + // Faça algo aqui como redirecionar para a primeira ou última página. + // $e->getPrevious()->getAttributes('pagingParams') fornecerá as informações necessárias. + } + } + +Usando uma classe de paginador diretamente +========================================== + +Você também pode usar um paginador diretamente.:: + + // Criar um paginador + $paginator = new \Cake\Datasource\Paginator\NumericPaginator(); + + // Paginar o model + $results = $paginator->paginate( + // Query ou instância de tabela que você precisa paginar + $this->fetchTable('Articles'), + // Parâmetros da requisição + $this->request->getQueryParams(), + // Array de configuração com a mesma estrutura das opções do Controller::$paginate + [ + 'finder' => 'latest', + ] + ); + +Paginação na View +====================== + +Verifique a documentação do :php:class:`~Cake\\View\\Helper\\PaginatorHelper` para +saber como criar links para navegação de paginação. + +.. meta:: + :title lang=pt: Paginação + :keywords lang=pt: paginate,pagination,paging diff --git a/pt/controllers/request-response.rst b/pt/controllers/request-response.rst index 4e2d2df319..06c8f18804 100644 --- a/pt/controllers/request-response.rst +++ b/pt/controllers/request-response.rst @@ -1,43 +1,53 @@ -Objetos de Requisição e Resposta -################################ +Objetos Request & Response +########################## .. php:namespace:: Cake\Http -Os objetos de solicitação e resposta fornecem uma abstração em torno de solicitações e -respostas HTTP. O objeto de solicitação no CakePHP permite que você examine uma solicitação -de entrada, enquanto o objeto de resposta permite criar respostas HTTP sem esforço do seus -controladores. +Os objetos de solicitação e resposta fornecem uma abstração em torno de solicitações +e respostas HTTP. O objeto de solicitação no CakePHP permite que você introspecte uma +solicitação recebida, enquanto o objeto de resposta permite que você crie respostas +HTTP facilmente a partir dos seus controllers. .. index:: $this->request .. _cake-request: -Requisição -========== +Request +======= .. php:class:: ServerRequest -``ServerRequest`` é o objeto de solicitação padrão usado no CakePHP. Ele centraliza -vários recursos para interrogar e interagir com os dados da solicitação. Em cada -solicitação, uma requisição é criada e depois passada por referência às várias camadas -de um aplicativo que usam dados da solicitação. Por padrão, a solicitação é atribuída -a ``$this->request`` e está disponível em Controllers, Cells, Views e Helpers. Você -também pode acessá-lo em Components usando a referência do controlador. Algumas das -tarefas que o ``ServerRequest`` executa incluem: +``ServerRequest`` é o objeto de requisição padrão usado no CakePHP. Ele centraliza +uma série de recursos para interrogar e interagir com os dados da requisição. +Em cada requisição, uma Requisição é criada e então passada por referência às +diversas camadas de uma aplicação que utilizam os dados da requisição. Por padrão, a requisição +é atribuída a ``$this->request`` e está disponível em Controllers, Células, Views +e Helpers. Você também pode acessá-la em Componentes usando a referência +ao controller. -* Processar as matrizes GET, POST e FILES nas estruturas de dados que você conhece. -* Fornecer introspecção do ambiente referente à solicitação. Informações como os - cabeçalhos enviados, o endereço IP do cliente e os nomes de subdomínio/domínio - no servidor em que seu aplicativo está sendo executado. -* Fornecendo acesso a parâmetros de solicitação, como índices de matriz e propriedades de objetos. +.. versionchanged:: 4.4.0 + O ``ServerRequest`` está disponível via DI. + Então você pode obtê-lo do contêiner ou usá-lo como uma dependência para o seu serviço. + +Algumas das tarefas que ``ServerRequest`` executa incluem: + +* Processando os arrays GET, POST e FILES nas estruturas de dados + com as quais você está familiarizado. +* Fornecendo introspecção do ambiente referente à solicitação. Informações + como os cabeçalhos enviados, o endereço IP do cliente e os nomes de subdomínio/domínio + do servidor em que sua aplicação está sendo executada. +* Fornecendo acesso aos parâmetros da solicitação, tanto como índices do array quanto como propriedades + do objeto. O objeto de solicitação do CakePHP implementa a `PSR-7 -ServerRequestInterface `_ -facilitando o uso de bibliotecas de fora do CakePHP. +ServerRequestInterface `_ facilitando o +uso de bibliotecas de fora do CakePHP. -Parâmetros de Requsição ------------------------ +.. _request-parameters: -A solicitação expõe parâmetros de roteamento através do método ``getParam()``:: +Request Parameters +------------------ + +A solicitação expõe parâmetros de roteamento por meio do método ``getParam()``:: $controllerName = $this->request->getParam('controller'); @@ -45,35 +55,39 @@ Para obter todos os parâmetros de roteamento como uma matriz, use ``getAttribut $parameters = $this->request->getAttribute('params'); -Todos :ref:`route-elements` são acessados através desta interface. +Todos os :ref:`route-elements` são acessados ​​por meio desta interface. -Além de :ref:`route-elements`, você também precisa frequentemente acessar :ref:`passed-arguments`. -Ambos estão disponíveis no objeto de solicitação também:: +Além de :ref:`route-elements`, você também precisa acessar frequentemente +:ref:`passed-arguments`. Ambos estão disponíveis no objeto de solicitação, +bem como:: // Argumentos passados $passedArgs = $this->request->getParam('pass'); -Todos fornecerão acesso aos argumentos passados. Existem vários parâmetros importantes/úteis -que o CakePHP usa internamente, todos eles também são encontrados nos parâmetros de roteamento: +Todos fornecerão acesso aos argumentos passados. Existem +vários parâmetros importantes/úteis que o CakePHP usa internamente, +todos eles também são encontrados nos parâmetros de roteamento: -* ``plugin`` O plug-in que manipula a solicitação. Será nulo quando não houver plug-in. -* ``controller`` O controlador que manipula a solicitação atual. -* ``action`` A ação que manipula a solicitação atual. -* ``prefix`` O prefixo da ação atual. Veja :ref:`prefix-routing` para mais informações. +* ``plugin`` O plugin que manipula a requisição. Será nulo quando não houver + plugin. +* ``controller`` O controller que manipula a requisição atual. +* ``action`` A ação que manipula a requisição atual. +* ``prefix`` O prefixo da ação atual. Veja :ref:`prefix-routing` para + mais informações. -Parâmetros em URL ------------------ +Parâmetros Query String +----------------------- .. php:method:: getQuery($name, $default = null) -Os parâmetros em URL podem ser lidos usando o método ``getQuery()``:: +Os parâmetros da string de consulta podem ser lidos usando o método ``getQuery()``:: // A URL é /posts/index?page=1&sort=title $page = $this->request->getQuery('page'); -Você pode acessar diretamente a propriedade query, ou pode usar o método ``getQuery()`` -para ler a matriz de consultas de URL de maneira livre de erros. Quaisquer chaves que -não existirem retornarão ``null``:: +Você pode acessar diretamente a propriedade de consulta ou usar o método +``getQuery()`` para ler o array de consultas de URL sem erros. +Quaisquer chaves que não existam retornarão ``null``:: $foo = $this->request->getQuery('value_that_does_not_exist'); // $foo === null @@ -81,158 +95,310 @@ não existirem retornarão ``null``:: // Você também pode fornecer valores padrão $foo = $this->request->getQuery('does_not_exist', 'default val'); -Se você deseja acessar todos os parâmetros da consulta, pode usar +Se você quiser acessar todos os parâmetros de consulta, você pode usar ``getQueryParams()``:: $query = $this->request->getQueryParams(); -Dados do Corpo da Requisição ----------------------------- +Você pode usar as funções de utilitário de conversão para fornecer acesso seguro a dados +de solicitação e outras entradas:: + + use function Cake\Core\toBool; + use function Cake\Core\toInt; + use function Cake\Core\toString; + use function Cake\I18n\toDate; + use function Cake\I18n\toDateTime; + + // $active é bool|null. + $active = toBool($this->request->getQuery('active')); + + // $page é int|null. + $page = toInt($this->request->getQuery('page')); + + // $query é string|null. + $query = toString($this->request->getQuery('query')); + + // Analisar uma data com base no formato ou nulo + $date = toDate($this->request->getQuery('date'), 'Y-m-d'); + + // Analisar uma data e hora com base em um formato ou nulo + $date = toDateTime($this->request->getQuery('datetime'), 'Y-m-d H:i:s'); + +.. versionadded:: 5.1.0 + Funções de transmissão foram adicionadas. + +Dados do corpo da solicitação +----------------------------- .. php:method:: getData($name, $default = null) -Todos os dados do POST podem ser acessados usando :php:meth:`Cake\\Http\\ServerRequest::getData()`. -Qualquer dado de formulário que contenha um prefixo ``data`` terá esse prefixo de dados removido. -Por exemplo:: +All POST data normally available through PHP's ``$_POST`` global variable can be +accessed using :php:meth:`Cake\\Http\\ServerRequest::getData()`. For example:: + + // An input with a name attribute equal to 'title' is accessible at + $title = $this->request->getData('title'); + +You can use a dot separated names to access nested data. For example:: - // Uma entrada com um atributo de nome igual a 'MyModel [title]' está acessível em - $title = $this->request->getData('MyModel.title'); + $value = $this->request->getData('address.street_name'); -Quaisquer chaves que não existem retornarão ``null``:: +For non-existent names the ``$default`` value will be returned:: - $foo = $this->request->getData('Value.that.does.not.exist'); + $foo = $this->request->getData('value.that.does.not.exist'); // $foo == null -Dados PUT, PATCH ou DELETE --------------------------- +You can also use :ref:`body-parser-middleware` to parse request body of different +content types into an array, so that it's accessible through ``ServerRequest::getData()``. -.. php:method:: input($callback, [$options]) +If you want to access all the data parameters you can use +``getParsedBody()``:: -Ao criar serviços REST, você geralmente aceita dados de solicitação em -solicitações ``PUT`` e ``DELETE``. Qualquer dado do corpo da solicitação -``application/x-www-form-urlencoded`` será automaticamente analisado e -definido como ``$this->data`` para as solicitações ``PUT`` e ``DELETE``. -Se você estiver aceitando dados JSON ou XML, veja abaixo como acessar -esses corpos de solicitação. + $data = $this->request->getParsedBody(); -Ao acessar os dados de entrada, você pode decodificá-los com uma função opcional. -Isso é útil ao interagir com o conteúdo do corpo da solicitação XML ou JSON. -Parâmetros adicionais para a função de decodificação podem ser passados como -argumentos para ``input()``:: +.. _request-file-uploads: - $jsonData = $this->request->input('json_decode'); +File Uploads +------------ + +Uploaded files can be accessed through the request body data, using the :php:meth:`Cake\\Http\\ServerRequest::getData()` +method described above. For example, a file from an input element with a name attribute of ``attachment``, can +be accessed like this:: + + $attachment = $this->request->getData('attachment'); + +By default file uploads are represented in the request data as objects that implement +`\\Psr\\Http\\Message\\UploadedFileInterface `__. In the current +implementation, the ``$attachment`` variable in the above example would by default hold an instance of +``\Laminas\Diactoros\UploadedFile``. + +Accessing the uploaded file details is fairly simple, here's how you can obtain the same data as provided by the old +style file upload array:: + + $name = $attachment->getClientFilename(); + $type = $attachment->getClientMediaType(); + $size = $attachment->getSize(); + $tmpName = $attachment->getStream()->getMetadata('uri'); + $error = $attachment->getError(); + +Moving the uploaded file from its temporary location to the desired target +location, doesn't require manually accessing the temporary file, instead it can +be easily done by using the objects ``moveTo()`` method:: + + $attachment->moveTo($targetPath); + +In an HTTP environment, the ``moveTo()`` method will automatically validate +whether the file is an actual uploaded file, and throw an exception in case +necessary. In an CLI environment, where the concept of uploading files doesn't +exist, it will allow to move the file that you've referenced irrespective of its +origins, which makes testing file uploads possible. + +.. php:method:: getUploadedFile($path) + +Returns the uploaded file at a specific path. The path uses the same dot syntax as the +:php:meth:`Cake\\Http\\ServerRequest::getData()` method:: + + $attachment = $this->request->getUploadedFile('attachment'); + +Unlike :php:meth:`Cake\\Http\\ServerRequest::getData()`, :php:meth:`Cake\\Http\\ServerRequest::getUploadedFile()` would +only return data when an actual file upload exists for the given path, if there is regular, non-file request body data +present at the given path, then this method will return ``null``, just like it would for any non-existent path. + +.. php:method:: getUploadedFiles() + +Returns all uploaded files in a normalized array structure. For the above example with the file input name of +``attachment``, the structure would look like:: + + [ + 'attachment' => object(Laminas\Diactoros\UploadedFile) { + // ... + } + ] + +.. php:method:: withUploadedFiles(array $files) + +This method sets the uploaded files of the request object, it accepts an array of objects that implement +`\\Psr\\Http\\Message\\UploadedFileInterface `__. It will +replace all possibly existing uploaded files:: + + $files = [ + 'MyModel' => [ + 'attachment' => new \Laminas\Diactoros\UploadedFile( + $streamOrFile, + $size, + $errorStatus, + $clientFilename, + $clientMediaType + ), + 'anotherAttachment' => new \Laminas\Diactoros\UploadedFile( + '/tmp/hfz6dbn.tmp', + 123, + \UPLOAD_ERR_OK, + 'attachment.txt', + 'text/plain' + ), + ], + ]; + + $this->request = $this->request->withUploadedFiles($files); + +.. note:: + + Uploaded files that have been added to the request via this method, will *not* be available in the request body + data, ie you cannot retrieve them via :php:meth:`Cake\\Http\\ServerRequest::getData()`! If you need them in the + request data (too), then you have to set them via :php:meth:`Cake\\Http\\ServerRequest::withData()` or + :php:meth:`Cake\\Http\\ServerRequest::withParsedBody()`. + +PUT, PATCH or DELETE Data +------------------------- + +.. php:method:: getBody() -Variáveis de Ambiente ($_SERVER e $_ENV) ----------------------------------------- +When building REST services, you often accept request data on ``PUT`` and +``DELETE`` requests. Any ``application/x-www-form-urlencoded`` request body data +will automatically be parsed and available via ``$request->getData()`` for ``PUT`` and +``DELETE`` requests. If you are accepting JSON or XML data, you can +access the raw data with ``getBody()``:: -.. php:method:: env($key, $value = null) + // Get the stream wrapper on the request body + $body = $request->getBody(); -``ServerRequest::env()`` é um wrapper para a função global ``env()`` e -atua como um getter/setter para variáveis de ambiente sem precisar modificar -as globais ``$_SERVER`` e ``$_ENV``:: + // Get the request body as a string + $bodyString = (string)$request->getBody(); - // Obter o host - $host = $this->request->env('HTTP_HOST'); +If your requests contain XML or JSON request content, you should consider using +:ref:`body-parser-middleware` to have CakePHP automatically parse those content +types making the parsed data available in ``$request->getData()`` and +``$request->getParsedBody()``. - // Defina um valor, geralmente útil nos testes. - $this->request->env('REQUEST_METHOD', 'POST'); +Environment Variables (from $_SERVER and $_ENV) +----------------------------------------------- -Para acessar todas as variáveis de ambiente em uma solicitação, use ``getServerParams()``:: +.. php:method:: getEnv($key, $default = null) + +``ServerRequest::getEnv()`` is a wrapper for ``getenv()`` global function and acts as +a getter for environment variables without possible undefined keys:: + + $host = $this->request->getEnv('HTTP_HOST'); + +To access all the environment variables in a request use ``getServerParams()``:: $env = $this->request->getServerParams(); -Dados XML ou JSON ------------------ +.. php:method:: withEnv($key, $value) + +``ServerRequest::withEnv()`` is a wrapper for ``putenv()`` global function and acts as +a setter for environment variables without having to modify globals +``$_SERVER`` and ``$_ENV``:: -Os aplicativos que empregam :doc:`/development/rest` geralmente trocam dados em -corpos de postagem não codificados em URL. Você pode ler dados de entrada em -qualquer formato usando :php:meth:`~Cake\\Http\\ServerRequest::input()`. Ao -fornecer uma função de decodificação, você pode receber o conteúdo em um -formato desserializado:: + // Set a value, generally helpful in testing. + $this->request->withEnv('REQUEST_METHOD', 'POST'); - // Obter dados codificados em JSON enviados para uma ação PUT/POST +XML or JSON Data +---------------- + +Applications employing :doc:`/development/rest` often exchange data in +non-URL-encoded post bodies. You can read input data in any format using +:php:meth:`~Cake\\Http\\ServerRequest::input()`. By providing a decoding function, +you can receive the content in a deserialized format:: + + // Get JSON encoded data submitted to a PUT/POST action $jsonData = $this->request->input('json_decode'); -Alguns métodos de desserialização requerem parâmetros adicionais quando chamados, -como o parâmetro 'as array' em ``json_decode``. Se você desejar que o XML seja -convertido em um objeto DOMDocument, :php:meth:`~Cake\\Http\\ServerRequest::input()` -também suporta a passagem de parâmetros adicionais:: +Some deserializing methods require additional parameters when called, such as +the 'as array' parameter on ``json_decode``. If you want XML converted into a +DOMDocument object, :php:meth:`~Cake\\Http\\ServerRequest::input()` supports +passing in additional parameters as well:: - // Obter dados codificados em XML enviados para uma ação PUT/POST + // Get XML encoded data submitted to a PUT/POST action $data = $this->request->input('Cake\Utility\Xml::build', ['return' => 'domdocument']); -Informações de Caminho ----------------------- +Path Information +---------------- -O objeto de solicitação também fornece informações úteis sobre os caminhos -em seu aplicativo. Os atributos ``base`` e ``webroot`` são úteis para -gerar URLs e determinar se seu aplicativo está ou não em um subdiretório. -Os atributos que você pode usar são:: +The request object also provides useful information about the paths in your +application. The ``base`` and ``webroot`` attributes are useful for +generating URLs, and determining whether or not your application is in a +subdirectory. The attributes you can use are:: - // Suponha que o URL da solicitação atual seja /subdir/articles/edit/1?page=1 + // Assume the current request URL is /subdir/articles/edit/1?page=1 - // Possui /subdir/articles/edit/1?page=1 + // Holds /subdir/articles/edit/1?page=1 $here = $request->getRequestTarget(); - // Possui /subdir + // Holds /subdir $base = $request->getAttribute('base'); - // Possui /subdir/ + // Holds /subdir/ $base = $request->getAttribute('webroot'); .. _check-the-request: -Verificando as Condições da Solicitação ---------------------------------------- +Checking Request Conditions +--------------------------- .. php:method:: is($type, $args...) -O objeto de solicitação fornece uma maneira fácil de inspecionar determinadas -condições em uma determinada solicitação. Usando o método ``is()``, você -pode verificar várias condições comuns, bem como inspecionar outros critérios -de solicitação específicos do aplicativo:: +The request object provides a way to inspect certain conditions in a given +request. By using the ``is()`` method you can check a number of common +conditions, as well as inspect other application specific request criteria:: $isPost = $this->request->is('post'); -Você também pode estender os detectores de solicitação disponíveis, usando -:php:meth:`Cake\\Http\\ServerRequest::addDetector()` para criar -novos tipos de detectores. Existem quatro tipos diferentes de detectores -que você pode criar: - -* Comparação de valores do ambiente - Compara um valor obtido de :php:func:`env()` - para igualdade com o valor fornecido. -* Comparação de valores padrão - A comparação de valores padrão permite comparar - um valor obtido de :php:func:`env()` com uma expressão regular. -* Comparação baseada em opção - Comparações baseadas em opção usam uma lista de - opções para criar uma expressão regular. As chamadas subseqüentes para adicionar - um detector de opções já definido mesclarão as opções. -* Detectores de retorno de chamada - Os detectores de retorno de chamada permitem - que você forneça um tipo de 'callback' para lidar com a verificação. - O retorno de chamada receberá o objeto de solicitação como seu único parâmetro. +You can also extend the request detectors that are available, by using +:php:meth:`Cake\\Http\\ServerRequest::addDetector()` to create new kinds of +detectors. There are different types of detectors that you can create: + +* Environment value comparison - Compares a value fetched from :php:func:`env()` + for equality with the provided value. +* Header value comparison - If the specified header exists with the specified + value, or if the callable returns true. +* Pattern value comparison - Pattern value comparison allows you to compare a + value fetched from :php:func:`env()` to a regular expression. +* Option based comparison - Option based comparisons use a list of options to + create a regular expression. Subsequent calls to add an already defined + options detector will merge the options. +* Callback detectors - Callback detectors allow you to provide a 'callback' type + to handle the check. The callback will receive the request object as its only + parameter. .. php:method:: addDetector($name, $options) -Alguns exemplos seriam:: +Some examples would be:: - // Adicione um detector de ambiente. + // Add an environment detector. $this->request->addDetector( 'post', ['env' => 'REQUEST_METHOD', 'value' => 'POST'] ); - // Adicione um detector de valor padrão. + // Add a pattern value detector. $this->request->addDetector( 'iphone', ['env' => 'HTTP_USER_AGENT', 'pattern' => '/iPhone/i'] ); - // Adicione um detector de opção + // Add an option detector $this->request->addDetector('internalIp', [ 'env' => 'CLIENT_IP', 'options' => ['192.168.0.101', '192.168.0.100'] ]); - // Adicione um detector de callback. Deve ser uma chamada válida. + + // Add a header detector with value comparison + $this->request->addDetector('fancy', [ + 'env' => 'CLIENT_IP', + 'header' => ['X-Fancy' => 1] + ]); + + // Add a header detector with callable comparison + $this->request->addDetector('fancy', [ + 'env' => 'CLIENT_IP', + 'header' => ['X-Fancy' => function ($value, $header) { + return in_array($value, ['1', '0', 'yes', 'no'], true); + }] + ]); + + // Add a callback detector. Must be a valid callable. $this->request->addDetector( 'awesome', function ($request) { @@ -240,236 +406,237 @@ Alguns exemplos seriam:: } ); - // Adicione um detector que use argumentos adicionais. + // Add a detector that uses additional arguments. $this->request->addDetector( - 'controller', - function ($request, $name) { - return $request->getParam('controller') === $name; - } + 'csv', + [ + 'accept' => ['text/csv'], + 'param' => '_ext', + 'value' => 'csv', + ] ); -``Request`` também inclui métodos como -:php:meth:`Cake\\Http\\ServerRequest::domain()`, -:php:meth:`Cake\\Http\\ServerRequest::subdomains()` e -:php:meth:`Cake\\Http\\ServerRequest::host()` para ajudar aplicativos com subdomínios, -tenha uma vida um pouco mais fácil. - -Existem vários detectores embutidos que você pode usar: - -* ``is('get')`` Verifique se a solicitação atual é um GET. -* ``is('put')`` Verifique se a solicitação atual é um PUT. -* ``is('patch')`` Verifique se a solicitação atual é um PATCH. -* ``is('post')`` Verifique se a solicitação atual é um POST. -* ``is('delete')`` Verifique se a solicitação atual é um DELETE. -* ``is('head')`` Verifique se a solicitação atual é HEAD. -* ``is('options')`` Verifique se a solicitação atual é OPTIONS. -* ``is('ajax')`` Verifique se a solicitação atual veio com +There are several built-in detectors that you can use: + +* ``is('get')`` Check to see whether the current request is a GET. +* ``is('put')`` Check to see whether the current request is a PUT. +* ``is('patch')`` Check to see whether the current request is a PATCH. +* ``is('post')`` Check to see whether the current request is a POST. +* ``is('delete')`` Check to see whether the current request is a DELETE. +* ``is('head')`` Check to see whether the current request is HEAD. +* ``is('options')`` Check to see whether the current request is OPTIONS. +* ``is('ajax')`` Check to see whether the current request came with X-Requested-With = XMLHttpRequest. -* ``is('ssl')`` Verifique se a solicitação é via SSL. -* ``is('flash')`` Verifique se a solicitação possui um User-Agent de Flash. -* ``is('requested')`` Verifique se a solicitação possui um parâmetro de consulta - 'solicitado' com o valor 1. -* ``is('json')`` Verifique se a solicitação possui extensão 'json' e aceite - mimetype 'application/json'. -* ``is('xml')`` Verifique se a solicitação possui extensão 'xml' e aceite - mimetype 'application/xml' ou 'text/xml'. - -Dados da Sessão ---------------- +* ``is('ssl')`` Check to see whether the request is via SSL. +* ``is('flash')`` Check to see whether the request has a User-Agent of Flash. +* ``is('json')`` Check to see whether the request URL has 'json' extension or the + `Accept` header is set to 'application/json'. +* ``is('xml')`` Check to see whether the request URL has 'xml' extension or the `Accept` header is set to + 'application/xml' or 'text/xml'. + +``ServerRequest`` also includes methods like +:php:meth:`Cake\\Http\\ServerRequest::domain()`, +:php:meth:`Cake\\Http\\ServerRequest::subdomains()` and +:php:meth:`Cake\\Http\\ServerRequest::host()` to make applications that use +subdomains simpler. -Para acessar a sessão para uma determinada solicitação, use o método ``getSession()`` ou use o atributo ``session``:: +Session Data +------------ + +To access the session for a given request use the ``getSession()`` method or use the ``session`` attribute:: $session = $this->request->getSession(); $session = $this->request->getAttribute('session'); - $userName = $session->read('Auth.User.name'); + $data = $session->read('sessionKey'); -Para obter mais informações, consulte a documentação :doc:`/development/sessions` -para saber como usar o objeto de sessão. +For more information, see the :doc:`/development/sessions` documentation for how +to use the session object. -Host e Nome de Domínio ----------------------- +Host and Domain Name +-------------------- .. php:method:: domain($tldLength = 1) -Retorna o nome de domínio em que seu aplicativo está sendo executado:: +Returns the domain name your application is running on:: // Prints 'example.org' echo $request->domain(); .. php:method:: subdomains($tldLength = 1) -Retorna os subdomínios em que seu aplicativo está sendo executado como uma matriz:: +Returns the subdomains your application is running on as an array:: - // Retorna ['my', 'dev'] para 'my.dev.example.org' + // Returns ['my', 'dev'] for 'my.dev.example.org' $subdomains = $request->subdomains(); .. php:method:: host() -Retorna o host em que seu aplicativo está:: +Returns the host your application is on:: - // Exibe 'my.dev.example.org' + // Prints 'my.dev.example.org' echo $request->host(); -Lendo o método HTTP -------------------- +Reading the HTTP Method +----------------------- .. php:method:: getMethod() -Retorna o método HTTP com o qual a solicitação foi feita:: +Returns the HTTP method the request was made with:: - // Saída POST + // Output POST echo $request->getMethod(); -Restringindo Qual Método HTTP Uma Ação Aceita ---------------------------------------------- +Restricting Which HTTP method an Action Accepts +----------------------------------------------- .. php:method:: allowMethod($methods) -Defina métodos HTTP permitidos. Se não corresponder, lançará ``MethodNotAllowedException``. -A resposta 405 incluirá o cabeçalho ``Allow`` necessário com os métodos passados:: +Set allowed HTTP methods. If not matched, will throw +``MethodNotAllowedException``. The 405 response will include the required +``Allow`` header with the passed methods:: public function delete() { - // Aceite apenas solicitações POST e DELETE + // Only accept POST and DELETE requests $this->request->allowMethod(['post', 'delete']); ... } -Lendo Cabeçalhos HTTP ---------------------- +Reading HTTP Headers +-------------------- -Permite acessar qualquer um dos cabeçalhos ``HTTP_*`` -que foram usados para a solicitação. Por exemplo:: +Allows you to access any of the ``HTTP_*`` headers that were used +for the request. For example:: - // Obter o cabeçalho como uma string + // Get the header as a string $userAgent = $this->request->getHeaderLine('User-Agent'); - // Obtenha uma matriz de todos os valores. + // Get an array of all values. $acceptHeader = $this->request->getHeader('Accept'); - // Verifique se existe um cabeçalho + // Check if a header exists $hasAcceptHeader = $this->request->hasHeader('Accept'); -Enquanto algumas instalações do apache não tornam o cabeçalho ``Authorization`` -acessível, o CakePHP o torna disponível através de métodos específicos do apache, -conforme necessário. +While some apache installs don't make the ``Authorization`` header accessible, +CakePHP will make it available through apache specific methods as required. .. php:method:: referer($local = true) -Retorna o endereço de referência para a solicitação. +Returns the referring address for the request. .. php:method:: clientIp() -Retorna o endereço IP do visitante atual. +Returns the current visitor's IP address. -Confiando em Cabeçalhos de Proxy --------------------------------- +Trusting Proxy Headers +---------------------- -Se o seu aplicativo estiver atrás de um balanceador de carga ou em execução em -um serviço de nuvem, geralmente você receberá o host, a porta e o esquema do -balanceador de carga em suas solicitações. Freqüentemente, os balanceadores de -carga também enviam cabeçalhos ``HTTP-X-Forwarded-*`` com os valores originais. -Os cabeçalhos encaminhados não serão usados pelo CakePHP imediatamente. Para -que o objeto de solicitação use esses cabeçalhos, defina a propriedade ``trustProxy`` -como ``true``:: +If your application is behind a load balancer or running on a cloud service, you +will often get the load balancer host, port and scheme in your requests. Often +load balancers will also send ``HTTP-X-Forwarded-*`` headers with the original +values. The forwarded headers will not be used by CakePHP out of the box. To +have the request object use these headers set the ``trustProxy`` property to +``true``:: $this->request->trustProxy = true; - // Esses métodos agora usarão os cabeçalhos com proxy. + // These methods will now use the proxied headers. $port = $this->request->port(); $host = $this->request->host(); $scheme = $this->request->scheme(); $clientIp = $this->request->clientIp(); -Uma vez que os proxies são confiáveis, o método ``clientIp()`` usará o *último* -endereço IP no cabeçalho ``X-Forwarded-For``. Se o seu aplicativo estiver protegido -por vários proxies, você poderá usar ``setTrustedProxies()`` para definir os -endereços IP dos proxies em seu controle:: +Once proxies are trusted the ``clientIp()`` method will use the *last* IP +address in the ``X-Forwarded-For`` header. If your application is behind +multiple proxies, you can use ``setTrustedProxies()`` to define the IP addresses +of proxies in your control:: $request->setTrustedProxies(['127.1.1.1', '127.8.1.3']); -Depois que os proxies forem confiáveis, o ``clientIp()`` usará o primeiro endereço -IP no cabeçalho ``X-Forwarded-For``, desde que seja o único valor que não seja de um -proxy confiável. +After proxies are trusted ``clientIp()`` will use the first IP address in the +``X-Forwarded-For`` header providing it is the only value that isn't from a trusted +proxy. -Verificando Aceitar Cabeçalhos ------------------------------- +Checking Accept Headers +----------------------- .. php:method:: accepts($type = null) -Descubra quais tipos de conteúdo o cliente aceita ou verifique se -ele aceita um tipo específico de conteúdo. +Find out which content types the client accepts, or check whether it accepts a +particular type of content. -Obter todos os tipos:: +Get all types:: $accepts = $this->request->accepts(); -Verifique se há um único tipo:: +Check for a single type:: $acceptsJson = $this->request->accepts('application/json'); .. php:method:: acceptLanguage($language = null) -Obtenha todos os idiomas aceitos pelo cliente, -ou verifique se um idioma específico é aceito. +Get all the languages accepted by the client, +or check whether a specific language is accepted. -Obter a lista de idiomas aceitos:: +Get the list of accepted languages:: $acceptsLanguages = $this->request->acceptLanguage(); -Verifique se um idioma específico é aceito:: +Check whether a specific language is accepted:: $acceptsSpanish = $this->request->acceptLanguage('es-es'); .. _request-cookies: -Lendo Cookies -------------- +Reading Cookies +--------------- -Os cookies de solicitação podem ser lidos através de vários métodos:: +Request cookies can be read through a number of methods:: - // Obtem o valor de um cookie, ou nulo se o cookie não existir. + // Get the cookie value, or null if the cookie is missing. $rememberMe = $this->request->getCookie('remember_me'); - // Leia o valor ou obtenha o padrão 0 + // Read the value, or get the default of 0 $rememberMe = $this->request->getCookie('remember_me', 0); - // Obter todos os cookies como um hash + // Get all cookies as an hash $cookies = $this->request->getCookieParams(); - // Obter uma instância CookieCollection + // Get a CookieCollection instance $cookies = $this->request->getCookieCollection() -Consulte a documentação :php:class:`Cake\\Http\\Cookie\\CookieCollection` -para saber como trabalhar com a coleção de cookies. +See the :php:class:`Cake\\Http\\Cookie\\CookieCollection` documentation for how +to work with cookie collection. -Arquivos Enviados ------------------ -Solicitações expõem os dados do arquivo carregado em ``getData()`` -como matrizes e como objetos ``UploadedFileInterface`` por ``getUploadedFiles()``:: +Uploaded Files +-------------- - // Obter uma lista de objetos UploadedFile +Requests expose the uploaded file data in ``getData()`` or +``getUploadedFiles()`` as ``UploadedFileInterface`` objects:: + + // Get a list of UploadedFile objects $files = $request->getUploadedFiles(); - // Leia os dados do arquivo. + // Read the file data. $files[0]->getStream(); $files[0]->getSize(); $files[0]->getClientFileName(); - // Move o arquivo. + // Move the file. $files[0]->moveTo($targetPath); -Manipulando URIs ----------------- +Manipulating URIs +----------------- -Requisições contêm um objeto URI, que tem métodos para interagir com o URI solicitado:: +Requests contain a URI object, which contains methods for interacting with the +requested URI:: - // Obtem o URI + // Get the URI $uri = $request->getUri(); - // Leia dados fora do URI. + // Read data out of the URI. $path = $uri->getPath(); $query = $uri->getQuery(); $host = $uri->getHost(); @@ -477,186 +644,176 @@ Requisições contêm um objeto URI, que tem métodos para interagir com o URI s .. index:: $this->response -Resposta +Response ======== .. php:class:: Response -:php:class:`Cake\\Http\\Response` é a classe de resposta padrão no CakePHP. -Ele encapsula vários recursos e funcionalidades para gerar respostas HTTP em -seu aplicativo. Também auxilia nos testes, pois pode ser simulado/esboçado, -permitindo que você inspecione os cabeçalhos que serão enviados. Como -:php:class:`Cake\\Http\\ServerRequest`, :php:class:`Cake\\Http\\Response` -consolida uma série de métodos encontrados anteriormente em :php:class:`Controller`, -:php:class:`RequestHandlerComponent` e :php:class:`Dispatcher`. Os métodos -antigos são preteridos no uso de :php:class:`Cake\\Http\\Response`. +:php:class:`Cake\\Http\\Response` is the default response class in CakePHP. +It encapsulates a number of features and functionality for generating HTTP +responses in your application. It also assists in testing, as it can be +mocked/stubbed allowing you to inspect headers that will be sent. -``Response`` fornece uma interface para agrupar tarefas comuns -relacionadas à resposta, como: +``Response`` provides an interface to wrap the common response-related +tasks such as: -* Enviar cabeçalhos para redirecionamentos. -* Enviar cabeçalhos de tipo de conteúdo. -* Enviar qualquer cabeçalho. -* Enviar o corpo da resposta. +* Sending headers for redirects. +* Sending content type headers. +* Sending any header. +* Sending the response body. -Lidando com Tipos de Conteúdo ------------------------------ +Dealing with Content Types +-------------------------- .. php:method:: withType($contentType = null) -Você pode controlar o tipo de conteúdo das respostas do seu aplicativo com -:php:meth:`Cake\\Http\\Response::withType()`. Se seu aplicativo precisar -lidar com tipos de conteúdo que não estão embutidos no Response, você pode -mapeá-los com ``type()`` também:: +You can control the Content-Type of your application's responses with +:php:meth:`Cake\\Http\\Response::withType()`. If your application needs to deal +with content types that are not built into Response, you can map them with +``setTypeMap()`` as well:: - // Adiciona um tipo de vCard - $this->response->type(['vcf' => 'text/v-card']); + // Add a vCard type + $this->response->setTypeMap('vcf', ['text/v-card']); - // Defina a resposta Content-Type como vcard + // Set the response Content-Type to vcard. $this->response = $this->response->withType('vcf'); -Normalmente, você deseja mapear tipos de conteúdo adicionais no retorno de -chamada do seu controlador :php:meth:`~Controller::beforeFilter()`, -para poder aproveitar os recursos de troca automática de exibição de -:php:class:`RequestHandlerComponent` se você está usando. +Usually, you'll want to map additional content types in your controller's +:php:meth:`~Controller::beforeFilter()` callback, so you can benefit from +automatic view switching provided by :ref:`controller-viewclasses`. .. _cake-response-file: -Enviando Arquivos ------------------ +Sending Files +------------- -.. php:method:: withFile($path, $options = []) +.. php:method:: withFile(string $path, array $options = []) -Há momentos em que você deseja enviar arquivos como respostas para suas -solicitações. Você pode fazer isso usando :php:meth:`Cake\\Http\\Response::withFile()`:: +There are times when you want to send files as responses for your requests. +You can accomplish that by using :php:meth:`Cake\\Http\\Response::withFile()`:: public function sendFile($id) { $file = $this->Attachments->getFile($id); $response = $this->response->withFile($file['path']); - // Retorna a resposta para impedir que o controlador tente renderizar - // uma view. + // Return the response to prevent controller from trying to render + // a view. return $response; } -Como mostrado no exemplo acima, você deve passar o caminho do arquivo para o -método. O CakePHP enviará um cabeçalho de tipo de conteúdo adequado se for um -tipo de arquivo conhecido listado em `Cake\\Http\\Response::$_mimeTypes`. -Você pode adicionar novos tipos antes de chamar :php:meth:`Cake\\Http\\Response::withFile()` -usando o método :php:meth:`Cake\\Http\\Response::withType()`. +As shown in the above example, you must pass the file path to the method. +CakePHP will send a proper content type header if it's a known file type listed +in `Cake\\Http\\Response::$_mimeTypes`. You can add new types prior to calling +:php:meth:`Cake\\Http\\Response::withFile()` by using the +:php:meth:`Cake\\Http\\Response::withType()` method. -Se desejar, você também pode forçar o download de um arquivo em vez de ser -exibido no navegador, especificando as opções:: +If you want, you can also force a file to be downloaded instead of displayed in +the browser by specifying the options:: $response = $this->response->withFile( $file['path'], ['download' => true, 'name' => 'foo'] ); -As opções suportadas são: +The supported options are: name - O nome permite especificar um nome de arquivo alternativo a ser enviado - ao usuário. + The name allows you to specify an alternate file name to be sent to + the user. download - Um valor booleano indicando se os cabeçalhos devem ser definidos para forçar o + A boolean value indicating whether headers should be set to force download. -Enviando uma String como Arquivo --------------------------------- +Sending a String as File +------------------------ -Você pode responder com um arquivo que não existe no disco, como um pdf ou um ics -gerado on-line a partir de uma string:: +You can respond with a file that does not exist on the disk, such as a pdf or an +ics generated on the fly from a string:: public function sendIcs() { $icsString = $this->Calendars->generateIcs(); $response = $this->response; - // Injetar conteúdo da string no corpo da resposta + // Inject string content into response body $response = $response->withStringBody($icsString); $response = $response->withType('ics'); - // Opcionalmente, obriga o download do arquivo + // Optionally force file download $response = $response->withDownload('filename_for_download.ics'); - // Retorne o objeto de resposta para impedir que o controlador tente renderizar - // uma view. + // Return response object to prevent controller from trying to render + // a view. return $response; } -Os retornos de chamada também podem retornar o corpo como uma sequência:: - - $path = '/some/file.png'; - $this->response->body(function () use ($path) { - return file_get_contents($path); - }); - -Definindo Cabeçalhos --------------------- +Setting Headers +--------------- .. php:method:: withHeader($header, $value) -A configuração dos cabeçalhos é feita com o método :php:meth:`Cake\\Http\\Response::withHeader()`. -Como todos os métodos de interface PSR-7, esse método retorna uma instância *new* com o novo cabeçalho:: +Setting headers is done with the :php:meth:`Cake\\Http\\Response::withHeader()` +method. Like all of the PSR-7 interface methods, this method returns a *new* +instance with the new header:: - // Adicionar/substituir um cabeçalho + // Add/replace a header $response = $response->withHeader('X-Extra', 'My header'); - // Define vários cabeçalhos + // Set multiple headers $response = $response->withHeader('X-Extra', 'My header') ->withHeader('Location', 'http://example.com'); - // Anexa um valor a um cabeçalho existente + // Append a value to an existing header $response = $response->withAddedHeader('Set-Cookie', 'remember_me=1'); -Os cabeçalhos não são enviados quando definidos. Em vez disso, eles são mantidos -até que a resposta seja emitida por ``Cake\Http\Server``. +Headers are not sent when set. Instead, they are held until the response is +emitted by ``Cake\Http\Server``. -Agora você pode usar o método conveniente :php:meth:`Cake\\Http\\Response::withLocation()` -para definir diretamente ou obter o cabeçalho do local de redirecionamento. +You can now use the convenience method +:php:meth:`Cake\\Http\\Response::withLocation()` to directly set or get the +redirect location header. -Definindo o Corpo ------------------ +Setting the Body +---------------- .. php:method:: withStringBody($string) -Para definir uma sequência como o corpo da resposta, faça o seguinte:: +To set a string as the response body, do the following:: - // Define uma string no corpo da resposta + // Set a string into the body $response = $response->withStringBody('My Body'); - // Se você deseja enviar uma resposta em JSON + // If you want a json response $response = $response->withType('application/json') ->withStringBody(json_encode(['Foo' => 'bar'])); .. php:method:: withBody($body) -Para definir o corpo da resposta, use o método ``withBody()``, fornecido pelo -:php:class:`Zend\\Diactoros\\MessageTrait`:: +To set the response body, use the ``withBody()`` method, which is provided by the +:php:class:`Laminas\\Diactoros\\MessageTrait`:: $response = $response->withBody($stream); -Certifique-se de que ``$stream`` seja um objeto :php:class:`Psr\\Http\\Message\\StreamInterface`. -Veja abaixo como criar um novo fluxo. +Be sure that ``$stream`` is a :php:class:`Psr\\Http\\Message\\StreamInterface` object. +See below on how to create a new stream. -Você também pode transmitir respostas de arquivos usando :php:class:`Zend\\Diactoros\\Stream` streams:: +You can also stream responses from files using :php:class:`Laminas\\Diactoros\\Stream` streams:: - // Para transmitir a partir de um arquivo - use Zend\Diactoros\Stream; + // To stream from a file + use Laminas\Diactoros\Stream; $stream = new Stream('/path/to/file', 'rb'); $response = $response->withBody($stream); -Você também pode transmitir respostas de um retorno de chamada usando o -``CallbackStream``. Isso é útil quando você possui recursos como imagens, -arquivos CSV ou PDFs que precisam ser transmitidos para o cliente:: +You can also stream responses from a callback using the ``CallbackStream``. This +is useful when you have resources like images, CSV files or PDFs you need to +stream to the client:: - // Streaming a partir de um retorno de chamada + // Streaming from a callback use Cake\Http\CallbackStream; - // Cria uma imagem + // Create an image. $img = imagecreate(100, 100); // ... @@ -665,173 +822,183 @@ arquivos CSV ou PDFs que precisam ser transmitidos para o cliente:: }); $response = $response->withBody($stream); -Definindo o Conjunto de Caracteres ----------------------------------- +Setting the Character Set +------------------------- .. php:method:: withCharset($charset) -Define o conjunto de caracteres que será usado na resposta:: +Sets the charset that will be used in the response:: $this->response = $this->response->withCharset('UTF-8'); -Interagindo com o Cache do Navegador ------------------------------------- +Interacting with Browser Caching +-------------------------------- .. php:method:: withDisabledCache() -Às vezes, você precisa forçar os navegadores a não armazenar em cache os resultados -de uma ação do controlador. :php:meth:`Cake\\Http\\Response::withDisabledCache()` -é destinado apenas para isso:: +You sometimes need to force browsers not to cache the results of a controller +action. :php:meth:`Cake\\Http\\Response::withDisabledCache()` is intended for just +that:: public function index() { - // Desabilita o caching + // Disable caching $this->response = $this->response->withDisabledCache(); } .. warning:: - Desativando o armazenamento em cache de domínios SSL - ao tentar enviar arquivos no Internet Explorer podem resultar em erros. + Disabling caching from SSL domains while trying to send + files to Internet Explorer can result in errors. .. php:method:: withCache($since, $time = '+1 day') -Você também pode dizer aos clientes que deseja que eles armazenem respostas em cache. -Usando :php:meth:`Cake\\Http\\Response::withCache()`:: +You can also tell clients that you want them to cache responses. By using +:php:meth:`Cake\\Http\\Response::withCache()`:: public function index() { - // Habilita o caching + // Enable caching $this->response = $this->response->withCache('-1 minute', '+5 days'); } -O exposto acima informava aos clientes para armazenar em cache a resposta -resultante por 5 dias, acelerando a experiência dos visitantes. O método ``withCache()`` -define o valor ``Last-Modified`` para o primeiro argumento. O cabeçalho ``Expires`` e -a diretiva ``max-age`` são configurados com base no segundo parâmetro. A diretiva -``public`` do Cache-Control também é definida. +The above would tell clients to cache the resulting response for 5 days, +hopefully speeding up your visitors' experience. +The ``withCache()`` method sets the ``Last-Modified`` value to the first +argument. ``Expires`` header and the ``max-age`` directive are set based on the +second parameter. Cache-Control's ``public`` directive is set as well. .. _cake-response-caching: -Ajuste Fino de Cache HTTP -------------------------- +Fine Tuning HTTP Cache +---------------------- -Uma das melhores e mais fáceis maneiras de acelerar seu aplicativo é usar o cache HTTP. -Sob esse modelo de armazenamento em cache, você só precisa ajudar os clientes a decidir -se devem usar uma cópia em cache da resposta, definindo alguns cabeçalhos, como tempo -modificado e tag da entidade de resposta. +One of the best and easiest ways of speeding up your application is to use HTTP +cache. Under this caching model, you are only required to help clients decide if +they should use a cached copy of the response by setting a few headers such as +modified time and response entity tag. -Em vez de forçar você a codificar a lógica para armazenar em cache e invalidá-la -(atualizando) depois que os dados forem alterados, o HTTP usa dois modelos, expiração -e validação, que geralmente são muito mais simples de usar. +Rather than forcing you to code the logic for caching and for invalidating +(refreshing) it once the data has changed, HTTP uses two models, expiration and +validation, which usually are much simpler to use. -Além de usar :php:meth:`Cake\\Http\\Response::withCache()`, você também pode usar -muitos outros métodos para ajustar os cabeçalhos de cache HTTP para tirar proveito -do cache do navegador ou do proxy reverso. +Apart from using :php:meth:`Cake\\Http\\Response::withCache()`, you can also use +many other methods to fine-tune HTTP cache headers to take advantage of browser +or reverse proxy caching. -O cabeçalho para Controle de Cache -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The Cache Control Header +~~~~~~~~~~~~~~~~~~~~~~~~ .. php:method:: withSharable($public, $time = null) -Usado como modelo de expiração, esse cabeçalho contém vários indicadores que podem -alterar a maneira como navegadores ou proxies usam o conteúdo em cache. Um -cabeçalho ``Cache-Control`` pode ser assim:: +Used under the expiration model, this header contains multiple indicators that +can change the way browsers or proxies use the cached content. A +``Cache-Control`` header can look like this:: Cache-Control: private, max-age=3600, must-revalidate -A classe ``Response`` ajuda a definir esse cabeçalho com alguns métodos utilitários -que produzirão um cabeçalho final ``Cache-Control`` válido. O primeiro é o método -``withSharable()``, que indica se uma resposta deve ser considerada compartilhável -entre diferentes usuários ou clientes. Este método realmente controla a parte ``public`` -ou ``private`` deste cabeçalho. Definir uma resposta como privada indica que a totalidade -ou parte dela é destinada a um único usuário. Para tirar proveito dos caches compartilhados, -a diretiva de controle deve ser definida como pública. +``Response`` class helps you set this header with some utility methods that will +produce a final valid ``Cache-Control`` header. The first is the +``withSharable()`` method, which indicates whether a response is to be +considered sharable across different users or clients. This method actually +controls the ``public`` or ``private`` part of this header. Setting a response +as private indicates that all or part of it is intended for a single user. To +take advantage of shared caches, the control directive must be set as public. -O segundo parâmetro desse método é usado para especificar uma ``idade máxima`` para o cache, -que é o número de segundos após os quais a resposta não é mais considerada nova:: +The second parameter of this method is used to specify a ``max-age`` for the +cache, which is the number of seconds after which the response is no longer +considered fresh:: public function view() { // ... - // Define o controle de cache como público por 3600 segundos + // Set the Cache-Control as public for 3600 seconds $this->response = $this->response->withSharable(true, 3600); } public function my_data() { // ... - // Define o Cache-Control como privado por 3600 segundos + // Set the Cache-Control as private for 3600 seconds $this->response = $this->response->withSharable(false, 3600); } -``Response`` expõe métodos separados para definir cada uma das diretivas no -cabeçalho ``Cache-Control``. +``Response`` exposes separate methods for setting each of the directives in +the ``Cache-Control`` header. -O Cabeçalho de Expiração -~~~~~~~~~~~~~~~~~~~~~~~~ +The Expiration Header +~~~~~~~~~~~~~~~~~~~~~ .. php:method:: withExpires($time) -Você pode definir o cabeçalho ``Expires`` para uma data e hora após a qual a -resposta não é mais considerada nova. Esse cabeçalho pode ser definido usando -o método ``withExpires()``:: +You can set the ``Expires`` header to a date and time after which the response +is no longer considered fresh. This header can be set using the +``withExpires()`` method:: public function view() { $this->response = $this->response->withExpires('+5 days'); } -Este método também aceita uma instância :php:class:`DateTime` ou qualquer string -que possa ser analisada pela classe :php:class:`DateTime`. +This method also accepts a :php:class:`DateTime` instance or any string that can +be parsed by the :php:class:`DateTime` class. -O Cabeçalho Etag -~~~~~~~~~~~~~~~~ +The Etag Header +~~~~~~~~~~~~~~~ .. php:method:: withEtag($tag, $weak = false) -A validação de cache no HTTP é frequentemente usada quando o conteúdo está em -constante mudança e solicita ao aplicativo que gere apenas o conteúdo da resposta -se o cache não estiver mais atualizado. Sob esse modelo, o cliente continua a armazenar -páginas no cache, mas pergunta sempre ao aplicativo se o recurso foi alterado, em vez de -usá-lo diretamente. Isso é comumente usado com recursos estáticos, como imagens e outros assets. +Cache validation in HTTP is often used when content is constantly changing, and +asks the application to only generate the response contents if the cache is no +longer fresh. Under this model, the client continues to store pages in the +cache, but it asks the application every time +whether the resource has changed, instead of using it directly. +This is commonly used with static resources such as images and other assets. -O método ``withEtag()`` (chamado tag de entidade) é uma string que identifica exclusivamente -o recurso solicitado, como a soma de verificação de um arquivo, para determinar se ele -corresponde a um recurso em cache. +The ``withEtag()`` method (called entity tag) is a string +that uniquely identifies the requested resource, as a checksum does for a file, +in order to determine whether it matches a cached resource. -Para tirar proveito desse cabeçalho, você deve chamar o método ``isNotModified()`` -manualmente ou incluir o seguinte :doc:`/controllers/components/request-handling` no seu controlador:: +To take advantage of this header, you must either call the +``isNotModified()`` method manually or include the +:doc:`/controllers/components/check-http-cache` in your controller:: public function index() { - $articles = $this->Articles->find('all'); - $response = $this->response->withEtag($this->Articles->generateHash($articles)); + $articles = $this->Articles->find('all')->all(); + + // Simple checksum of the article contents. + // You should use a more efficient implementation + // in a real world application. + $checksum = md5(json_encode($articles)); + + $response = $this->response->withEtag($checksum); if ($response->isNotModified($this->request)) { return $response; } + $this->response = $response; // ... } .. note:: - A maioria dos usuários proxy provavelmente deve considerar o uso do Último - Cabeçalho Modificado em vez de Etags por motivos de desempenho e compatibilidade. + Most proxy users should probably consider using the Last Modified Header + instead of Etags for performance and compatibility reasons. -O Último Cabeçalho Modificado -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The Last Modified Header +~~~~~~~~~~~~~~~~~~~~~~~~ .. php:method:: withModified($time) -Além disso, no modelo de validação de cache HTTP, você pode definir o cabeçalho -``Last-Modified`` para indicar a data e a hora em que o recurso foi modificado -pela última vez. Definir este cabeçalho ajuda o CakePHP a informar aos clientes -de armazenamento em cache se a resposta foi modificada ou não com base em seu cache. +Also, under the HTTP cache validation model, you can set the ``Last-Modified`` +header to indicate the date and time at which the resource was modified for the +last time. Setting this header helps CakePHP tell caching clients whether the +response was modified or not based on their cache. -Para tirar proveito desse cabeçalho, você deve chamar o método ``isNotModified()`` -manualmente ou incluir o seguinte :doc:`/controllers/components/request-handling` -no seu controlador:: +To take advantage of this header, you must either call the +``isNotModified()`` method manually or include the +:doc:`/controllers/components/check-http-cache` in your controller:: public function view() { @@ -844,68 +1011,75 @@ no seu controlador:: // ... } -O Cabeçalho Vary -~~~~~~~~~~~~~~~~ +The Vary Header +~~~~~~~~~~~~~~~ .. php:method:: withVary($header) -Em alguns casos, convém veicular conteúdo diferente usando o mesmo URL. Geralmente, -esse é o caso se você tiver uma página multilíngue ou responder com HTML diferente, -dependendo do navegador. Nessas circunstâncias, você pode usar o cabeçalho ``Vary``:: +In some cases, you might want to serve different content using the same URL. +This is often the case if you have a multilingual page or respond with different +HTML depending on the browser. Under such circumstances you can use the ``Vary`` +header:: $response = $this->response->withVary('User-Agent'); $response = $this->response->withVary('Accept-Encoding', 'User-Agent'); $response = $this->response->withVary('Accept-Language'); -Enviando Respostas Não Modificadas -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Sending Not-Modified Responses +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. php:method:: isNotModified(Request $request) -Compara os cabeçalhos de cache do objeto de solicitação com o cabeçalho de cache -da resposta e determina se ele ainda pode ser considerado novo. Nesse caso, exclui -o conteúdo da resposta e envia o cabeçalho `304 Not Modified`:: +Compares the cache headers for the request object with the cache header from the +response and determines whether it can still be considered fresh. If so, deletes +the response content, and sends the `304 Not Modified` header:: - // Em um método do controlador. + // In a controller action. if ($this->response->isNotModified($this->request)) { return $this->response; } .. _response-cookies: -Configurando Cookies --------------------- +Setting Cookies +--------------- -Os cookies podem ser adicionados à resposta usando um array ou um objeto :php:class:`Cake\\Http\\Cookie\\Cookie`:: +Cookies can be added to response using either an array or a :php:class:`Cake\\Http\\Cookie\\Cookie` +object:: use Cake\Http\Cookie\Cookie; use DateTime; - // Adiciona um cookie - $this->response = $this->response->withCookie(new Cookie( + // Add a cookie + $this->response = $this->response->withCookie(Cookie::create( 'remember_me', 'yes', - new DateTime('+1 year'), // expiration time - '/', // path - '', // domain - false, // secure - true // httponly - ]); - -Veja a seção `created-cookies` para saber como usar o objeto cookie. -Você pode usar ``withExpiredCookie()`` para enviar um cookie expirado na -resposta. Isso fará com que o navegador remova seu cookie local:: - - $this->response = $this->response->withExpiredCookie('remember_me'); + // All keys are optional + [ + 'expires' => new DateTime('+1 year'), + 'path' => '', + 'domain' => '', + 'secure' => false, + 'httponly' => false, + 'samesite' => null // Or one of CookieInterface::SAMESITE_* constants + ] + )); + +See the :ref:`creating-cookies` section for how to use the cookie object. You +can use ``withExpiredCookie()`` to send an expired cookie in the response. This +will make the browser remove its local cookie:: + + $this->response = $this->response->withExpiredCookie(new Cookie('remember_me')); .. _cors-headers: -Definindo Cabeçalho de Solicitação de Origem Cruzada (CORS) -=========================================================== +Setting Cross Origin Request Headers (CORS) +------------------------------------------- -O método ``cors()`` é usado para definir o `HTTP Access Control -`__, -são cabeçalhos relacionados com uma interface fluente:: +The ``cors()`` method returns a ``CorsBuilder`` instance which provides a fluent +interface for defining `HTTP Access Control +`__ +related headers:: $this->response = $this->response->cors($this->request) ->allowOrigin(['*.cakephp.org']) @@ -916,28 +1090,212 @@ são cabeçalhos relacionados com uma interface fluente:: ->maxAge(300) ->build(); -Os cabeçalhos relacionados ao CORS somente serão aplicados à resposta se os seguintes -critérios forem atendidos: +CORS related headers will only be applied to the response if the following +criteria are met: + +#. The request has an ``Origin`` header. +#. The request's ``Origin`` value matches one of the allowed Origin values. + +CorsBuilder Methods +~~~~~~~~~~~~~~~~~~~ + +.. php:class:: CorsBuilder + +The ``CorsBuilder`` provides the following methods for configuring CORS: + +.. php:method:: allowOrigin(array|string $domains) + + Set the list of allowed domains. You can use wildcards ``*.example.com`` to + accept subdomains, or ``*`` to allow all domains:: + + // Allow a specific domain + ->allowOrigin('https://example.com') + + // Allow multiple domains + ->allowOrigin(['https://example.com', 'https://app.example.com']) + + // Allow all subdomains + ->allowOrigin(['*.example.com']) + + // Allow all origins (use with caution!) + ->allowOrigin('*') + +.. php:method:: allowMethods(array $methods) + + Set the list of allowed HTTP methods:: + + ->allowMethods(['GET', 'POST', 'PUT', 'DELETE']) + +.. php:method:: allowHeaders(array $headers) + + Define which headers can be sent in CORS requests:: + + ->allowHeaders(['X-CSRF-Token', 'Content-Type', 'Authorization']) + +.. php:method:: allowCredentials() + + Enable cookies to be sent in CORS requests. This sets the + ``Access-Control-Allow-Credentials`` header to ``true``:: + + ->allowCredentials() + +.. php:method:: exposeHeaders(array $headers) + + Define which headers the client library/browser can expose to scripting:: + + ->exposeHeaders(['X-Total-Count', 'Link']) + +.. php:method:: maxAge(string|int $age) + + Define how long preflight OPTIONS requests are valid for (in seconds):: -#. A solicitação possui um cabeçalho ``Origin``. -#. O valor ``Origem`` da solicitação corresponde a um dos valores de Origin permitidos. + ->maxAge(3600) // Cache preflight for 1 hour -Erros Comuns com Respostas Imutáveis -==================================== +.. php:method:: build() -Os objetos de resposta oferecem vários métodos que tratam as respostas como objetos -imutáveis. Objetos imutáveis ajudam a evitar efeitos colaterais acidentais difíceis -de controlar e reduzem os erros causados por chamadas de método causadas pela refatoração -dessa ordem de alteração. Embora ofereçam vários benefícios, objetos imutáveis podem levar -algum tempo para se acostumar. Qualquer método que comece com ``with`` opera a resposta de -maneira imutável e **sempre** retorna uma **nova** instância. Esquecer de manter a instância -modificada é o erro mais frequente que as pessoas cometem ao trabalhar com objetos imutáveis:: + Apply the configured headers to the response and return it. This must be + called to actually apply the CORS headers:: + + $response = $corsBuilder->build(); + +Practical CORS Examples +~~~~~~~~~~~~~~~~~~~~~~~ + +Here are some common CORS configurations: + +**API accepting requests from a SPA frontend**:: + + // In your controller + public function beforeFilter(EventInterface $event) + { + parent::beforeFilter($event); + + if ($this->request->is('options')) { + // Handle preflight requests + $this->response = $this->response->cors($this->request) + ->allowOrigin(['https://app.example.com']) + ->allowMethods(['GET', 'POST', 'PUT', 'DELETE']) + ->allowHeaders(['Content-Type', 'Authorization']) + ->allowCredentials() + ->maxAge(86400) + ->build(); + + return $this->response; + } + } + + public function index() + { + // Apply CORS to regular requests + $this->response = $this->response->cors($this->request) + ->allowOrigin(['https://app.example.com']) + ->allowCredentials() + ->build(); + + // Your regular controller logic... + } + +**Public API with relaxed CORS**:: + + $this->response = $this->response->cors($this->request) + ->allowOrigin('*') + ->allowMethods(['GET']) + ->exposeHeaders(['X-Total-Count', 'X-Page']) + ->maxAge(3600) + ->build(); + +Creating CORS Middleware +~~~~~~~~~~~~~~~~~~~~~~~~ + +For consistent CORS handling across your application, create a middleware:: + + // src/Middleware/CorsMiddleware.php + namespace App\Middleware; + + use Psr\Http\Message\ResponseInterface; + use Psr\Http\Message\ServerRequestInterface; + use Psr\Http\Server\MiddlewareInterface; + use Psr\Http\Server\RequestHandlerInterface; + + class CorsMiddleware implements MiddlewareInterface + { + public function process( + ServerRequestInterface $request, + RequestHandlerInterface $handler + ): ResponseInterface { + // Handle preflight requests + if ($request->getMethod() === 'OPTIONS') { + $response = new \Cake\Http\Response(); + $response = $response->cors($request) + ->allowOrigin(['*.myapp.com']) + ->allowMethods(['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']) + ->allowHeaders(['Content-Type', 'Authorization']) + ->allowCredentials() + ->maxAge(3600) + ->build(); + + return $response; + } + + $response = $handler->handle($request); + + // Add CORS headers to regular requests + return $response->cors($request) + ->allowOrigin(['*.myapp.com']) + ->allowCredentials() + ->build(); + } + } + +Then add it to your application middleware stack in ``src/Application.php``:: + + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue + { + $middlewareQueue + // Add CORS middleware early in the stack + ->add(new \App\Middleware\CorsMiddleware()) + // ... other middleware + ->add(new ErrorHandlerMiddleware(Configure::read('Error'))) + ->add(new AssetMiddleware([ + 'cacheTime' => Configure::read('Asset.cacheTime'), + ])) + ->add(new RoutingMiddleware($this)); + + return $middlewareQueue; + } + +Running logic after the Response has been sent +---------------------------------------------- + +In fastcgi based environments you can listen to the ``Server.terminate`` event +to run logic **after** the response has been sent to the client. The +``terminate`` event will be passed a ``request`` and ``response``. The +``request`` is fetched from the applications' DI container, or from +``Router::getRequest()`` if the DI container does not have a request registered. + +.. warning:: + In non fastcgi environments the ``Server.terminate`` event is fired before + the response is sent. + +.. versionadded:: 5.1.0 + +Common Mistakes with Immutable Responses +======================================== + +Response objects offer a number of methods that treat +responses as immutable objects. Immutable objects help prevent difficult to +track accidental side-effects, and reduce mistakes caused by method calls caused +by refactoring that change ordering. While they offer a number of benefits, +immutable objects can take some getting used to. Any method that starts with +``with`` operates on the response in an immutable fashion, and will **always** +return a **new** instance. Forgetting to retain the modified instance is the most +frequent mistake people make when working with immutable objects:: $this->response->withHeader('X-CakePHP', 'yes!'); -No código acima, a resposta não terá o cabeçalho ``X-CakePHP``, pois o valor de -retorno do método ``withHeader()`` não foi mantido. Para corrigir o código acima, -você escreveria:: +In the above code, the response will be lacking the ``X-CakePHP`` header, as the +return value of the ``withHeader()`` method was not retained. To correct the +above code you would write:: $this->response = $this->response->withHeader('X-CakePHP', 'yes!'); @@ -948,34 +1306,34 @@ Cookie Collections .. php:class:: CookieCollection -Os objetos ``CookieCollection`` são acessíveis a partir dos objetos de solicitação -e resposta. Eles permitem que você interaja com grupos de cookies usando padrões -imutáveis, que permitem preservar a imutabilidade da solicitação e resposta. +``CookieCollection`` objects are accessible from the request and response objects. +They let you interact with groups of cookies using immutable patterns, which +allow the immutability of the request and response to be preserved. .. _creating-cookies: -Criando Cookies ---------------- +Creating Cookies +---------------- .. php:class:: Cookie -Os objetos ``Cookie`` podem ser definidos por meio de objetos construtores ou usando -a interface fluente que segue padrões imutáveis:: +``Cookie`` objects can be defined through constructor objects, or by using the +fluent interface that follows immutable patterns:: use Cake\Http\Cookie\Cookie; - // Todos os argumentos no construtor + // All arguments in the constructor $cookie = new Cookie( - 'remember_me', // nome + 'remember_me', // name 1, // value - new DateTime('+1 year'), // prazo de validade, se aplicável - '/', // caminho, se aplicável - 'example.com', // doomínio, se aplicável - false, // somente seguro? - true // somente HTTP? + new DateTime('+1 year'), // expiration time, if applicable + '/', // path, if applicable + 'example.com', // domain, if applicable + false, // secure only? + true // http only ? ); - // Usando os métodos do construtor + // Using the builder methods $cookie = (new Cookie('remember_me')) ->withValue('1') ->withExpiry(new DateTime('+1 year')) @@ -984,63 +1342,70 @@ a interface fluente que segue padrões imutáveis:: ->withSecure(false) ->withHttpOnly(true); -Depois de criar um cookie, você pode adicioná-lo a um ``CookieCollection`` -novo ou existente:: +Once you have created a cookie, you can add it to a new or existing +``CookieCollection``:: use Cake\Http\Cookie\CookieCollection; - // Crie uma nova coleção + // Create a new collection $cookies = new CookieCollection([$cookie]); - // Adicionar a uma coleção existente + // Add to an existing collection $cookies = $cookies->add($cookie); - // Remover um cookie pelo nome + // Remove a cookie by name $cookies = $cookies->remove('remember_me'); .. note:: - Lembre-se de que as coleções são imutáveis e a adição de cookies ou a remoção - de cookies de uma coleção cria um *novo* objeto de coleção. + Remember that collections are immutable and adding cookies into, or removing + cookies from a collection, creates a *new* collection object. -Objetos de cookie podem ser adicionados às respostas:: +Cookie objects can be added to responses:: - // Adiciona um cookie + // Add one cookie $response = $this->response->withCookie($cookie); - // Substitui inteiramente uma coleção de cookie + // Replace the entire cookie collection $response = $this->response->withCookieCollection($cookies); -Os cookies definidos como respostas podem ser criptografados usando o +Cookies set to responses can be encrypted using the :ref:`encrypted-cookie-middleware`. -Lendo Cookies -------------- +Reading Cookies +--------------- -Depois de ter uma instância ``CookieCollection``, você pode acessar os cookies que ela contém:: +Once you have a ``CookieCollection`` instance, you can access the cookies it +contains:: - // Verifica se o cookie existe + // Check if a cookie exists $cookies->has('remember_me'); - // Obter o número de cookies na coleção + // Get the number of cookies in the collection count($cookies); - // Obter uma instância de cookie + // Get a cookie instance. Will throw an error if the cookie is not found $cookie = $cookies->get('remember_me'); -Depois de ter um objeto ``Cookie``, você pode interagir com seu estado e modificá-lo. -Lembre-se de que os cookies são imutáveis, portanto, você precisará atualizar a coleção -se modificar um cookie:: + // Get a cookie or null + $cookie = $cookies->remember_me; + + // Check if a cookie exists + $exists = isset($cookies->remember_me) + +Once you have a ``Cookie`` object you can interact with it's state and modify +it. Keep in mind that cookies are immutable, so you'll need to update the +collection if you modify a cookie:: - // Obtenha o valor + // Get the value $value = $cookie->getValue() - // Acessar dados dentro de um valor JSON + // Access data inside a JSON value $id = $cookie->read('User.id'); - // Verifica o estado + // Check state $cookie->isHttpOnly(); $cookie->isSecure(); .. meta:: - :title lang=pt: Objectos de requisição e resposta - :keywords lang=pt: controlador de solicitação, parâmetros de solicitação, índices de arrays, índice de finalidade, objetos de resposta, informações de domínio, objeto de solicitação, dados de solicitação, interrogação, parâmetros, versões anteriores, introspecção, dispatcher, rota, estruturas de dados, matrizes, endereço IP, migração, índices, cakephp, PSR-7, imutável + :title lang=pt: Objetos Request e Response + :keywords lang=pt: request controller,request parameters,array indexes,purpose index,response objects,domain information,request object,request data,interrogating,params,parameters,previous versions,introspection,dispatcher,rout,data structures,arrays,ip address,migration,indexes,cakephp,PSR-7,immutable diff --git a/pt/core-libraries/app.rst b/pt/core-libraries/app.rst index 668f6967ac..6b787644c6 100644 --- a/pt/core-libraries/app.rst +++ b/pt/core-libraries/app.rst @@ -5,86 +5,85 @@ Classe App .. php:class:: App -A classe App é responsável pela localização dos recursos e pelo gerenciamento de caminhos. +A classe App é responsável pela localização de recursos e gerenciamento de caminhos. Encontrando Classes =================== -.. php:staticmethod:: classname($name, $type = '', $suffix = '') +.. php:staticmethod:: className($name, $type = '', $suffix = '') -Este método é usado para resolver nomes de classes no CakePHP. Resolve os -nomes abreviados do CakePHP e retorna o nome da classe totalmente resolvido:: +Este método é usado para resolver nomes de classe em todo o CakePHP. Ele resolve +os nomes abreviados que o CakePHP usa e retorna o nome de classe totalmente resolvido:: - // Resolva um nome de classe curto com o namespace + sufixo. - App::classname('Auth', 'Controller/Component', 'Component'); - // Retorna Cake\Controller\Component\AuthComponent + // Resolve a short class name with the namespace + suffix. + App::className('Flash', 'Controller/Component', 'Component'); + // Returns Cake\Controller\Component\FlashComponent - // Resolve o nome do plugin - App::classname('DebugKit.Toolbar', 'Controller/Component', 'Component'); - // Retorna DebugKit\Controller\Component\ToolbarComponent + // Resolve a plugin name. + App::className('DebugKit.Toolbar', 'Controller/Component', 'Component'); + // Returns DebugKit\Controller\Component\ToolbarComponent - // Os nomes com \ serão retornados inalterados. - App::classname('App\Cache\ComboCache'); - // Retorna App\Cache\ComboCache + // Names with \ in them will be returned unaltered. + App::className('App\Cache\ComboCache'); + // Returns App\Cache\ComboCache -Ao resolver as classes, o namespace ``App`` será tentado e, se -a classe não existir, o espaço para nome ``Cake`` será tentado. Se ambos +Ao resolver classes, o namespace ``App`` será tentado primeiro e, se a +classe não existir, o namespace ``Cake`` será tentado. Se ambos os nomes de classe não existirem, ``false`` será retornado. -Localizando Caminhos para Namespaces -==================================== +Encontrando Caminhos para Recursos +=================================== -.. php:staticmethod:: path(string $package, string $plugin = null) +.. php:staticmethod:: path(string $package, ?string $plugin = null) -Usado para obter locais para caminhos com base em convenções:: +O método retorna caminhos definidos usando a configuração da aplicação ``App.paths``:: - // Obtenha o caminho para o Controller / no seu aplicativo - App::path('Controller'); + // Get the templates path set using ``App.paths.templates`` app config. + App::path('templates'); -Isso pode ser feito para todos os namespaces que fazem parte do seu aplicativo. -Você também pode buscar caminhos para um plug-in:: +Da mesma forma, você pode recuperar caminhos para ``locales`` e ``plugins``. - // Retorna os caminhos do componente no DebugKit - App::path('Component', 'DebugKit'); +Encontrando Caminhos para Namespaces +===================================== -``App::path()`` retornará apenas o caminho padrão e não poderá fornecer -informações sobre caminhos adicionais para os quais o carregador automático -está configurado. +.. php:staticmethod:: classPath(string $package, ?string $plugin = null) -.. php:staticmethod:: core(string $package) +Usado para obter localizações de caminhos baseados em convenções:: -Usado para encontrar o caminho para um pacote dentro do CakePHP:: + // Get the path to Controller/ in your application + App::classPath('Controller'); - // Obtenha o caminho para os mecanismos de cache. - App::core('Cache/Engine'); +Isso pode ser feito para todos os namespaces que fazem parte da sua aplicação. -Localizando Plugins -=================== +``App::classPath()`` retornará apenas o caminho padrão e não será capaz de +fornecer informações sobre caminhos adicionais configurados no autoloader. -.. php:staticmethod:: Plugin::path(string $plugin) +.. php:staticmethod:: core(string $package) -Os plug-ins podem ser localizados com o Plugin. Usar ``Plugin::path('DebugKit');`` -por exemplo, fornecerá o caminho completo para o plug-in DebugKit:: +Usado para encontrar o caminho para um pacote dentro do CakePHP:: - $path = Plugin::path('DebugKit'); + // Get the path to Cache engines. + App::core('Cache/Engine'); -Localizando Temas -================= +Localizando Themes +================== -Como os temas são plugins, você pode usar os métodos acima para obter o caminho para um tema. +Como os themes são plugins, você pode usar os métodos acima para obter o caminho para +um theme. -Carregando Arquivos do Fornecedor -================================= +Carregando Arquivos de Vendor +============================== -O ideal é que os arquivos do fornecedor sejam carregados automaticamente com -o ``Composer``, se você tiver arquivos que não possam ser carregados ou instalados -automaticamente com o Composer, será necessário usar o ``require`` para carregá-los. +Idealmente, arquivos de vendor devem ser carregados automaticamente com o ``Composer``. Se você tem arquivos +de vendor que não podem ser carregados automaticamente ou instalados com Composer, você precisará usar +``require`` para carregá-los. -Se você não conseguir instalar uma biblioteca com o Composer, é melhor instalar cada -biblioteca em um diretório, seguindo a convenção do Composer de ``vendor/$author/$ package``. -Se você tiver uma biblioteca chamada AcmeLib, poderá instalá-la em ``vendor/Acme/AcmeLib``. -Supondo que ele não usasse nomes de classe compatíveis com PSR-0, você poderia carregar -automaticamente as classes dentro dele usando ``classmap`` no ``composer.json`` do seu aplicativo:: +Se você não puder instalar uma biblioteca com Composer, é melhor instalar cada biblioteca em +um diretório seguindo a convenção do Composer de ``vendor/$author/$package``. +Se você tivesse uma biblioteca chamada AcmeLib, você poderia instalá-la em +``vendor/Acme/AcmeLib``. Supondo que ela não use nomes de classe compatíveis com PSR-0, +você poderia carregar automaticamente as classes dentro dela usando ``classmap`` no +``composer.json`` da sua aplicação:: "autoload": { "psr-4": { @@ -96,9 +95,9 @@ automaticamente as classes dentro dele usando ``classmap`` no ``composer.json`` ] } -Se a sua biblioteca de fornecedores não usa classes e, em vez disso, fornece funções, -você pode configurar o Composer para carregar esses arquivos no início de cada solicitação -usando a estratégia de carregamento automático ``files``:: +Se sua biblioteca de vendor não usa classes e, em vez disso, fornece funções, você +pode configurar o Composer para carregar esses arquivos no início de cada requisição +usando a estratégia de autoloading ``files``:: "autoload": { "psr-4": { @@ -110,13 +109,13 @@ usando a estratégia de carregamento automático ``files``:: ] } -Depois de configurar as bibliotecas do fornecedor, você precisará regenerar -o carregador automático do seu aplicativo usando:: +Após configurar as bibliotecas de vendor, você precisará regenerar o +autoloader da sua aplicação usando:: $ php composer.phar dump-autoload -Se você não estiver usando o Composer em seu aplicativo, precisará carregar -manualmente todas as bibliotecas de fornecedores. +Se você não estiver usando Composer na sua aplicação, você precisará +carregar manualmente todas as bibliotecas de vendor. .. meta:: :title lang=pt: Classe App diff --git a/pt/core-libraries/caching.rst b/pt/core-libraries/caching.rst index 9f315b8185..7deb4519b7 100644 --- a/pt/core-libraries/caching.rst +++ b/pt/core-libraries/caching.rst @@ -29,12 +29,9 @@ seu próprio back-end. Os mecanismos de armazenamento em cache integrados são: * ``Apcu`` O cache do APCu usa a extensão PHP `APCu `_. Essa extensão usa memória compartilhada no servidor da web para armazenar objetos. Isso o torna muito rápido e capaz de fornecer recursos atômicos de leitura/gravação. -* ``Wincache`` O Wincache usa a extensão `Wincache `_. - O Wincache é semelhante ao APC em recursos e desempenho, mas otimizado para - Windows e IIS. -* ``Array`` Armazena todos os dados em uma matriz. Esse mecanismo não fornece - armazenamento persistente e deve ser usado em conjuntos de testes de aplicativos. -* ``Null`` O mecanismo nulo não armazena nada e falha em todas as operações de leitura. +* ``Array`` Armazena todos os dados em um array. Esse mecanismo não fornece + armazenamento persistente e é destinado ao uso em conjuntos de testes de aplicativos. +* ``Null`` O mecanismo nulo não armazena nada realmente e falha em todas as operações de leitura. Independentemente do CacheEngine que você escolher, seu aplicativo interage com :php:class:`Cake\\Cache\\Cache`. @@ -155,6 +152,8 @@ O ``FileEngine`` usa as seguintes opções específicas do mecanismo: * ``path`` Caminho para onde os arquivos de cache devem ser salvos. O padrão é o diretório temporário do sistema. +.. _caching-redisengine: + Opções RedisEngine ------------------ @@ -166,7 +165,14 @@ O RedisEngine usa as seguintes opções específicas do mecanismo: * ``password`` Senha do servidor Redis. * ``persistent`` Uma conexão persistente deve ser feita com Redis. * ``timeout`` Tempo limite de conexão para Redis. -* ``unix_socket`` Caminho para um soquete unix para Redist. +* ``unix_socket`` Caminho para um soquete unix para Redis. +* ``tls`` Conectar ao Redis por TLS. +* ``ssl_key`` A chave privada ssl usada para conexões TLS. +* ``ssl_ca`` O arquivo de autoridade de certificação ssl para conexões TLS. +* ``ssl_cert`` O certificado ssl usado para conexões TLS. + +.. versionadded:: 5.1.0 + Conexões TLS foram adicionadas na versão 5.1 Opções do MemcacheEngine ------------------------ @@ -180,6 +186,8 @@ Opções do MemcacheEngine igbinary e json. Ao lado do php, a extensão memcached deve ser compilada com o suporte serializador apropriado. - ``servers`` Cadeia ou matriz de servidores com cache de memória. Se for um array, o MemcacheEngine os usará como um pool. +- ``duration`` Esteja ciente de que qualquer duração maior que 30 dias será tratada como um + valor de tempo Unix real, em vez de um deslocamento do tempo atual. - ``options`` Opções adicionais para o cliente memcached. Deve ser uma matriz de opção => valor. Use as constantes ``\Memcached::OPT_*`` como chaves. @@ -247,7 +255,8 @@ será usado. ``Cache::write()`` pode armazenar qualquer tipo de objeto e é ideal para armazenar resultados de descobertas de modelos:: - if (($posts = Cache::read('posts')) === false) { + $posts = Cache::read('posts'); + if ($posts === null) { $posts = $someService->getAllPosts(); Cache::write('posts', $posts); } @@ -279,8 +288,31 @@ usando ``writeMany()`` salve várias conexões de rede ao usar o Memcached:: // $result poderá conter ['article-first-post' => true, 'article-first-post-comments' => true] +Gravações Atômicas +------------------ + +.. php:staticmethod:: add($key, $value $config = 'default') + +Usar ``Cache::add()`` permitirá que você defina atomicamente uma chave para um valor, +se a chave ainda não existir no cache. Se a chave já existir no backend do cache +ou a gravação falhar, ``add()`` retornará ``false``:: + + // Definir uma chave para atuar como um bloqueio + $result = Cache::add($lockKey, true); + if (!$result) { + return; + } + // Executar uma ação onde pode haver apenas um processo ativo por vez. + + // Remover a chave de bloqueio. + Cache::delete($lockKey); + +.. warning:: + + O cache baseado em arquivo não suporta gravações atômicas. + Armazenamento em Cache de Leitura ---------------------------------- +---------------------------------- .. php:staticmethod:: remember($key, $callable, $config = 'default') @@ -309,18 +341,17 @@ Lendo de um Cache ``Cache::read()`` é usado para ler o valor em cache armazenado em ``$key`` do ``$config``. Se ``$config`` for nulo, a configuração padrão será usada. ``Cache::read()`` retornará o valor em cache se for um cache válido ou -``false`` se o cache expirou ou não existe. O conteúdo do cache pode ser -avaliado como falso, portanto, use os operadores de comparação estritos: -``===`` ou ``!==``. +``null`` se o cache expirou ou não existe. Use os operadores de comparação +estritos ``===`` ou ``!==`` para verificar o sucesso da operação ``Cache::read()``. Por exemplo:: $cloud = Cache::read('cloud'); - if ($cloud !== false) { + if ($cloud !== null) { return $cloud; } - // Gere dados na nuvem + // Gerar dados na nuvem // ... // Armazenar dados no cache @@ -333,17 +364,14 @@ poderá especificá-la nas chamadas ``Cache::read()`` e ``Cache::write()``, conforme abaixo:: // Leia a chave "cloud", mas a partir da configuração curta em vez do padrão - $cloud = Cache::read('cloud', 'short'); - if ($cloud !== false) { - return $cloud; - } - - // Gere dados na nuvem - // ... + if ($cloud === null) { + // Gerar dados na nuvem + // ... - // Armazene dados no cache, usando a configuração de cache "short" em vez do padrão - Cache::write('cloud', $cloud, 'short'); + // Armazene dados no cache, usando a configuração de cache "short" em vez do padrão + Cache::write('cloud', $cloud, 'short'); + } return $cloud; @@ -374,6 +402,11 @@ Exclusão de um Cache // Remove uma chave Cache::delete('my_key'); +A partir da versão 4.4.0, o ``RedisEngine`` também fornece um método ``deleteAsync()`` +que usa a operação ``UNLINK`` para remover chaves de cache:: + + Cache::pool('redis')->deleteAsync('my_key'); + Exclusão de Várias Chaves de uma só Vez --------------------------------------- @@ -395,22 +428,24 @@ de rede ao usar o Memcached:: Limpando Dados em Cache ======================= -.. php:staticmethod:: clear($check, $config = 'default') +.. php:staticmethod:: clear($config = 'default') Destrua todos os valores em cache para uma configuração de cache. Em mecanismos -como: Apcu, Memcached e Wincache, o prefixo da configuração do cache é usado +como: Apcu e Memcached, o prefixo da configuração do cache é usado para remover as entradas do cache. Verifique se diferentes configurações de cache têm prefixos diferentes:: - // Limpa apenas as chaves expiradas. - Cache::clear(true); - // Limpará todas as chaves. - Cache::clear(false); + Cache::clear(); + +A partir da versão 4.4.0, o ``RedisEngine`` também fornece um método ``clearBlocking()`` +que usa a operação ``UNLINK`` para remover chaves de cache:: + + Cache::pool('redis')->clearBlocking(); .. note:: - Como o APCu e o Wincache usam caches isolados para servidor da web e CLI, + Como o APCu usa caches isolados para servidor da web e CLI, eles devem ser limpos separadamente (a CLI não pode limpar o servidor da web e vice-versa). Usando Cache para Armazenar Contadores @@ -441,7 +476,7 @@ Depois de definir um valor inteiro, você pode manipulá-lo usando ``increment() .. note:: Incrementar e decrementar não funcionam com o ``FileEngine``. - Você deve usar APCu, Wincache, Redis ou Memcached. + Você deve usar APCu, Redis ou Memcached. Usando o Cache para Armazenar Resultados Comuns de Consulta =========================================================== @@ -452,6 +487,9 @@ perfeito disso são os resultados de :php:meth:`Cake\\ORM\\Table::find()`. O obj Query permite armazenar resultados em cache usando o método ``cache()``. Veja a seção :ref:`caching-query-results` para mais informações. + +.. _cache-groups: + Usando Grupos ============= diff --git a/pt/core-libraries/collections.rst b/pt/core-libraries/collections.rst index 090dee81d6..478550e5ce 100644 --- a/pt/core-libraries/collections.rst +++ b/pt/core-libraries/collections.rst @@ -5,44 +5,47 @@ Coleções .. php:class:: Collection -As classes de coleção fornecem um conjunto de ferramentas para manipular matrizes -ou objetos ``Traversable``. Se você já usou underscore.js, tem uma idéia do que -pode esperar das classes de coleção. +As classes de coleção fornecem um conjunto de ferramentas para manipular arrays ou +objetos ``Traversable``. Se você já usou o underscore.js, +você tem uma ideia do que pode esperar das classes de coleção. -Instâncias de coleção são imutáveis; modificar uma coleção irá gerar uma nova coleção. -Isso torna o trabalho com objetos de coleção mais previsível, pois as operações são -livres de efeitos colaterais. +Instâncias de coleção são imutáveis; modificar uma coleção irá gerar +uma nova coleção. Isso torna o trabalho com objetos de coleção mais previsível, pois +as operações são livres de efeitos colaterais. Exemplo Rápido ============== -Coleções podem ser criadas usando uma matriz ou um objeto ``Traversable``. Você -também interagirá com as coleções sempre que interagir com o ORM no CakePHP. Um -simples uso de uma coleção seria:: +Coleções podem ser criadas usando um array ou objeto ``Traversable``. Você também +interagirá com coleções toda vez que interagir com o ORM no CakePHP. +Um uso simples de uma Collection seria:: use Cake\Collection\Collection; $items = ['a' => 1, 'b' => 2, 'c' => 3]; $collection = new Collection($items); - // Crie uma nova coleção contendo elementos + // Cria uma nova coleção contendo elementos // com um valor maior que um. $overOne = $collection->filter(function ($value, $key, $iterator) { return $value > 1; }); -Você também pode usar a função auxiliar ``collection()`` em vez de ``new Collection()``:: +Você também pode usar a função auxiliar ``collection()`` em vez de ``new +Collection()``:: $items = ['a' => 1, 'b' => 2, 'c' => 3]; - // Ambos formam uma instância de coleção. + // Ambos criam uma instância de Collection. $collectionA = new Collection($items); $collectionB = collection($items); -O benefício do método auxiliar é que é mais fácil encadear do que ``(new Collection($items))``. +O benefício do método auxiliar é que é mais fácil encadear do que +``(new Collection($items))``. -O :php:trait:`~Cake\\Collection\\CollectionTrait` permite integrar recursos semelhantes a -coleções em qualquer objeto ``Traversable`` que você possui no seu aplicativo. +O :php:trait:`~Cake\\Collection\\CollectionTrait` permite integrar +recursos semelhantes a coleções em qualquer objeto ``Traversable`` que você tenha em sua +aplicação também. Lista de Métodos ================ @@ -66,28 +69,27 @@ Lista de Métodos :php:meth:`take`, :php:meth:`through`, :php:meth:`transpose` :php:meth:`unfold`, :php:meth:`zip` -Iterando +Iteração ======== .. php:method:: each($callback) -As coleções podem ser iteradas e/ou transformadas em novas coleções com os -métodos ``each()`` e ``map()``. O método ``each()`` não criará uma -nova coleção, mas permitirá que você modifique quaisquer objetos dentro da -coleção:: +Coleções podem ser iteradas e/ou transformadas em novas coleções com os +métodos ``each()`` e ``map()``. O método ``each()`` não criará uma nova +coleção, mas permitirá que você modifique quaisquer objetos dentro da coleção:: $collection = new Collection($items); $collection = $collection->each(function ($value, $key) { - echo "Element $key: $value"; + echo "Elemento $key: $value"; }); -O retorno de ``each()`` será um objeto collection. Cada um iterará a coleção -imediatamente aplicando o retorno de chamada a cada valor na coleção. +O retorno de ``each()`` será o objeto de coleção. Each irá iterar a +coleção imediatamente aplicando o callback a cada valor na coleção. .. php:method:: map($callback) -O método ``map()`` criará uma nova coleção com base no retorno -de chamada que está sendo aplicada a cada objeto na coleção original:: +O método ``map()`` criará uma nova coleção com base na saída do +callback sendo aplicado a cada objeto na coleção original:: $items = ['a' => 1, 'b' => 2, 'c' => 3]; $collection = new Collection($items); @@ -102,14 +104,14 @@ de chamada que está sendo aplicada a cada objeto na coleção original:: // $result contém ['a' => 2, 'b' => 4, 'c' => 6]; $result = $new->toArray(); -O método ``map()`` criará um novo iterador que cria preguiçosamente os -itens resultantes quando iterado. +O método ``map()`` criará um novo iterador que cria preguiçosamente +os itens resultantes quando iterado. .. php:method:: extract($path) -Um dos usos mais comuns de uma função ``map()`` é extrair uma única coluna -de uma coleção. Se você deseja criar uma lista de elementos contendo os valores -de uma propriedade específica, pode usar o método ``extract()``:: +Um dos usos mais comuns para uma função ``map()`` é extrair uma única +coluna de uma coleção. Se você está procurando construir uma lista de elementos +contendo os valores de uma propriedade específica, você pode usar o método ``extract()``:: $collection = new Collection($people); $names = $collection->extract('name'); @@ -117,9 +119,9 @@ de uma propriedade específica, pode usar o método ``extract()``:: // $result contém ['mark', 'jose', 'barbara']; $result = $names->toList(); -Como em muitas outras funções da classe de coleção, você pode especificar um caminho -separado por pontos para extrair colunas. Este exemplo retornará uma coleção que -contém os nomes dos autores de uma lista de artigos:: +Como em muitas outras funções na classe de coleção, você pode especificar +um caminho separado por pontos para extrair colunas. Este exemplo retornará +uma coleção contendo os nomes dos autores de uma lista de artigos:: $collection = new Collection($articles); $names = $collection->extract('author.name'); @@ -127,18 +129,18 @@ contém os nomes dos autores de uma lista de artigos:: // $result contém ['Maria', 'Stacy', 'Larry']; $result = $names->toList(); -Por fim, se a propriedade que você está procurando não pode ser expressa como um caminho, -você pode usar uma função de retorno de chamada para retorná-la:: +Finalmente, se a propriedade que você está procurando não puder ser expressa como um caminho, +você pode usar uma função de callback para retorná-la:: $collection = new Collection($articles); $names = $collection->extract(function ($article) { return $article->author->name . ', ' . $article->author->last_name; }); -Freqüentemente, existem propriedades necessárias para extrair uma chave comum -presente em várias matrizes ou objetos profundamente aninhados em outras estruturas. -Para esses casos, você pode usar o combinador ``{*}`` na chave do caminho. -Esse correspondente geralmente é útil ao combinar dados da associação HasMany e BelongsToMany:: +Muitas vezes, as propriedades que você precisa extrair são uma chave comum presente em vários +arrays ou objetos que estão profundamente aninhados dentro de outras estruturas. Para esses +casos, você pode usar o matcher ``{*}`` na chave do caminho. Este matcher é frequentemente +útil ao combinar dados de associação HasMany e BelongsToMany:: $data = [ [ @@ -147,35 +149,33 @@ Esse correspondente geralmente é útil ao combinar dados da associação HasMan ['number' => 'number-1'], ['number' => 'number-2'], ['number' => 'number-3'], - ] + ], ], [ 'name' => 'James', 'phone_numbers' => [ ['number' => 'number-4'], ['number' => 'number-5'], - ] - ] + ], + ], ]; $numbers = (new Collection($data))->extract('phone_numbers.{*}.number'); - $numbers->toList(); - // Retorna ['number-1', 'number-2', 'number-3', 'number-4', 'number-5'] + $result = $numbers->toList(); + // $result contém ['number-1', 'number-2', 'number-3', 'number-4', 'number-5'] -Este último exemplo usa ``toList()`` diferente de outros exemplos, o que é -importante quando estamos obtendo resultados com chaves possivelmente duplicadas. -Ao usar ``toList()``, garantimos a obtenção de todos os valores, mesmo que haja -chaves duplicadas. +Este último exemplo usa ``toList()`` ao contrário de outros exemplos, o que é importante +quando estamos obtendo resultados com chaves possivelmente duplicadas. Ao usar ``toList()`` +teremos a garantia de obter todos os valores mesmo se houver chaves duplicadas. -Ao contrário de :php:meth:`Cake\\Utility\\Hash::extract()` este método suporta -apenas o curinga ``{*}``. Todos os outros correspondentes de curinga e atributos -não são suportados. +Ao contrário de :php:meth:`Cake\\Utility\\Hash::extract()` este método suporta apenas o +wildcard ``{*}``. Todos os outros matchers de wildcard e atributos não são suportados. .. php:method:: combine($keyPath, $valuePath, $groupPath = null) Coleções permitem que você crie uma nova coleção feita de chaves e valores em -uma coleção existente. Os caminhos de chave e valor podem ser especificados com -notação de caminhos com ponto:: +uma coleção existente. Tanto a chave quanto os caminhos de valor podem ser especificados com +caminhos de notação de ponto:: $items = [ ['id' => 1, 'name' => 'foo', 'parent' => 'a'], @@ -183,35 +183,38 @@ notação de caminhos com ponto:: ['id' => 3, 'name' => 'baz', 'parent' => 'a'], ]; $combined = (new Collection($items))->combine('id', 'name'); + $result = $combined->toArray(); - // O resultado ficará assim quando convertido em array + // $result contém [ 1 => 'foo', 2 => 'bar', 3 => 'baz', ]; -Opcionalmente, você também pode usar um ``groupPath`` para agrupar resultados com base em um caminho:: +Você também pode, opcionalmente, usar um ``groupPath`` para agrupar resultados com base em um caminho:: $combined = (new Collection($items))->combine('id', 'name', 'parent'); + $result = $combined->toArray(); - // O resultado ficará assim quando convertido em array + // $result contém [ 'a' => [1 => 'foo', 3 => 'baz'], 'b' => [2 => 'bar'] ]; -E por fim, você pode usar *closures* para criar caminhos de chaves/valores/grupos dinamicamente, -por exemplo, ao trabalhar com entidades e datas (convertidas em instâncias ``Cake/Time`` pelo ORM), -você pode querer agrupar os resultados por data:: +Finalmente, você pode usar *closures* para construir dinamicamente caminhos de chaves/valores/grupos, +por exemplo, ao trabalhar com entidades e datas (convertidas em instâncias ``I18n\DateTime`` +pelo ORM), você pode querer agrupar resultados por data:: $combined = (new Collection($entities))->combine( 'id', function ($entity) { return $entity; }, function ($entity) { return $entity->date->toDateString(); } ); + $result = $combined->toArray(); - // O resultado ficará assim quando convertido em array + // $result contém [ 'date string like 2015-05-01' => ['entity1->id' => entity1, 'entity2->id' => entity2, ..., 'entityN->id' => entityN] 'date string like 2015-06-01' => ['entity1->id' => entity1, 'entity2->id' => entity2, ..., 'entityN->id' => entityN] @@ -219,15 +222,15 @@ você pode querer agrupar os resultados por data:: .. php:method:: stopWhen(callable $c) -Você pode parar a iteração a qualquer momento usando o método ``stopWhen()``. -A chamada em uma coleção criará uma nova e irá interromper a execução de novos resultados -se a chamada passada retornar verdadeira para um dos elementos:: +Você pode parar a iteração em qualquer ponto usando o método ``stopWhen()``. Chamá-lo +em uma coleção criará uma nova que parará de produzir resultados se o +callable passado retornar true para um dos elementos:: $items = [10, 20, 50, 1, 2]; $collection = new Collection($items); $new = $collection->stopWhen(function ($value, $key) { - // Pare no primeiro valor maior que 30 + // Para no primeiro valor maior que 30 return $value > 30; }); @@ -236,10 +239,10 @@ se a chamada passada retornar verdadeira para um dos elementos:: .. php:method:: unfold(callable $callback) -Às vezes, os itens internos de uma coleção contêm matrizes ou iteradores com mais -itens. Se você deseja nivelar a estrutura interna para iterar uma vez todos os -elementos, pode usar o método ``unfold()``. Ele criará uma nova coleção que -produzirá todos os elementos aninhados na coleção:: +Às vezes, os itens internos de uma coleção conterão arrays ou iteradores +com mais itens. Se você deseja achatar a estrutura interna para iterar uma vez +sobre todos os elementos, você pode usar o método ``unfold()``. Ele criará uma nova +coleção que produzirá cada elemento único aninhado na coleção:: $items = [[1, 2, 3], [4, 5]]; $collection = new Collection($items); @@ -248,21 +251,21 @@ produzirá todos os elementos aninhados na coleção:: // $result contém [1, 2, 3, 4, 5]; $result = $new->toList(); -Ao passar uma chamada para ``unfold()``, você pode controlar quais elementos -serão desdobrados de cada item da coleção original. Isso é útil para retornar +Ao passar um callable para ``unfold()`` você pode controlar quais elementos serão +desdobrados de cada item na coleção original. Isso é útil para retornar dados de serviços paginados:: $pages = [1, 2, 3, 4]; $collection = new Collection($pages); $items = $collection->unfold(function ($page, $key) { - // Um serviço da web imaginário que retorna uma página de resultados + // Um serviço web imaginário que retorna uma página de resultados return MyService::fetchPage($page)->toList(); }); $allPagesItems = $items->toList(); -Se você estiver usando o PHP 5.5+, você pode usar a palavra-chave ``yield`` dentro de -``unfold()`` para retornar quantos elementos de cada item da coleção você precisará:: +Se você estiver usando PHP 5.5+, você pode usar a palavra-chave ``yield`` dentro de ``unfold()`` +para retornar quantos elementos você precisar para cada item na coleção:: $oddNumbers = [1, 3, 5, 7]; $collection = new Collection($oddNumbers); @@ -277,20 +280,20 @@ Se você estiver usando o PHP 5.5+, você pode usar a palavra-chave ``yield`` de .. php:method:: chunk($chunkSize) Ao lidar com grandes quantidades de itens em uma coleção, pode fazer sentido -processar os elementos em lotes, em vez de um por um. Para dividir uma coleção -em várias matrizes de um determinado tamanho, você pode usar a função ``chunk()``:: +processar os elementos em lotes em vez de um por um. Para dividir +uma coleção em vários arrays de um determinado tamanho, você pode usar a função ``chunk()``:: $items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; $collection = new Collection($items); $chunked = $collection->chunk(2); $chunked->toList(); // [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10], [11]] -A função ``chunk`` é particularmente útil ao realizar o processamento em lote, por -exemplo, com um resultado no banco de dados:: +A função ``chunk`` é particularmente útil ao fazer processamento em lote, por +exemplo com um resultado de banco de dados:: $collection = new Collection($articles); $collection->map(function ($article) { - // Alterar uma propriedade no artigo + // Altera uma propriedade no artigo $article->property = 'changed'; }) ->chunk(20) @@ -300,8 +303,9 @@ exemplo, com um resultado no banco de dados:: .. php:method:: chunkWithKeys($chunkSize) -Bem como :php:meth:`chunk()`, ``chunkWithKeys()`` permite dividir uma coleção -em lotes menores, mas com as chaves preservadas. Isso é útil ao agrupar matrizes associativas:: +Assim como :php:meth:`chunk()`, ``chunkWithKeys()`` permite que você divida +uma coleção em lotes menores, mas com as chaves preservadas. Isso é útil ao +fragmentar arrays associativos:: $collection = new Collection([ 'a' => 1, @@ -309,8 +313,10 @@ em lotes menores, mas com as chaves preservadas. Isso é útil ao agrupar matriz 'c' => 3, 'd' => [4, 5] ]); - $chunked = $collection->chunkWithKeys(2)->toList(); - // Cria + $chunked = $collection->chunkWithKeys(2); + $result = $chunked->toList(); + + // $result contém [ ['a' => 1, 'b' => 2], ['c' => 3, 'd' => [4, 5]] @@ -321,9 +327,9 @@ Filtragem .. php:method:: filter($callback) -As coleções facilitam a filtragem e a criação de novas coleções com base no resultado -das funções de retorno de chamada. Você pode usar ``filter()`` para criar uma nova -coleção de elementos que correspondem a um retorno de chamada de critério:: +Coleções permitem que você filtre e crie novas coleções com base no +resultado de funções de callback. Você pode usar ``filter()`` para criar uma nova +coleção de elementos correspondentes a um callback de critério:: $collection = new Collection($people); $ladies = $collection->filter(function ($person, $key) { @@ -335,7 +341,7 @@ coleção de elementos que correspondem a um retorno de chamada de critério:: .. php:method:: reject(callable $c) -O inverso de ``filter()`` é ``reject()``. Este método cria um filtro negativo, +O inverso de ``filter()`` é ``reject()``. Este método faz uma filtragem negativa, removendo elementos que correspondem à função de filtro:: $collection = new Collection($people); @@ -345,8 +351,8 @@ removendo elementos que correspondem à função de filtro:: .. php:method:: every($callback) -Você pode fazer testes de verificação com funções de filtro. Para ver se todos -os elementos de uma coleção correspondem a um teste, você pode usar ``every()``:: +Você pode fazer testes de verdade com funções de filtro. Para ver se todos os elementos em +uma coleção correspondem a um teste, você pode usar ``every()``:: $collection = new Collection($people); $allYoungPeople = $collection->every(function ($person) { @@ -355,8 +361,8 @@ os elementos de uma coleção correspondem a um teste, você pode usar ``every() .. php:method:: some($callback) -Você pode ver se a coleção contém pelo menos um elemento que corresponde a -uma função de filtro usando o método ``some()``:: +Você pode ver se a coleção contém pelo menos um elemento que corresponda a uma função de filtro +usando o método ``some()``:: $collection = new Collection($people); $hasYoungPeople = $collection->some(function ($person) { @@ -365,18 +371,17 @@ uma função de filtro usando o método ``some()``:: .. php:method:: match($conditions) -Se você precisar extrair uma nova coleção contendo apenas os elementos que -contêm um determinado conjunto de propriedades, use o método ``match()``:: +Se você precisa extrair uma nova coleção contendo apenas os elementos que +contêm um determinado conjunto de propriedades, você deve usar o método ``match()``:: $collection = new Collection($comments); $commentsFromMark = $collection->match(['user.name' => 'Mark']); .. php:method:: firstMatch($conditions) -O nome da propriedade pode ser um caminho separado por pontos. Você pode -percorrer entidades aninhadas e verificar valores que elas contêm. -Quando você só precisa do primeiro elemento correspondente de uma coleção, -pode usar ``firstMatch()``:: +O nome da propriedade pode ser um caminho separado por pontos. Você pode atravessar +entidades aninhadas e corresponder aos valores que elas contêm. Quando você precisa apenas do primeiro +elemento correspondente de uma coleção, você pode usar ``firstMatch()``:: $collection = new Collection($comments); $comment = $collection->firstMatch([ @@ -384,45 +389,45 @@ pode usar ``firstMatch()``:: 'active' => true ]); -Como você pode ver acima, ``match()`` e ``firstMatch()`` permitem fornecer -várias condições para a correspondência. Além disso, as condições -podem ser para caminhos diferentes, permitindo expressar condições complexas -para comparação. +Como você pode ver acima, tanto ``match()`` quanto ``firstMatch()`` permitem que você +forneça várias condições para corresponder. Além disso, as condições podem ser +para caminhos diferentes, permitindo que você expresse condições complexas para corresponder. Agregação ========= -.. php:method:: reduce($callback) +.. php:method:: reduce($callback, $initial) -A contraparte de uma operação ``map()`` geralmente é uma ``reduce``. -Esta função ajudará você a criar um único resultado de todos os elementos -em uma coleção:: +A contraparte de uma operação ``map()`` geralmente é um ``reduce``. Esta +função o ajudará a construir um único resultado a partir de todos os elementos em uma +coleção:: $totalPrice = $collection->reduce(function ($accumulated, $orderLine) { return $accumulated + $orderLine->price; }, 0); -No exemplo acima, ``$totalPrice`` será a soma de todos os preços únicos contidos na -coleção. Observe que o segundo argumento para da função ``reduce()`` assume o valor -inicial da operação de redução que você está executando:: +No exemplo acima, ``$totalPrice`` será a soma de todos os preços únicos +contidos na coleção. Note o segundo argumento para a função ``reduce()`` +que recebe o valor inicial para a operação de redução que você está +executando:: $allTags = $collection->reduce(function ($accumulated, $article) { return array_merge($accumulated, $article->tags); }, []); -.. php:method:: min(string|$callback, $type = SORT_NUMERIC) +.. php:method:: min(string|callable $callback, $type = SORT_NUMERIC) -Para extrair o valor mínimo de uma coleção com base em uma propriedade, -basta usar a função ``min()``. Isso retornará o elemento completo da coleção -e não apenas o menor valor encontrado:: +Para extrair o valor mínimo de uma coleção com base em uma propriedade, use apenas a +função ``min()``. Isso retornará o elemento completo da coleção e +não apenas o menor valor encontrado:: $collection = new Collection($people); $youngest = $collection->min('age'); echo $youngest->name; -Você também pode expressar a propriedade para comparar, fornecendo um caminho ou uma -função de retorno de chamada:: +Você também pode expressar a propriedade a comparar fornecendo um caminho ou uma +função de callback:: $collection = new Collection($people); $personYoungestChild = $collection->min(function ($person) { @@ -431,10 +436,10 @@ função de retorno de chamada:: $personWithYoungestDad = $collection->min('dad.age'); -.. php:method:: max($callback, $type = SORT_NUMERIC) +.. php:method:: max(string|callable $callback, $type = SORT_NUMERIC) -O mesmo pode ser aplicado à função ``max()``, que retornará um único elemento -da coleção com o maior valor de propriedade:: +O mesmo pode ser aplicado à função ``max()``, que retornará um único +elemento da coleção tendo o maior valor de propriedade:: $collection = new Collection($people); $oldest = $collection->max('age'); @@ -447,7 +452,8 @@ da coleção com o maior valor de propriedade:: .. php:method:: sumOf($path = null) -Finalmente, o método ``sumOf()`` retornará a soma de uma propriedade de todos os elementos:: +Finalmente, o método ``sumOf()`` retornará a soma de uma propriedade de todos +os elementos:: $collection = new Collection($people); $sumOfAges = $collection->sumOf('age'); @@ -460,21 +466,22 @@ Finalmente, o método ``sumOf()`` retornará a soma de uma propriedade de todos .. php:method:: avg($path = null) -Calcule o valor médio dos elementos na coleção. Opcionalmente, forneça um -caminho correspondente ou função para extrair valores e gerar a média:: +Calcula o valor médio dos elementos na coleção. Opcionalmente, +forneça um caminho de correspondência ou função para extrair valores para gerar a média +para:: $items = [ ['invoice' => ['total' => 100]], ['invoice' => ['total' => 200]], ]; - // Média: 150 + // $average contém 150 $average = (new Collection($items))->avg('invoice.total'); .. php:method:: median($path = null) -Calcule o valor mediano de um conjunto de elementos. Opcionalmente, poderá fornecer -um caminho correspondente ou função para extrair valores para gerar a mediana:: +Calcula o valor mediano de um conjunto de elementos. Opcionalmente, forneça um caminho de correspondência +ou função para extrair valores para gerar a mediana para:: $items = [ ['invoice' => ['total' => 400]], @@ -484,16 +491,17 @@ um caminho correspondente ou função para extrair valores para gerar a mediana: ['invoice' => ['total' => 200]], ]; - // Média: 333 + // $median contém 333 $median = (new Collection($items))->median('invoice.total'); + Agrupamento e Contagem ----------------------- +----------------------- .. php:method:: groupBy($callback) -Os valores da coleção podem ser agrupados por chaves diferentes em uma nova -coleção quando eles compartilham o mesmo valor para uma propriedade:: +Os valores da coleção podem ser agrupados por chaves diferentes em uma nova coleção quando +compartilham o mesmo valor para uma propriedade:: $students = [ ['name' => 'Mark', 'grade' => 9], @@ -503,8 +511,9 @@ coleção quando eles compartilham o mesmo valor para uma propriedade:: ]; $collection = new Collection($students); $studentsByGrade = $collection->groupBy('grade'); + $result = $studentsByGrade->toArray(); - // O resultado ficará assim quando convertido em array: + // $result contém [ 10 => [ ['name' => 'Andrew', 'grade' => 10], @@ -516,8 +525,8 @@ coleção quando eles compartilham o mesmo valor para uma propriedade:: ] ] -Como de costume, é possível fornecer um caminho separado por pontos para propriedades -aninhadas ou sua própria função de retorno de chamada para gerar os grupos dinamicamente:: +Como de costume, é possível fornecer um caminho separado por pontos para propriedades aninhadas +ou sua própria função de callback para gerar os grupos dinamicamente:: $commentsByUserId = $comments->groupBy('user.id'); @@ -527,33 +536,34 @@ aninhadas ou sua própria função de retorno de chamada para gerar os grupos di .. php:method:: countBy($callback) -Se você deseja apenas saber o número de ocorrências por grupo, pode fazê-lo usando o -método ``countBy()``. Ele usa os mesmos argumentos de ``groupBy``, portanto já +Se você deseja apenas saber o número de ocorrências por grupo, você pode fazê-lo +usando o método ``countBy()``. Ele recebe os mesmos argumentos que ``groupBy``, então deve ser familiar para você:: $classResults = $students->countBy(function ($student) { return $student->grade > 6 ? 'approved' : 'denied'; }); - // O resultado ficará assim quando convertido em array: + // O resultado pode parecer com isso quando convertido para array: ['approved' => 70, 'denied' => 20] .. php:method:: indexBy($callback) -Em certos casos, você sabe que um elemento é exclusivo para a propriedade que -você deseja agrupar. Se você deseja um único resultado por grupo, pode usar a +Haverá certos casos em que você sabe que um elemento é único para a propriedade +pela qual deseja agrupar. Se você deseja um único resultado por grupo, pode usar a função ``indexBy()``:: $usersById = $users->indexBy('id'); - // Quando convertido em resultado da matriz, pode parecer + // Quando convertido para array, o resultado pode parecer [ 1 => 'markstory', 3 => 'jose_zap', 4 => 'jrbasso' ] -Assim como na função ``groupBy()``, você também pode usar um caminho de propriedade ou um retorno de chamada:: +Assim como com a função ``groupBy()`` você também pode usar um caminho de propriedade ou +um callback:: $articlesByAuthorId = $articles->indexBy('author.id'); @@ -563,22 +573,24 @@ Assim como na função ``groupBy()``, você também pode usar um caminho de prop .. php:method:: zip($items) -Os elementos de diferentes coleções podem ser agrupados usando o método ``zip()``. -Ele retornará uma nova coleção contendo uma matriz que agrupa os elementos de cada -coleção que são colocados na mesma posição:: +Os elementos de diferentes coleções podem ser agrupados usando o +método ``zip()``. Ele retornará uma nova coleção contendo um array agrupando +os elementos de cada coleção que estão colocados na mesma posição:: $odds = new Collection([1, 3, 5]); $pairs = new Collection([2, 4, 6]); $combined = $odds->zip($pairs)->toList(); // [[1, 2], [3, 4], [5, 6]] -Você também pode compactar várias coleções de uma só vez:: +Você também pode compactar várias coleções de uma vez:: $years = new Collection([2013, 2014, 2015, 2016]); $salaries = [1000, 1500, 2000, 2300]; $increments = [0, 500, 500, 300]; - $rows = $years->zip($salaries, $increments)->toList(); - // Retorna: + $rows = $years->zip($salaries, $increments); + $result = $rows->toList(); + + // $result contém [ [2013, 1000, 0], [2014, 1500, 500], @@ -587,22 +599,22 @@ Você também pode compactar várias coleções de uma só vez:: ] Como você já pode ver, o método ``zip()`` é muito útil para transpor -matrizes multidimensionais:: +arrays multidimensionais:: $data = [ 2014 => ['jan' => 100, 'feb' => 200], 2015 => ['jan' => 300, 'feb' => 500], 2016 => ['jan' => 400, 'feb' => 600], - ] + ]; - // Reunindo dados de janeiro e fevereiro + // Obtendo dados de janeiro e fevereiro juntos $firstYear = new Collection(array_shift($data)); - $firstYear->zip($data[0], $data[1])->toList(); + $result = $firstYear->zip($data[0], $data[1])->toList(); // Ou $firstYear->zip(...$data) em PHP >= 5.6 - // Retorna + // $result contém [ [100, 300, 400], [200, 500, 600] @@ -613,47 +625,47 @@ Ordenação .. php:method:: sortBy($callback, $order = SORT_DESC, $sort = SORT_NUMERIC) -Os valores da coleção podem ser classificados em ordem crescente ou decrescente -com base em uma coluna ou função personalizada. Para criar uma nova coleção -classificada com os valores de outra, você pode usar ``sortBy``:: +Os valores da coleção podem ser ordenados em ordem crescente ou decrescente com base em +uma coluna ou função personalizada. Para criar uma nova coleção ordenada a partir dos valores +de outra, você pode usar ``sortBy``:: $collection = new Collection($people); $sorted = $collection->sortBy('age'); -Como visto acima, você pode classificar passando o nome de uma coluna ou -propriedade presente nos valores da coleção. Você também pode especificar -um caminho de propriedade usando a notação de ponto. O próximo exemplo -classificará os artigos pelo nome do autor:: +Como visto acima, você pode ordenar passando o nome de uma coluna ou propriedade que +está presente nos valores da coleção. Você também pode especificar um caminho de propriedade +em vez disso usando a notação de ponto. O próximo exemplo ordenará artigos por +nome do autor:: $collection = new Collection($articles); $sorted = $collection->sortBy('author.name'); -O método ``sortBy()`` é flexível o suficiente para permitir que você -especifique uma função extratora que permitirá selecionar dinamicamente o -valor a ser usado para comparar dois valores diferentes na coleção:: +O método ``sortBy()`` é flexível o suficiente para permitir que você especifique uma função extratora +que permitirá selecionar dinamicamente o valor a ser usado para comparar dois +valores diferentes na coleção:: $collection = new Collection($articles); $sorted = $collection->sortBy(function ($article) { return $article->author->name . '-' . $article->title; }); -Para especificar em qual direção a coleção deve ser classificada, é -necessário fornecer ``SORT_ASC`` ou ``SORT_DESC`` como o segundo -parâmetro para classificar na direção ascendente ou descendente, -respectivamente. Por padrão, as coleções são classificadas em direção descendente:: +Para especificar em qual direção a coleção deve ser ordenada, você precisa +fornecer ``SORT_ASC`` ou ``SORT_DESC`` como o segundo parâmetro para +ordenação em direção crescente ou decrescente, respectivamente. Por padrão, +as coleções são ordenadas em direção decrescente:: $collection = new Collection($people); $sorted = $collection->sortBy('age', SORT_ASC); -Às vezes, você precisará especificar que tipo de dados você está tentando -comparar para obter resultados consistentes. Para esse fim, você deve fornecer -um terceiro argumento na função ``sortBy()`` com uma das seguintes constantes: +Às vezes, você precisará especificar qual tipo de dados está tentando comparar +para obter resultados consistentes. Para esse propósito, você deve fornecer um terceiro +argumento na função ``sortBy()`` com uma das seguintes constantes: - **SORT_NUMERIC**: Para comparar números -- **SORT_STRING**: Para comparar valores de sequência -- **SORT_NATURAL**: Para classificar sequência contendo números e se você desejar que esses números - sejam ordenados de maneira natural. Por exemplo: mostrando "10" depois de "2". -- **SORT_LOCALE_STRING**: Para comparar seqüências de caracteres com base na localidade atual. +- **SORT_STRING**: Para comparar valores de string +- **SORT_NATURAL**: Para ordenar strings contendo números e você gostaria que esses + números fossem ordenados de forma natural. Por exemplo: mostrando "10" após "2". +- **SORT_LOCALE_STRING**: Para comparar strings com base na localidade atual. Por padrão, ``SORT_NUMERIC`` é usado:: @@ -662,22 +674,23 @@ Por padrão, ``SORT_NUMERIC`` é usado:: .. warning:: - Muitas vezes, é caro iterar coleções classificadas mais de uma vez. Se você planeja fazer isso, - considere converter a coleção em uma matriz ou simplesmente use o método ``compile()`` nela. + Muitas vezes é caro iterar coleções ordenadas mais de uma vez. Se você + planeja fazer isso, considere converter a coleção em um array ou simplesmente use + o método ``compile()`` nela. -Trabalhando com dados em Árvore -=============================== +Trabalhando com Dados de Árvore +================================ -.. php:method:: nest($idPath, $parentPath) +.. php:method:: nest($idPath, $parentPath, $nestingKey = 'children') -Nem todos os dados devem ser representados de maneira linear. As coleções facilitam -a construção e o nivelamento de estruturas hierárquicas ou aninhadas. Criar uma estrutura -aninhada em que os filhos são agrupados por uma propriedade de identificador pai é fácil -com o método ``nest()``. +Nem todos os dados devem ser representados de forma linear. Coleções facilitam +a construção e achatamento de estruturas hierárquicas ou aninhadas. Criar +uma estrutura aninhada onde os filhos são agrupados por uma propriedade de identificador pai +pode ser feito com o método ``nest()``. -Dois parâmetros são necessários para esta função. O primeiro é a propriedade que representa o -identificador do item. O segundo parâmetro é o nome da propriedade que representa o identificador -para o item pai:: +Dois parâmetros são necessários para esta função. O primeiro é a propriedade +representando o identificador do item. O segundo parâmetro é o nome da +propriedade representando o identificador do item pai:: $collection = new Collection([ ['id' => 1, 'parent_id' => null, 'name' => 'Birds'], @@ -687,9 +700,10 @@ para o item pai:: ['id' => 5, 'parent_id' => 6, 'name' => 'Clown Fish'], ['id' => 6, 'parent_id' => null, 'name' => 'Fish'], ]); + $nested = $collection->nest('id', 'parent_id'); + $result = $nested->toList(); - $collection->nest('id', 'parent_id')->toList(); - // Retorna + // $result contém [ [ 'id' => 1, @@ -699,7 +713,7 @@ para o item pai:: ['id' => 2, 'parent_id' => 1, 'name' => 'Land Birds', 'children' => []], ['id' => 3, 'parent_id' => 1, 'name' => 'Eagle', 'children' => []], ['id' => 4, 'parent_id' => 1, 'name' => 'Seagull', 'children' => []], - ] + ], ], [ 'id' => 6, @@ -707,26 +721,28 @@ para o item pai:: 'name' => 'Fish', 'children' => [ ['id' => 5, 'parent_id' => 6, 'name' => 'Clown Fish', 'children' => []], - ] - ] + ], + ], ]; -Os elementos filhos são aninhados dentro da propriedade ``children`` dentro de -cada um dos itens da coleção. Esse tipo de representação de dados é útil para -renderizar menus ou percorrer elementos até um determinado nível na árvore. +Os elementos filhos são aninhados dentro da propriedade ``children`` dentro de cada um dos +itens na coleção. Este tipo de representação de dados é útil para +renderizar menus ou atravessar elementos até um certo nível na árvore. .. php:method:: listNested($order = 'desc', $nestingKey = 'children') -O inverso de ``nest()`` é ``listNested()``. Este método permite nivelar -uma estrutura de árvore novamente em uma estrutura linear. São necessários dois -parâmetros; o primeiro é o modo de deslocamento (asc, desc ou leaves) e o segundo -é o nome da propriedade que contém os filhos de cada elemento da coleção. +O inverso de ``nest()`` é ``listNested()``. Este método permite achatar +uma estrutura de árvore de volta em uma estrutura linear. Ele recebe dois parâmetros; o +primeiro é o modo de travessia (asc, desc ou leaves), e o segundo é +o nome da propriedade contendo os filhos para cada elemento na +coleção. -Tomando a entrada da coleção aninhada criada no exemplo anterior, podemos deixar nivelado:: +Tomando a entrada da coleção aninhada construída no exemplo anterior, podemos +achatá-la:: - $nested->listNested()->toList(); + $result = $nested->listNested()->toList(); - // Retorna + // $result contém [ ['id' => 1, 'parent_id' => null, 'name' => 'Birds', 'children' => [...]], ['id' => 2, 'parent_id' => 1, 'name' => 'Land Birds'], @@ -736,32 +752,37 @@ Tomando a entrada da coleção aninhada criada no exemplo anterior, podemos deix ['id' => 5, 'parent_id' => 6, 'name' => 'Clown Fish'] ] -Por padrão, a árvore é atravessada da raiz para as extremidades. Você também pode -instruí-lo a retornar apenas os elementos filhos da árvore:: +Por padrão, a árvore é percorrida da raiz às folhas. Você também pode +instruí-la a retornar apenas os elementos folha na árvore:: - $nested->listNested()->toList(); + $result = $nested->listNested('leaves')->toList(); - // Retorna + // $result contém [ - ['id' => 3, 'parent_id' => 1, 'name' => 'Eagle'], - ['id' => 4, 'parent_id' => 1, 'name' => 'Seagull'], - ['id' => 5, 'parent_id' => 6, 'name' => 'Clown Fish'] + ['id' => 2, 'parent_id' => 1, 'name' => 'Land Birds', 'children' => [], ], + ['id' => 3, 'parent_id' => 1, 'name' => 'Eagle', 'children' => [], ], + ['id' => 4, 'parent_id' => 1, 'name' => 'Seagull', 'children' => [], ], + ['id' => 5, 'parent_id' => 6, 'name' => 'Clown Fish', 'children' => [], ], ] -Depois de converter uma árvore em uma lista aninhada, você pode usar o método -``printer()`` para configurar como a saída da lista deve ser formatada:: - $nested->listNested()->printer('name', 'id', '--')->toArray(); +Depois de converter uma árvore em uma lista aninhada, você pode usar o método ``printer()`` +para configurar como a saída da lista deve ser formatada:: + + $result = $nested->listNested()->printer('name', 'id', '--')->toArray(); - // Retorna + // $result contém [ - 3 => 'Eagle', - 4 => 'Seagull', - 5 -> '--Clown Fish', + 1 => 'Birds', + 2 => '--Land Birds', + 3 => '--Eagle', + 4 => '--Seagull', + 6 => 'Fish', + 5 => '--Clown Fish', ] -O método ``printer()`` também permite usar um retorno de chamada para gerar as -chaves e/ou valores:: +O método ``printer()`` também permite que você use um callback para gerar as chaves e +ou valores:: $nested->listNested()->printer( function ($el) { @@ -789,169 +810,171 @@ Permite que você veja se uma coleção contém algum elemento:: .. php:method:: contains($value) -As coleções permitem que você verifique rapidamente se elas contêm um -valor específico usando o método ``contains()``:: +Coleções permitem que você verifique rapidamente se elas contêm um valor específico +usando o método ``contains()``:: $items = ['a' => 1, 'b' => 2, 'c' => 3]; $collection = new Collection($items); $hasThree = $collection->contains(3); -As comparações são realizadas usando o operador ``===``. Se você -deseja fazer tipos de comparação mais flexíveis, pode usar o método ``some()``. +As comparações são realizadas usando o operador ``===``. Se você deseja fazer tipos de comparação +mais frouxos, você pode usar o método ``some()``. .. php:method:: shuffle() -Às vezes, você pode querer mostrar uma coleção de valores em uma ordem aleatória. -Para criar uma nova coleção que retornará cada valor em uma posição diferente, -use o ``shuffle``:: +Às vezes, você pode desejar mostrar uma coleção de valores em ordem aleatória. Em +ordem para criar uma nova coleção que retornará cada valor em uma posição +aleatória, use o ``shuffle``:: $collection = new Collection(['a' => 1, 'b' => 2, 'c' => 3]); - // Isso poderia retornar [2, 3, 1] + // Isso pode retornar [2, 3, 1] $collection->shuffle()->toList(); .. php:method:: transpose() -Ao transpor uma coleção, você obtém uma nova coleção contendo uma linha feita de -cada uma das colunas originais:: +Quando você transpõe uma coleção, você obtém uma nova coleção contendo uma linha feita +de cada uma das colunas originais:: - $items = [ + $items = [ ['Products', '2012', '2013', '2014'], ['Product A', '200', '100', '50'], ['Product B', '300', '200', '100'], ['Product C', '400', '300', '200'], - ] - $transpose = (new Collection($items))->transpose()->toList(); + ]; + $transpose = (new Collection($items))->transpose(); + $result = $transpose->toList(); - // Retorna - [ - ['Products', 'Product A', 'Product B', 'Product C'], - ['2012', '200', '300', '400'], - ['2013', '100', '200', '300'], - ['2014', '50', '100', '200'], - ] + // $result contém + [ + ['Products', 'Product A', 'Product B', 'Product C'], + ['2012', '200', '300', '400'], + ['2013', '100', '200', '300'], + ['2014', '50', '100', '200'], + ] Retirando Elementos ------------------- .. php:method:: sample($length = 10) -Baralhar uma coleção geralmente é útil ao fazer análises estatísticas rápidas. -Outra operação comum ao executar esse tipo de tarefa é retirar alguns valores -aleatórios de uma coleção, para que mais testes possam ser realizados. Por exemplo, -se você quiser selecionar 5 usuários aleatórios aos quais deseja aplicar alguns -testes A/B, poderá usar a função ``sample()``:: +Embaralhar uma coleção geralmente é útil ao fazer análises estatísticas rápidas. +Outra operação comum ao fazer esse tipo de tarefa é retirar alguns +valores aleatórios de uma coleção para que mais testes possam ser realizados neles. +Por exemplo, se você quisesse selecionar 5 usuários aleatórios aos quais gostaria de aplicar +alguns testes A/B, você pode usar a função ``sample()``:: $collection = new Collection($people); - // Retire no máximo 20 usuários aleatórios desta coleção + // Retira no máximo 20 usuários aleatórios desta coleção $testSubjects = $collection->sample(20); -``sample()`` terá no máximo o número de valores que você especificar no primeiro -argumento. Se não houver elementos suficientes na coleção para satisfazer a amostra, -a coleção completa em uma ordem aleatória será retornada. +``sample()`` pegará no máximo o número de valores que você especificar no primeiro +argumento. Se não houver elementos suficientes na coleção para satisfazer a +amostra, a coleção completa em ordem aleatória é retornada. .. php:method:: take($length, $offset) -Sempre que você desejar obter uma fatia de uma coleção, use a função ``take()``, -ela criará uma nova coleção com, no máximo, o número de valores que você especificar -no primeiro argumento, iniciando na posição passada no segundo argumento:: +Sempre que você quiser pegar uma fatia de uma coleção, use a função ``take()``, +ela criará uma nova coleção com no máximo o número de valores que você especificar no +primeiro argumento, começando da posição passada no segundo argumento:: $topFive = $collection->sortBy('age')->take(5); - // Leve 5 pessoas da coleção a partir da posição 4 + // Pega 5 pessoas da coleção começando da posição 4 $nextTopFive = $collection->sortBy('age')->take(5, 4); -As posições são baseadas em zero, portanto, o número da primeira posição é ``0``. +As posições são baseadas em zero, portanto o primeiro número de posição é ``0``. .. php:method:: skip($length) -Embora o segundo argumento de ``take()`` possa ajudá-lo a pular alguns -elementos antes de obtê-los da coleção, você também pode usar ``skip()`` -para o mesmo objetivo que uma maneira de tirar o resto dos elementos depois -de uma certa posição:: +Embora o segundo argumento de ``take()`` possa ajudá-lo a pular alguns elementos antes +de obtê-los da coleção, você também pode usar ``skip()`` para o mesmo +propósito como uma forma de pegar o restante dos elementos após uma certa posição:: $collection = new Collection([1, 2, 3, 4]); $allExceptFirstTwo = $collection->skip(2)->toList(); // [3, 4] .. php:method:: first() -Um dos usos mais comuns de ``take()`` é obter o primeiro elemento da +Um dos usos mais comuns de ``take()`` é obter o primeiro elemento na coleção. Um método de atalho para alcançar o mesmo objetivo é usar o método ``first()``:: $collection = new Collection([5, 4, 3, 2]); - $collection->first(); // Returns 5 + $collection->first(); // Retorna 5 .. php:method:: last() -Da mesma forma, você pode obter o último elemento de uma coleção usando o -método ``last()``:: +Da mesma forma, você pode obter o último elemento de uma coleção usando o método ``last()``:: $collection = new Collection([5, 4, 3, 2]); $collection->last(); // Retorna 2 -Expansão de Coleções +Expandindo Coleções -------------------- .. php:method:: append(array|Traversable $items) -Você pode compor várias coleções em uma única. Isso permite coletar dados de -várias fontes, concatená-los e aplicar outras funções de coleta de maneira -muito suave. O método ``append()`` retornará uma nova coleção contendo os -valores das duas fontes:: +Você pode compor várias coleções em uma única. Isso permite que você +reúna dados de várias fontes, concatene-os e aplique outras funções de coleção +a eles de forma muito suave. O método ``append()`` retornará uma nova +coleção contendo os valores de ambas as fontes:: $cakephpTweets = new Collection($tweets); $myTimeline = $cakephpTweets->append($phpTweets); - // Tweets contendo cakefest de ambas as fontes + // Tweets contendo `cakefest` de ambas as fontes $myTimeline->filter(function ($tweet) { return strpos($tweet, 'cakefest'); }); .. php:method:: appendItem($value, $key) -Permite anexar um item com uma chave opcional à coleção. Se você especificar -uma chave que já existe na coleção, o valor não será substituído:: +Permite adicionar um item com uma chave opcional à coleção. Se você +especificar uma chave que já existe na coleção, o valor não será +sobrescrito:: $cakephpTweets = new Collection($tweets); $myTimeline = $cakephpTweets->appendItem($newTweet, 99); .. php:method:: prepend($items) -O método ``prepend()`` retornará uma nova coleção contendo os valores das duas fontes:: +O método ``prepend()`` retornará uma nova coleção contendo os valores de +ambas as fontes:: $cakephpTweets = new Collection($tweets); $myTimeline = $cakephpTweets->prepend($phpTweets); .. php:method:: prependItem($value, $key) -Permite anexar um item com uma chave opcional à coleção. Se você especificar uma -chave que já existe na coleção, o valor não será substituído:: +Permite adicionar um item ao início com uma chave opcional à coleção. Se você +especificar uma chave que já existe na coleção, o valor não será +sobrescrito:: $cakephpTweets = new Collection($tweets); $myTimeline = $cakephpTweets->prependItem($newTweet, 99); .. warning:: - Ao anexar de fontes diferentes, você pode esperar que algumas chaves de - ambas as coleções sejam iguais. Por exemplo, ao anexar duas matrizes simples. - Isso pode apresentar um problema ao converter uma coleção em uma matriz usando - ``toArray()``. Se você não deseja que os valores de uma coleção substituam os - outros na coleção anterior com base em sua chave, certifique-se de chamar - ``toList()`` para soltar as chaves e preservar todos os valores. + Ao anexar de diferentes fontes, você pode esperar algumas chaves de ambas + as coleções serem as mesmas. Por exemplo, ao anexar dois arrays simples. + Isso pode apresentar um problema ao converter uma coleção em um array usando + ``toArray()``. Se você não quiser que valores de uma coleção substituam + outros na anterior com base em sua chave, certifique-se de chamar + ``toList()`` para descartar as chaves e preservar todos os valores. -Elementos de Modificação ------------------------- +Modificando Elementos +---------------------- .. php:method:: insert($path, $items) -Às vezes, você pode ter dois conjuntos de dados separados que gostaria de -inserir os elementos de um conjunto em cada um dos elementos do outro conjunto. -Este é um caso muito comum quando você busca dados de uma fonte que não -oferece suporte à mesclagem de dados ou se une nativamente. +Às vezes, você pode ter dois conjuntos separados de dados que gostaria de inserir +os elementos de um conjunto em cada um dos elementos do outro conjunto. Este é +um caso muito comum quando você busca dados de uma fonte de dados que não suporta +mesclagem de dados ou junções nativamente. -As coleções oferecem um método ``insert()`` que permitirá inserir cada um dos +Coleções oferecem um método ``insert()`` que permitirá inserir cada um dos elementos em uma coleção em uma propriedade dentro de cada um dos elementos de outra coleção:: @@ -968,26 +991,25 @@ outra coleção:: ]; $merged = (new Collection($users))->insert('skills', $languages); + $result = $merged->toArray(); -Quando convertida em uma matriz, a coleção ``$merged`` ficará assim:: - + // $result contém [ ['username' => 'mark', 'skills' => ['PHP', 'Python', 'Ruby']], ['username' => 'juan', 'skills' => ['Bash', 'PHP', 'Javascript']], ['username' => 'jose', 'skills' => ['Javascript', 'Prolog']] ]; -O primeiro parâmetro para o método ``insert()`` é um caminho de propriedades -separado por pontos a seguir para que os elementos possam ser inseridos nessa -posição. O segundo argumento é qualquer coisa que possa ser convertida em um -objeto de coleção. +O primeiro parâmetro para o método ``insert()`` é um caminho separado por pontos de +propriedades a seguir para que os elementos possam ser inseridos nessa posição. O +segundo argumento é qualquer coisa que possa ser convertida em um objeto de coleção. -Observe que os elementos são inseridos pela posição em que foram encontrados, -portanto, o primeiro elemento da segunda coleção é mesclado no primeiro elemento -da primeira coleção. +Por favor, observe que os elementos são inseridos pela posição em que são encontrados, portanto, +o primeiro elemento da segunda coleção é mesclado no primeiro +elemento da primeira coleção. -Se não houver elementos suficientes na segunda coleção para inserir na primeira, -a propriedade target será preenchida com valores ``null``:: +Se não houver elementos suficientes na segunda coleção para inserir na +primeira, então a propriedade de destino não estará presente:: $languages = [ ['PHP', 'Python', 'Ruby'], @@ -995,28 +1017,30 @@ a propriedade target será preenchida com valores ``null``:: ]; $merged = (new Collection($users))->insert('skills', $languages); + $result = $merged->toArray(); - // Irá fornecer + // $result contém [ ['username' => 'mark', 'skills' => ['PHP', 'Python', 'Ruby']], ['username' => 'juan', 'skills' => ['Bash', 'PHP', 'Javascript']], - ['username' => 'jose', 'skills' => null] + ['username' => 'jose'] ]; -O método ``insert()`` pode operar elementos ou objetos da matriz -implementando a interface ``ArrayAccess``. +O método ``insert()`` pode operar elementos de array ou objetos que implementam a +interface ``ArrayAccess``. -Tornando Reutilizáveis os Métodos de Coleta -------------------------------------------- +Tornando os Métodos de Coleção Reutilizáveis +--------------------------------------------- -Usar closures para métodos de coleta é ótimo quando o trabalho a ser feito é -pequeno e focado, mas pode ficar confuso muito rapidamente. Isso se torna mais -óbvio quando muitos métodos diferentes precisam ser chamados ou quando o comprimento -dos métodos de closures é superior a apenas algumas linhas. +Usar closures para métodos de coleção é ótimo quando o trabalho a ser feito é pequeno +e focado, mas pode ficar confuso muito rapidamente. Isso se torna mais óbvio quando +muitos métodos diferentes precisam ser chamados ou quando o comprimento do closure +dos métodos é mais do que apenas algumas linhas. -Também existem casos em que a lógica usada para os métodos de coleta pode ser reutilizada -em várias partes do seu aplicativo. É recomendável considerar a extração de lógica de -coleção complexa para separar classes. Por exemplo, imagine uma closure longa como esta:: +Também há casos em que a lógica usada para os métodos de coleção pode ser +reutilizada em várias partes de sua aplicação. É recomendável que você +considere extrair lógica de coleção complexa para classes separadas. Por exemplo, +imagine um closure longo como este:: $collection ->map(function ($row, $key) { @@ -1053,16 +1077,15 @@ Isso pode ser refatorado criando outra classe:: } } - // Usa a lógica em sua chamada de map() + // Use a lógica em sua chamada map() $collection->map(new TotalOrderCalculator) .. php:method:: through($callback) -Às vezes, uma cadeia de chamadas de método de coleção pode se tornar reutilizável -em outras partes do seu aplicativo, mas apenas se elas forem chamadas nessa ordem -específica. Nesses casos, você pode usar ``through()`` em combinação com uma -classe implementando ``__invoke`` para distribuir suas chamadas úteis de -processamento de dados:: +Às vezes, uma cadeia de chamadas de métodos de coleção pode se tornar reutilizável em outras partes +de sua aplicação, mas apenas se elas forem chamadas nessa ordem específica. Em +esses casos, você pode usar ``through()`` em combinação com uma classe implementando +``__invoke`` para distribuir suas chamadas úteis de processamento de dados:: $collection ->map(new ShippingCostCalculator) @@ -1071,8 +1094,8 @@ processamento de dados:: ->buffered() ... -As chamadas de método acima podem ser extraídas para uma nova classe, para que -não precisem ser repetidas sempre:: +As chamadas de método acima podem ser extraídas para uma nova classe para que não precisem +ser repetidas toda vez:: class FinalCheckOutRowProcessor { @@ -1087,24 +1110,24 @@ não precisem ser repetidas sempre:: } } - // Agora você pode usar o método through() para chamar todos os métodos de uma só vez + // Agora você pode usar o método through() para chamar todos os métodos de uma vez $collection->through(new FinalCheckOutRowProcessor); Otimizando Coleções -------------------- +-------------------- .. php:method:: buffered() -As coleções geralmente executam a maioria das operações que você cria usando -suas funções de maneira lenta. Isso significa que, embora você possa chamar uma -função, isso não significa que ela seja executada imediatamente. Isso é verdade -para muitas funções nesta classe. A avaliação lenta permite economizar recursos -em situações em que você não usa todos os valores em uma coleção. Você não pode -usar todos os valores quando a iteração parar mais cedo ou quando um caso de exceção/falha -for atingido mais cedo. +Coleções geralmente executam a maioria das operações que você cria usando suas funções de +forma preguiçosa. Isso significa que, mesmo que você possa chamar uma função, isso não +significa que ela seja executada imediatamente. Isso é verdade para muitas funções nesta +classe. A avaliação preguiçosa permite que você economize recursos em situações +onde você não usa todos os valores em uma coleção. Você pode não usar todos os +valores quando a iteração para cedo, ou quando uma exceção/caso de falha é alcançado +cedo. -Além disso, a avaliação lenta ajuda a acelerar algumas operações. Considere -o seguinte exemplo:: +Além disso, a avaliação preguiçosa ajuda a acelerar algumas operações. Considere o +seguinte exemplo:: $collection = new Collection($oneMillionItems); $collection = $collection->map(function ($item) { @@ -1112,15 +1135,15 @@ o seguinte exemplo:: }); $itemsToShow = $collection->take(30); -Se as coleções não tivessem sido preguiçosas, teríamos executado um milhão -de operações, embora desejássemos mostrar apenas 30 elementos. Em vez disso, -nossa operação de mapa foi aplicada apenas aos 30 elementos que usamos. Também -podemos obter benefícios dessa avaliação preguiçosa para coleções menores quando -fazemos mais de uma operação nelas. Por exemplo: chamando ``map()`` duas vezes -e depois ``filter()``. +Se as coleções não fossem preguiçosas, teríamos executado um milhão de operações, +mesmo que quiséssemos mostrar apenas 30 elementos. Em vez disso, nossa operação de map +foi aplicada apenas aos 30 elementos que usamos. Também podemos +derivar benefícios dessa avaliação preguiçosa para coleções menores quando fazemos +mais de uma operação nelas. Por exemplo: chamar ``map()`` duas vezes e +depois ``filter()``. -A avaliação preguiçosa também traz sua desvantagem. Você pode estar executando as -mesmas operações mais de uma vez se otimizar uma coleção prematuramente. Considere +A avaliação preguiçosa também tem suas desvantagens. Você pode estar fazendo as mesmas +operações mais de uma vez se otimizar uma coleção prematuramente. Considere este exemplo:: $ages = $collection->extract('age'); @@ -1133,27 +1156,29 @@ este exemplo:: return $item > 30; }); -Se iterarmos ``youngerThan30`` e ``olderThan30``, infelizmente a coleção -executaria a operação ``extract()`` duas vezes. Isso ocorre porque as coleções -são imutáveis e a operação de extração lenta é feita para os dois filtros. +Se iterarmos tanto ``youngerThan30`` quanto ``olderThan30``, a coleção +infelizmente executaria a operação ``extract()`` duas vezes. Isso ocorre porque +as coleções são imutáveis e a operação de extração preguiçosa seria feita para +ambos os filtros. -Felizmente, podemos superar esse problema com uma única função. Se você planeja -reutilizar os valores de determinadas operações mais de uma vez, é possível -compilar os resultados em outra coleção usando a função ``buffered()``:: +Felizmente, podemos superar esse problema com uma única função. Se você planeja reutilizar +os valores de certas operações mais de uma vez, você pode compilar os resultados +em outra coleção usando a função ``buffered()``:: $ages = $collection->extract('age')->buffered(); $youngerThan30 = ... $olderThan30 = ... -Agora, quando as duas coleções forem iteradas, elas chamarão a operação de extração apenas uma vez. +Agora, quando ambas as coleções forem iteradas, elas chamarão apenas a +operação de extração uma vez. -Tornando as Coleções Rebobináveis ---------------------------------- +Tornando Coleções Rebobináveis +------------------------------- -O método ``buffered()`` também é útil para converter iteradores não-rebobináveis em -coleções que podem ser iteradas mais de uma vez:: +O método ``buffered()`` também é útil para converter iteradores não rebobináveis +em coleções que podem ser iteradas mais de uma vez:: - // Em PHP 5.5+ + // No PHP 5.5+ public function results() { ... @@ -1163,14 +1188,15 @@ coleções que podem ser iteradas mais de uma vez:: } $rewindable = (new Collection(results()))->buffered(); -Coleções de Clonagem --------------------- +Clonando Coleções +------------------ .. php:method:: compile($preserveKeys = true) -Às vezes, você precisa obter um clone dos elementos de outra coleção. Isso é -útil quando você precisa repetir o mesmo conjunto de locais diferentes ao mesmo -tempo. Para clonar uma coleção de outra, use o método ``compile()``:: +Às vezes você precisa obter um clone dos elementos de outra +coleção. Isso é útil quando você precisa iterar o mesmo conjunto de diferentes +lugares ao mesmo tempo. Para clonar uma coleção de outra, use o +método ``compile()``:: $ages = $collection->extract('age')->compile(); @@ -1182,4 +1208,4 @@ tempo. Para clonar uma coleção de outra, use o método ``compile()``:: .. meta:: :title lang=pt: Coleções - :keywords lang=pt: collections, cakephp, append, sort, compile, contains, countBy, each, every, extract, filter, first, firstMatch, groupBy, indexBy, jsonSerialize, map, match, max, min, reduce, reject, sample, shuffle, some, random, sortBy, take, toArray, insert, sumOf, stopWhen, unfold, through + :keywords lang=pt: coleções, cakephp, append, sort, compile, contains, countBy, each, every, extract, filter, first, firstMatch, groupBy, indexBy, jsonSerialize, map, match, max, min, reduce, reject, sample, shuffle, some, random, sortBy, take, toArray, insert, sumOf, stopWhen, unfold, through diff --git a/pt/core-libraries/email.rst b/pt/core-libraries/email.rst index 2dce0dcc7f..2bcbf89986 100644 --- a/pt/core-libraries/email.rst +++ b/pt/core-libraries/email.rst @@ -213,7 +213,7 @@ Ao configurar ajudantes, certifique-se de incluir 'Html' ou ele será removido d ajudantes carregados em seu modelo de email. Se você deseja enviar e-mail usando templates em um plugin, você pode usar a familiar -:term:`sintaxe plugin` para fazer isso:: +:term:`sintaxe de plugin` para fazer isso:: $mailer = new Mailer(); $mailer->viewBuilder()->setTemplate('Blog.new_comment'); diff --git a/pt/core-libraries/events.rst b/pt/core-libraries/events.rst index b965fa5dd3..1b9f878f84 100644 --- a/pt/core-libraries/events.rst +++ b/pt/core-libraries/events.rst @@ -4,9 +4,9 @@ Sistema de Eventos Criar aplicações com facilidade de manutenção é uma ciência e uma arte ao mesmo tempo. É de conhecimento geral que a chave para ter um código de qualidade é fazer objetos desacoplados e coesos ao mesmo tempo. Coesão significa que todos os -metodos e propriedades de uma classe são fortemente relacionados entre classes em sí +métodos e propriedades de uma classe são fortemente relacionados entre classes em si e não estão tentando fazer o trabalho que deveria ser feito por outros objetos, -equanto o desacoplamento é a medida de quão "estranha" uma classe é para objetos +enquanto o desacoplamento é a medida de quão "estranha" uma classe é para objetos externos e o quanto essa classe depende desses objetos. Existem alguns casos onde você precisa se comunicar com outras partes da @@ -32,13 +32,13 @@ View e Helper. Se você já usou um deles, você já está de alguma forma famil eventos no CakePHP. Exemplo de Uso dos Eventos -========================== +=========================== Vamos assumir que você está construindo um plugin de carrinho de compras e gostaria de focar somente na lógica de lidar com o pedido. Você não quer incluir nenhuma lógica de envios, notificação dos usuários ou incrementar/remover um item do estoque. Mas, essas são tarefas importantes para pessoas que vão usar o seu plugin. Se você não -estivesse usando eventos, você poderia tentar implementar isso incluindo Bahaviors no +estivesse usando eventos, você poderia tentar implementar isso incluindo Behaviors no seu Model, ou adicionando Components no seu Controller. Fazer isso é um desvio na maioria das vezes, já que você teria que adicionar código para carregar externamente esses Behaviors, ou adicionar hooks ao Controller do seu plugin. @@ -61,10 +61,10 @@ o Model Orders limpo você poderia usar eventos:: { if ($this->save($order)) { $this->Cart->remove($order); - $event = new Event('Model.Order.afterPlace', $this, [ + $event = new Event('Order.afterPlace', $this, [ 'order' => $order ]); - $this->eventManager()->dispatch($event); + $this->getEventManager()->dispatch($event); return true; } @@ -73,16 +73,13 @@ o Model Orders limpo você poderia usar eventos:: } } -.. deprecated:: 3.5.0 - Use ``getEventManager()``. - O exemplo acima permite você notificar outras partes da aplicação em que um pedido foi feito e você pode então, enviar emails, notificações, atualizar o estoque, fazer o log das estatísticas relevantes e outras tarefas em um objeto separado que foca nessas responsabilidades. -Acessando os Gerenciadores de Evento (Event Menagers) -===================================================== +Acessando os Gerenciadores de Evento (Event Managers) +====================================================== No CakePHP os eventos são disparados para os gerenciadores de evento (event managers). Gerenciadores de evento disponíveis estão em todas as Table, View e @@ -90,37 +87,37 @@ Controller, utilizando ``getEventManager()``:: $events = $this->getEventManager(); -Cada Model tem o seu próprio gerenciador de evento, enquando View e Controller -compartilham o mesmo, Isso permite que os eventos dos Models sejam isolados, e +Cada Model tem o seu próprio gerenciador de evento, enquanto View e Controller +compartilham o mesmo. Isso permite que os eventos dos Models sejam isolados, e permitem os Components ou Controller reagirem a eventos criados na View, caso necessário. Gerenciador de Eventos Global ------------------------------ +------------------------------ Adicionado aos gerenciadores de evento no nível da instância, o CakePHP provê um gerenciador de evento global, que permite ouvir a qualquer evento disparado pela -aplicação. isso é útil quando anexar Ouvintes a uma instancia pode ser incômodo ou +aplicação. Isso é útil quando anexar Ouvintes a uma instância pode ser incômodo ou difícil. O gerenciador de eventos global é um singleton de :php:class:`Cake\\Event\\EventManager`. Ouvintes anexados ao gerenciador de eventos global são executados antes dos Ouvintes de instâncias com a mesma prioridade. -você pode acessar o gerenciador de eventos glocal utilizando o metodo estático:: +Você pode acessar o gerenciador de eventos global utilizando o método estático:: // Em qualquer arquivo de configuração ou arquivo que seja executado *antes* do evento use Cake\Event\EventManager; EventManager::instance()->on( - 'Model.Order.afterPlace', + 'Order.afterPlace', $aCallback ); Uma coisa que deve ser levada em conta é que existem eventos com o mesmo nome, mas com assuntos divergentes, então verificar se o evento é requerido em qualquer função -que é anexada globalmente, desse modo, evitando bugs, lembre-se que com a +que é anexada globalmente, desse modo, evitando bugs. Lembre-se que com a flexibilidade de um gerenciador de evento global, uma certa complexidade é adicionada. -O metodo :php:meth:`Cake\\Event\\EventManager::dispatch()` aceita o objeto do evento -como um argumento, e notifica a todos os Ouvintes e Callbacks parando esse objeto +O método :php:meth:`Cake\\Event\\EventManager::dispatch()` aceita o objeto do evento +como um argumento, e notifica a todos os Ouvintes e Callbacks passando esse objeto adiante. Os Ouvintes vão lidar com toda a lógica extra ligada ao evento ``afterPlace``, você pode, enviar emails, atualizar estatísticas do usuário em objetos separados, ou também delegar isso para tarefas offline que você @@ -156,6 +153,43 @@ ouvir. Cada camada do CakePHP emite um evento que você pode utilizar na sua apl * :ref:`Controller events ` * :ref:`View events ` +``Server.terminate`` +-------------------- + +O evento ``Server.terminate`` é disparado após a resposta ter sido enviada ao +cliente. Esse evento é útil para executar tarefas que devem ser feitas após a +resposta ter sido enviada, como envio de emails ou logging. + +Você pode ouvir esse evento usando uma instância do gerenciador de eventos:: + + use Cake\Event\EventManager; + + EventManager::instance()->on('Server.terminate', function ($event) { + // Executar tarefas que devem ser feitas após a resposta ter sido + // enviada ao cliente. + }); + +Ou usando o hook ``events`` na sua classe Application/Plugin:: + + use Cake\Event\EventManagerInterface; + + public function events(EventManagerInterface $eventManager): EventManagerInterface + { + $eventManager->on('Server.terminate', function ($event) { + // Executar tarefas que devem ser feitas após a resposta ter sido + // enviada ao cliente. + }); + + return $eventManager; + } + +.. tip:: + Isso é chamado mesmo se uma exceção for lançada durante a requisição, por exemplo em páginas 404. + +.. note:: + O evento ``Server.terminate`` apenas funciona para implementações PHP-FPM que + suportam a função ``fastcgi_finish_request``. + .. _registering-event-listeners: Registrando Listeners @@ -164,54 +198,81 @@ Registrando Listeners Listeners são o meio preferido para registrar callbacks de qualquer evento. Isso é feito implementando a interface :php:class:`Cake\\Event\\EventListenerInterface` em qualquer classe que você deseje registrar um callback. Classes implementando a -interface devem ter o metodo ``implementedEvents()``. Esse método deve retornar um +interface devem ter o método ``implementedEvents()``. Esse método deve retornar um array associativo com o nome de todos os eventos que a classe vai gerenciar. -Para continuar o exemplo anterior, vamos imaginas que temos uma classe UserStatistic +Para continuar o exemplo anterior, vamos imaginar que temos uma classe UserStatistic responsável por calcular o histórico de compras do usuário, e compilar nas estatísticas globais do site. Esse é um ótimo exemplo de onde usar uma classe Listener. Fazendo isso permite você se concentrar nas lógica das estatísticas em um -local e responder ao eventos como necessários. Nosso listener ``UserStatistics`` pode +local e responder aos eventos como necessários. Nosso listener ``UserStatistics`` pode começar como abaixo:: + namespace App\Event; + use Cake\Event\EventListenerInterface; class UserStatistic implements EventListenerInterface { - public function implementedEvents() + public function implementedEvents(): array { return [ - 'Model.Order.afterPlace' => 'updateBuyStatistic', + // Nomes de eventos personalizados permitem projetar seus eventos de aplicação + // conforme necessário. + 'Order.afterPlace' => 'updateBuyStatistic', ]; } - public function updateBuyStatistic($event, $order) + public function updateBuyStatistic($event) { // Código para atualizar as estatísticas - - // Code to update statistics } } - // Anexa o objeto UserStatistic para o gerenciador de evento da Order + // Do seu controller, anexe o objeto UserStatistic ao gerenciador de evento da Order $statistics = new UserStatistic(); $this->Orders->getEventManager()->on($statistics); -Como você pôde ver nó código acima, o metodo ``on()`` aceita instancias da interface -``EventListener``. Internamente o gerenciador de eventos vai utilizar os +Como você pôde ver no código acima, o método ``on()`` aceita instâncias da interface +``EventListener``. Internamente o gerenciador de eventos vai utilizar ``implementedEvents()`` para anexar ao callback corretamente. +.. versionadded:: 5.1.0 + O hook ``events`` foi adicionado ao ``BaseApplication`` assim como à classe ``BasePlugin`` + +A partir do CakePHP 5.1 é recomendado registrar event listeners adicionando-os através do hook ``events`` na sua classe de aplicação ou plugin:: + + namespace App; + + use App\Event\UserStatistic; + use Cake\Event\EventManagerInterface; + use Cake\Http\BaseApplication; + + class Application extends BaseApplication + { + // O resto da sua classe Application + + public function events(EventManagerInterface $eventManager): EventManagerInterface + { + $statistics = new UserStatistic(); + $eventManager->on($statistics); + + return $eventManager; + } + } + Registrando Listeners Anônimos ------------------------------- +------------------------------- -Enquanto objeto de Event Listerners são geralmente um melhor método para implementar -Listeners você pode utilizar uma ``callable`` como Event Listener. Por exemplo, se nós -quisessemos colocar qualquer pedido nos arquivos de log, nós poderiamos utilizar +Enquanto objetos event listener são geralmente um melhor método para implementar +Listeners você pode utilizar qualquer ``callable`` como Event Listener. Por exemplo, se nós +quiséssemos colocar qualquer pedido nos arquivos de log, nós poderíamos utilizar uma função anônima para isso:: use Cake\Log\Log; - $this->Orders->getEventManager()->on('Model.Order.afterPlace', function ($event) { + // Do controller, ou durante o bootstrap da aplicação. + $this->Orders->getEventManager()->on('Order.afterPlace', function ($event) { Log::write( 'info', 'A new order was placed with id: ' . $event->getSubject()->id @@ -225,30 +286,27 @@ Além de funções anônimas você pode usar qualquer outro callable no qual o P 'inventory' => [$this->InventoryManager, 'decrement'], ]; foreach ($events as $callable) { - $eventManager->on('Model.Order.afterPlace', $callable); + $eventManager->on('Order.afterPlace', $callable); } -Quando trabalhamos com plugins que não dispara eventos especificos, você pode -utilizar Event Listeners dos eventos padrão. Vamos pensar, por exemplo o plugin +Quando trabalhamos com plugins que não disparam eventos específicos, você pode +utilizar Event Listeners dos eventos padrão. Vamos pensar, por exemplo, o plugin 'UserFeedback' que lida com o feedback dos usuários. A partir da sua aplicação, você poderia querer saber quando um feedback foi salvo no banco de dados e intervir nele. -Você pode utilizar o gerenciador de eventos global para pegar o evento -``Model.afterSave``. No entendo, você pode pegar um caminho mais direto. e escutar -somente o que você realmente precisa:: +Você pode utilizar o evento global ``Model.afterSave``. No entanto, você pode pegar um +caminho mais direto e escutar somente o que você realmente precisa:: // Você pode criar o código a seguir antes de persistir os dados no banco // exemplo no config/bootstrap.php - - use Cake\ORM\TableRegistry; + use Cake\Datasource\FactoryLocator; // Se está enviando emails use Cake\Mailer\Email; - TableRegistry::getTableLocator()->get('ThirdPartyPlugin.Feedbacks') + FactoryLocator::get('Table')->get('ThirdPartyPlugin.Feedbacks') ->getEventManager() ->on('Model.afterSave', function($event, $entity) { - // Por exemplo, podemos mandar um email para o admin - // Antes da versão 3.4 use os métodos from()/to()/subject() + // Por exemplo, podemos mandar um email para o admin $email = new Email('default'); $email->setFrom(['info@yoursite.com' => 'Your Site']) ->setTo('admin@yoursite.com') @@ -272,11 +330,11 @@ evento específico pode ser usada como base de alguma ação:: // Em algum outro local da sua aplicação. $events = $this->getEventManager()->matchingListeners('Verification'); if (!empty($events)) { - // Executa a lógica relacionada a precença do Event Listener 'Verification'. + // Executa a lógica relacionada à presença do Event Listener 'Verification'. // Por exemplo, remover o Listener caso esteja presente. $this->getEventManager()->off('User.Verification'); } else { - // Executa a lógica relacionada a ausencia do event listener 'Verification' + // Executa a lógica relacionada à ausência do event listener 'Verification' } .. note:: @@ -285,18 +343,18 @@ evento específico pode ser usada como base de alguma ação:: .. _event-priorities: Estabelecendo Prioridades -------------------------- +-------------------------- Em alguns casos você pode querer controlar a ordem em que os Listeners são invocados, por exemplo, se nós voltarmos ao nosso exemplo das estatísticas do usuários. Seria ideal se esse Listener fosse chamado no final da pilha. Ao chamar no -final do pilha de ouvintes, nós garantimos que o evento não foi cancelado e que, +final da pilha de ouvintes, nós garantimos que o evento não foi cancelado e que nenhum outro listeners retornou exceptions. Nós podemos também pegar o estado final dos objetos, no caso de outros ouvintes possam terem modificado o objeto de assunto ou do evento. Prioridades são definidas como inteiros (integer) quando adicionadas ao ouvinte. -Quando maior for o número, mais tarde esse metodo será disparado. A prioridade padrão +Quanto maior for o número, mais tarde esse método será disparado. A prioridade padrão para todos os listeners é ``10``. Se você precisa que o seu método seja executado antes, utilize um valor menor que o padrão. Por outro lado se você deseja rodar o seu callback depois dos outros, usando um número acima de ``10`` será suficiente. @@ -309,7 +367,7 @@ os Event Listeners:: // Definindo a prioridade para um callback $callback = [$this, 'doSomething']; $this->getEventManager()->on( - 'Model.Order.afterPlace', + 'Order.afterPlace', ['priority' => 2], $callback ); @@ -317,10 +375,10 @@ os Event Listeners:: // Definindo a prioridade para um Listener class UserStatistic implements EventListenerInterface { - public function implementedEvents() + public function implementedEvents(): array { return [ - 'Model.Order.afterPlace' => [ + 'Order.afterPlace' => [ 'callable' => 'updateBuyStatistic', 'priority' => 100 ], @@ -329,51 +387,51 @@ os Event Listeners:: } Como você pôde ver, a principal diferença entre objetos ``EventListener`` é que você -precisa usar uma array para especificar o metodo callable e a preferência de +precisa usar um array para especificar o método callable e a preferência de prioridade. A chave ``callable`` é uma array especial que o gerenciador vai ler para saber qual função na classe ele deverá chamar. Obtendo Dados do Evento como Argumentos da Função -------------------------------------------------- +-------------------------------------------------- Quando eventos tem dados definidos no seu construtor, esses dados são convertidos em -argumentos para os ouvintes. Um exemplo da camada ViewView é o afterRender callback:: +argumentos para os ouvintes. Um exemplo da camada View é o afterRender callback:: $this->getEventManager() ->dispatch(new Event('View.afterRender', $this, ['view' => $viewFileName])); Os ouvintes do callback ``View.afterRender`` devem ter a seguinte assinatura:: - function (Event $event, $viewFileName) + function (EventInterface $event, $viewFileName) Cada valor fornecido ao construtor Event será convertido em parâmetros de função na ordem em que aparecem na matriz de dados. Se você usar uma matriz associativa, o resultado ``array_values`` determinará a ordem dos argumentos da função. .. note:: - Diferente do CakePHP 2.x, converter dados para os arqumentos do listener é o + Diferente do CakePHP 2.x, converter dados para os argumentos do listener é o comportamento padrão e não pode ser desativado. Disparando Eventos ================== -Uma vez que você tem uma instancia do event manager você pode disparar eventos +Uma vez que você tem uma instância do event manager você pode disparar eventos utilizando :php:meth:`~Cake\\Event\\EventManager::dispatch()`. Esse método aceita uma -instancia da class :php:class:`Cake\\Event\\Event`. Vamos ver como disparar um evento:: +instância da classe :php:class:`Cake\\Event\\Event`. Vamos ver como disparar um evento:: // Um event listener tem que ser instanciado antes de disparar um evento. // Crie um evento e dispare ele. - $event = new Event('Model.Order.afterPlace', $this, [ + $event = new Event('Order.afterPlace', $this, [ 'order' => $order ]); $this->getEventManager()->dispatch($event); :php:class:`Cake\\Event\\Event` aceita três argumentos no seu construtor. O primeiro é o nome do evento, você deve tentar manter esse nome o mais único possível, ainda assim, -deve ser de fácil entendimento . Nós sugerimos a seguinte convenção: +deve ser de fácil entendimento. Nós sugerimos a seguinte convenção: ``Camada.nomeDoEvento`` para eventos acontecendo a nível de uma camada (ex. ``Controller.startup``, ``View.beforeRender``) e ``Camada.Classe.NomeDoEvento`` para -eventos que acontecen em uma classe especifica em uma camada, exemplo +eventos que acontecem em uma classe específica em uma camada, exemplo ``Model.User.afterRegister`` ou ``Controller.Courses.invalidAccess``. O segundo argumento é o ``subject``, ou seja, o objeto associado ao evento, geralmente @@ -387,7 +445,7 @@ evento. Esses dados podem ser qualquer coisa que você considere útil enviar ao listeners. Enquanto esse argumento pode ser de qualquer tipo, nós recomendamos que seja uma array associativa. -O medoto :php:meth:`~Cake\\Event\\EventManager::dispatch()` aceita um objeto de +O método :php:meth:`~Cake\\Event\\EventManager::dispatch()` aceita um objeto de evento como argumento e notifica a todos os listeners inscritos. .. _stopping-events: @@ -397,8 +455,8 @@ Parando Eventos Assim como nos eventos do DOM, você pode querer parar um evento para previnir que outros listeners sejam notificados. Você pode ver isso em ação nos Callbacks do model -(ex. beforeSave) onde é possível parar o operação de persistir os dados se o código -decidir que não pode continuar +(ex. beforeSave) onde é possível parar a operação de persistir os dados se o código +decidir que não pode continuar. Para parar um evento você pode retornar ``false`` nos seus callbacks ou chamar o método ``stopPropagation()`` no objeto do evento:: @@ -415,17 +473,17 @@ chamar o método ``stopPropagation()`` no objeto do evento:: $event->stopPropagation(); } -Parar um evento vai previnir que qualquer callback adicional seja chamado. +Parar um evento vai prevenir que qualquer callback adicional seja chamado. Além disso o código que disparou o evento pode se comportar de maneira diferente baseado no evento sendo parado ou não. Geralmente não faz sentido parar 'depois' do evento, mas parar 'antes' do evento costuma ser usado para impedir toda a operação de acontecer. -Para verificar se um evento foi parado você pode chamar o metodo ``isStopped()`` no -objeto do evento object:: +Para verificar se um evento foi parado você pode chamar o método ``isStopped()`` no +objeto do evento:: public function place($order) { - $event = new Event('Model.Order.beforePlace', $this, ['order' => $order]); + $event = new Event('Order.beforePlace', $this, ['order' => $order]); $this->getEventManager()->dispatch($event); if ($event->isStopped()) { return false; @@ -439,13 +497,13 @@ objeto do evento object:: No exemplo anterior o pedido não será salvo se o evento for parado durante o processamento do callback ``beforePlace``. -Parando o Resultado de um Evento --------------------------------- +Obtendo o Resultado de um Evento +--------------------------------- Toda vez que um callback retorna um valor não nulo ou não falso, ele é armazenado na propriedade ``$result`` do objeto do evento. Isso é útil quando você quer permitir -callbacks a modificar a execução do evento. Vajamos novamente nosso exemplo -``beforePlace``e vamos deixar os callbacks modififcar os dados de ``$order``. +callbacks a modificar a execução do evento. Vejamos novamente nosso exemplo +``beforePlace`` e vamos deixar os callbacks modificarem os dados de ``$order``. Resultados de eventos podem ser alterados utilizando o resultado do objeto do evento diretamente ou retornando o valor no próprio callback:: @@ -458,6 +516,7 @@ diretamente ou retornando o valor no próprio callback:: return $alteredData; } + // Outro callback public function doSomethingElse($event) { @@ -468,7 +527,7 @@ diretamente ou retornando o valor no próprio callback:: // Utilizando o resultado do evento public function place($order) { - $event = new Event('Model.Order.beforePlace', $this, ['order' => $order]); + $event = new Event('Order.beforePlace', $this, ['order' => $order]); $this->getEventManager()->dispatch($event); if (!empty($event->getResult()['order'])) { $order = $event->getResult()['order']; @@ -485,8 +544,8 @@ como dados ou resultado de eventos e alterar diretamente o objeto é a melhor solução, pois a referência é mantida a mesma e as modificações são compartilhadas em todas as chamadas de retorno de chamada. -Removento Callbacks e Ouvintes ------------------------------- +Removendo Callbacks e Ouvintes +------------------------------- Se por qualquer motivo você desejar remover os callbacks do gerenciador de eventos é só chamar o método :php:meth:`Cake\\Event\\EventManager::off()` utilizando como argumentos os @@ -512,7 +571,7 @@ dois primeiros parâmetros usados para anexá-lo:: // Removendo uma única chave de um evento em um ouvinte $this->getEventManager()->off('My.event', $listener); - // Removento todos os callbacks implemantados por um ouvinte + // Removendo todos os callbacks implementados por um ouvinte $this->getEventManager()->off($listener); Eventos são uma ótima maneira de separar responsabilidades na sua aplicação e fazer @@ -526,6 +585,7 @@ Leitura Adicional ================= * :doc:`/orm/behaviors` +* :doc:`/console-commands/commands` * :doc:`/controllers/components` * :doc:`/views/helpers` * :ref:`testing-events` diff --git a/pt/core-libraries/file-folder.rst b/pt/core-libraries/file-folder.rst deleted file mode 100644 index f44241def5..0000000000 --- a/pt/core-libraries/file-folder.rst +++ /dev/null @@ -1,444 +0,0 @@ -Pasta & Arquivo -############### - -.. php:namespace:: Cake\Filesystem - -Os utilitários de pasta e arquivo são classes convenientes para ajudá-lo a ler -e gravar/anexar arquivos, listar arquivos dentro de uma pasta e outras tarefas -comuns relacionadas ao diretório. - -.. deprecated:: 4.0 - As classes ``File`` e ``Folder`` serão removidas na 5.0. - Use classes SPL como ``SplFileInfo`` ou ``SplFileObject`` e classes iterator - como ``RecursiveDirectoryIterator``, ``RecursiveRegexIterator`` etc. - -Uso Básico -========== - -Certifique-se de que as classes estejam carregadas:: - - use Cake\Filesystem\Folder; - use Cake\Filesystem\File; - -Com isso podemos configurar uma nova instância da pasta:: - - $dir = new Folder('/path/to/folder'); - -e então pesquise todos os arquivos *.php* dentro dessa pasta usando regex:: - - $files = $dir->find('.*\.php'); - -Agora podemos percorrer os arquivos e ler ou escrever/anexar ao -conteúdo ou simplesmente excluir o arquivo:: - - foreach ($files as $file) { - $file = new File($dir->pwd() . DS . $file); - $contents = $file->read(); - // $file->write('Estou substituindo o conteúdo deste arquivo'); - // $file->append('Estou adicionando ao final deste arquivo.'); - // $file->delete(); // Estou excluindo este arquivo - $file->close(); // Certifique-se de fechar o arquivo quando terminar - } - -API Pastas -========== - -.. php:class:: Folder(string $path = false, boolean $create = false, string|boolean $mode = false) - -:: - - // Cria uma nova pasta com as permissões 0755 - $dir = new Folder('/path/to/folder', true, 0755); - -.. php:attr:: path - - Caminho da pasta atual. :php:meth:`Folder::pwd()` retornará a mesma informação. - -.. php:attr:: sort - - Se os resultados da lista devem ou não ser classificados por nome. - -.. php:attr:: mode - - Modo a ser usado ao criar pastas. O padrão é ``0755``. Não faz nada em máquinas Windows. - -.. php:staticmethod:: addPathElement(string $path, string $element) - - Retorna $path com $elemento adicionado, com a barra correta:: - - $path = Folder::addPathElement('/a/path/for', 'testing'); - // $path é igual a /a/path/for/testing - - $element também pode ser um array:: - - $path = Folder::addPathElement('/a/path/for', ['testing', 'another']); - // $path é igual a /a/path/for/testing/another - -.. php:method:: cd( $path ) - - Mude o diretório para $path. Retorna ``false`` em caso de falha:: - - $folder = new Folder('/foo'); - echo $folder->path; // Exibe /foo - $folder->cd('/bar'); - echo $folder->path; // Exibe /bar - $false = $folder->cd('/non-existent-folder'); - -.. php:method:: chmod(string $path, integer $mode = false, boolean $recursive = true, array $exceptions = []) - - Altere o modo em uma estrutura de diretório recursivamente. Isso inclui - alterar o modo dos arquivos também:: - - $dir = new Folder(); - $dir->chmod('/path/to/folder', 0755, true, ['skip_me.php']); - -.. php:method:: copy(array|string $options = []) - - Copie recursivamente um diretório. O único parâmetro $options pode ser - um caminho para a cópia ou um conjunto de opções:: - - $folder1 = new Folder('/path/to/folder1'); - $folder1->copy('/path/to/folder2'); - // Colocará a pasta1 e todo o seu conteúdo na pasta2 - - $folder = new Folder('/path/to/folder'); - $folder->copy([ - 'to' => '/path/to/new/folder', - 'from' => '/path/to/copy/from', // Irá causar a ocorrência de um cd() - 'mode' => 0755, - 'skip' => ['skip-me.php', '.git'], - 'scheme' => Folder::SKIP // Pule diretórios/arquivos que já existem. - ]); - - Existem 3 esquemas suportados: - - * ``Folder::SKIP`` pule a cópia/movimentação de arquivos e diretórios - que existem no diretório de destino. - * ``Folder::MERGE`` mescla os diretórios de origem/destino. Os arquivos no diretório de origem - substituirão os arquivos no diretório de destino. O conteúdo do diretório será mesclado. - * ``Folder::OVERWRITE`` sobrescreve os arquivos e diretórios existentes no diretório de destino pelos do - diretório de origem. Se ambos contiverem o mesmo subdiretório, o conteúdo do diretório - de destino será removido e substituído pelo de origem. - -.. php:staticmethod:: correctSlashFor(string $path) - - Retorna um conjunto correto de barras para o $path - fornecido ('\\' para caminhos do Windows e '/' para outros caminhos). - -.. php:method:: create(string $pathname, integer $mode = false) - - Crie uma estrutura de diretório recursivamente. Pode ser usado para - criar estruturas de caminho mais profundo como `/foo/bar/baz/shoe/horn`:: - - $folder = new Folder(); - if ($folder->create('foo' . DS . 'bar' . DS . 'baz' . DS . 'shoe' . DS . 'horn')) { - // As pastas aninhadas foram criadas com sucesso - } - -.. php:method:: delete(string $path = null) - - Remova diretórios recursivamente se o sistema permitir:: - - $folder = new Folder('foo'); - if ($folder->delete()) { - // Foo foi excluído com sucesso e também suas pastas aninhadas - } - -.. php:method:: dirsize() - - Retorna o tamanho em bytes desta pasta e seu conteúdo. - -.. php:method:: errors() - - Obtenha o erro do método mais recente. - -.. php:method:: find(string $regexpPattern = '.*', boolean $sort = false) - - Retorna uma matriz de todos os arquivos correspondentes no diretório atual:: - - // Encontre todos os .png em sua pasta webroot/img/ e classifique os resultados - $dir = new Folder(WWW_ROOT . 'img'); - $files = $dir->find('.*\.png', true); - /* - Array - ( - [0] => cake.icon.png - [1] => test-error-icon.png - [2] => test-fail-icon.png - [3] => test-pass-icon.png - [4] => test-skip-icon.png - ) - */ - -.. note:: - - Os métodos find e findRecursive da pasta só encontrarão arquivos. Se você - gostaria de obter pastas e arquivos, consulte :php:meth:`Folder::read()` ou - :php:meth:`Folder::tree()` - -.. php:method:: findRecursive(string $pattern = '.*', boolean $sort = false) - - Retorna uma matriz de todos os arquivos correspondentes dentro e abaixo do diretório atual:: - - // Encontre arquivos recursivamente começando com teste ou índice - $dir = new Folder(WWW_ROOT); - $files = $dir->findRecursive('(test|index).*'); - /* - Array - ( - [0] => /var/www/cake/webroot/index.php - [1] => /var/www/cake/webroot/test.php - [2] => /var/www/cake/webroot/img/test-skip-icon.png - [3] => /var/www/cake/webroot/img/test-fail-icon.png - [4] => /var/www/cake/webroot/img/test-error-icon.png - [5] => /var/www/cake/webroot/img/test-pass-icon.png - ) - */ - -.. php:method:: inCakePath(string $path = '') - - Retorna ``true`` se o arquivo está em um determinado CakePath. - -.. php:method:: inPath(string $path = '', boolean $reverse = false) - - Retorna ``true`` se o arquivo está no caminho fornecido:: - - $Folder = new Folder(WWW_ROOT); - $result = $Folder->inPath(APP); - // $result = false, /var/www/example/src/ não está em /var/www/example/webroot/ - - $result = $Folder->inPath(WWW_ROOT . 'img' . DS, true); - // $result = true, /var/www/example/webroot/img/ está em /var/www/example/webroot/ - -.. php:staticmethod:: isAbsolute(string $path) - - Retorna ``true`` se o $path fornecido for um caminho absoluto. - -.. php:staticmethod:: isSlashTerm(string $path) - - Retorna ``true`` se o $path termina em uma barra (ou seja, termina com uma barra):: - - $result = Folder::isSlashTerm('/my/test/path'); - // $result = false - $result = Folder::isSlashTerm('/my/test/path/'); - // $result = true - -.. php:staticmethod:: isWindowsPath(string $path) - - Retorna ``true`` se o $path fornecido for um caminho do Windows. - -.. php:method:: messages() - - Obtenha as mensagens do método mais recente. - -.. php:method:: move(array $options) - - Move recursivamente o diretório. - -.. php:staticmethod:: normalizeFullPath(string $path) - - Retorna um caminho com barras normalizadas para o sistema operacional. - -.. php:method:: pwd() - - Retorna o caminho atual - -.. php:method:: read(boolean $sort = true, array|boolean $exceptions = false, boolean $fullPath = false) - - Retorna uma matriz do conteúdo do diretório atual. A matriz retornada contém - duas submatrizes e uma de diretórios e uma de arquivos:: - - $dir = new Folder(WWW_ROOT); - $files = $dir->read(true, ['files', 'index.php']); - /* - Array - ( - [0] => Array // Folders - ( - [0] => css - [1] => img - [2] => js - ) - [1] => Array // Files - ( - [0] => .htaccess - [1] => favicon.ico - [2] => test.php - ) - ) - */ - -.. php:method:: realpath(string $path) - - Pegue o caminho real (levando ".." em consideração). - -.. php:staticmethod:: slashTerm(string $path) - - Retorna $path com barra de terminação adicionada (corrigido para - Windows ou outro sistema operacional). - -.. php:method:: tree(null|string $path = null, array|boolean $exceptions = true, null|string $type = null) - - Retorna uma matriz de diretórios e arquivos aninhados em cada diretório. - -API de Arquivos -=============== - -.. php:class:: File(string $path, boolean $create = false, integer $mode = 755) - -:: - - // Cria um novo arquivo com as permissões 0644 - $file = new File('/path/to/file.php', true, 0644); - -.. php:attr:: Folder - - O objeto Folder do arquivo. - -.. php:attr:: name - - O nome do arquivo com a extensão. É diferente de :php:meth:`File::name()` que retorna o nome sem a extensão. - -.. php:attr:: info - - Uma matriz de informações do arquivo. Ao invés disso use :php:meth:`File::info()`. - -.. php:attr:: handle - - Contém o recurso de manipulador de arquivo se o arquivo for aberto. - -.. php:attr:: lock - - Habilite o bloqueio para leitura e gravação de arquivos. - -.. php:attr:: path - - O caminho absoluto do arquivo atual. - -.. php:method:: append(string $data, boolean $force = false) - - Anexe a string de dados fornecida ao arquivo atual. - -.. php:method:: close() - - Fecha o arquivo atual se estiver aberto. - -.. php:method:: copy(string $dest, boolean $overwrite = true) - - Copie o arquivo para o caminho absoluto ``$dest``. - -.. php:method:: create() - - Cria o arquivo. - -.. php:method:: delete() - - Apaga o arquivo; - -.. php:method:: executable() - - Returna ``true`` se o arquivo for executável - -.. php:method:: exists() - - Retorna ``true`` se o arquivo existe. - -.. php:method:: ext() - - Retorna a extensão do arquivo. - -.. php:method:: Folder() - - Retorna a pasta atual. - -.. php:method:: group() - - Retorna o grupo do arquivo, ou ``false`` em caso de erro. - -.. php:method:: info() - - Retorna as informações do arquivo. - -.. php:method:: lastAccess( ) - - Retorna a hora do último acesso. - -.. php:method:: lastChange() - - Retorna a hora da última modificação ou ``false`` em caso de erro. - -.. php:method:: md5(integer|boolean $maxsize = 5) - - Obtenha o MD5 Checksum do arquivo com a verificação anterior do - tamanho do arquivo, ou ``false`` no caso de um erro. - -.. php:method:: name() - - Retorna o nome do arquivo sem extensão. - -.. php:method:: offset(integer|boolean $offset = false, integer $seek = 0) - - Define ou obtém o deslocamento do arquivo aberto no momento. - -.. php:method:: open(string $mode = 'r', boolean $force = false) - - Abre o arquivo atual com o $mode fornecido. - -.. php:method:: owner() - - Retorna o proprietário do arquivo. - -.. php:method:: perms() - - Retorna o "chmod" (permissões) do arquivo. - -.. php:staticmethod:: prepare(string $data, boolean $forceWindows = false) - - Prepara uma string ascii para escrita. Converte as terminações de linha no terminador - correto para a plataforma atual. Para Windows, será usado "\\r\\n", - para todas as outras plataformas "\\ n". - -.. php:method:: pwd() - - Retorna o caminho completo do arquivo. - -.. php:method:: read(string $bytes = false, string $mode = 'rb', boolean $force = false) - - Retorne o conteúdo do arquivo atual como uma string ou retorne ``false`` em caso de falha. - -.. php:method:: readable() - - Retorna ``true`` se o arquivo é legível. - -.. php:method:: safe(string $name = null, string $ext = null) - - Torna o nome do arquivo seguro para salvar. - -.. php:method:: size() - - Retorna o tamanho do arquivo em bytes. - -.. php:method:: writable() - - Retorna ``true`` se o arquivo for gravável. - -.. php:method:: write(string $data, string $mode = 'w', boolean$force = false) - - Grave os dados fornecidos no arquivo atual. - -.. php:method:: mime() - - Pega o tipo MIME do arquivo, retorna ``false`` em caso de falha. - -.. php:method:: replaceText( $search, $replace ) - - Substitui o texto em um arquivo. Retorna ``false`` em caso de falha e ``true`` em caso de sucesso. - -.. todo:: - - Explique melhor como usar cada método com ambas as classes. - -.. meta:: - :title lang=pt: Pasta & Arquivo - :description lang=pt: Os utilitários de pasta e arquivo são classes convenientes para ajudá-lo a ler, escrever e anexar a arquivos; listar arquivos dentro de uma pasta e outras tarefas comuns relacionadas ao diretório. - :keywords lang=pt: arquivo,pasta,utilitario cakephp,ler arquivo,escrever arquivo,anexar arquivo,copia recursiva,opcoes de copia,caminho de pasta,classe de pasta,arquivo php,mudar de diretorio,utilitario de arquivo,nova pasta,estrutura de diretorio,apagar arquivo diff --git a/pt/core-libraries/form.rst b/pt/core-libraries/form.rst index a51d5051c4..a624168a33 100644 --- a/pt/core-libraries/form.rst +++ b/pt/core-libraries/form.rst @@ -5,18 +5,18 @@ Formulários sem Models .. php:class:: Form -Muitas vezes você precisará ter formulários associados ao :doc:`ORM entities ` -e :doc:`ORM tables ` ou outras persistência de dados, -mas há vezes quando você precisará validar um campo de usuário e então realizar uma -ação se o dado é válido. O exemplo mais comum para esta situação é o formulário de contato. +Na maioria das vezes você terá formulários associados ao :doc:`ORM entities ` +e :doc:`ORM tables ` ou outras persistências de dados, +mas há vezes quando você precisará validar dados de usuário e então realizar uma +ação se os dados forem válidos. O exemplo mais comum para isto é um formulário de contato. Criando o Formulário ==================== -Geralmente quando se usa a classe Form será necessário utilizar uma sub-classe para definir -seu formulário. Isso facilita o teste, e permite o reuso do formulário. Formulários ficam dentro -de **src/Form** e comumente tem ``Form`` como sufixo da classe. Por exemplo, -um simples formulário de contato poderia ficar assim:: +Geralmente quando se usa a classe Form você vai querer usar uma sub-classe para definir +seu formulário. Isso facilita o teste, e permite reusar seu formulário. Formulários ficam dentro +de **src/Form** e comumente têm ``Form`` como sufixo da classe. Por exemplo, +um simples formulário de contato ficaria assim:: // em src/Form/ContactForm.php namespace App\Form; @@ -27,26 +27,22 @@ um simples formulário de contato poderia ficar assim:: class ContactForm extends Form { - - protected function _buildSchema(Schema $schema) + protected function _buildSchema(Schema $schema): Schema { return $schema->addField('name', 'string') ->addField('email', ['type' => 'string']) ->addField('body', ['type' => 'text']); } - protected function _buildValidator(Validator $validator) + public function validationDefault(Validator $validator): Validator { - return $validator->add('name', 'length', [ - 'rule' => ['minLength', 10], - 'message' => 'A name is required' - ])->add('email', 'format', [ - 'rule' => 'email', - 'message' => 'A valid email address is required', - ]); + $validator->minLength('name', 10) + ->email('email'); + + return $validator; } - protected function _execute(array $data) + protected function _execute(array $data): bool { // Envie um email. return true; @@ -57,20 +53,20 @@ No exemplo acima vemos os 3 métodos hooks que o formulário fornece: * ``_buildSchema`` é usado para definir o esquema de dados usado pelo FormHelper para criar um formulário HTML. Você pode definir o tipo de campo, tamanho, e precisão. -* ``_buildValidator`` Pega uma instância do :php:class:`Cake\\Validation\\Validator` - que você pode você juntar com os validadores. -* ``_execute`` permite definir o comportamento desejado quando o - ``execute()`` é chamado e o dado é válido. +* ``validationDefault`` Pega uma instância do :php:class:`Cake\\Validation\\Validator` + que você pode anexar validadores. +* ``_execute`` permite definir o comportamento que você deseja que aconteça quando + ``execute()`` é chamado e os dados são válidos. -Você sempre pode adicionar métodos públicos a sua maneira. +Você sempre pode definir métodos públicos adicionais conforme necessário também. -Processando Requisição de Dados -=============================== +Processando Dados de Requisição +================================ -Uma vez definido o formulário, é possível usá-lo em seu controller para processar -e validar os dados:: +Uma vez que você definiu seu formulário, é possível usá-lo em seu controller para processar +e validar os dados de requisição:: - // No Controller + // Em um controller namespace App\Controller; use App\Controller\AppController; @@ -83,27 +79,40 @@ e validar os dados:: $contact = new ContactForm(); if ($this->request->is('post')) { if ($contact->execute($this->request->getData())) { - $this->Flash->success('We will get back to you soon.'); + $this->Flash->success('Retornaremos o contato em breve.'); } else { - $this->Flash->error('There was a problem submitting your form.'); + $this->Flash->error('Houve um problema ao enviar seu formulário.'); } } $this->set('contact', $contact); } } -No exemplo acima, usamos o método ``execute()`` para chamar o nosso método -``_execute()`` do formulário apenas quando o dado é válido, e definimos as mensagens flash -adequadas. Poderíamos também ter usado o método ``validate()`` apenas para validar -a requisição de dados:: +No exemplo acima, usamos o método ``execute()`` para executar o método +``_execute()`` do nosso formulário apenas quando os dados são válidos, e definimos as mensagens flash +adequadas. Se quisermos usar um conjunto de validação não padrão, podemos usar a +opção ``validate``:: + + if ($contact->execute($this->request->getData(), 'update')) { + // Lidar com sucesso do formulário. + } + +Esta opção também pode ser definida como ``false`` para desabilitar a validação. + +Poderíamos também ter usado o método ``validate()`` apenas para validar +os dados de requisição:: $isValid = $form->validate($this->request->getData()); + // Você também pode usar outros conjuntos de validação. O seguinte + // usaria as regras definidas por `validationUpdate()` + $isValid = $form->validate($this->request->getData(), 'update'); + Definindo os Valores do Formulário -================================== +=================================== -Na sequência para definir os valores para os campos do formulário sem modelo, basta apenas definir -os valores usando ``$this->request->getData()``, como em todos os outros formulários criados pelo FormHelper:: +Você pode definir valores padrão para formulários sem models usando o método ``setData()``. +Valores definidos com este método sobrescreverão dados existentes no objeto de formulário:: // Em um controller namespace App\Controller; @@ -125,38 +134,57 @@ os valores usando ``$this->request->getData()``, como em todos os outros formul } if ($this->request->is('get')) { - //Values from the User Model e.g. - $this->request->getData('name', 'John Doe'); - $this->request->getData('email','john.doe@example.com'); + $contact->setData([ + 'name' => 'John Doe', + 'email' => 'john.doe@example.com' + ]); } $this->set('contact', $contact); } } -Valores devem apenas serem definidos se a requesição é do tipo GET, caso contrário -você sobreescreverá os dados anteriormente passados via POST que de certa forma -poderiam estar incorretos e não salvos. +Valores devem apenas ser definidos se o método de requisição é GET, caso contrário +você sobrescreverá seus dados POST anteriores que podem ter erros de validação +que precisam ser corrigidos. Você pode usar ``set()`` para adicionar ou substituir campos individuais +ou um subconjunto de campos:: -Pegando os Erros do Formulário -============================== + // Definir um campo. + $contact->set('name', 'John Doe'); + + // Definir múltiplos campos; + $contact->set([ + 'name' => 'John Doe', + 'email' => 'john.doe@example.com', + ]); + +Obtendo Erros do Formulário +============================ -Uma vez sido validado, o formulário pode recuperar seus próprios erros:: +Uma vez que um formulário foi validado, você pode recuperar os erros dele:: - $errors = $form->errors(); - /* $errors contains + $errors = $form->getErrors(); + /* $errors contém [ - 'email' => ['A valid email address is required'] + 'name' => ['length' => 'Nome deve ter pelo menos dois caracteres'], + 'email' => ['format' => 'Um endereço de email válido é necessário'], + ] + */ + + $error = $form->getError('email'); + /* $error contém + [ + 'format' => 'Um endereço de email válido é necessário', ] */ Invalidando Campos Individuais do Formulário no Controller -========================================================== +=========================================================== -É possível invalidar campos únicos do controller sem o uso da classe Validator. -O Uso mais comum neste caso é quando a validação -é feita no servidor remoto. Neste caso, você deve manualmente invalidar -os campos de acordo com a resposta do servidor:: +É possível invalidar campos individuais do controller sem o uso da classe Validator. +O uso mais comum para isto é quando a validação +é feita em um servidor remoto. Neste caso, você deve manualmente invalidar +os campos de acordo com o feedback do servidor remoto:: // em src/Form/ContactForm.php public function setErrors($errors) @@ -164,34 +192,33 @@ os campos de acordo com a resposta do servidor:: $this->_errors = $errors; } -Conforme como a classe validadora poderia ter retornado os erros, ``$errors`` +Conforme como a classe validadora teria retornado os erros, ``$errors`` deve estar neste formato:: - ["fieldName" => ["validatorName" => "The error message to display"]] + ['fieldName' => ['validatorName' => 'A mensagem de erro para exibir']] -Agora você pode invalidar os campos determinar o fieldName, e então +Agora você será capaz de invalidar campos do formulário definindo o fieldName, e então definir as mensagens de erro:: // Em um controller $contact = new ContactForm(); - $contact->setErrors(["email" => ["_required" => "Seu email é necessário"]]); + $contact->setErrors(['email' => ['_required' => 'Seu email é necessário']]); -Prossiga para Criação do HTML com o FormHelper para ver o resultado. +Prossiga para Criação do HTML com FormHelper para ver os resultados. Criando o HTML com FormHelper -============================= +============================== -Uma vez sido criado uma class Form, -Once you've created a Form class, você provavelmente vai querer criar um formulário -HTML para isso. FormHelper compreende objetos Form apenas como entidades ORM:: +Uma vez que você criou uma classe Form, você provavelmente vai querer criar um formulário +HTML para ela. FormHelper compreende objetos Form assim como entidades ORM:: echo $this->Form->create($contact); - echo $this->Form->input('name'); - echo $this->Form->input('email'); - echo $this->Form->input('body'); + echo $this->Form->control('name'); + echo $this->Form->control('email'); + echo $this->Form->control('body'); echo $this->Form->button('Submit'); echo $this->Form->end(); -O código acima criar um formulário HTML para o ``ContactForm`` definidos anteriormente. -Formulários HTML criados com FormHelper usará o esquema definido -e validador para determinar os tipos de campos, tamanhos máximos, e validação de erros. +O código acima criaria um formulário HTML para o ``ContactForm`` que definimos anteriormente. +Formulários HTML criados com FormHelper usarão o esquema definido e validador para +determinar os tipos de campos, tamanhos máximos, e erros de validação. diff --git a/pt/core-libraries/global-constants-and-functions.rst b/pt/core-libraries/global-constants-and-functions.rst index ec1507d453..1d84f6574c 100644 --- a/pt/core-libraries/global-constants-and-functions.rst +++ b/pt/core-libraries/global-constants-and-functions.rst @@ -1,203 +1,216 @@ Constantes e Funções #################### -A maior parte do seu trabalho diário com o CakePHP será feito utilizando classes -e métodos do *core*. O CakePHP disponibiliza funções -globais de conveniência que podem ajudar. Muitas dessas funções são usadas em -classes do CakePHP (carregando um *model* ou um *component*), mas outras tornam -mais fácil o trabalho de lidar com *arrays* ou *strings*. +Embora a maior parte do seu trabalho diário no CakePHP seja utilizando classes e +métodos principais, o CakePHP possui várias funções de conveniência globais que podem ser +úteis. Muitas dessas funções são para uso com classes do CakePHP (carregando +classes de modelo ou componente), mas muitas outras tornam o trabalho com arrays ou +strings um pouco mais fácil. -Nós também vamos cobrir algumas das constantes existentes em aplicações CakePHP. -Constantes essas, que facilitam *upgrades* e apontam convenientemente para -arquivos e diretórios chaves da sua aplicação. +Também cobriremos algumas das constantes disponíveis em aplicações CakePHP. Usar +essas constantes ajudará a tornar as atualizações mais suaves, mas também são +formas convenientes de apontar para certos arquivos ou diretórios em sua aplicação CakePHP. -Funções globais -=============== +Funções Globais +================ -Aqui estão as funções disponíveis globalmente no CakePHP. A maioria delas são -*wrappers* de conveniência para funcionalidades do CakePHP, como por exemplo, -*debug* e localização de conteúdo. +Aqui estão as funções globalmente disponíveis do CakePHP. A maioria delas são apenas +wrappers de conveniência para outras funcionalidades do CakePHP, como depuração e +tradução de conteúdo. Por padrão, apenas funções com namespace são carregadas automaticamente, +no entanto, você pode opcionalmente carregar aliases globais adicionando:: + + require CAKE . 'functions.php'; + +No arquivo ``config/bootstrap.php`` da sua aplicação. Fazer isso carregará aliases globais +para *todas* as funções listadas abaixo. + +.. php:namespace:: Cake\I18n .. php:function:: \_\_(string $string_id, [$formatArgs]) - Essa função lida com a localização da sua aplicação. O ``$string_id`` - identifica o ID usado para a tradução. *Strings* são tratadas seguindo o - formato usado no ``sprintf()``. Você pode fornecer argumentos adicionais - para substituir *placeholders* na sua string:: + Esta função lida com a localização em aplicações CakePHP. O + ``$string_id`` identifica o ID de uma tradução. Você pode fornecer + argumentos adicionais para substituir marcadores de posição em sua string:: + + __('You have {0} unread messages', $number); - __('Você tem {0} mensagens', $number); + Você também pode fornecer um array de substituições indexado por nome:: + + __('You have {unread} unread messages', ['unread' => $number]); .. note:: - Verifique a seção - :doc:`/core-libraries/internationalization-and-localization` para mais - informações. + + Confira a seção + :doc:`/core-libraries/internationalization-and-localization` para + mais informações. .. php:function:: __d(string $domain, string $msg, mixed $args = null) - Permite sobrescrever o domínio atual por uma mensagem simples. + Permite que você substitua o domínio atual para uma única pesquisa de mensagem. + + Útil ao internacionalizar um plugin: + ``echo __d('plugin_name', 'This is my plugin');`` + + .. note:: - Muito útil ao localizar um *plugin*: - ``echo __d('PluginName', 'Esse é meu plugin');`` + Certifique-se de usar a versão sublinhada do nome do plugin aqui como domínio. .. php:function:: __dn(string $domain, string $singular, string $plural, integer $count, mixed $args = null) - Permite sobrescrever o domínio atual por uma mensagem no plural. Retorna - a forma corrreta da mensagem no plural identificada por ``$singular`` e - ``$plural``, pelo contador ``$count`` e pelo domínio ``$domain``. + Permite que você substitua o domínio atual para uma única pesquisa de mensagem + no plural. Retorna a forma plural correta da mensagem identificada por ``$singular`` + e ``$plural`` para a contagem ``$count`` do domínio ``$domain``. .. php:function:: __dx(string $domain, string $context, string $msg, mixed $args = null) - Permite sobrescrever o domínio atual por uma mensagem simples. Também - permite a especificação de um contexto. + Permite que você substitua o domínio atual para uma única pesquisa de mensagem. Também + permite que você especifique um contexto. - O contexto é um identificador único para as *strings* de tradução que a - tornam únicas sob um mesmo domínio. + O contexto é um identificador único para a string de traduções que a torna + única dentro do mesmo domínio. .. php:function:: __dxn(string $domain, string $context, string $singular, string $plural, integer $count, mixed $args = null) - Permite sobrescrever o domínio atual por uma mensagem no plural. Também - permite a especificação de um contexto. Retorna a forma corrreta - da mensagem no plural identificada por ``$singular`` e - ``$plural``, pelo contador ``$count`` e pelo domínio ``$domain``. Alguns - idiomas tem mais de uma forma para o plural dependendo do contador. + Permite que você substitua o domínio atual para uma única pesquisa de mensagem + no plural. Também permite que você especifique um contexto. Retorna a forma plural + correta da mensagem identificada por ``$singular`` e ``$plural`` para a contagem + ``$count`` do domínio ``$domain``. Algumas línguas têm mais de uma forma + para mensagens no plural dependentes da contagem. - O contexto é um identificador único para as *strings* de tradução que a - tornam únicas sob um mesmo domínio. + O contexto é um identificador único para a string de traduções que a torna + única dentro do mesmo domínio. .. php:function:: __n(string $singular, string $plural, integer $count, mixed $args = null) - Retorna a forma corrreta da mensagem no plural identificada por - ``$singular`` e ``$plural``, pelo contador ``$count`` e pelo domínio - ``$domain``. Alguns idiomas tem mais de uma forma para o plural dependendo - do contador. + Retorna a forma plural correta da mensagem identificada por ``$singular`` e + ``$plural`` para a contagem ``$count``. Algumas línguas têm mais de uma forma para + mensagens no plural dependentes da contagem. .. php:function:: __x(string $context, string $msg, mixed $args = null) - O contexto é um identificador único para as *strings* de tradução que a - tornam únicas sob um mesmo domínio. + O contexto é um identificador único para a string de traduções que a torna + única dentro do mesmo domínio. .. php:function:: __xn(string $context, string $singular, string $plural, integer $count, mixed $args = null) - Retorna a forma corrreta da mensagem no plural identificada por - ``$singular`` e ``$plural``, pelo contador ``$count`` e pelo domínio - ``$domain``. Alguns idiomas tem mais de uma forma para o plural dependendo - do contador. + Retorna a forma plural correta da mensagem identificada por ``$singular`` e + ``$plural`` para a contagem ``$count`` do domínio ``$domain``. Também permite que você + especifique um contexto. Algumas línguas têm mais de uma forma para + mensagens no plural dependentes da contagem. + + O contexto é um identificador único para a string de traduções que a torna + única dentro do mesmo domínio. - O contexto é um identificador único para as *strings* de tradução que a - tornam únicas sob um mesmo domínio. +.. php:namespace:: Cake\Collection .. php:function:: collection(mixed $items) - *Wrapper* de conveniência para instanciar um novo objeto - :php:class:`Cake\\Collection\\Collection`, re-passando o devido argumento. - O parâmetro ``$items`` recebe tanto um objeto ``Traversable`` quanto um - *array*. + Wrapper de conveniência para instanciar um novo objeto :php:class:`Cake\\Collection\\Collection`, + envolvendo o argumento passado. O parâmetro ``$items`` aceita tanto + um objeto ``Traversable`` quanto um array. + +.. php:namespace:: Cake\Core .. php:function:: debug(mixed $var, boolean $showHtml = null, $showFrom = true) - .. versionchanged:: 3.3.0 - Esse método retorna a ``$var`` passada para que você possa, por - instância, colocá-la em uma declaração de retorno. + Se a variável ``$debug`` do núcleo for ``true``, ``$var`` é impresso. + Se ``$showHTML`` for ``true`` ou deixado como ``null``, os dados são renderizados para serem + amigáveis ao navegador. Se ``$showFrom`` não for definido como ``false``, a saída de depuração + começará com a linha de onde foi chamada. Veja também + :doc:`/development/debugging` - Se a variável do core ``$debug`` for ``true``, ``$var`` será imprimida. - Se ``$showHTML`` for ``true``, ou for deixada como ``null`` os dados serão - renderizados formatados para melhor exibição em navegadores. Se - ``$showFrom`` não for definida como ``false``, o *debug* começará a partir - da linha em que foi chamado. Também veja :doc:`/development/debugging` +.. php:function:: dd(mixed $var, boolean $showHtml = null) -.. php:function:: pr(mixed $var) + Comporta-se como ``debug()``, mas a execução também é interrompida. + Se a variável ``$debug`` do núcleo for ``true``, ``$var`` é impresso. + Se ``$showHTML`` for ``true`` ou deixado como ``null``, os dados são renderizados para serem + amigáveis ao navegador. Veja também :doc:`/development/debugging` - .. versionchanged:: 3.3.0 - Chamar esse método vai retornar a ``$var`` passada, então, você pode, - por instância, colocá-la em uma declaração de retorno. +.. php:function:: pr(mixed $var) - *Wrapper* de conveniência para ``print_r()`` com a adição das *tags* - ``
`` ao redor da saída.
+    Wrapper de conveniência para ``print_r()``, com a adição de
+    envolver tags ``
`` ao redor da saída.
 
 .. php:function:: pj(mixed $var)
 
-    .. versionchanged:: 3.3.0
-        Chamar esse método vai retornar a ``$var`` passada, então, você pode,
-        por instância, colocá-la em uma declaração de retorno.
-
-    Função de conveniência para formatação de JSON, com a adição das *tags*
-    ``
`` ao redor da saída.
+    Função de conveniência para impressão bonita de JSON, com a adição de
+    envolver tags ``
`` ao redor da saída.
 
-    Deve ser usada com o intuito de *debugar* JSON de objetos e *arrays*.
+    É destinada para depurar a representação JSON de objetos e arrays.
 
 .. php:function:: env(string $key, string $default = null)
 
-    .. versionchanged:: 3.1.1
-        O parâmetro ``$default`` será adicionado.
+    Obtém uma variável de ambiente de fontes disponíveis. Usada como backup se
+    ``$_SERVER`` ou ``$_ENV`` estiverem desabilitadas.
 
-    Recebe uma variável de ambiente de fontes disponíveis. Usada como *backup*
-    se ``$_SERVER`` ou ``$_ENV`` estiverem desabilitados.
-
-    Essa função também emula ``PHP_SELF`` e ``DOCUMENT_ROOT`` em servidores
-    não suportados. De fato, é sempre uma boa ideia usar ``env()`` ao invés de
-    ``$_SERVER``ou ``getenv()`` (especialmente se você planeja distribuir o
-    código), pois é um *wrapper* completo de emulação.
+    Esta função também emula ``PHP_SELF`` e ``DOCUMENT_ROOT`` em
+    servidores sem suporte. Na verdade, é uma boa ideia sempre usar ``env()``
+    em vez de ``$_SERVER`` ou ``getenv()`` (especialmente se você planeja
+    distribuir o código), já que é um wrapper de emulação completo.
 
 .. php:function:: h(string $text, boolean $double = true, string $charset = null)
 
-    *Wrapper* de conveniência para ``htmlspecialchars()``.
+    Wrapper de conveniência para ``htmlspecialchars()``.
 
 .. php:function:: pluginSplit(string $name, boolean $dotAppend = false, string $plugin = null)
 
-    Divide um nome de plugin que segue o padrão de sintaxe de pontos e o
-    transforma em um nome de classe ou do *plugin*. Se ``$name`` não tem um
-    ponto, então o índice 0 será ``null``.
+    Divide um nome de plugin com sintaxe de ponto em seu plugin e nome de classe. Se ``$name``
+    não tiver um ponto, então o índice 0 será ``null``.
 
-    Comumente usada assim: ``list($plugin, $name) = pluginSplit('Users.User');``
+    Comumente usado como ``list($plugin, $name) = pluginSplit('Users.User');``
 
 .. php:function:: namespaceSplit(string $class)
 
-    Divide o *namespace* do nome da classe.
+    Divide o namespace do nome da classe.
 
-    Comumente usada assim: ``list($namespace, $className) = namespaceSplit('Cake\Core\App');``
+    Comumente usado como ``list($namespace, $className) = namespaceSplit('Cake\Core\App');``
 
-Constantes de definição do Core
-===============================
+Constantes de Definição do Núcleo
+==================================
 
-A maior parte das constantes a seguir referem-se a caminhos da sua aplicação.
+A maioria das seguintes constantes se refere a caminhos em sua aplicação.
 
 .. php:const:: APP
 
-    Caminho absoluto para o diretório de sua aplicação, incluindo a barra final.
+   Caminho absoluto para o diretório da sua aplicação, incluindo uma barra final.
 
 .. php:const:: APP_DIR
 
-    Igual a ``app`` ou ao nome do diretório de sua aplicação.
+    Igual a ``app`` ou o nome do diretório da sua aplicação.
 
 .. php:const:: CACHE
 
-    Caminho para o diretório de arquivos de cache. Pode ser compartilhado entre
-    hosts em uma configuração multi-servidores.
+    Caminho para o diretório de arquivos de cache. Pode ser compartilhado entre hosts em uma
+    configuração multi-servidor.
 
 .. php:const:: CAKE
 
-    Caminho para o diretório do CakePHP.
+    Caminho para o diretório cake.
 
 .. php:const:: CAKE_CORE_INCLUDE_PATH
 
-    Caminho para o diretório raiz de bibliotecas.
+    Caminho para o diretório lib raiz.
 
 .. php:const:: CONFIG
 
-    Caminho para o diretório de configurações.
+   Caminho para o diretório config.
 
 .. php:const:: CORE_PATH
 
-    Caminho para o diretório raiz com contra-barra no final.
+   Caminho para o diretório CakePHP com barra de diretório final.
 
 .. php:const:: DS
 
-    Atalho para o ``DIRECTORY_SEPARATOR`` do PHP, que é ``/`` no Linux e ``\\``
+    Abreviação para ``DIRECTORY_SEPARATOR`` do PHP, que é ``/`` no Linux e ``\``
     no Windows.
 
 .. php:const:: LOGS
 
-    Caminho para o diretório de logs.
+    Caminho para o diretório logs.
+
+.. php:const:: RESOURCES
+
+   Caminho para o diretório resources.
 
 .. php:const:: ROOT
 
@@ -205,51 +218,23 @@ A maior parte das constantes a seguir referem-se a caminhos da sua aplicação.
 
 .. php:const:: TESTS
 
-    Caminho para o diretório de testes.
+    Caminho para o diretório tests.
 
 .. php:const:: TMP
 
     Caminho para o diretório de arquivos temporários.
 
-.. php:const:: WWW\_ROOT
+.. php:const:: WWW_ROOT
 
-    Caminho completo para o diretório webroot.
+    Caminho completo para o webroot.
 
-Constantes de definição de tempo
-================================
+Constantes de Definição de Tempo
+=================================
 
 .. php:const:: TIME_START
 
-    Timestamp unix em microsegundos como *float* de quando a aplicação começou.
-
-.. php:const:: SECOND
-
-    Igual a 1
-
-.. php:const:: MINUTE
-
-    Igual a 60
-
-.. php:const:: HOUR
-
-    Igual a 3600
-
-.. php:const:: DAY
-
-    Igual a 86400
-
-.. php:const:: WEEK
-
-    Igual a 604800
-
-.. php:const:: MONTH
-
-    Igual a 2592000
-
-.. php:const:: YEAR
-
-    Igual a 31536000
+    Timestamp Unix em microssegundos como um float de quando a aplicação iniciou.
 
 .. meta::
-    :title lang=pt: Constantes globais e funções
-    :keywords lang=pt: constantes,funções,internacionalização,diretórios,caminhos
+    :title lang=pt: Constantes e Funções Globais
+    :keywords lang=pt: internacionalização e localização,constantes globais,exemplo config,array php,funções de conveniência,bibliotecas do núcleo,classes de componente,número opcional,funções globais,string string,classes do núcleo,strings de formato,mensagens não lidas,marcadores de posição,funções úteis,arrays,parâmetros,existência,traduções
diff --git a/pt/core-libraries/hash.rst b/pt/core-libraries/hash.rst
index 356c82fd3e..fcbfe2b947 100644
--- a/pt/core-libraries/hash.rst
+++ b/pt/core-libraries/hash.rst
@@ -5,94 +5,95 @@ Hash
 
 .. php:class:: Hash
 
-O gerenciamento de matrizes, se feito da maneira certa, pode ser uma 
-ferramenta muito poderosa e útil para construir um código mais inteligente 
-e otimizado. O CakePHP oferece um conjunto muito útil de utilitários estáticos 
-na classe Hash que permitem que você faça exatamente isso.
+O gerenciamento de arrays, se feito corretamente, pode ser uma ferramenta muito poderosa e útil
+para construir código mais inteligente e otimizado. O CakePHP oferece um
+conjunto muito útil de utilitários estáticos na classe Hash que permitem fazer
+exatamente isso.
 
-A classe Hash do CakePHP pode ser chamada de qualquer template ou controlador da 
-mesma forma que o Inflector é chamado. Exemplo: :php:meth:`Hash::combine()`.
+A classe Hash do CakePHP pode ser chamada de qualquer model ou controller da
+mesma forma que Inflector é chamado. Exemplo: :php:meth:`Hash::combine()`.
 
 .. _hash-path-syntax:
 
-Sintaxe do Caminho de Hash
-==========================
+Sintaxe de Caminho do Hash
+===========================
 
-A sintaxe de caminho descrita abaixo é usada por todos os métodos em ``Hash``. 
-Nem todas as partes da sintaxe do caminho estão disponíveis em todos os métodos. 
-Uma expressão de caminho é feita de qualquer número de tokens. Os tokens são compostos 
-por dois grupos. Expressões são usadas para percorrer os dados da matriz, enquanto as
-expressões são usadas para qualificar elementos.
+A sintaxe de caminho descrita abaixo é usada por todos os métodos em ``Hash``. Nem todas
+as partes da sintaxe de caminho estão disponíveis em todos os métodos. Uma expressão de caminho é
+composta por qualquer número de tokens. Tokens são compostos de dois grupos. Expressões
+são usadas para atravessar os dados do array, enquanto matchers são usados para qualificar
+elementos. Você aplica matchers a elementos de expressão.
 
 Tipos de Expressão
-------------------
+-------------------
 
 +--------------------------------+--------------------------------------------+
 | Expressão                      | Definição                                  |
 +================================+============================================+
 | ``{n}``                        | Representa uma chave numérica. Irá         |
-|                                | corresponder a qualquer string ou chave    |
-|                                | numérica                                   |
+|                                | corresponder qualquer chave string ou      |
+|                                | numérica.                                  |
 +--------------------------------+--------------------------------------------+
-| ``{s}``                        | Representa uma string. Irá corresponder a  |
-|                                | qualquer valor de string, incluindo        |
-|                                | valores de string numéricos.               |
+| ``{s}``                        | Representa uma string. Irá corresponder    |
+|                                | qualquer valor string incluindo valores de |
+|                                | string numéricos.                          |
 +--------------------------------+--------------------------------------------+
-| ``{*}``                        | Corresponde a qualquer valor.              |
+| ``{*}``                        | Corresponde qualquer valor.                |
 +--------------------------------+--------------------------------------------+
-| ``Foo``                        | Corresponde às chaves exatamente com o     |
-|                                | mesmo valor.                               |
+| ``Foo``                        | Corresponde chaves com exatamente o mesmo  |
+|                                | valor.                                     |
 +--------------------------------+--------------------------------------------+
 
-Todos os elementos de expressão são suportados por todos os métodos. Além de 
-elementos de expressão, você pode usar a correspondência de atributos com certos 
-métodos. Eles são: ``extract()``, ``combine()``, ``format()``, ``check()``, ``map()``, ``reduce()``,
+Todos os elementos de expressão são suportados por todos os métodos. Além dos elementos de expressão,
+você pode usar correspondência de atributos com certos métodos. Eles são ``extract()``,
+``combine()``, ``format()``, ``check()``, ``map()``, ``reduce()``,
 ``apply()``, ``sort()``, ``insert()``, ``remove()`` e ``nest()``.
 
 Tipos de Correspondência de Atributos
--------------------------------------
+--------------------------------------
 
 +--------------------------------+--------------------------------------------+
-| Expressão                      | Definição                                  |
+| Matcher                        | Definição                                  |
 +================================+============================================+
-| ``[id]``                       | Combine elementos com uma determinada      |
+| ``[id]``                       | Corresponde elementos com uma determinada  |
 |                                | chave de array.                            |
 +--------------------------------+--------------------------------------------+
-| ``[id=2]``                     | Combine elementos com id igual a 2.        |
+| ``[id=2]``                     | Corresponde elementos com id igual a 2.    |
 +--------------------------------+--------------------------------------------+
-| ``[id!=2]``                    | Combine elementos com id diferente de 2.   |
+| ``[id!=2]``                    | Corresponde elementos com id diferente     |
+|                                | de 2.                                      |
 +--------------------------------+--------------------------------------------+
-| ``[id>2]``                     | Combine elementos com id maior que 2.      |
+| ``[id>2]``                     | Corresponde elementos com id maior que 2.  |
 +--------------------------------+--------------------------------------------+
-| ``[id>=2]``                    | Combine elementos com id maior ou          |
+| ``[id>=2]``                    | Corresponde elementos com id maior ou      |
 |                                | igual a 2.                                 |
 +--------------------------------+--------------------------------------------+
-| ``[id<2]``                     | Combine elementos com id menor que 2       |
+| ``[id<2]``                     | Corresponde elementos com id menor que 2   |
 +--------------------------------+--------------------------------------------+
-| ``[id<=2]``                    | Combine elementos com id menor ou          |
+| ``[id<=2]``                    | Corresponde elementos com id menor ou      |
 |                                | igual a 2.                                 |
 +--------------------------------+--------------------------------------------+
-| ``[text=/.../]``               | Combine elementos que possuem valores      |
-|                                | correspondentes à expressão regular        |
-|                                | dentro de ``...``.                         |
+| ``[text=/.../]``               | Corresponde elementos que têm valores      |
+|                                | correspondentes à expressão regular dentro |
+|                                | de ``...``.                                |
 +--------------------------------+--------------------------------------------+
 
 .. php:staticmethod:: get(array|\ArrayAccess $data, $path, $default = null)
 
-    ``get()`` é uma versão simplificada de ``extract()``, ele só suporta expressões 
-    de caminho direto. Caminhos como ``{n}``, ``{s}``, ``{*}`` ou expressões não 
-    são suportados. Use ``get()`` quando quiser exatamente um valor de uma matriz. 
-    Se um caminho correspondente não for encontrado, o valor padrão será retornado.
+    ``get()`` é uma versão simplificada de ``extract()``, suporta apenas
+    expressões de caminho direto. Caminhos com ``{n}``, ``{s}``, ``{*}`` ou matchers não são
+    suportados. Use ``get()`` quando você deseja exatamente um valor de um array. Se
+    um caminho correspondente não for encontrado, o valor padrão será retornado.
 
 .. php:staticmethod:: extract(array|\ArrayAccess $data, $path)
 
-    ``Hash::extract()`` suporta todas as expressões e componentes de correspondência 
-    :ref:`hash-path-syntax`. Você pode usar a extração para recuperar dados de matrizes
-    ou objetos que implementam a interface ``ArrayAccess``, ao longo de caminhos arbitrários 
-    rapidamente, sem ter que percorrer as estruturas de dados. Em vez disso, você usa expressões 
-    de caminho para qualificar quais elementos você deseja que sejam retornados::
+    ``Hash::extract()`` suporta todos os componentes de expressão e matcher de
+    :ref:`hash-path-syntax`. Você pode usar extract para recuperar dados de arrays
+    ou objetos que implementam a interface ``ArrayAccess``, ao longo de caminhos arbitrários
+    rapidamente sem ter que fazer loop pelas estruturas de dados. Em vez disso, você
+    usa expressões de caminho para qualificar quais elementos você deseja retornados::
 
-        // Uso comum:
+        // Uso Comum:
         $users = [
             ['id' => 1, 'name' => 'mark'],
             ['id' => 2, 'name' => 'jane'],
@@ -105,13 +106,13 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: Hash::insert(array $data, $path, $values = null)
 
-    Insere ``$values`` em uma matriz conforme definido por ``$path``::
+    Insere ``$values`` em um array conforme definido por ``$path``::
 
         $a = [
             'pages' => ['name' => 'page']
         ];
         $result = Hash::insert($a, 'files', ['name' => 'files']);
-        // $result agora parece:
+        // $result agora parece com:
         [
             [pages] => [
                 [name] => page
@@ -121,11 +122,12 @@ Tipos de Correspondência de Atributos
             ]
         ]
 
-    Você pode usar caminhos usando ``{n}``, ``{s}`` e ``{*}`` para inserir dados em vários pontos::
+    Você pode usar caminhos usando ``{n}``, ``{s}`` e ``{*}`` para inserir dados em múltiplos
+    pontos::
 
         $users = Hash::insert($users, '{n}.new', 'value');
 
-    As expressões de atributos funcionam com ``insert()`` também::
+    Matchers de atributos também funcionam com ``insert()``::
 
         $data = [
             0 => ['up' => true, 'Item' => ['id' => 1, 'title' => 'first']],
@@ -135,7 +137,7 @@ Tipos de Correspondência de Atributos
             4 => ['Item' => ['id' => 5, 'title' => 'fifth']],
         ];
         $result = Hash::insert($data, '{n}[up].Item[id=4].new', 9);
-        /* $result agora se parece:
+        /* $result agora parece com:
             [
                 ['up' => true, 'Item' => ['id' => 1, 'title' => 'first']],
                 ['Item' => ['id' => 2, 'title' => 'second']],
@@ -147,14 +149,14 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: remove(array $data, $path)
 
-    Remove todos os elementos de uma matriz que corresponde a ``$path``. ::
+    Remove todos os elementos de um array que correspondem a ``$path``. ::
 
         $a = [
             'pages' => ['name' => 'page'],
             'files' => ['name' => 'files']
         ];
         $result = Hash::remove($a, 'files');
-        /* $result agora se parece:
+        /* $result agora parece com:
             [
                 [pages] => [
                     [name] => page
@@ -163,8 +165,8 @@ Tipos de Correspondência de Atributos
             ]
         */
 
-    Usando ``{n}``, ``{s}`` e ``{*}`` permitirá que você remova múltiplos valores 
-    de uma vez. Você também pode usar expressões de atributo com ``remove()``::
+    Usar ``{n}``, ``{s}`` e ``{*}`` permitirá que você remova vários valores de uma vez.
+    Você também pode usar matchers de atributos com ``remove()``::
 
         $data = [
             0 => ['clear' => true, 'Item' => ['id' => 1, 'title' => 'first']],
@@ -174,7 +176,7 @@ Tipos de Correspondência de Atributos
             4 => ['Item' => ['id' => 5, 'title' => 'fifth']],
         ];
         $result = Hash::remove($data, '{n}[clear].Item[id=4]');
-        /* $result agora se parece:
+        /* $result agora parece com:
             [
                 ['clear' => true, 'Item' => ['id' => 1, 'title' => 'first']],
                 ['Item' => ['id' => 2, 'title' => 'second']],
@@ -186,11 +188,11 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: combine(array $data, $keyPath, $valuePath = null, $groupPath = null)
 
-    Cria uma matriz associativa usando um ``$keyPath`` como o caminho para construir 
-    suas chaves, e opcionalmente ``$valuePath`` como o caminho para obter os valores. 
-    Se ``$valuePath`` não for especificado, ou não corresponder a nada, os valores 
-    serão inicializados como nulos. Você pode opcionalmente agrupar os valores pelo 
-    que é obtido ao seguir o caminho especificado em ``$groupPath``.::
+    Cria um array associativo usando um ``$keyPath`` como o caminho para construir suas chaves,
+    e opcionalmente ``$valuePath`` como caminho para obter os valores. Se ``$valuePath`` não for
+    especificado, ou não corresponder a nada, os valores serão inicializados como null.
+    Você pode opcionalmente agrupar os valores pelo que é obtido ao seguir o
+    caminho especificado em ``$groupPath``. ::
 
         $a = [
             [
@@ -216,7 +218,7 @@ Tipos de Correspondência de Atributos
         ];
 
         $result = Hash::combine($a, '{n}.User.id');
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [2] =>
                 [14] =>
@@ -224,7 +226,7 @@ Tipos de Correspondência de Atributos
         */
 
         $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.user');
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [2] => 'mariano.iglesias'
                 [14] => 'phpnut'
@@ -232,7 +234,7 @@ Tipos de Correspondência de Atributos
         */
 
         $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data');
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [2] => [
                         [user] => mariano.iglesias
@@ -246,7 +248,7 @@ Tipos de Correspondência de Atributos
         */
 
         $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name');
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [2] => Mariano Iglesias
                 [14] => Larry E. Masters
@@ -254,7 +256,7 @@ Tipos de Correspondência de Atributos
         */
 
         $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data', '{n}.User.group_id');
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [1] => [
                         [2] => [
@@ -272,7 +274,7 @@ Tipos de Correspondência de Atributos
         */
 
         $result = Hash::combine($a, '{n}.User.id', '{n}.User.Data.name', '{n}.User.group_id');
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [1] => [
                         [2] => Mariano Iglesias
@@ -283,17 +285,17 @@ Tipos de Correspondência de Atributos
             ]
         */
 
-        // A partir de 3.9.0 $keyPath pode ser nulo 
+        // A partir da versão 3.9.0 $keyPath pode ser null
         $result = Hash::combine($a, null, '{n}.User.Data.name');
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [0] => Mariano Iglesias
                 [1] => Larry E. Masters
             ]
         */
 
-    Você pode fornecer matrizes para ``$keyPath`` e ``$valuePath``. Se você fizer isso, 
-    o primeiro valor será usado com o formato de string, para valores extraídos por 
+    Você pode fornecer arrays para ambos ``$keyPath`` e ``$valuePath``. Se você fizer isso,
+    o primeiro valor será usado como uma string de formato, para valores extraídos pelos
     outros caminhos::
 
         $result = Hash::combine(
@@ -302,7 +304,7 @@ Tipos de Correspondência de Atributos
             ['%s: %s', '{n}.User.Data.user', '{n}.User.Data.name'],
             '{n}.User.group_id'
         );
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [1] => [
                         [2] => mariano.iglesias: Mariano Iglesias
@@ -318,7 +320,7 @@ Tipos de Correspondência de Atributos
             ['%s: %s', '{n}.User.Data.user', '{n}.User.Data.name'],
             '{n}.User.id'
         );
-        /* $result agora se parece com:
+        /* $result agora parece com:
             [
                 [mariano.iglesias: Mariano Iglesias] => 2
                 [phpnut: Larry E. Masters] => 14
@@ -327,8 +329,8 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: format(array $data, array $paths, $format)
 
-    Retorna uma série de valores extraídos de uma matriz, formatados 
-    com uma string::
+    Retorna uma série de valores extraídos de um array, formatados com uma
+    string de formato::
 
         $data = [
             [
@@ -380,7 +382,8 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: contains(array $data, array $needle)
 
-    Determina se um Hash ou matriz contém as chaves e valores exatos de outro::
+    Determina se um Hash ou array contém as chaves e valores exatos
+    de outro::
 
         $a = [
             0 => ['name' => 'main'],
@@ -390,7 +393,7 @@ Tipos de Correspondência de Atributos
             0 => ['name' => 'main'],
             1 => ['name' => 'about'],
             2 => ['name' => 'contact'],
-            'a' => 'b'
+            'a' => 'b',
         ];
 
         $result = Hash::contains($a, $a);
@@ -402,7 +405,7 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: check(array $data, string $path = null)
 
-    Verifica se um determinado caminho está definido em uma matriz::
+    Verifica se um caminho específico está definido em um array::
 
         $set = [
             'My Index 1' => ['First' => 'The first item']
@@ -438,10 +441,9 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: filter(array $data, $callback = ['Hash', 'filter'])
 
-    Filtra os elementos vazios da matriz, excluindo '0'. Você também pode 
-    fornecer um ``$callback`` personalizado para filtrar os elementos da matriz. 
-    O retorno de chamada deve retornar ``false`` para remover elementos da matriz
-    resultante::
+    Filtra elementos vazios do array, excluindo '0'. Você também pode fornecer um
+    ``$callback`` personalizado para filtrar os elementos do array. O callback deve
+    retornar ``false`` para remover elementos do array resultante::
 
         $data = [
             '0',
@@ -452,7 +454,7 @@ Tipos de Correspondência de Atributos
         ];
         $res = Hash::filter($data);
 
-        /* $res agora se parece:
+        /* $res agora parece com:
             [
                 [0] => 0
                 [2] => true
@@ -467,7 +469,7 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: flatten(array $data, string $separator = '.')
 
-    Nivela uma matriz multidimensional em uma única dimensão::
+    Colapsa um array multidimensional em uma única dimensão::
 
         $arr = [
             [
@@ -480,7 +482,7 @@ Tipos de Correspondência de Atributos
             ],
         ];
         $res = Hash::flatten($arr);
-        /* $res now looks like:
+        /* $res agora parece com:
             [
                 [0.Post.id] => 1
                 [0.Post.title] => First Post
@@ -495,7 +497,7 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: expand(array $data, string $separator = '.')
 
-    Expande uma matriz que foi previamente achatada com 
+    Expande um array que foi previamente achatado com
     :php:meth:`Hash::flatten()`::
 
         $data = [
@@ -509,7 +511,7 @@ Tipos de Correspondência de Atributos
             '1.Author.user' => Crystal,
         ];
         $res = Hash::expand($data);
-        /* $res agora se parece com:
+        /* $res agora parece com:
         [
             [
                 'Post' => ['id' => '1', 'title' => 'First Post'],
@@ -524,16 +526,16 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: merge(array $data, array $merge[, array $n])
 
-    Esta função pode ser considerada um híbrido entre ``array_merge`` e 
-    ``array_merge_recursive`` do PHP. A diferença entre as duas é que se 
-    uma chave da matriz contém outra matriz, então a função se comporta 
-    recursivamente (ao contrário de ``array_merge``), mas não se comporta 
-    do mesmo jeito para chaves contendo strings (ao contrário de ``array_merge_recursive``).
+    Esta função pode ser pensada como um híbrido entre
+    ``array_merge`` e ``array_merge_recursive`` do PHP. A diferença para os dois
+    é que se uma chave de array contiver outro array, então a função
+    se comporta recursivamente (ao contrário de ``array_merge``), mas não faz isso para chaves
+    contendo strings (ao contrário de ``array_merge_recursive``).
 
     .. note::
 
-        Esta função funcionará com uma quantidade ilimitada de argumentos 
-        e casting de parâmetros primitivos para matrizes.
+        Esta função funcionará com uma quantidade ilimitada de argumentos e
+        converte parâmetros não-array em arrays.
 
     ::
 
@@ -541,7 +543,7 @@ Tipos de Correspondência de Atributos
             [
                 'id' => '48c2570e-dfa8-4c32-a35e-0d71cbdd56cb',
                 'name' => 'mysql raleigh-workshop-08 < 2008-09-05.sql ',
-                'description' => 'Importing an sql dump'
+                'description' => 'Importing an sql dump',
             ],
             [
                 'id' => '48c257a8-cf7c-4af2-ac2f-114ecbdd56cb',
@@ -554,7 +556,7 @@ Tipos de Correspondência de Atributos
         $arrayD = ["cats" => "felines", "dog" => "angry"];
         $res = Hash::merge($array, $arrayB, $arrayC, $arrayD);
 
-        /* $res agora se parece com:
+        /* $res agora parece com:
         [
             [0] => [
                     [id] => 48c2570e-dfa8-4c32-a35e-0d71cbdd56cb
@@ -576,7 +578,7 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: numeric(array $data)
 
-    Verifica se todos os valores da matriz são numéricas::
+    Verifica se todos os valores no array são numéricos::
 
         $data = ['one'];
         $res = Hash::numeric(array_keys($data));
@@ -588,8 +590,8 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: dimensions (array $data)
 
-    Conta as dimensões de uma matriz. Este método irá considerar 
-    apenas a dimensão do primeiro elemento na matriz::
+    Conta as dimensões de um array. Este método considerará apenas
+    a dimensão do primeiro elemento no array::
 
         $data = ['one', '2', 'three'];
         $result = Hash::dimensions($data);
@@ -613,8 +615,8 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: maxDimensions(array $data)
 
-    Semelhante a :php:meth:`~Hash::dimensions()`, no entanto, este método 
-    retorna, o maior número de dimensões de qualquer elemento na matriz::
+    Semelhante a :php:meth:`~Hash::dimensions()`, porém este método retorna
+    o número mais profundo de dimensões de qualquer elemento no array::
 
         $data = ['1' => '1.1', '2', '3' => ['3.1' => '3.1.1']];
         $result = Hash::maxDimensions($data);
@@ -626,29 +628,29 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: map(array $data, $path, $function)
 
-    Cria uma nova matriz, extraindo ``$path``, e mapeando ``$function`` nos 
-    resultados. Você pode usar expressões e elementos correspondentes com este método::
+    Cria um novo array, extraindo ``$path`` e mapeando ``$function``
+    através dos resultados. Você pode usar elementos de expressão e correspondência com
+    este método::
 
-        // Chame a função noop $this->noop() em cada elemento de $data
+        // Chama a função noop $this->noop() em cada elemento de $data
         $result = Hash::map($data, "{n}", [$this, 'noop']);
 
         public function noop(array $array)
         {
-            // Faça coisas para a matriz e retorne o resultado
+            // Faça algo com o array e retorne o resultado
             return $array;
         }
 
 .. php:staticmethod:: reduce(array $data, $path, $function)
 
-    Cria um único valor, extraindo ``$path``, e reduzindo os resultados extraídos 
-    com ``$function``. Você pode usar expressões e elementos correspondentes com 
-    este método.
+    Cria um único valor, extraindo ``$path`` e reduzindo os resultados extraídos
+    com ``$function``. Você pode usar elementos de expressão e correspondência
+    com este método.
 
 .. php:staticmethod:: apply(array $data, $path, $function)
 
-    Aplique um retorno de chamada a um conjunto de valores extraídos 
-    usando ``$function``. A função obterá os valores extraídos do 
-    primeiro argumento::
+    Aplica um callback a um conjunto de valores extraídos usando ``$function``. A função
+    receberá os valores extraídos como o primeiro argumento::
 
         $data = [
             ['date' => '01-01-2016', 'booked' => true],
@@ -665,8 +667,8 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: sort(array $data, $path, $dir, $type = 'regular')
 
-    Classifica uma matriz por qualquer valor, determinado por :ref:`hash-path-syntax`
-    Somente elementos de expressão são suportados por este método::
+    Ordena um array por qualquer valor, determinado por uma :ref:`hash-path-syntax`
+    Apenas elementos de expressão são suportados por este método::
 
         $a = [
             0 => ['Person' => ['name' => 'Jeff']],
@@ -688,18 +690,18 @@ Tipos de Correspondência de Atributos
             ]
         */
 
-    ``$dir`` pode ser ``asc`` ou ``desc``. ``$type`` pode 
-    ser um dos seguintes valores:
+    ``$dir`` pode ser ``asc`` ou ``desc``. ``$type``
+    pode ser um dos seguintes valores:
 
-    * ``regular`` para ordenamento padrão
-    * ``numeric`` para classificar valores como seus equivalentes numéricos.
-    * ``string`` para classificar valores como seu valor de string.
-    * ``natural`` para classificar valores de uma forma amigável ao humano. 
-      Classificará ``foo10`` abaixo de ``foo2`` por exemplo.
+    * ``regular`` para ordenação regular.
+    * ``numeric`` para ordenar valores como seus equivalentes numéricos.
+    * ``string`` para ordenar valores como seu valor de string.
+    * ``natural`` para ordenar valores de forma amigável ao usuário. Irá
+      ordenar ``foo10`` abaixo de ``foo2`` como exemplo.
 
 .. php:staticmethod:: diff(array $data, array $compare)
 
-    Calcula a diferença entre duas matrizes::
+    Calcula a diferença entre dois arrays::
 
         $a = [
             0 => ['name' => 'main'],
@@ -722,8 +724,8 @@ Tipos de Correspondência de Atributos
 
 .. php:staticmethod:: mergeDiff(array $data, array $compare)
 
-    Essa função mescla duas matrizes e empurra as diferenças nos 
-    dados para a parte inferior da matriz resultante.
+    Esta função mescla dois arrays e empurra as diferenças nos
+    dados para o final do array resultante.
 
     **Exemplo 1**
     ::
@@ -762,12 +764,12 @@ Tipos de Correspondência de Atributos
             ]
         */
 
-.. php:staticmethod:: normalize(array $data, $assoc = true)
+.. php:staticmethod:: normalize(array $data, $assoc = true, $default = null)
 
-    Normaliza uma matriz. Se ``$assoc`` for ``true``, a matriz resultante 
-    será normalizada para ser uma matriz associativa. Chaves numéricas com 
-    valores serão convertidas em chaves de string com valores nulos. Normalizar 
-    uma matriz torna o uso dos resultados com :php:meth:`Hash::merge()` mais fácil::
+    Normaliza um array. Se ``$assoc`` for ``true``, o array resultante será
+    normalizado para ser um array associativo. Chaves numéricas com valores serão
+    convertidas em chaves string com valores ``$default``. Normalizar um array
+    torna o uso dos resultados com :php:meth:`Hash::merge()` mais fácil::
 
         $a = ['Tree', 'CounterCache',
             'Upload' => [
@@ -795,7 +797,7 @@ Tipos de Correspondência de Atributos
             'Limit',
             'Bindable',
             'Validator',
-            'Transactional'
+            'Transactional',
         ];
         $result = Hash::normalize($b);
         /* $result agora parece com:
@@ -811,21 +813,24 @@ Tipos de Correspondência de Atributos
             ]
         */
 
+.. versionchanged:: 4.5.0
+    O parâmetro ``$default`` foi adicionado.
+
 .. php:staticmethod:: nest(array $data, array $options = [])
 
-    Pega um conjunto de matriz simples e cria uma estrutura de dados aninhada ou encadeada.
+    Pega um conjunto de array plano e cria uma estrutura de dados aninhada ou encadeada.
 
     **Opções:**
 
-    - ``children`` O nome da chave a ser usada no conjunto de resultados para 
-      os valores aninhados. O padrão é 'children'.
-    - ``idPath`` O caminho para uma chave que identifica cada entrada. Deve ser compatível 
-      com :php:meth:`Hash::extract()`. O padrão é ``{n}.$alias.id``
-    - ``parentPath`` O caminho para uma chave que identifica o pai de cada entrada. Deve ser compatível com 
-      :php:meth:`Hash::extract()`. O padrão é ``{n}.$alias.parent_id``
-    - ``root`` O id do resultado desejado mais alto.
+    - ``children`` O nome da chave a ser usado no conjunto de resultados para filhos. Padrão
+      é 'children'.
+    - ``idPath`` O caminho para uma chave que identifica cada entrada. Deve ser
+      compatível com :php:meth:`Hash::extract()`. Padrão é ``{n}.$alias.id``
+    - ``parentPath`` O caminho para uma chave que identifica o pai de cada entrada.
+      Deve ser compatível com :php:meth:`Hash::extract()`. Padrão é ``{n}.$alias.parent_id``
+    - ``root`` O id do resultado de nível superior desejado.
 
-    Por exemplo, se você tivesse a seguinte matriz de dados::
+    Por exemplo, se você tivesse o seguinte array de dados::
 
         $data = [
             ['ThreadPost' => ['id' => 1, 'parent_id' => null]],
@@ -884,4 +889,4 @@ Tipos de Correspondência de Atributos
 
 .. meta::
     :title lang=pt: Hash
-    :keywords lang=pt: matriz matriz,caminho de matriz,nome da matriz,chave numerica,expressao regular,configuracao de resultado,nome de pessoas,brackets,sintaxe,cakephp,elementos,php,definir caminho
+    :keywords lang=pt: array array,path array,array name,chave numérica,expressão regular,conjunto de resultados,nome de pessoa,colchetes,sintaxe,cakephp,elementos,php,definir caminho
diff --git a/pt/core-libraries/httpclient.rst b/pt/core-libraries/httpclient.rst
index 3b7bc2c66a..1928f94bb4 100644
--- a/pt/core-libraries/httpclient.rst
+++ b/pt/core-libraries/httpclient.rst
@@ -1,18 +1,18 @@
-Cliente Http
+Cliente HTTP
 ############
 
 .. php:namespace:: Cake\Http
 
 .. php:class:: Client(mixed $config = [])
 
-O CakePHP inclui um cliente HTTP compatível com a PSR-18 que pode ser usado
-para fazer solicitações. É uma ótima maneira de se comunicar com serviços da web e
+O CakePHP inclui um cliente HTTP compatível com PSR-18 que pode ser usado para
+fazer requisições. É uma ótima maneira de se comunicar com webservices e
 APIs remotas.
 
-Fazendo Solicitações
-====================
+Fazendo Requisições
+===================
 
-Fazer solicitações é simples e direto. Fazer uma solicitação GET parece::
+Fazer requisições é simples e direto. Fazer uma requisição GET é assim::
 
     use Cake\Http\Client;
 
@@ -24,24 +24,24 @@ Fazer solicitações é simples e direto. Fazer uma solicitação GET parece::
     // GET simples com querystring
     $response = $http->get('http://example.com/search', ['q' => 'widget']);
 
-    // GET simples com querystring & cabeçalhos adicionais
+    // GET simples com querystring e cabeçalhos adicionais
     $response = $http->get('http://example.com/search', ['q' => 'widget'], [
-      'headers' => ['X-Requested-With' => 'XMLHttpRequest']
+      'headers' => ['X-Requested-With' => 'XMLHttpRequest'],
     ]);
 
-Fazer solicitações POST e PUT é igualmente simples::
+Fazer requisições POST e PUT é igualmente simples::
 
-    // Envie uma solicitação POST com dados codificados em application/x-www-form-urlencoded
+    // Enviar uma requisição POST com dados codificados em application/x-www-form-urlencoded
     $http = new Client();
     $response = $http->post('http://example.com/posts/add', [
       'title' => 'testing',
-      'body' => 'content in the post'
+      'body' => 'content in the post',
     ]);
 
-    // Envie uma solicitação PUT com dados codificados application/x-www-form-urlencoded
+    // Enviar uma requisição PUT com dados codificados em application/x-www-form-urlencoded
     $response = $http->put('http://example.com/posts/add', [
       'title' => 'testing',
-      'body' => 'content in the post'
+      'body' => 'content in the post',
     ]);
 
     // Outros métodos também.
@@ -49,7 +49,7 @@ Fazer solicitações POST e PUT é igualmente simples::
     $http->head(/* ... */);
     $http->patch(/* ... */);
 
-Se você criou um objeto de solicitação PSR-7, pode enviá-lo usando
+Se você criou um objeto de requisição PSR-7, pode enviá-lo usando
 ``sendRequest()``::
 
     use Cake\Http\Client;
@@ -59,58 +59,58 @@ Se você criou um objeto de solicitação PSR-7, pode enviá-lo usando
         'http://example.com/search',
         ClientRequest::METHOD_GET
     );
-    $client = new Client();
-    $response = $client->sendRequest($request);
+    $http = new Client();
+    $response = $http->sendRequest($request);
 
-Criação de Solicitações Multipart com Arquivos
-==============================================
+Criando Requisições Multipart com Arquivos
+===========================================
 
-Você pode incluir arquivos em corpos de solicitação::
+Você pode incluir arquivos nos corpos das requisições incluindo um filehandle no array::
 
     $http = new Client();
     $response = $http->post('http://example.com/api', [
       'image' => fopen('/path/to/a/file', 'r'),
     ]);
 
-O arquivo será lido até o fim; não será rebobinado antes de ser lido.
+O filehandle será lido até o final; ele não será rebobinado antes de ser lido.
 
-Criação de Corpos de Solicitação de Várias Partes Manualmente
--------------------------------------------------------------
+Construindo Corpos de Requisição Multipart
+-------------------------------------------
 
-Pode haver momentos em que você precise criar um corpo de solicitação de
-uma maneira muito específica. Nessas situações, você pode frequentemente usar
-``Cake\Http\Client\FormData`` para criar a solicitação HTTP multipart que você deseja::
+Pode haver momentos em que você precise construir um corpo de requisição de uma maneira muito específica.
+Nessas situações, você pode frequentemente usar ``Cake\Http\Client\FormData`` para criar
+a requisição HTTP multipart específica que você deseja::
 
     use Cake\Http\Client\FormData;
 
     $data = new FormData();
 
-    // Crie uma parte XML
+    // Criar uma parte XML
     $xml = $data->newPart('xml', $xmlString);
-    // Defina o tipo de conteúdo.
+    // Definir o tipo de conteúdo.
     $xml->type('application/xml');
     $data->add($xml);
 
-    // Crie um upload de arquivo com addFile()
-    // Isso irá anexar o arquivo aos dados do formulário também.
+    // Criar um upload de arquivo com addFile()
+    // Isso também adicionará o arquivo aos dados do formulário.
     $file = $data->addFile('upload', fopen('/some/file.txt', 'r'));
     $file->contentId('abc123');
     $file->disposition('attachment');
 
-    // Envie a solicitação.
+    // Enviar a requisição.
     $response = $http->post(
         'http://example.com/api',
         (string)$data,
         ['headers' => ['Content-Type' => $data->contentType()]]
     );
 
-Enviando o Corpo da Solicitação
-===============================
+Enviando Corpos de Requisição
+==============================
 
-Ao lidar com APIs REST, você geralmente precisa enviar corpos de solicitação que
-não são codificados por formulário. Http\\Cliente expõe isso através da opção de tipo::
+Ao lidar com APIs REST, você frequentemente precisa enviar corpos de requisição que não são
+codificados como formulário. Http\\Client expõe isso através da opção type::
 
-    // Envie um corpo de solicitação JSON.
+    // Enviar um corpo de requisição JSON.
     $http = new Client();
     $response = $http->post(
       'http://example.com/tasks',
@@ -119,11 +119,11 @@ não são codificados por formulário. Http\\Cliente expõe isso através da op
     );
 
 A chave ``type`` pode ser 'json', 'xml' ou um tipo MIME completo.
-Ao usar a opção ``type``, você deve fornecer os dados como uma string.
-Se você estiver fazendo uma solicitação GET que precisa de parâmetros de
-string de consulta e um corpo de solicitação, você pode fazer o seguinte::
+Ao usar a opção ``type``, você deve fornecer os dados como uma string. Se você estiver
+fazendo uma requisição GET que precisa de parâmetros de querystring e de um corpo de requisição,
+você pode fazer o seguinte::
 
-    // Envie um corpo JSON em uma solicitação GET com parâmetros de string de consulta.
+    // Enviar um corpo JSON em uma requisição GET com parâmetros de query string.
     $http = new Client();
     $response = $http->get(
       'http://example.com/tasks',
@@ -133,150 +133,170 @@ string de consulta e um corpo de solicitação, você pode fazer o seguinte::
 
 .. _http_client_request_options:
 
-Opções de Método para Solicitação
-=================================
-
-Cada método HTTP leva um parâmetro ``$options`` que é usado para fornecer informações
-adicionais de solicitação. As seguintes chaves podem ser usadas em ``$options``:
-
-- ``headers`` - Matriz de cabeçalhos adicionais
-- ``cookie`` - Matriz de cookies para usar.
-- ``proxy`` - Matriz de informações do proxy.
-- ``auth`` - Matriz de dados de autenticação, a chave ``type`` é usada para delegar a uma estratégia
-  de autenticação. Por padrão, a autenticação básica é usada.
-- ``ssl_verify_peer`` - o padrão é ``true``. Defina como ``false`` para desativar a
-  verificação de certificação SSL (não recomendado).
-- ``ssl_verify_peer_name`` - o padrão é ``true``. Defina como ``false`` para desabilitar a verificação do nome
-  do host ao verificar os certificados SSL (não recomendado).
-- ``ssl_verify_depth`` - o padrão é 5. Profundidade a ser percorrida na cadeia de CA.
-- ``ssl_verify_host`` - o padrão é ``true``. Valide o certificado SSL em relação ao nome do host.
-- ``ssl_cafile`` - o padrão é construído em cafile. Substitua para usar pacotes CA personalizados.
-- ``timeout`` - Duração de espera antes de expirar em segundos.
-- ``type`` - Envie um corpo de solicitação em um tipo de conteúdo personalizado. Requer que ``$data``
-  seja uma string ou que a opção ``_content`` seja definida ao fazer solicitações GET.
-- ``redirect`` - Número de redirecionamentos a seguir. O padrão é ``false``.
-
-O parâmetro options é sempre o terceiro parâmetro em cada um dos métodos HTTP.
-Eles também podem ser usados ao construir ``Client`` para criar :ref:`scoped clients `.
+Opções de Método de Requisição
+===============================
+
+Cada método HTTP recebe um parâmetro ``$options`` que é usado para fornecer
+informações adicionais de requisição. As seguintes chaves podem ser usadas em ``$options``:
+
+- ``headers`` - Array de cabeçalhos adicionais
+- ``cookie`` - Array de cookies a usar.
+- ``proxy`` - Array de informações de proxy.
+- ``auth`` - Array de dados de autenticação, a chave ``type`` é usada para delegar a
+  uma estratégia de autenticação. Por padrão, a autenticação básica é usada.
+- ``ssl_verify_peer`` - padrão é ``true``. Defina como ``false`` para desabilitar a verificação de
+  certificação SSL (não recomendado).
+- ``ssl_verify_peer_name`` - padrão é ``true``. Defina como ``false`` para desabilitar
+  a verificação do nome do host ao verificar certificados SSL (não recomendado).
+- ``ssl_verify_depth`` - padrão é 5. Profundidade para percorrer na cadeia de CA.
+- ``ssl_verify_host`` - padrão é ``true``. Validar o certificado SSL contra o nome do host.
+- ``ssl_cafile`` - padrão é o cafile integrado. Sobrescrever para usar pacotes de CA personalizados.
+- ``timeout`` - Duração a esperar antes de expirar em segundos.
+- ``type`` - Enviar um corpo de requisição em um tipo de conteúdo personalizado. Requer que ``$data`` seja
+  uma string, ou que a opção ``_content`` seja definida ao fazer requisições GET.
+- ``redirect`` - Número de redirecionamentos a seguir. Padrão é ``false``.
+- ``curl`` - Um array de opções adicionais do curl (se o adaptador curl for usado),
+  por exemplo, ``[CURLOPT_SSLKEY => 'key.pem']``.
+
+O parâmetro options é sempre o 3º parâmetro em cada um dos métodos HTTP.
+Eles também podem ser usados ao construir ``Client`` para criar
+:ref:`clientes com escopo `.
 
 Autenticação
 ============
 
-``Cake\Http\Client`` suporta alguns sistemas de autenticação. Diferentes
-estratégias de autenticação podem ser adicionadas pelos desenvolvedores.
-As estratégias de autenticação são chamadas antes do envio da solicitação
-e permitem que cabeçalhos sejam adicionados ao contexto da solicitação.
+``Cake\Http\Client`` suporta alguns sistemas de autenticação diferentes. Diferentes
+estratégias de autenticação podem ser adicionadas por desenvolvedores. As estratégias de autenticação são chamadas
+antes do envio da requisição e permitem que cabeçalhos sejam adicionados ao
+contexto da requisição.
 
 Usando Autenticação Básica
---------------------------
+---------------------------
 
 Um exemplo de autenticação básica::
 
     $http = new Client();
     $response = $http->get('http://example.com/profile/1', [], [
-      'auth' => ['username' => 'mark', 'password' => 'secret']
+      'auth' => ['username' => 'mark', 'password' => 'secret'],
     ]);
 
-Por padrão, o ``Cake\Http\Client`` usará a autenticação básica se não
-houver uma chave ``'type'`` na opção auth.
+Por padrão, ``Cake\Http\Client`` usará autenticação básica se não houver
+chave ``'type'`` na opção auth.
 
-Usando a Autenticação Digest
-----------------------------
+Usando Autenticação Digest
+---------------------------
 
-Um exemplo de autenticação básica::
+Um exemplo de autenticação digest::
 
     $http = new Client();
     $response = $http->get('http://example.com/profile/1', [], [
-      'auth' => [
-        'type' => 'digest',
-        'username' => 'mark',
-        'password' => 'secret',
-        'realm' => 'myrealm',
-        'nonce' => 'onetimevalue',
-        'qop' => 1,
-        'opaque' => 'someval'
-      ]
+        'auth' => [
+            'type' => 'digest',
+            'username' => 'mark',
+            'password' => 'secret',
+            'realm' => 'myrealm',
+            'nonce' => 'onetimevalue',
+            'qop' => 1,
+            'opaque' => 'someval',
+        ],
     ]);
 
-Ao definir a chave 'type' como 'digest', você informa ao subsistema de autenticação
-para usar a autenticação digest.
+Ao definir a chave 'type' como 'digest', você informa ao subsistema de autenticação para
+usar autenticação digest. A autenticação digest suporta os seguintes
+algoritmos:
+
+* MD5
+* SHA-256
+* SHA-512-256
+* MD5-sess
+* SHA-256-sess
+* SHA-512-256-sess
+
+O algoritmo será escolhido automaticamente com base no desafio do servidor.
 
 Autenticação OAuth 1
---------------------
+---------------------
 
-Muitos serviços da web moderna exigem autenticação OAuth para acessar suas APIs.
-A autenticação OAuth incluída pressupõe que você já tenha sua chave e segredo do
-consumidor::
+Muitos webservices modernos exigem autenticação OAuth para acessar suas APIs.
+A autenticação OAuth incluída assume que você já tem sua chave de consumidor
+e segredo de consumidor::
 
     $http = new Client();
     $response = $http->get('http://example.com/profile/1', [], [
-      'auth' => [
-        'type' => 'oauth',
-        'consumerKey' => 'bigkey',
-        'consumerSecret' => 'secret',
-        'token' => '...',
-        'tokenSecret' => '...',
-        'realm' => 'tickets',
-      ]
+        'auth' => [
+            'type' => 'oauth',
+            'consumerKey' => 'bigkey',
+            'consumerSecret' => 'secret',
+            'token' => '...',
+            'tokenSecret' => '...',
+            'realm' => 'tickets',
+        ],
     ]);
 
 Autenticação OAuth 2
---------------------
+---------------------
 
-Como OAuth2 geralmente é um único cabeçalho, não há um adaptador de
-autenticação especializado. Em vez disso, você pode criar um cliente
-com o token de acesso::
+Como OAuth2 é frequentemente um único cabeçalho, não há um adaptador de
+autenticação especializado. Em vez disso, você pode criar um cliente com o token de acesso::
 
     $http = new Client([
-        'headers' => ['Authorization' => 'Bearer ' . $accessToken]
+        'headers' => ['Authorization' => 'Bearer ' . $accessToken],
     ]);
     $response = $http->get('https://example.com/api/profile/1');
 
-Autenticação no Proxy
----------------------
+Autenticação de Proxy
+----------------------
 
-Alguns proxies requerem autenticação para serem usados. Geralmente, essa
-autenticação é Básica, mas pode ser implementada por qualquer adaptador
-de autenticação. Por padrão, o Http\\Client assumirá a autenticação Básica,
-a menos que a chave de tipo seja definida::
+Alguns proxies exigem autenticação para usá-los. Geralmente, essa autenticação
+é básica, mas pode ser implementada por qualquer adaptador de autenticação. Por padrão,
+Http\\Client assumirá autenticação básica, a menos que a chave type seja definida::
 
     $http = new Client();
     $response = $http->get('http://example.com/test.php', [], [
-      'proxy' => [
-        'username' => 'mark',
-        'password' => 'testing',
-        'proxy' => '127.0.0.1:8080',
-      ]
+        'proxy' => [
+            'username' => 'mark',
+            'password' => 'testing',
+            'proxy' => '127.0.0.1:8080',
+        ],
     ]);
 
-O segundo parâmetro de proxy deve ser uma string com um IP ou um domínio
-sem protocolo. As informações de nome de usuário e senha serão passadas
-pelos cabeçalhos da solicitação, enquanto a string do proxy será passada
-por `stream_context_create()
+O segundo parâmetro proxy deve ser uma string com um IP ou um domínio sem
+protocolo. As informações de nome de usuário e senha serão passadas através dos
+cabeçalhos da requisição, enquanto a string proxy será passada através de
+`stream_context_create()
 `_.
 
 .. _http_client_scoped_client:
 
-Criação de Clientes com Escopo
-==============================
+Criando Clientes com Escopo
+============================
 
-Ter que redigitar o nome de domínio, as configurações de autenticação e
-proxy pode se tornar tedioso e sujeito a erros. Para reduzir a chance de
-erro e aliviar um pouco do tédio, você pode criar clientes com escopo::
+Ter que redigitar o nome de domínio, autenticação e configurações de proxy pode se tornar
+tedioso e propenso a erros. Para reduzir a chance de erro e aliviar parte do
+tédio, você pode criar clientes com escopo::
 
-    // Crie um cliente com escopo definido.
+    // Criar um cliente com escopo.
     $http = new Client([
-      'host' => 'api.example.com',
-      'scheme' => 'https',
-      'auth' => ['username' => 'mark', 'password' => 'testing']
+        'host' => 'api.example.com',
+        'scheme' => 'https',
+        'auth' => ['username' => 'mark', 'password' => 'testing'],
     ]);
 
-    // Faça uma solicitação para api.example.com
+    // Fazer uma requisição para api.example.com
     $response = $http->get('/test.php');
 
+Se seu cliente com escopo precisa apenas de informações da URL, você pode usar
+``createFromUrl()``::
+
+    $http = Client::createFromUrl('https://api.example.com/v1/test');
+
+O código acima criaria uma instância de cliente com as opções ``protocol``, ``host`` e
+``basePath`` definidas.
+
 As seguintes informações podem ser usadas ao criar um cliente com escopo:
 
 * host
+* basePath
 * scheme
 * proxy
 * auth
@@ -287,48 +307,47 @@ As seguintes informações podem ser usadas ao criar um cliente com escopo:
 * ssl_verify_depth
 * ssl_verify_host
 
-Qualquer uma dessas opções pode ser substituída, especificando-as ao fazer
-solicitações. host, scheme, proxy, port são substituídos no URL do pedido::
+Qualquer uma dessas opções pode ser sobrescrita especificando-as ao fazer requisições.
+host, scheme, proxy, port são sobrescritos na URL da requisição::
 
-    // Usando o cliente com escopo criado anteriormente.
+    // Usando o cliente com escopo que criamos anteriormente.
     $response = $http->get('http://foo.com/test.php');
 
-O exemplo acima irá substituir o domínio, esquema e porta. No entanto, essa solicitação
-continuará usando todas as outras opções definidas quando o cliente com escopo foi criado.
-Veja :ref:`http_client_request_options` para mais informações sobre as opções suportadas.
+O código acima substituirá o domínio, esquema e porta. No entanto, esta requisição continuará
+usando todas as outras opções definidas quando o cliente com escopo foi criado.
+Veja :ref:`http_client_request_options` para mais informações sobre as opções
+suportadas.
 
-Configuração e Gerenciamento de Cookies
-=======================================
+Definindo e Gerenciando Cookies
+================================
 
-Http\\Client também pode aceitar cookies ao fazer solicitações.
-Além de aceitar cookies, ele também armazenará automaticamente
-cookies válidos definidos nas respostas. Qualquer resposta com
-cookies, os terá armazenados na instância de origem do Http\\Client.
-Os cookies armazenados em uma instância do cliente são incluídos
-automaticamente em solicitações futuras para combinações de
-domínio + caminho que corresponderem::
+Http\\Client também pode aceitar cookies ao fazer requisições. Além de
+aceitar cookies, ele também armazenará automaticamente cookies válidos definidos nas
+respostas. Qualquer resposta com cookies os armazenará na instância
+de origem do Http\\Client. Os cookies armazenados em uma instância de Client são
+automaticamente incluídos em requisições futuras para combinações de domínio + caminho que
+correspondam::
 
     $http = new Client([
         'host' => 'cakephp.org'
     ]);
 
-    // Faça uma solicitação que defina alguns cookies
+    // Fazer uma requisição que define alguns cookies
     $response = $http->get('/');
 
-    // Os cookies da primeira solicitação serão incluídos
+    // Os cookies da primeira requisição serão incluídos
     // por padrão.
     $response2 = $http->get('/changelogs');
 
-Você sempre pode substituir os cookies incluídos automaticamente,
-definindo-os nos parâmetros ``$options`` da solicitação::
+Você sempre pode sobrescrever os cookies incluídos automaticamente definindo-os nos
+parâmetros ``$options`` da requisição::
 
-    // Substitua um cookie armazenado por um valor personalizado.
+    // Substituir um cookie armazenado com um valor personalizado.
     $response = $http->get('/changelogs', [], [
-        'cookies' => ['sessionid' => '123abc']
+        'cookies' => ['sessionid' => '123abc'],
     ]);
 
-Você pode adicionar objetos de cookie ao cliente após criá-lo
-usando o método ``addCookie()``::
+Você pode adicionar objetos de cookie ao cliente após criá-lo usando o método ``addCookie()``::
 
     use Cake\Http\Cookie\Cookie;
 
@@ -337,6 +356,17 @@ usando o método ``addCookie()``::
     ]);
     $http->addCookie(new Cookie('session', 'abc123'));
 
+Eventos do Cliente
+==================
+
+``Client`` emitirá eventos quando requisições forem enviadas. O evento
+``HttpClient.beforeSend`` é disparado antes que uma requisição seja enviada, e
+``HttpClient.afterSend`` é disparado após uma requisição ser enviada. Você pode modificar a
+requisição ou definir uma resposta em um listener ``beforeSend``. O evento ``afterSend``
+é disparado para todas as requisições, mesmo aquelas que tiveram suas respostas definidas por
+um evento ``beforeSend``.
+
+
 .. _httpclient-response-objects:
 
 Objetos de Resposta
@@ -346,88 +376,86 @@ Objetos de Resposta
 
 .. php:class:: Response
 
-Os objetos de resposta têm vários métodos para inspecionar os dados recebidos.
+Os objetos de resposta têm vários métodos para inspecionar os dados da resposta.
 
-Leitura do Corpo da Resposta
-----------------------------
+Lendo Corpos de Resposta
+-------------------------
 
 Você lê todo o corpo da resposta como uma string::
 
-    // Leia toda a resposta como uma string.
+    // Ler toda a resposta como uma string.
     $response->getStringBody();
 
-Você também pode acessar o objeto stream para a resposta e usar seus métodos::
+Você também pode acessar o objeto stream da resposta e usar seus métodos::
 
-    // Obtêm um Psr\Http\Message\StreamInterface contendo o corpo da resposta
+    // Obter um Psr\Http\Message\StreamInterface contendo o corpo da resposta
     $stream = $response->getBody();
 
-    // Leia um fluxo de 100 bytes por vez.
+    // Ler um stream de 100 bytes por vez.
     while (!$stream->eof()) {
         echo $stream->read(100);
     }
 
 .. _http-client-xml-json:
 
-Lendo Corpo de Respostas JSON e XML
------------------------------------
+Lendo Corpos de Resposta JSON e XML
+------------------------------------
 
-Como as respostas JSON e XML são comumente usadas, os objetos de resposta
-fornecem acessores fáceis de usar para ler dados decodificados. Os dados
-JSON são decodificados em uma matriz, enquanto os dados XML são decodificados
-em uma árvore ``SimpleXMLElement``::
+Como respostas JSON e XML são comumente usadas, objetos de resposta fornecem uma maneira
+de usar acessores para ler dados decodificados. Dados JSON são decodificados em um array, enquanto
+dados XML são decodificados em uma árvore ``SimpleXMLElement``::
 
-    // Obtêm algum XML
+    // Obter algum XML
     $http = new Client();
     $response = $http->get('http://example.com/test.xml');
     $xml = $response->getXml();
 
-    // Obtêm algum JSON
+    // Obter algum JSON
     $http = new Client();
     $response = $http->get('http://example.com/test.json');
     $json = $response->getJson();
 
-Os dados de resposta decodificados são armazenados no objeto de resposta,
-portanto, acessá-lo várias vezes não tem custo adicional.
+Os dados de resposta decodificados são armazenados no objeto de resposta, então acessá-los
+várias vezes não tem custo adicional.
 
-Acessando Cabeçalhos da Resposta
---------------------------------
+Acessando Cabeçalhos de Resposta
+---------------------------------
 
-Você pode acessar os cabeçalhos por meio de alguns métodos diferentes. Os nomes
-dos cabeçalhos são sempre tratados como valores que não diferenciam maiúsculas
-de minúsculas ao acessá-los por meio de métodos::
+Você pode acessar cabeçalhos através de alguns métodos diferentes. Os nomes dos cabeçalhos são sempre
+tratados como valores não sensíveis a maiúsculas/minúsculas ao acessá-los através de métodos::
 
-    // Obtenha todos os cabeçalhos como uma matriz associativa.
+    // Obter todos os cabeçalhos como um array associativo.
     $response->getHeaders();
 
-    // Obtenha um único cabeçalho como uma matriz.
+    // Obter um único cabeçalho como um array.
     $response->getHeader('content-type');
 
-    // Obtenha um cabeçalho como uma string
+    // Obter um cabeçalho como uma string
     $response->getHeaderLine('content-type');
 
-    // Obtenha a codificação da resposta
+    // Obter a codificação da resposta
     $response->getEncoding();
 
-Acessando Dados do Cookie
--------------------------
+Acessando Dados de Cookie
+--------------------------
 
-Você pode ler os cookies com alguns métodos diferentes,
-dependendo de quantos dados você precisa sobre os cookies::
+Você pode ler cookies com alguns métodos diferentes, dependendo de quanto
+dado você precisa sobre os cookies::
 
-    // Obtenha todos os cookies (dados completos)
+    // Obter todos os cookies (dados completos)
     $response->getCookies();
 
-    // Obtenha o valor de um único cookie.
+    // Obter o valor de um único cookie.
     $response->getCookie('session_id');
 
-    // Obtenha os dados completos para um único cookie,
-    // incluindo valor, expiração, caminho, httponly, chaves seguras.
+    // Obter os dados completos de um único cookie
+    // inclui as chaves value, expires, path, httponly, secure.
     $response->getCookieData('session_id');
 
 Verificando o Código de Status
-------------------------------
+-------------------------------
 
-Os objetos de resposta fornecem alguns métodos para verificar os códigos de status::
+Objetos de resposta fornecem alguns métodos para verificar códigos de status::
 
     // A resposta foi 20x
     $response->isOk();
@@ -435,21 +463,129 @@ Os objetos de resposta fornecem alguns métodos para verificar os códigos de st
     // A resposta foi 30x
     $response->isRedirect();
 
-    // Obtenha o código de status
+    // Obter o código de status
     $response->getStatusCode();
 
-Alteração de Adaptadores de Transporte
-======================================
+Alterando Adaptadores de Transporte
+====================================
 
-Por padrão, o ``Http\Client`` irá preferir usar um adaptador de transporte
-baseado em ``curl``. Se a extensão curl não estiver disponível, um adaptador
-baseado em fluxo será usado. Você pode forçar a seleção de um adaptador de
-transporte usando uma opção de construtor::
+Por padrão, ``Http\Client`` preferirá usar um adaptador de transporte baseado em ``curl``.
+Se a extensão curl não estiver disponível, um adaptador baseado em stream será usado
+em vez disso. Você pode forçar a seleção de um adaptador de transporte usando uma opção de construtor::
 
     use Cake\Http\Client\Adapter\Stream;
 
-    $client = new Client(['adapter' => Stream::class]);
+    $http = new Client(['adapter' => Stream::class]);
+
+Eventos
+=======
+
+O cliente HTTP dispara alguns eventos antes e depois de enviar uma requisição
+que permitem modificar a requisição ou resposta ou fazer outras tarefas como
+cache, registro, etc.
+
+HttpClient.beforeSend
+---------------------
+
+::
+
+    // Em algum lugar antes de chamar um dos métodos do cliente HTTP que faz uma requisição
+    $http->getEventManager()->on(
+        'HttpClient.beforeSend',
+        function (
+            \Cake\Http\Client\ClientEvent $event,
+            \Cake\Http\Client\Request $request,
+            array $adapterOptions,
+            int $redirects
+        ) {
+            // Modificar a requisição
+            $event->setRequest(....);
+            // Modificar as opções do adaptador
+            $event->setAdapterOptions(....);
+
+            // Pular a requisição real retornando uma resposta.
+            // Você pode usar $event->setResult($response) para obter o mesmo resultado.
+            return new \Cake\Http\Client\Response(body: 'something');
+        }
+    );
+
+HttpClient.afterSend
+--------------------
+
+::
+
+    // Em algum lugar antes de chamar um dos métodos do cliente HTTP que faz uma requisição
+    $http->getEventManager()->on(
+        'HttpClient.afterSend',
+        function (
+            \Cake\Http\Client\ClientEvent $event,
+            \Cake\Http\Client\Request $request,
+            array $adapterOptions,
+            int $redirects,
+            bool $requestSent // Indica se a requisição foi realmente enviada
+                              // ou resposta retornada do evento ``beforeSend``
+        ) {
+            // Obter a resposta
+            $response = $event->getResponse();
+
+            // Retornar uma nova/modificada resposta.
+            // Você pode usar $event->setResult($response) para obter o mesmo resultado.
+            return new \Cake\Http\Client\Response(body: 'something');
+        }
+    );
+
+.. _httpclient-testing:
+
+Testes
+======
+
+.. php:namespace:: Cake\Http\TestSuite
+
+.. php:trait:: HttpClientTrait
+
+Em testes, você frequentemente desejará criar respostas simuladas para APIs externas. Você pode
+usar o ``HttpClientTrait`` para definir respostas para as requisições que sua aplicação
+está fazendo::
+
+    use Cake\Http\TestSuite\HttpClientTrait;
+    use Cake\TestSuite\TestCase;
+
+    class CartControllerTests extends TestCase
+    {
+        use HttpClientTrait;
+
+        public function testCheckout()
+        {
+            // Simular uma requisição POST que será feita.
+            $this->mockClientPost(
+                'https://example.com/process-payment',
+                $this->newClientResponse(200, [], json_encode(['ok' => true]))
+            );
+            $this->post("/cart/checkout");
+            // Fazer asserções.
+        }
+    }
+
+Existem métodos para simular os métodos HTTP mais comumente usados::
+
+    $this->mockClientGet(/* ... */);
+    $this->mockClientPatch(/* ... */);
+    $this->mockClientPost(/* ... */);
+    $this->mockClientPut(/* ... */);
+    $this->mockClientDelete(/* ... */);
+
+.. php:method:: newClientResponse(int $code = 200, array $headers = [], string $body = '')
+
+Como visto acima, você pode usar o método ``newClientResponse()`` para criar respostas
+para as requisições que sua aplicação fará. Os cabeçalhos precisam ser uma lista de
+strings::
+
+    $headers = [
+        'Content-Type: application/json',
+        'Connection: close',
+    ];
+    $response = $this->newClientResponse(200, $headers, $body)
 
 .. meta::
-    :title lang=pt: Cliente Http
-    :keywords lang=pt: nome de matriz,dados de matriz,parametros de consulta,string de consulta,classe php,teste de tipo,string de dado,google,consulta de resultados,webservices,apis,parametros,cakephp,metodos,pesquisando resultados
+    :title lang=pt: HttpClient
+    :keywords lang=pt: array name,array data,query parameter,query string,php class,string query,test type,string data,google,query results,webservices,apis,parameters,cakephp,meth,search results
diff --git a/pt/core-libraries/inflector.rst b/pt/core-libraries/inflector.rst
index 06e44d0998..438f2f08c0 100644
--- a/pt/core-libraries/inflector.rst
+++ b/pt/core-libraries/inflector.rst
@@ -5,24 +5,25 @@ Inflector
 
 .. php:class:: Inflector
 
-A classe ``Inflector`` recebe uma string e a manipula afim de suportar variações
-de palavas como pluralizações ou CamelCase e normalmente é acessada
+A classe Inflector pega uma string e pode manipulá-la para lidar com variações de palavras
+como pluralização ou camelização e normalmente é acessada
 estaticamente. Exemplo:
 ``Inflector::pluralize('example')`` retorna "examples".
 
-Você pode testar as inflexões em `inflector.cakephp.org
-`_.
+Você pode testar as inflexões online em `inflector.cakephp.org
+`_ ou `sandbox.dereuromark.de
+`_.
 
 .. _inflector-methods-summary:
 
-Resumo dos métodos de Inflexão e Suas Saídas
-============================================
+Resumo dos Métodos do Inflector e Suas Saídas
+==============================================
 
-Resumo rápido dos métodos embutidos no Inflector e os resultados que produzem
-quando fornecidos um argumento de palavra composta.
+Resumo rápido dos métodos integrados do Inflector e os resultados que eles produzem
+quando fornecido um argumento com várias palavras:
 
 +-------------------+---------------+---------------+
-| Method            | Argument      | Output        |
+| Método            | Argumento     | Saída         |
 +===================+===============+===============+
 | ``pluralize()``   | BigApple      | BigApples     |
 +                   +---------------+---------------+
@@ -60,27 +61,23 @@ quando fornecidos um argumento de palavra composta.
 +                   +---------------+---------------+
 |                   | big apples    | bigApples     |
 +-------------------+---------------+---------------+
-| ``slug()``        | Big Apple     | big-apple     |
-+                   +---------------+---------------+
-|                   | BigApples     | BigApples     |
-+-------------------+---------------+---------------+
 
-Criando as formas singulares e plurais
-======================================
+Criando Formas Plural e Singular
+=================================
 
 .. php:staticmethod:: singularize($singular)
 .. php:staticmethod:: pluralize($singular)
 
-Tanto ``pluralize()`` quanto ``singularize()`` funcionam para a maioria dos
-substantivos do Inglês. Caso seja necessário o suporte para outras línguas,
-você pode usar :ref:`inflection-configuration` para personalizar as regras usadas::
+Tanto ``pluralize`` quanto ``singularize()`` funcionam na maioria dos substantivos em inglês. Se você precisa
+suportar outros idiomas, você pode usar :ref:`inflection-configuration` para
+personalizar as regras usadas::
 
     // Apples
     echo Inflector::pluralize('Apple');
 
 .. note::
-    ``pluralize()`` pode não funcionar corretamente nos casos onde um substantivo já
-    esteja em sua forma plural.
+
+    ``pluralize()`` não deve ser usado em um substantivo que já está em sua forma plural.
 
 .. code-block:: php
 
@@ -88,16 +85,16 @@ você pode usar :ref:`inflection-configuration` para personalizar as regras usad
     echo Inflector::singularize('People');
 
 .. note::
-    ``singularize()`` pode não funcionar corretamente nos casos onde um substantivo já
-    esteja em sua forma singular.
 
-Criando as formas CamelCase e nome_sublinhado
-=============================================
+    ``singularize()`` não deve ser usado em um substantivo que já está em sua forma singular.
+
+Criando Formas CamelCase e under_scored
+========================================
 
 .. php:staticmethod:: camelize($underscored)
 .. php:staticmethod:: underscore($camelCase)
 
-Estes métodos são úteis para a criação de nomes de classe ou de propriedades::
+Esses métodos são úteis ao criar nomes de classes ou nomes de propriedades::
 
     // ApplePie
     Inflector::camelize('Apple_pie')
@@ -105,32 +102,32 @@ Estes métodos são úteis para a criação de nomes de classe ou de propriedade
     // apple_pie
     Inflector::underscore('ApplePie');
 
-É importante ressaltar que ``underscore()`` irá converter apenas palavras formatadas
-em CamelCase. Palavras com espaços serão convertidas para caixa baixa, mas não serão
-separadas por sublinhado.
+Deve-se notar que underscore converterá apenas palavras formatadas em camelCase.
+Palavras que contêm espaços serão colocadas em minúsculas, mas não conterão um
+underscore.
 
-Criando formas legíveis para humanos
-====================================
+Criando Formas Legíveis para Humanos
+=====================================
 
 .. php:staticmethod:: humanize($underscored)
 
-Este método é útil para converter da forma sublinhada para o "Formato Título" para
-a leitura humana::
+Este método é útil ao converter formas com underscore em formas "Title Case"
+para valores legíveis por humanos::
 
     // Apple Pie
     Inflector::humanize('apple_pie');
 
-Criando formatos para nomes de tabelas e classes
-================================================
+Criando Formas de Nome de Tabela e Classe
+==========================================
 
 .. php:staticmethod:: classify($underscored)
 .. php:staticmethod:: dasherize($dashed)
 .. php:staticmethod:: tableize($camelCase)
 
-Ao gerar o código ou usar as convenções do CakePHP, você pode precisar inferir
-os nomes das tabelas ou classes::
+Ao gerar código ou usar as convenções do CakePHP, você pode precisar inflexionar
+nomes de tabelas ou nomes de classes::
 
-    // UserProfileSettings
+    // UserProfileSetting
     Inflector::classify('user_profile_settings');
 
     // user-profile-setting
@@ -139,66 +136,52 @@ os nomes das tabelas ou classes::
     // user_profile_settings
     Inflector::tableize('UserProfileSetting');
 
-Criando nomes de variáveis
-==========================
+Criando Nomes de Variáveis
+===========================
 
 .. php:staticmethod:: variable($underscored)
 
-Nomes de variáveis geralmente são úteis em tarefas de meta-programação que
-involvem a geração de código ou rotinas baseadas em convenções::
+Nomes de variáveis são frequentemente úteis ao fazer tarefas de meta-programação que envolvem
+gerar código ou fazer trabalho baseado em convenções::
 
     // applePie
     Inflector::variable('apple_pie');
 
-Criando strings de URL seguras
-==============================
-
-.. php:staticmethod:: slug($word, $replacement = '-')
-
-``slug()`` converte caracteres especiais em suas versões normais e converte
-os caracteres não encontrados e espaços em traços. O método ``slug()`` espera
-que a codificação seja UTF-8::
-
-    // apple-puree
-    Inflector::slug('apple purée');
-
-.. note::
-    ``Inflector::slug()`` foi depreciado desde a versão 3.2.7. Procure usar ``Text::slug()``
-    de agora em diante.
 
 .. _inflection-configuration:
 
-Configuração da inflexão
-========================
+Configuração de Inflexão
+=========================
 
-As convenções de nomes do CakePHP podem ser bem confortáveis. Você pode nomear sua
-tabela no banco de dados como ``big_boxes``, seu modelo como ``BigBoxes``, seu
-controlador como ``BigBoxesController`` e tudo funcionará automaticamente. O CakePHP
-entrelaça todos estes conceitos através da inflexão das palavras em suas formas
-singulares e plurais.
+As convenções de nomenclatura do CakePHP podem ser realmente boas - você pode nomear sua tabela
+de banco de dados ``big_boxes``, seu modelo ``BigBoxes``, seu controller
+``BigBoxesController``, e tudo funciona junto automaticamente. A
+maneira como o CakePHP sabe como unir as coisas é *inflexionando* as palavras
+entre suas formas singular e plural.
 
-Porém ocasionalmente (especialmente para os nossos amigos não Anglófonos) podem encontrar
-situações onde o infletor do CakePHP (a classe que pluraliza, singulariza, transforma em
-CamelCase e em nome\_sublinhado) não funciona como você gostaria. Caso o CakePHP não
-reconheça seu "quaisquer" ou "lápis", você pode ensiná-lo a entender seus casos especiais.
+Há ocasiões (especialmente para nossos amigos que não falam inglês) em que você
+pode se deparar com situações em que o inflector do CakePHP (a classe que pluraliza,
+singulariza, cameliza e usa under\_scores) pode não funcionar como você gostaria. Se
+o CakePHP não reconhecer seus Foci ou Fish, você pode informar ao CakePHP sobre seus
+casos especiais.
 
-Carregando inflexões personalizadas
------------------------------------
+Carregando Inflexões Personalizadas
+------------------------------------
 
 .. php:staticmethod:: rules($type, $rules, $reset = false)
 
-Define novas inflexões e transliterações para o ``Inflector`` usar. Geralmente este método
-deve ser chamado no seu **config/bootstrap.php**::
+Defina novas regras de inflexão e transliteração para o Inflector usar. Frequentemente,
+este método é usado em seu **config/bootstrap.php**::
 
     Inflector::rules('singular', ['/^(bil)er$/i' => '\1', '/^(inflec|contribu)tors$/i' => '\1ta']);
     Inflector::rules('uninflected', ['singulars']);
-    Inflector::rules('irregular', ['phylum' => 'phyla']); // The key is singular form, value is plural form
+    Inflector::rules('irregular', ['phylum' => 'phyla']); // A chave é a forma singular, o valor é a forma plural
 
-As regras ditadas por este método serão agregadas aos conjuntos de inflexão definidos em ``Cake/Utility/Inflector``,
-onde elas terão prioridade sobre as regras já declaradas por padrão. Você pode usar ``Inflector::reset()``
-para limpar todas as regras e retornar o ``Inflector`` para seu estado original.
+As regras fornecidas serão mescladas nos respectivos conjuntos de inflexão definidos em
+``Cake/Utility/Inflector``, com as regras adicionadas tendo precedência sobre as regras
+principais. Você pode usar ``Inflector::reset()`` para limpar regras e restaurar o
+estado original do Inflector.
 
 .. meta::
     :title lang=pt: Inflector
-    :keywords lang=en: apple orange,word variations,apple pie,person man,latin versions,profile settings,php class,initial state,puree,slug,apples,oranges,user profile,underscore
-    :keywords lang=pt: inflexão, infletor, variações de palavras, caracteres especiais, conversão, sublinhado, variações, plural, pluralização, singular, singularização, regras, urls seguras
+    :keywords lang=pt: apple orange,word variations,apple pie,person man,latin versions,profile settings,php class,initial state,puree,slug,apples,oranges,user profile,underscore
diff --git a/pt/core-libraries/internationalization-and-localization.rst b/pt/core-libraries/internationalization-and-localization.rst
index bf1b286e94..b905886198 100644
--- a/pt/core-libraries/internationalization-and-localization.rst
+++ b/pt/core-libraries/internationalization-and-localization.rst
@@ -1,97 +1,93 @@
-Internacionalização e Localização
-#################################
+Internacionalização & Localização
+##################################
 
-.. note::
-    Atualmente, a documentação desta página não é suportada em português.
-
-    Por favor, sinta-se a vontade para nos enviar um *pull request* para o
-    `Github `_ ou use o botão
-    **IMPROVE THIS DOC** para propor suas mudanças diretamente.
-
-    Você pode consultar a versão em inglês deste tópico através do seletor de
-    idiomas localizado ao lado direito do campo de buscas da documentação.
+Uma das melhores maneiras de uma aplicação alcançar um público maior é atender
+a vários idiomas. Isso pode frequentemente se revelar uma tarefa assustadora, mas os
+recursos de internacionalização e localização no CakePHP tornam isso muito mais fácil.
 
-Uma das melhores maneiras para uma aplicação alcançar uma maior audiência é
-atender a vários idiomas. Isso muitas vezes pode provar ser uma tarefa difícil,
-mas a internacionalização e recursos de localização do CakePHP tornam muito mais
-fácil.
-
-Primeiro, é importante entender a terminologia.  *Internacionalização* refere-se
-à capacidade de um aplicativo ser localizado. O termo *localização* refere-se à
-adaptação de uma aplicação, para atender idioma específico (ou cultura)
-requisitos (Isto é, uma "localidade"). Internacionalização e Localização são
-frequentemente abreviado como i18n (internacionalization) e l10n (localization);
-18 e 10 são o número de caracteres entre a primeira e última letra de cada
-termo.
+Primeiro, é importante entender alguma terminologia. *Internacionalização*
+refere-se à capacidade de uma aplicação ser localizada. O termo *localização*
+refere-se à adaptação de uma aplicação para atender requisitos específicos de idioma (ou
+cultura) (ou seja, uma "locale"). Internacionalização e localização
+são frequentemente abreviadas como i18n e l10n respectivamente; 18 e 10 são o número
+de caracteres entre o primeiro e o último caractere.
 
 Configurando Traduções
 ======================
 
-Existem apenas alguns passos para ir de um aplicativo de um único idioma a uma
-aplicação multi-lingual, o primeiro deles é fazer uso da função
-:php:func: `__()` em seu código. Abaixo está um exemplo de algum código para uma
-aplicação de um único idioma::
+Existem apenas alguns passos para ir de uma aplicação de idioma único para uma
+aplicação multi-idioma, o primeiro dos quais é fazer uso da
+função :php:func:`__()` no seu código. Abaixo está um exemplo de algum código para uma
+aplicação de idioma único::
 
     

Popular Articles

-Para Internacionalizar seu código, tudo que você precisa fazer é refatorar a -string usando :php:func: `__()` por exemplo:: +Para internacionalizar seu código, tudo que você precisa fazer é envolver strings na +função :php:func:`__()` assim::

-Fazendo nada mais, estes dois exemplos de código são funcionalmente idênticos - -ambos irão enviar o mesmo conteúdo para o navegador. A função :php:func: `__()` -irá traduzir a string passada se a tradução estiver disponível, ou devolvê-la -inalterada. +Não fazendo nada mais, esses dois exemplos de código são funcionalmente idênticos - eles +enviarão o mesmo conteúdo para o navegador. A função :php:func:`__()` +traduzirá a string passada se uma tradução estiver disponível, ou a retornará +sem modificações. -Arquivos de Idiomas -------------------- +Arquivos de Idioma +------------------ -Traduções podem ser disponibilizados usando arquivos de idiomas armazenados na -aplicação. O formato padrão para arquivos de tradução do CakePHP é o formato -`Gettext `_. Os arquivos precisam ser -colocado dentro do Diretório **resources/locales/** e dentro deste diretório, deve -haver uma subpasta para cada idioma, por exemplo:: +Traduções podem ser disponibilizadas usando arquivos de idioma armazenados na +aplicação. O formato padrão para arquivos de tradução do CakePHP é o +formato `Gettext `_. Os arquivos precisam ser +colocados em **resources/locales/** e dentro deste diretório, deve haver uma +subpasta para cada idioma que a aplicação precisa suportar:: - /resources - /locales - /en_US + resources/ + locales/ + en_US/ default.po - /en_GB + en_GB/ default.po validation.po - /es + es/ default.po -O domínio padrão é 'default', portanto, a pasta **resources/locales/** deve pelo menos -conter o arquivo **default.po** como mostrado acima. Um domínio refere-se a -qualquer arbitrário agrupamento de mensagens de tradução. Quando nenhum grupo é -usado, o grupo padrão é selecionado. - -As mensagens das Strings do core extraídos da biblioteca CakePHP podem ser -armazenado separadamente em um arquivo chamado **cake.po** em **resources/locales/**. -O `CakePHP localized library `_ possui -traduções para as mensagens traduzidas voltados para o cliente no núcleo (o -domínio Cake). Para usar esses arquivos, baixar ou copiá-los para o seu local -esperado: **resources/locales//cake.po**. Se sua localidade está incompleta ou -incorreta, por favor envie um PR neste repositório para corrigi-lo. - -Plugins também podem conter arquivos de tradução, a convenção é usar o -``under_score`` do nome do plugin como o domínio para a tradução mensagens:: - - MyPlugin - /resources - /locales - /fr +O domínio padrão é 'default', portanto a pasta de locale deve pelo menos +conter o arquivo **default.po** como mostrado acima. Um domínio refere-se a qualquer +agrupamento arbitrário de mensagens de tradução. Quando nenhum grupo é usado, o grupo padrão +é selecionado. + +As mensagens de strings principais extraídas da biblioteca CakePHP podem ser armazenadas +separadamente em um arquivo chamado **cake.po** em **resources/locales/**. +A `biblioteca localizada do CakePHP `_ abriga +traduções para as strings traduzidas voltadas para o cliente no núcleo (o domínio cake). +Para usar esses arquivos, vincule ou copie-os para o local esperado: +**resources/locales//cake.po**. Se sua locale estiver incompleta ou incorreta, +por favor envie um PR neste repositório para corrigi-la. + +Plugins também podem conter arquivos de tradução, a convenção é usar a +versão ``under_scored`` do nome do plugin como domínio para as mensagens +de tradução:: + + MyPlugin/ + resources/ + locales/ + fr/ my_plugin.po - /de + additional.po + de/ my_plugin.po -Pastas de tradução pode ser o código ISO de duas letras do idioma ou nome do -local completo, como ``fr_FR``, ``es_AR``, ``da_DK`` que contém tanto o idioma e -o país onde ele é falado. +As pastas de tradução podem ser o código ISO de duas ou três letras do idioma ou +o nome completo da locale ICU como ``fr_FR``, ``es_AR``, ``da_DK`` que contém +tanto o idioma quanto o país onde é falado. + +Veja https://www.localeplanet.com/icu/ para a lista completa de locales. + +.. versionchanged:: 4.5.0 + A partir de 4.5.0, plugins podem conter múltiplos domínios de tradução. Use + ``MyPlugin.additional`` para referenciar domínios de plugin. -Um exemplo de arquivo de tradução pode ser visto como: +Um exemplo de arquivo de tradução pode ser assim: .. code-block:: pot @@ -102,24 +98,25 @@ Um exemplo de arquivo de tradução pode ser visto como: msgstr "J'ai {0,number} ans" .. note:: - As traduções são armazenadas em cache - Certifique-se de que você sempre limpa - o cache após fazer alterações nas traduções! Você pode utilizar a ferramenta - :doc:`cache tool ` e executar por exemplo - ``bin/cake cache clear _cake_core_``, ou limpar manualmente a pasta - ``tmp/cache/persistent`` (se estiver utilizando o cache baseado em arquivo). + Traduções são armazenadas em cache - Certifique-se de sempre limpar o cache após + fazer alterações nas traduções! Você pode usar a + :doc:`ferramenta de cache ` e executar por exemplo + ``bin/cake cache clear _cake_core_``, ou limpar manualmente a pasta ``tmp/cache/persistent`` + (se estiver usando cache baseado em arquivo). -Extraindo arquivos .pot com I18n Shell --------------------------------------- +Extrair Arquivos Pot com I18n Shell +------------------------------------ -Para criar os arquivos .pot apartir de `__()` e outros tipos de mensagens -internacionalizadas que podem ser encontrados no código do aplicativo, você pode -usar o shell i18n. Por favor, leia o :doc:`Capítulo Seguinte -` para saber mais. +Para criar os arquivos pot a partir de `__()` e outros tipos internacionalizados de +mensagens que podem ser encontradas no código da aplicação, você pode usar o comando i18n. +Por favor leia o :doc:`capítulo seguinte ` para +aprender mais. -Definir a localidade padrão ---------------------------- -A localidade padrão pode ser definida em no arquivo **config/app.php**, -definindo ``App.default Locale``:: +Definindo a Locale Padrão +-------------------------- + +A locale padrão pode ser definida no seu arquivo **config/app.php** definindo +``App.defaultLocale``:: 'App' => [ ... @@ -127,99 +124,110 @@ definindo ``App.default Locale``:: ... ] -Isto vai controlar vários aspectos da aplicação, incluindo o padrão da linguagem -de traduções, o formato da data, formato de número e moeda sempre que qualquer -daqueles é exibida usando as bibliotecas de localização que o CakePHP fornece. +Isso controlará vários aspectos da aplicação, incluindo o idioma padrão das +traduções, o formato de data, formato de número e moeda sempre que qualquer +um deles for exibido usando as bibliotecas de localização que o CakePHP fornece. -Alterando o local em tempo de execução --------------------------------------- +Alterando a Locale em Tempo de Execução +---------------------------------------- -Para alterar o idioma para as mensagens traduzidas você pode chamar esse -método:: +Para alterar o idioma das strings traduzidas, você pode chamar este método:: use Cake\I18n\I18n; I18n::setLocale('de_DE'); -Isso também irá alterar a forma como números e datas são formatadas quando -usamos uma das ferramentas de localização. +Isso também mudará como números e datas são formatados ao usar uma das +ferramentas de localização. -Usando funções de tradução -========================== +Usando Funções de Tradução +=========================== -CakePHP fornece várias funções que o ajudarão a internacionalizar sua aplicação. -O mais utilizado é :php:func: `__()`. Esta função é usada para recuperar uma -única mensagem de tradução ou devolver a mesma String se não houver tradução:: +O CakePHP fornece várias funções que ajudarão você a internacionalizar sua +aplicação. A mais frequentemente usada é :php:func:`__()`. Esta função +é usada para recuperar uma única mensagem de tradução ou retornar a mesma string se nenhuma +tradução foi encontrada:: echo __('Popular Articles'); -Se você precisa agrupar suas mensagens, por exemplo, traduções dentro de um -plugin, você pode usar a função :php:func: `__d()` para buscar mensagens de -outro domínio:: +Se você precisa agrupar suas mensagens, por exemplo, traduções dentro de um plugin, +você pode usar a função :php:func:`__d()` para buscar mensagens de outro +domínio:: echo __d('my_plugin', 'Trending right now'); -Às vezes traduções de Strings podem ser ambíguos para as pessoas traduzindo-os. -Isso pode acontecer se duas sequências são idênticas, mas referem-se a coisas -diferentes. Por exemplo, "letter" tem vários significados em Inglês. Para -resolver esse problema, você pode usar a função :php:func: `__x()`:: +.. note:: + + Se você quiser traduzir plugins que têm namespace de vendor, você deve usar + a string de domínio ``vendor/plugin_name``. Mas o arquivo de idioma relacionado + será ``plugins///resources/locales//plugin_name.po`` + dentro da pasta do seu plugin. + +Às vezes, strings de tradução podem ser ambíguas para as pessoas que as traduzem. +Isso pode acontecer se duas strings são idênticas mas se referem a coisas diferentes. Por +exemplo, 'letter' tem vários significados em inglês. Para resolver esse problema, você +pode usar a função :php:func:`__x()`:: echo __x('written communication', 'He read the first letter'); echo __x('alphabet learning', 'He read the first letter'); -O primeiro argumento é o contexto da mensagem e a segunda é a mensagem a ser -traduzida. +O primeiro argumento é o contexto da mensagem e o segundo é a mensagem +a ser traduzida. -Usando variáveis em mensagens de tradução ------------------------------------------ +.. code-block:: pot -Funções de tradução permitem que você interpole variáveis para as mensagens -usando marcadores especiais definidos na própria mensagem ou na string -traduzida:: + msgctxt "written communication" + msgid "He read the first letter" + msgstr "Er las den ersten Brief" - echo __("Hello, my name is {0}, I'm {1} years old", ['Jefferson', 19]); +Usando Variáveis em Mensagens de Tradução +------------------------------------------ -Marcadores são numéricos, e correspondem às teclas na matriz passada. Você pode -também passar variáveis como argumentos independentes para a função:: +Funções de tradução permitem que você interpole variáveis nas mensagens usando +marcadores especiais definidos na própria mensagem ou na string traduzida:: + + echo __("Hello, my name is {0}, I'm {1} years old", ['Sara', 12]); + +Marcadores são numéricos e correspondem às chaves no array passado. Você também +pode passar variáveis como argumentos independentes para a função:: echo __("Small step for {0}, Big leap for {1}", 'Man', 'Humanity'); -Todas as funções de tradução apoiam as substituições de espaço reservado:: +Todas as funções de tradução suportam substituições de placeholder:: __d('validation', 'The field {0} cannot be left empty', 'Name'); __x('alphabet', 'He read the letter {0}', 'Z'); -O caracter ``'`` (aspas simples) age como um código de escape na mensagem de -tradução. Todas as variáveis entre aspas simples não serão substituídos e é -tratado como texto literal. Por exemplo:: +O caractere ``'`` (aspas simples) age como um código de escape em mensagens +de tradução. Quaisquer variáveis entre aspas simples não serão substituídas e são +tratadas como texto literal. Por exemplo:: __("This variable '{0}' be replaced.", 'will not'); -Ao usar duas aspas adjacentes suas variáveis e serão substituídos -adequadamente:: +Ao usar duas aspas adjacentes, suas variáveis serão substituídas adequadamente:: __("This variable ''{0}'' be replaced.", 'will'); -Estas funções tiram vantagem do -`UTI MessageFormatter `_ -para que possa traduzir mensagens e localizar datas, números e moeda, ao mesmo -tempo:: +Essas funções tiram proveito do +`ICU MessageFormatter `_ +para que você possa traduzir mensagens e localizar datas, números e moeda ao +mesmo tempo:: echo __( - 'Hi {0,string}, your balance on the {1,date} is {2,number,currency}', - ['Charles', '2014-01-13 11:12:00', 1354.37] + 'Hi {0}, your balance on the {1,date} is {2,number,currency}', + ['Charles', new DateTime('2014-01-13 11:12:00'), 1354.37] ); // Returns Hi Charles, your balance on the Jan 13, 2014, 11:12 AM is $ 1,354.37 -Os números em espaços reservados podem ser formatados, bem como com o controle -de grão fino da saída:: +Números em placeholders também podem ser formatados com controle refinado da +saída:: echo __( - 'You have traveled {0,number,decimal} kilometers in {1,number,integer} weeks', + 'You have traveled {0,number} kilometers in {1,number,integer} weeks', [5423.344, 5.1] ); @@ -231,61 +239,54 @@ de grão fino da saída:: // Returns There are 6,100,000,000 people on earth -Esta é a lista de especificadores de formato que você pode colocar após -a palavra ``number``: +Esta é a lista de especificadores de formatação que você pode colocar após a palavra ``number``: -* ``integer``: Remove a parte Decimal -* ``decimal``: Formata o número como um float -* ``currency``: Coloca o local do símbolo de moeda e números de casas decimais +* ``integer``: Remove a parte decimal +* ``currency``: Coloca o símbolo de moeda da locale e arredonda decimais * ``percent``: Formata o número como porcentagem -Datas também pode ser formatadas usando a palavra ``date`` após o número do -espaço reservado. Uma lista de opções adicionais a seguir: +Datas também podem ser formatadas usando a palavra ``date`` após o número +do placeholder. Uma lista de opções extras segue: * ``short`` * ``medium`` * ``long`` * ``full`` -A palavra ``time`` após o número de espaço reservado também é aceito e -compreende as mesmas opções que ``date``. - -.. note:: +A palavra ``time`` após o número do placeholder também é aceita e ela +entende as mesmas opções que ``date``. - Espaços reservados nomeados são suportados no PHP 5.5+ e são formatados como - ``{name}``. Ao usar espaços reservados nomeados para passar as variáveis em - uma matriz usando pares de chave/valor, por exemplo ``['name' => - 'Jefferson', 'age' => 19]``. +Você também pode usar placeholders nomeados como ``{name}`` nas strings de mensagem. +Ao usar placeholders nomeados, passe o placeholder e a substituição em um array usando pares chave/valor, +por exemplo:: - Recomenda-se usar o PHP 5.5 ou superior ao fazer uso de recursos de - internacionalização no CakePHP. A extensão ``php5-intl`` deve ser instalada - e a versão UTI deve estar acima 48.x.y (para verificar a versão UTI - ``Intl::getIcuVersion ()``). + // echos: Hi. My name is Sara. I'm 12 years old. + echo __("Hi. My name is {name}. I'm {age} years old.", ['name' => 'Sara', 'age' => 12]); Plurais ------- -Uma parte crucial de internacionalizar sua aplicação é a pluralização das suas -mensagens corretamente, dependendo do idioma que eles são mostrados. O CakePHP -fornece algumas maneiras de selecionar corretamente plurais em suas mensagens. +Uma parte crucial da internacionalização da sua aplicação é fazer com que suas mensagens +sejam pluralizadas corretamente dependendo do idioma em que são exibidas. O CakePHP fornece +algumas maneiras de selecionar corretamente plurais em suas mensagens. -Usando UTI para Seleção de Plural -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Usando Seleção de Plural ICU +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -O primeiro está aproveitando o formato de mensagem ``ICU`` que vem por padrão -nas funções de tradução. Nos arquivos de traduções você pode ter as seguintes -cadeias +A primeira é tirar proveito do formato de mensagem ``ICU`` que vem por +padrão nas funções de tradução. No arquivo de traduções você poderia ter +as seguintes strings .. code-block:: pot msgid "{0,plural,=0{No records found} =1{Found 1 record} other{Found # records}}" - msgstr "{0,plural,=0{Nenhum resultado} =1{1 resultado} other{# resultados}}" + msgstr "{0,plural,=0{Ningún resultado} =1{1 resultado} other{# resultados}}" msgid "{placeholder,plural,=0{No records found} =1{Found 1 record} other{Found {1} records}}" - msgstr "{placeholder,plural,=0{Nenhum resultado} =1{1 resultado} other{{1} resultados}}" + msgstr "{placeholder,plural,=0{Ningún resultado} =1{1 resultado} other{{1} resultados}}" -E na aplicação utilize o seguinte código para a saída de uma das traduções para -essa seqüência:: +E na aplicação use o seguinte código para exibir qualquer uma das +traduções para tal string:: __('{0,plural,=0{No records found }=1{Found 1 record} other{Found # records}}', [0]); @@ -300,40 +301,41 @@ essa seqüência:: // Returns "many resultados" because the argument {placeholder} is 2 and // argument {1} is 'many' -Um olhar mais atento para o formato que acabamos utilizado tornará evidente -como as mensagens são construídas:: +Uma olhada mais de perto no formato que acabamos de usar tornará evidente como as mensagens são +construídas:: { [count placeholder],plural, case1{message} case2{message} case3{...} ... } -O ``[count placeholder]`` pode ser o número-chave de qualquer das variáveis que -você passar para a função de tradução. Ele será usado para selecionar o plural -correto. +O ``[count placeholder]`` pode ser o número da chave do array de qualquer uma das variáveis +que você passa para a função de tradução. Ele será usado para selecionar a forma +plural correta. -Note que essa referência para ``[count placeholder]`` dentro de ``{message}`` -você tem que usar ``#``. +Note que para referenciar ``[count placeholder]`` dentro de ``{message}`` você tem que +usar ``#``. -Você pode usar ids de mensagem mais simples se você não deseja digitar a plena -seqüência de seleção para plural em seu código +Você pode, é claro, usar IDs de mensagem mais simples se não quiser digitar a sequência +completa de seleção de plural no seu código .. code-block:: pot msgid "search.results" - msgstr "{0,plural,=0{Nenhum resultado} =1{1 resultado} other{{1} resultados}}" + msgstr "{0,plural,=0{Ningún resultado} =1{1 resultado} other{{1} resultados}}" -Em seguida, use a nova string em seu código:: +Then use the new string in your code:: __('search.results', [2, 2]); // Returns: "2 resultados" -A última versão tem a desvantagem na qual existe uma necessidade de arquivar -mensagens e precisa de tradução para o idioma padrão mesmo, mas tem a vantagem -de que torna o código mais legível. +A última versão tem a desvantagem de que há necessidade de ter um arquivo +de mensagens de tradução mesmo para o idioma padrão, mas tem a vantagem de que torna +o código mais legível e deixa as strings complicadas de seleção de plural nos +arquivos de tradução. -Às vezes, usando o número de correspondência direta nos plurais é impraticável. -Por exemplo, idiomas como o árabe exigem um plural diferente quando você se -refere a algumas coisas. Nesses casos, você pode usar o UTI correspondentes. Em -vez de escrever:: +Às vezes usar correspondência direta de números em plurais é impraticável. Por exemplo, +idiomas como árabe requerem um plural diferente quando você se refere a +poucas coisas e outra forma plural para muitas coisas. Nesses casos você pode +usar os aliases de correspondência ICU. Em vez de escrever:: =0{No results} =1{...} other{...} @@ -341,16 +343,16 @@ Você pode fazer:: zero{No Results} one{One result} few{...} many{...} other{...} -Certifique-se de ler a -`Language Plural Rules Guide `_ +Certifique-se de ler o +`Guia de Regras de Plural de Idiomas `_ para obter uma visão completa dos aliases que você pode usar para cada idioma. -Usando Gettext para Seleção de Plural -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Usando Seleção de Plural Gettext +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -O segundo formato para seleção de plural aceito é a utilização das capacidades -embutidas de Gettext. Neste caso, plurais será armazenado nos arquivos ``.po``, -criando uma linha de tradução de mensagens separada por forma de plural: +O segundo formato de seleção de plural aceito é usar os recursos integrados +do Gettext. Neste caso, plurais serão armazenados no arquivo ``.po`` +criando uma linha de tradução de mensagem separada por forma plural: .. code-block:: pot @@ -363,19 +365,19 @@ criando uma linha de tradução de mensagens separada por forma de plural: # Translation in plural msgstr[1] "{0} ficheros eliminados" -Ao usar este outro formato, você é obrigado a usar outra tradução de forma -funcional:: +Ao usar este outro formato, você deve usar outra função +de tradução:: // Returns: "10 ficheros eliminados" $count = 10; __n('One file removed', '{0} files removed', $count, $count); - // Também é possível utilizá-lo dentro de um domínio + // It is also possible to use it inside a domain __dn('my_plugin', 'One file removed', '{0} files removed', $count, $count); -O número dentro de ``msgstr[]`` é o número atribuído pela Gettext para o plural -na forma da língua. Algumas línguas têm mais de duas formas plurais, para -exemplo *Croatian*: +O número dentro de ``msgstr[]`` é o número atribuído pelo Gettext para a forma +plural do idioma. Alguns idiomas têm mais de duas formas plurais, por +exemplo Croata: .. code-block:: pot @@ -385,21 +387,21 @@ exemplo *Croatian*: msgstr[1] "{0} datoteke su uklonjene" msgstr[2] "{0} datoteka je uklonjeno" -Por favor visite a `Launchpad languages page -`_ para uma explicação detalhada -dos números de formulário de plurais para cada idioma. +Por favor visite a `página de idiomas do Launchpad `_ +para uma explicação detalhada dos números de forma plural para cada idioma. -Criar seus próprios Tradutores -============================== +Criando Seus Próprios Tradutores +================================= -Se você precisar a divergir convenções do CakePHP sobre onde e como as mensagens -de tradução são armazenadas, você pode criar seu próprio carregador de mensagem -de tradução. A maneira mais fácil de criar o seu próprio tradutor é através da -definição de um carregador para um único domínio e localidade:: +Se você precisa divergir das convenções do CakePHP em relação a onde e como +mensagens de tradução são armazenadas, você pode criar seu próprio carregador de +mensagens de tradução. A maneira mais fácil de criar seu próprio tradutor é definindo um loader +para um único domínio e locale:: - use Aura\Intl\Package; + use Cake\I18n\Package; + // Prior to 4.2 you need to use Aura\Intl\Package - I18n::translator('animals', 'fr_FR', function () { + I18n::setTranslator('animals', function () { $package = new Package( 'default', // The formatting strategy (ICU) 'default' // The fallback domain @@ -412,31 +414,288 @@ definição de um carregador para um único domínio e localidade:: ]); return $package; - }); + }, 'fr_FR'); -O código acima pode ser adicionado ao seu **config/bootstrap.php** de modo que -as traduções podem ser encontradas antes de qualquer função de tradução é usada. -O mínimo absoluto que é necessário para a criação de um tradutor é que a função -do carregador deve retornar um ``Aura\Intl\Package`` objeto. Uma vez que o -código é no lugar que você pode usar as funções de tradução, como de costume:: +O código acima pode ser adicionado ao seu **config/bootstrap.php** para que +traduções possam ser encontradas antes de qualquer função de tradução ser usada. O mínimo +absoluto necessário para criar um tradutor é que a função loader +deve retornar um objeto ``Cake\I18n\Package`` (antes de 4.2 deveria ser um objeto ``Aura\Intl\Package``). +Uma vez que o código esteja no lugar, você pode usar as funções de tradução como de costume:: I18n::setLocale('fr_FR'); - __d('animals', 'Dog'); // Retorna "Chien" + __d('animals', 'Dog'); // Returns "Chien" -Como você vê objetos, ``Package`` carregam mensagens de tradução como uma -matriz. Você pode passar o método ``setMessages()`` da maneira que quiser: com -código inline, incluindo outro arquivo, chamar outra função, etc. CakePHP -fornece algumas funções da carregadeira que podem ser reutilizadas se você só -precisa mudar para onde as mensagens são carregadas. Por exemplo, você ainda -pode usar **.po**, mas carregado de outro local:: +Como você vê, objetos ``Package`` recebem mensagens de tradução como um array. Você pode +passar o método ``setMessages()`` como quiser: com código inline, incluindo +outro arquivo, chamando outra função, etc. O CakePHP fornece algumas funções loader +que você pode reutilizar se precisar apenas mudar de onde as mensagens são carregadas. +Por exemplo, você ainda pode usar arquivos **.po**, mas carregados de outro local:: use Cake\I18n\MessagesFileLoader as Loader; // Load messages from resources/locales/folder/sub_folder/filename.po + I18n::setTranslator( + 'animals', + new Loader('filename', 'folder/sub_folder', 'po'), + 'fr_FR' + ); + +Criando Parsers de Mensagem +---------------------------- + +É possível continuar usando as mesmas convenções que o CakePHP usa, mas usar +um parser de mensagem diferente de ``PoFileParser``. Por exemplo, se você quisesse carregar +mensagens de tradução usando ``YAML``, você primeiro precisará criar a classe +do parser:: + + namespace App\I18n\Parser; - I18n::translator( + class YamlFileParser + { + public function parse($file) + { + return yaml_parse_file($file); + } + } + +O arquivo deve ser criado no diretório **src/I18n/Parser** da sua +aplicação. Em seguida, crie o arquivo de traduções em +**resources/locales/fr_FR/animals.yaml** + +.. code-block:: yaml + + Dog: Chien + Cat: Chat + Bird: Oiseau + +E finalmente, configure o loader de tradução para o domínio e locale:: + + use Cake\I18n\MessagesFileLoader as Loader; + + I18n::setTranslator( 'animals', - 'fr_FR', - new Loader('filename', 'folder/sub_folder', 'po') + new Loader('animals', 'fr_FR', 'yaml'), + 'fr_FR' ); +.. _creating-generic-translators: + +Criando Tradutores Genéricos +----------------------------- + +Configurar tradutores chamando ``I18n::setTranslator()`` para cada domínio e +locale que você precisa suportar pode ser tedioso, especialmente se você precisa suportar mais +de algumas locales diferentes. Para evitar este problema, o CakePHP permite que você defina +loaders de tradutor genéricos para cada domínio. + +Imagine que você queira carregar todas as traduções para o domínio padrão e para +qualquer idioma de um serviço externo:: + + use Cake\I18n\Package; + // Prior to 4.2 you need to use Aura\Intl\Package + + I18n::config('default', function ($domain, $locale) { + $locale = Locale::parseLocale($locale); + $lang = $locale['language']; + $messages = file_get_contents("http://example.com/translations/$lang.json"); + + return new Package( + 'default', // Formatter + null, // Fallback (none for default domain) + json_decode($messages, true) + ) + }); + +O exemplo acima chama um serviço externo de exemplo para carregar um arquivo JSON com as +traduções e então apenas constrói um objeto ``Package`` para qualquer locale que seja +solicitada na aplicação. + +Se você quiser mudar como os pacotes são carregados para todos os pacotes que não +têm loaders específicos definidos, você pode substituir o loader de pacote de fallback usando +o pacote ``_fallback``:: + + I18n::config('_fallback', function ($domain, $locale) { + // Custom code that yields a package here. + }); + +Plurais e Contexto em Tradutores Personalizados +------------------------------------------------ + +Os arrays usados para ``setMessages()`` podem ser criados para instruir o tradutor +a armazenar mensagens em diferentes domínios ou para acionar seleção de plural +estilo Gettext. O seguinte é um exemplo de armazenar traduções para a mesma chave +em diferentes contextos:: + + [ + 'He reads the letter {0}' => [ + 'alphabet' => 'Él lee la letra {0}', + 'written communication' => 'Él lee la carta {0}', + ], + ] + +Da mesma forma, você pode expressar plurais estilo Gettext usando o array de mensagens +tendo uma chave de array aninhada por forma plural:: + + [ + 'I have read one book' => 'He leído un libro', + 'I have read {0} books' => [ + 'He leído un libro', + 'He leído {0} libros', + ], + ] + +Usando Diferentes Formatadores +------------------------------- + +Em exemplos anteriores vimos que Packages são construídos usando ``default`` como +primeiro argumento, e foi indicado com um comentário que ele correspondia ao +formatador a ser usado. Formatadores são classes responsáveis por interpolar +variáveis em mensagens de tradução e selecionar a forma plural correta. + +Se você está lidando com uma aplicação legada, ou não precisa do poder oferecido +pela formatação de mensagem ICU, o CakePHP também fornece o formatador ``sprintf``:: + + return Package('sprintf', 'fallback_domain', $messages); + +As mensagens a serem traduzidas serão passadas para a função ``sprintf()`` para +interpolar as variáveis:: + + __('Hello, my name is %s and I am %d years old', 'José', 29); + +É possível definir o formatador padrão para todos os tradutores criados pelo +CakePHP antes de serem usados pela primeira vez. Isso não inclui tradutores criados +manualmente usando os métodos ``setTranslator()`` e ``config()``:: + + I18n::setDefaultFormatter('sprintf'); + +Localizando Datas e Números +============================ + +Ao exibir Datas e Números na sua aplicação, você frequentemente precisará que +eles sejam formatados de acordo com o formato preferido para o país ou região +em que você deseja que sua página seja exibida. + +Para mudar como datas e números são exibidos, você só precisa mudar +a configuração de locale atual e usar as classes corretas:: + + use Cake\I18n\I18n; + use Cake\I18n\DateTime; + use Cake\I18n\Number; + + I18n::setLocale('fr-FR'); + + $date = new DateTime('2015-04-05 23:00:00'); + + echo $date; // Displays 05/04/2015 23:00 + + echo Number::format(524.23); // Displays 524,23 + +Certifique-se de ler as seções :doc:`/core-libraries/time` e :doc:`/core-libraries/number` +para aprender mais sobre opções de formatação. + +Por padrão, datas retornadas para resultados ORM usam a classe ``Cake\I18n\DateTime``, +então exibi-las diretamente na sua aplicação será afetado ao mudar a +locale atual. + +.. _parsing-localized-dates: + +Analisando Dados de Datetime Localizados +----------------------------------------- + +Ao aceitar dados localizados da requisição, é bom aceitar informações de datetime +no formato localizado do usuário. Em um controller, ou +:doc:`/controllers/middleware` você pode configurar os tipos Date, Time e +DateTime para analisar formatos localizados:: + + use Cake\Database\TypeFactory; + + // Enable default locale format parsing. + TypeFactory::build('datetime')->useLocaleParser(); + + // Configure a custom datetime format parser format. + TypeFactory::build('datetime')->useLocaleParser()->setLocaleFormat('dd-M-y'); + + // You can also use IntlDateFormatter constants. + TypeFactory::build('datetime')->useLocaleParser() + ->setLocaleFormat([IntlDateFormatter::SHORT, -1]); + +O formato de análise padrão é o mesmo que o formato de string padrão. + +.. _converting-request-data-from-user-timezone: + +Convertendo Dados de Requisição do Fuso Horário do Usuário +----------------------------------------------------------- + +Ao lidar com dados de usuários em fusos horários diferentes, você precisará converter +os datetimes nos dados da requisição para o fuso horário da sua aplicação. Você pode usar +``setUserTimezone()`` de um controller ou :doc:`/controllers/middleware` para +tornar este processo mais simples:: + + // Set the user's timezone + TypeFactory::build('datetime')->setUserTimezone($user->timezone); + +Uma vez definido, quando sua aplicação cria ou atualiza entidades a partir de dados de requisição, +o ORM irá automaticamente converter valores datetime do fuso horário do usuário para +o fuso horário da sua aplicação. Isso garante que sua aplicação esteja sempre +trabalhando no fuso horário definido em ``App.defaultTimezone``. + +Se sua aplicação lida com informações de datetime em várias actions, você pode +usar um middleware para definir tanto a conversão de fuso horário quanto a análise de locale:: + + namespace App\Middleware; + + use Cake\Database\TypeFactory; + use Psr\Http\Message\ResponseInterface; + use Psr\Http\Message\ServerRequestInterface; + use Psr\Http\Server\MiddlewareInterface; + use Psr\Http\Server\RequestHandlerInterface; + + class DatetimeMiddleware implements MiddlewareInterface + { + public function process( + ServerRequestInterface $request, + RequestHandlerInterface $handler + ): ResponseInterface { + // Get the user from the request. + // This example assumes your user entity has a timezone attribute. + $user = $request->getAttribute('identity'); + if ($user) { + TypeFactory::build('datetime') + ->useLocaleParser() + ->setUserTimezone($user->timezone); + } + + return $handler->handle($request); + } + } + +Escolhendo Automaticamente a Locale Baseado em Dados da Requisição +=================================================================== + +Ao usar o ``LocaleSelectorMiddleware`` na sua aplicação, o CakePHP irá +automaticamente definir a locale baseada no usuário atual:: + + // in src/Application.php + use Cake\I18n\Middleware\LocaleSelectorMiddleware; + + // Update the middleware function, adding the new middleware + public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue + { + // Add middleware and set the valid locales + $middlewareQueue->add(new LocaleSelectorMiddleware(['en_US', 'fr_FR'])); + // To accept any locale header value + $middlewareQueue->add(new LocaleSelectorMiddleware(['*'])); + } + +O ``LocaleSelectorMiddleware`` usará o cabeçalho ``Accept-Language`` para +automaticamente definir a locale preferida do usuário. Você pode usar a opção de lista de locale +para restringir quais locales serão usadas automaticamente. + +Traduzir Conteúdo/Entidades +============================ + +Se você quiser traduzir conteúdo/entidades, então você deve ver o :doc:`Translate Behavior `. + +.. meta:: + :title lang=en: Internationalization & Localization + :keywords lang=en: internationalization localization,internationalization and localization,language application,gettext,l10n,pot,i18n,translation,languages diff --git a/pt/core-libraries/logging.rst b/pt/core-libraries/logging.rst index ed8bafcc39..12e1d15dc5 100644 --- a/pt/core-libraries/logging.rst +++ b/pt/core-libraries/logging.rst @@ -1,17 +1,550 @@ Logging ####### +Embora as configurações da Classe Configure do núcleo do CakePHP possam realmente ajudar você a ver +o que está acontecendo internamente, há certos momentos em que +você precisará registrar dados no disco para descobrir o que está +acontecendo. Com tecnologias como SOAP, AJAX e APIs REST, a depuração pode ser +bastante difícil. + +O logging também pode ser uma maneira de descobrir o que está acontecendo em sua +aplicação ao longo do tempo. Quais termos de pesquisa estão sendo usados? Que tipos +de erros meus usuários estão vendo? Com que frequência uma consulta específica +está sendo executada? + +O registro de dados no CakePHP é feito com a função ``log()``. Ela é fornecida pelo +``LogTrait``, que é o ancestral comum para muitas classes do CakePHP. Se o +contexto é uma classe CakePHP (Controller, Component, View,...), você pode registrar seus +dados. Você também pode usar ``Log::write()`` diretamente. Veja :ref:`writing-to-logs`. + .. _log-configuration: -Logging Configuration +Configuração de Logging +======================== + +Configurar o ``Log`` deve ser feito durante a fase de bootstrap da sua aplicação. +O arquivo **config/app.php** é destinado exatamente para isso. Você pode definir +quantos loggers sua aplicação precisar. Loggers devem ser +configurados usando :php:class:`Cake\\Log\\Log`. Um exemplo seria:: + + use Cake\Log\Engine\FileLog; + use Cake\Log\Log; + + // Classname using logger 'class' constant + Log::setConfig('info', [ + 'className' => FileLog::class, + 'path' => LOGS, + 'levels' => ['info'], + 'file' => 'info', + ]); + + // Short classname + Log::setConfig('debug', [ + 'className' => 'File', + 'path' => LOGS, + 'levels' => ['notice', 'debug'], + 'file' => 'debug', + ]); + + // Fully namespaced name. + Log::setConfig('error', [ + 'className' => 'Cake\Log\Engine\FileLog', + 'path' => LOGS, + 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], + 'file' => 'error', + ]); + +O exemplo acima cria três loggers, chamados ``info``, ``debug`` e ``error``. +Cada um é configurado para lidar com diferentes níveis de mensagens. Eles também armazenam suas +mensagens de log em arquivos separados, para que possamos separar logs de debug/notice/info +de erros mais sérios. Veja a seção sobre :ref:`logging-levels` para mais +informações sobre os diferentes níveis e o que eles significam. + +Uma vez que uma configuração é criada, você não pode alterá-la. Em vez disso, você deve remover +a configuração e recriá-la usando :php:meth:`Cake\\Log\\Log::drop()` e +:php:meth:`Cake\\Log\\Log::setConfig()`. + +Também é possível criar loggers fornecendo uma closure. Isso é útil +quando você precisa de controle total sobre como o objeto logger é construído. A closure +tem que retornar a instância do logger construída. Por exemplo:: + + Log::setConfig('special', function () { + return new \Cake\Log\Engine\FileLog(['path' => LOGS, 'file' => 'log']); + }); + +Opções de configuração também podem ser fornecidas como uma string :term:`DSN`. Isso é +útil ao trabalhar com variáveis de ambiente ou provedores :term:`PaaS`:: + + Log::setConfig('error', [ + 'url' => 'file:///full/path/to/logs/?levels[]=warning&levels[]=error&file=error', + ]); + +.. warning:: + Se você não configurar engines de logging, as mensagens de log não serão armazenadas. + +Logging de Erros e Exceções +============================ + +Erros e Exceções também podem ser registrados. Configurando os valores correspondentes +no seu arquivo **config/app.php**. Erros serão exibidos quando debug estiver +``true`` e registrados quando debug estiver ``false``. Para registrar exceções não capturadas, defina a +opção ``log`` como ``true``. Veja :doc:`/development/configuration` para mais +informações. + +.. _writing-to-logs: + +Escrevendo nos Logs +=================== + +Escrever nos arquivos de log pode ser feito de duas maneiras diferentes. A primeira +é usar o método estático :php:meth:`Cake\\Log\\Log::write()`:: + + Log::write('debug', 'Something did not work'); + +A segunda é usar a função de atalho ``log()`` disponível em qualquer +classe usando o ``LogTrait``. Chamar ``log()`` chamará internamente +``Log::write()``:: + + // Executing this inside a class using LogTrait + $this->log('Something did not work!', 'debug'); + +Todos os streams de log configurados são escritos sequencialmente cada vez que +:php:meth:`Cake\\Log\\Log::write()` é chamado. Se você não tiver configurado nenhum +engine de logging, ``log()`` retornará ``false`` e nenhuma mensagem de log será +escrita. + +Usando Placeholders em Mensagens +--------------------------------- + +Se você precisa registrar dados definidos dinamicamente, você pode usar placeholders em suas +mensagens de log e fornecer um array de pares chave/valor no parâmetro ``$context``:: + + // Will log `Could not process for userid=1` + Log::write('error', 'Could not process for userid={user}', ['user' => $user->id]); + +Placeholders que não têm chaves definidas não serão substituídos. Se você precisa +usar uma palavra entre chaves literal, você deve escapar o placeholder:: + + // Will log `No {replace}` + Log::write('error', 'No \\{replace}', ['replace' => 'no']); + +Se você incluir objetos em seus placeholders de logging, esses objetos devem implementar +um dos seguintes métodos: + +* ``__toString()`` +* ``toArray()`` +* ``__debugInfo()`` + +.. _logging-levels: + +Usando Níveis +------------- + +O CakePHP suporta o conjunto padrão POSIX de níveis de logging. Cada nível representa +um nível crescente de gravidade: + +* Emergency: sistema está inutilizável +* Alert: ação deve ser tomada imediatamente +* Critical: condições críticas +* Error: condições de erro +* Warning: condições de aviso +* Notice: condição normal mas significativa +* Info: mensagens informativas +* Debug: mensagens de nível debug + +Você pode se referir a esses níveis por nome ao configurar loggers e ao escrever +mensagens de log. Alternativamente, você pode usar métodos de conveniência como +:php:meth:`Cake\\Log\\Log::error()` para indicar claramente o nível de +logging. Usar um nível que não está nos níveis acima resultará em uma +exceção. + +.. note:: + Quando ``levels`` é definido como um valor vazio na configuração de um logger, ele + receberá mensagens de qualquer nível. + +.. _logging-scopes: + +Escopos de Logging +------------------ + +Muitas vezes você vai querer configurar diferentes comportamentos de logging para diferentes +subsistemas ou partes da sua aplicação. Tome como exemplo uma loja de e-commerce. +Você provavelmente vai querer lidar com o logging para pedidos e pagamentos de forma diferente do que +faz com outros logs menos críticos. + +O CakePHP expõe este conceito como escopos de logging. Quando mensagens de log são escritas, +você pode incluir um nome de escopo. Se houver um logger configurado para esse escopo, +as mensagens de log serão direcionadas para esses loggers. Por exemplo:: + + use Cake\Log\Engine\FileLog; + + // Configure logs/shops.log to receive all levels, but only + // those with `orders` and `payments` scope. + Log::setConfig('shops', [ + 'className' => FileLog::class, + 'path' => LOGS, + 'levels' => [], + 'scopes' => ['orders', 'payments'], + 'file' => 'shops.log', + ]); + + // Configure logs/payments.log to receive all levels, but only + // those with `payments` scope. + Log::setConfig('payments', [ + 'className' => FileLog::class, + 'path' => LOGS, + 'levels' => [], + 'scopes' => ['payments'], + 'file' => 'payments.log', + ]); + + Log::warning('this gets written only to shops.log', ['scope' => ['orders']]); + Log::warning('this gets written to both shops.log and payments.log', ['scope' => ['payments']]); + +Escopos também podem ser passados como uma única string ou um array indexado numericamente. +Note que usar este formato limitará a capacidade de passar mais dados como contexto:: + + Log::warning('This is a warning', ['orders']); + Log::warning('This is a warning', 'payments'); + +.. note:: + Quando ``scopes`` é definido como um array vazio ou ``null`` na + configuração de um logger, ele receberá mensagens de qualquer escopo. Defini-lo como ``false`` + só corresponderá a mensagens sem escopo. + +.. _file-log: + +Logging para Arquivos ===================== +Como o nome implica, ``FileLog`` escreve mensagens de log em arquivos. O nível da mensagem de log +sendo escrita determina o nome do arquivo onde a mensagem é armazenada. +Se um nível não for fornecido, :php:const:`LOG_ERR` é usado, que escreve no +log de erro. O local de log padrão é **logs/$level.log**:: + + // Executing this inside a CakePHP class + $this->log("Something didn't work!"); + + // Results in this being appended to logs/error.log + // 2007-11-02 10:22:02 Error: Something didn't work! + +O diretório configurado deve ser gravável pelo usuário do servidor web para +que o logging funcione corretamente. + +Você pode configurar locais FileLog adicionais/alternativos ao configurar +um logger. FileLog aceita um ``path`` que permite que +caminhos personalizados sejam usados:: + + Log::setConfig('custom_path', [ + 'className' => 'File', + 'path' => '/path/to/custom/place/' + ]); + +O engine ``FileLog`` aceita as seguintes opções: + +* ``size`` Usado para implementar rotação básica de arquivo de log. Se o tamanho do arquivo de log + atingir o tamanho especificado, o arquivo existente é renomeado anexando timestamp + ao nome do arquivo e um novo arquivo de log é criado. Pode ser valor inteiro em bytes ou + valores de string legíveis como '10MB', '100KB' etc. Padrão é 10MB. +* ``rotate`` Arquivos de log são rotacionados o número de vezes especificado antes de serem removidos. + Se o valor for 0, versões antigas são removidas em vez de rotacionadas. Padrão é 10. +* ``mask`` Define as permissões de arquivo para arquivos criados. Se deixado vazio, as permissões + padrão são usadas. + +.. note:: + + Diretórios ausentes serão criados automaticamente para evitar + erros desnecessários lançados ao usar o FileEngine. + +.. _syslog-log: + +Logging para Syslog +=================== + +Em ambientes de produção, é altamente recomendado que você configure seu sistema para +usar syslog em vez do logger de arquivo. Isso terá um desempenho muito melhor, pois qualquer +gravação será feita de forma (quase) não bloqueante e o logger do seu sistema operacional +pode ser configurado separadamente para rotacionar arquivos, pré-processar gravações ou usar +um armazenamento completamente diferente para seus logs. + +Usar syslog é praticamente como usar o engine FileLog padrão, você só precisa +especificar ``Syslog`` como o engine a ser usado para logging. O seguinte +snippet de configuração substituirá o logger padrão pelo syslog, isso deve +ser feito no arquivo **config/bootstrap.php**:: + + Log::setConfig('default', [ + 'engine' => 'Syslog' + ]); + +O array de configuração aceito para o engine de logging Syslog entende as +seguintes chaves: + +* ``format``: Uma string template sprintf com dois placeholders, o primeiro + para o nível de erro e o segundo para a própria mensagem. Esta chave é + útil para adicionar informações adicionais sobre o servidor ou processo na + mensagem registrada. Por exemplo: ``%s - Web Server 1 - %s`` parecerá + ``error - Web Server 1 - An error occurred in this request`` após + substituir os placeholders. Esta opção está obsoleta. Você deve usar + :ref:`logging-formatters` em vez disso. +* ``prefix``: Uma string que será prefixada a cada mensagem registrada. +* ``flag``: Uma flag inteira a ser usada para abrir a conexão com o + logger, por padrão ``LOG_ODELAY`` será usado. Veja a documentação ``openlog`` + para mais opções +* ``facility``: O slot de logging a ser usado no syslog. Por padrão ``LOG_USER`` é + usado. Veja a documentação ``syslog`` para mais opções + +Criando Engines de Log +======================= + +Engines de log podem fazer parte da sua aplicação ou parte de +plugins. Se, por exemplo, você tivesse um logger de banco de dados chamado +``DatabaseLog``. Como parte da sua aplicação, ele seria colocado em +**src/Log/Engine/DatabaseLog.php**. Como parte de um plugin, seria colocado em +**plugins/LoggingPack/src/Log/Engine/DatabaseLog.php**. Para configurar +engine de log, você deve usar :php:meth:`Cake\\Log\\Log::setConfig()`. Por exemplo, +configurar nosso DatabaseLog ficaria assim:: + + // For src/Log + Log::setConfig('otherFile', [ + 'className' => 'Database', + 'model' => 'LogEntry', + // ... + ]); + + // For plugin called LoggingPack + Log::setConfig('otherFile', [ + 'className' => 'LoggingPack.Database', + 'model' => 'LogEntry', + // ... + ]); + +Ao configurar um engine de log, o parâmetro ``className`` é usado para +localizar e carregar o manipulador de log. Todas as outras propriedades de +configuração são passadas para o construtor do engine de log como um array. :: + + namespace App\Log\Engine; + use Cake\Log\Engine\BaseLog; + + class DatabaseLog extends BaseLog + { + public function __construct(array $config = []) + { + parent::__construct($config); + // ... + } + + public function log($level, string $message, array $context = []) + { + // Write to the database. + } + } + +O CakePHP requer que todos os engines de logging implementem ``Psr\Log\LoggerInterface``. +A classe :php:class:`Cake\Log\Engine\BaseLog` é uma maneira fácil de satisfazer a +interface, pois requer apenas que você implemente o método ``log()``. + +.. _logging-formatters: + +Formatadores de Logging +======================== + +Formatadores de logging permitem que você controle como as mensagens de log são formatadas +independentemente do engine de armazenamento. Cada engine de logging fornecido pelo núcleo vem com +um formatador configurado para manter a saída compatível com versões anteriores. No entanto, você pode +ajustar os formatadores para atender às suas necessidades. Formatadores são configurados +junto com o engine de logging:: + + use Cake\Log\Engine\SyslogLog; + use App\Log\Formatter\CustomFormatter; + + // Simple formatting configuration with no options. + Log::setConfig('error', [ + 'className' => SyslogLog::class, + 'formatter' => CustomFormatter::class, + ]); + + // Configure a formatter with additional options. + Log::setConfig('error', [ + 'className' => SyslogLog::class, + 'formatter' => [ + 'className' => CustomFormatter::class, + 'key' => 'value', + ], + ]); + +Para implementar seu próprio formatador de logging, você precisa estender +``Cake\Log\Format\AbstractFormatter`` ou uma de suas subclasses. O método principal +que você precisa implementar é ``format($level, $message, $context)``, que é +responsável por formatar mensagens de log. + +.. _log-testing: + +Testando Logs +============= + +Para testar logging, adicione ``Cake\TestSuite\LogTestTrait`` ao seu caso de teste. O +``LogTestTrait`` usa hooks do PHPUnit para anexar engines de log que interceptam as mensagens de log +que sua aplicação está fazendo. Uma vez que você capturou logs, você pode realizar +asserções em mensagens de log que sua aplicação está emitindo. Por exemplo:: + + namespace App\Test\TestCase\Controller; + + use Cake\TestSuite\LogTestTrait; + use Cake\TestSuite\TestCase; + + class UsersControllerTest extends TestCase + { + use LogTestTrait; + + public function setUp(): void + { + parent::setUp(); + $this->setupLog([ + 'error' => ['scopes' => ['app.security']] + ]); + } + + public function testResetPassword() + { + $this->post('/users/resetpassword', ['email' => 'bob@example.com']); + $this->assertLogMessageContains('info', 'bob@example.com reset password', 'app.security'); + } + } + +Você usa ``setupLog()`` para definir as mensagens de log que deseja capturar e +realizar asserções. Depois que os logs foram emitidos, você pode fazer asserções sobre +o conteúdo dos logs ou a ausência deles: + +* ``assertLogMessage(string $level, string $expectedMessage, ?string $scope + = null, string $failMsg = '')`` Afirma que uma mensagem de log foi encontrada. +* ``assertLogMessageContains(string $level, string $expectedMessage, ?string + $scope = null, string $failMsg = '')`` Afirma que uma mensagem de log contém a + substring. +* ``assertLogAbsent(string $level, ?string $failMsg = '')`` Afirma que nenhuma mensagem de log + do nível fornecido foi capturada. + +O ``LogTestTrait`` irá automaticamente limpar quaisquer loggers que foram +configurados. + +API de Log +========== + +.. php:namespace:: Cake\Log + +.. php:class:: Log + + Uma classe simples para escrever em logs. + +.. php:staticmethod:: setConfig($key, $config) + + :param string $name: Nome para o logger sendo conectado, usado + para remover um logger posteriormente. + :param array $config: Array de informações de configuração e + argumentos do construtor para o logger. + + Obter ou definir a configuração para um Logger. Veja :ref:`log-configuration` para + mais informações. + +.. php:staticmethod:: configured() + + :returns: Um array de loggers configurados. + + Obter os nomes dos loggers configurados. + +.. php:staticmethod:: drop($name) + + :param string $name: Nome do logger que você deseja que não receba mais + mensagens. + +.. php:staticmethod:: write($level, $message, $scope = []) + + Escrever uma mensagem em todos os loggers configurados. + ``$level`` indica o nível da mensagem de log sendo criada. + ``$message`` é a mensagem da entrada de log sendo escrita. + ``$scope`` é o(s) escopo(s) em que uma mensagem de log está sendo criada. + +.. php:staticmethod:: levels() + +Chame este método sem argumentos, ex: `Log::levels()` para obter a +configuração de nível atual. + +Métodos de Conveniência +------------------------ + +Os seguintes métodos de conveniência foram adicionados para registrar `$message` com o +nível de log apropriado. + +.. php:staticmethod:: emergency($message, $scope = []) +.. php:staticmethod:: alert($message, $scope = []) +.. php:staticmethod:: critical($message, $scope = []) +.. php:staticmethod:: error($message, $scope = []) +.. php:staticmethod:: warning($message, $scope = []) +.. php:staticmethod:: notice($message, $scope = []) +.. php:staticmethod:: info($message, $scope = []) +.. php:staticmethod:: debug($message, $scope = []) + +Trait de Logging +================= + +.. php:trait:: LogTrait + + Um trait que fornece métodos de atalho para logging + +.. php:method:: log($msg, $level = LOG_ERR) + + Registrar uma mensagem nos logs. Por padrão, as mensagens são registradas como + mensagens ERROR. + +Usando Monolog +============== + +Monolog é um logger popular para PHP. Como ele implementa as mesmas interfaces que +os loggers do CakePHP, você pode usá-los em sua aplicação como o logger +padrão. + +Após instalar o Monolog usando o composer, configure o logger usando o +método ``Log::setConfig()``:: + + // config/bootstrap.php + + use Monolog\Logger; + use Monolog\Handler\StreamHandler; + + Log::setConfig('default', function () { + $log = new Logger('app'); + $log->pushHandler(new StreamHandler('path/to/your/combined.log')); + + return $log; + }); + + // Optionally stop using the now redundant default loggers + Log::drop('debug'); + Log::drop('error'); + +Use métodos similares se você quiser configurar um logger diferente para seu console:: + + // config/bootstrap_cli.php + + use Monolog\Logger; + use Monolog\Handler\StreamHandler; + + Log::setConfig('default', function () { + $log = new Logger('cli'); + $log->pushHandler(new StreamHandler('path/to/your/combined-cli.log')); + + return $log; + }); + + // Optionally stop using the now redundant default CLI loggers + Configure::delete('Log.debug'); + Configure::delete('Log.error'); + .. note:: - Atualmente, a documentação desta página não é suportada em português. - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. + Ao usar um logger específico do console, certifique-se de configurar condicionalmente + o logger da sua aplicação. Isso evitará entradas de log duplicadas. - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. \ No newline at end of file +.. meta:: + :title lang=pt: Logging + :description lang=pt: Registre dados do CakePHP no disco para ajudar a depurar sua aplicação por períodos mais longos de tempo. + :keywords lang=pt: cakephp logging,registrar erros,debug,logging data,classe cakelog,ajax logging,soap logging,debugging,logs diff --git a/pt/core-libraries/number.rst b/pt/core-libraries/number.rst index c650ea9ef2..df27293b70 100644 --- a/pt/core-libraries/number.rst +++ b/pt/core-libraries/number.rst @@ -1,12 +1,12 @@ -Número +Number ###### .. php:namespace:: Cake\I18n .. php:class:: Number -Se você precisa das funcionalidades do :php:class:`NumberHelper` fora da ``View``, -use a classe ``Number`` :: +Se você precisa das funcionalidades do :php:class:`NumberHelper` fora de uma ``View``, +use a classe ``Number``:: namespace App\Controller; @@ -17,14 +17,15 @@ use a classe ``Number`` :: public function initialize(): void { parent::initialize(); - $this->loadComponent('Auth'); + $this->loadComponent('Authentication.Authentication'); } public function afterLogin() { - $storageUsed = $this->Auth->user('storage_used'); + $identity = $this->Authentication->getIdentity(); + $storageUsed = $identity->storage_used; if ($storageUsed > 5000000) { - // Notify users of quota + // Notificar usuários sobre cota $this->Flash->success(__('You are using {0} storage', Number::toReadableSize($storageUsed))); } } @@ -32,30 +33,29 @@ use a classe ``Number`` :: .. start-cakenumber -Todas essas funções retornam o número formatado; eles não -são impressas automaticamente na visualização de saída. +Todas essas funções retornam o número formatado; elas não +ecoam automaticamente a saída na view. -Formatação de Valores Monetários -================================ +Formatando Valores de Moeda +============================ .. php:method:: currency(mixed $value, string $currency = null, array $options = []) -Este método é usado para exibir um número em formatos monetários comuns -(EUR, GBP, USD), com base no código de moeda ISO 4217 de 3 letras. O uso em uma view se parece com:: +Este método é usado para exibir um número em formatos de moeda comuns +(EUR, GBP, USD), com base no código de moeda ISO 4217 de 3 letras. O uso em uma view é assim:: - // Called as NumberHelper + // Chamado como NumberHelper echo $this->Number->currency($value, $currency); - // Called as Number + // Chamado como Number echo Number::currency($value, $currency); O primeiro parâmetro, ``$value``, deve ser um número de ponto flutuante -que representa a quantidade de dinheiro que você está expressando. -O segundo parâmetro é uma string usada para escolher um esquema de -formatação de monetária predefinida: +que representa a quantidade de dinheiro que você está expressando. O segundo +parâmetro é uma string usada para escolher um esquema de formatação de moeda predefinido: +---------------------+----------------------------------------------------+ -| $ moeda | 1234.56, formatação pelo tipo monetário | +| $currency | 1234.56, formatado por tipo de moeda | +=====================+====================================================+ | EUR | €1.234,56 | +---------------------+----------------------------------------------------+ @@ -64,128 +64,129 @@ formatação de monetária predefinida: | USD | $1,234.56 | +---------------------+----------------------------------------------------+ -O terceiro parâmetro é um conjunto de opções para definir melhor a saída. -As seguintes opções estão disponíveis: +O terceiro parâmetro é um array de opções para definir ainda mais a +saída. As seguintes opções estão disponíveis: +---------------------+----------------------------------------------------+ | Opção | Descrição | +=====================+====================================================+ -| before | Texto a ser exibido antes do número renderizado. | +| before | Texto a exibir antes do número renderizado. | +---------------------+----------------------------------------------------+ -| after | Texto a ser exibido após o número renderizado. | +| after | Texto a exibir após o número renderizado. | +---------------------+----------------------------------------------------+ -| zero | O texto a ser usado para valores zero; pode ser | -| | uma string ou um número. ou seja, 0, 'Grátis!'. | +| zero | O texto a usar para valores zero; pode ser uma | +| | string ou um número. Ex: 0, 'Grátis!'. | +---------------------+----------------------------------------------------+ -| places | Número de casas decimais a serem usadas, ou seja, 2| +| places | Número de casas decimais a usar, ex: 2 | +---------------------+----------------------------------------------------+ -| precision | Número máximo de casas decimais a serem usadas, | -| | ou seja, 2 | +| precision | Número máximo de casas decimais a usar, ex: 2 | +---------------------+----------------------------------------------------+ -| locale | O nome do local a ser usado para formatar o número,| -| | ou seja. “Fr_FR”. | +| locale | O nome da localidade a usar para formatar o | +| | número, ex: "fr_FR". | +---------------------+----------------------------------------------------+ -| fractionSymbol | String a ser usada para números fracionários, ou | -| | seja, 'centavos'. | +| fractionSymbol | String a usar para números fracionários, | +| | ex: ' centavos'. | +---------------------+----------------------------------------------------+ -| fractionPosition | Ou 'antes' ou 'depois' para colocar o símbolo de | +| fractionPosition | 'before' ou 'after' para posicionar o símbolo de | | | fração. | +---------------------+----------------------------------------------------+ -| pattern | Um padrão de número ICU a ser usado para formatar | -| | o número, ou seja. #, ###. 00 | +| pattern | Um padrão de número ICU a usar para formatar o | +| | número, ex: #,###.00 | +---------------------+----------------------------------------------------+ -| useIntlCode | Defina como ``true`` para substituir o símbolo da | -| | moeda pelo código de moeda internacional | +| useIntlCode | Defina como ``true`` para substituir o símbolo de | +| | moeda pelo código de moeda internacional. | +---------------------+----------------------------------------------------+ -Se de ``$currency`` for ``null``, a moeda padrão será retornada em +Se o valor de ``$currency`` for ``null``, a moeda padrão será recuperada de :php:meth:`Cake\\I18n\\Number::defaultCurrency()`. Para formatar moedas em um -formato de contabilidade, você deve definir o formato da moeda:: +formato contábil, você deve definir o formato de moeda:: Number::setDefaultCurrencyFormat(Number::FORMAT_CURRENCY_ACCOUNTING); -Definição da moeda padrão +Definindo a Moeda Padrão ========================= .. php:method:: setDefaultCurrency($currency) -Atribui a moeda padrão. Isso elimina a necessidade de sempre passar a moeda -para :php:meth:`Cake\\I18n\\Number::currency()` e alterar todas as saídas de -moeda definindo outro padrão. Se ``$currency`` atribuído o valor ``null``, -ele apagará o valor armazenado no momento. +Setter para a moeda padrão. Isso remove a necessidade de sempre passar a +moeda para :php:meth:`Cake\\I18n\\Number::currency()` e alterar todas +as saídas de moeda definindo outro padrão. Se ``$currency`` for definido como ``null``, +isso limpará o valor armazenado atualmente. -Obtendo a moeda padrão -====================== +Obtendo a Moeda Padrão +======================= .. php:method:: getDefaultCurrency() -Obtem a moeda padrão. Se a moeda padrão foi definida anteriormente usando -``setDefaultCurrency()``, então esse valor será retornado. Por padrão, ele irá -retornar o valor ``intl.default_locale`` do ini se estiver atribuído e ``'en_US'`` se não estiver. +Getter para a moeda padrão. Se a moeda padrão foi definida anteriormente usando +``setDefaultCurrency()``, então esse valor será retornado. Por padrão, ele +recuperará o valor ini ``intl.default_locale`` se definido e ``'en_US'`` se não. -Formatando números de ponto flutuante -===================================== +Formatando Números de Ponto Flutuante +====================================== .. php:method:: precision(float $value, int $precision = 3, array $options = []) -Este método exibe um número com a quantidade especificada de precisão (casas decimais). -Ele será arredondado para manter o nível de precisão definido. :: +Este método exibe um número com a quantidade especificada de +precisão (casas decimais). Ele arredondará para manter o +nível de precisão definido. :: - // Called as NumberHelper + // Chamado como NumberHelper echo $this->Number->precision(456.91873645, 2); - // Outputs + // Saída 456.92 - // Called as Number + // Chamado como Number echo Number::precision(456.91873645, 2); -Formatação de Porcentagens -========================== +Formatando Porcentagens +======================== .. php:method:: toPercentage(mixed $value, int $precision = 2, array $options = []) -+---------------------+--------------------------------------------------------+ -| Opção | Descrição | -+=====================+========================================================+ -| multiply | Booleano para indicar se o valor deve ser | -| | multiplicado por 100. Útil para porcentagens decimais. | -+---------------------+--------------------------------------------------------+ ++---------------------+----------------------------------------------------+ +| Opção | Descrição | ++=====================+====================================================+ +| multiply | Booleano para indicar se o valor deve ser | +| | multiplicado por 100. Útil para porcentagens | +| | decimais. | ++---------------------+----------------------------------------------------+ -Da mesma forma :php:meth:`Cake\\I18n\\Number::precision()`, ste método formata um -número de acordo com a precisão fornecida (onde os números são arredondados para -atender à precisão fornecida). Este método também expressa o número como uma -porcentagem e anexa a saída com um sinal de porcentagem. :: +Como :php:meth:`Cake\\I18n\\Number::precision()`, este método formata um número +de acordo com a precisão fornecida (onde os números são arredondados para atender à +precisão fornecida). Este método também expressa o número como uma porcentagem +e acrescenta a saída com um sinal de porcentagem. :: - // Called as NumberHelper. Output: 45.69% + // Chamado como NumberHelper. Saída: 45.69% echo $this->Number->toPercentage(45.691873645); - // Called as Number. Output: 45.69% + // Chamado como Number. Saída: 45.69% echo Number::toPercentage(45.691873645); - // Called with multiply. Output: 45.7% + // Chamado com multiply. Saída: 45.7% echo Number::toPercentage(0.45691, 1, [ 'multiply' => true ]); -Interagindo com valores legíveis para humanos -============================================= +Interagindo com Valores Legíveis para Humanos +============================================== .. php:method:: toReadableSize(string $size) -Este método formata o tamanho dos dados em formatos legíveis -por humanos. Ele fornece uma forma de atalho para converter bytes -em KB, MB, GB e TB. O tamanho é exibido com um nível de precisão de dois dígitos, -de acordo com o tamanho dos dados fornecidos (ou seja, tamanhos maiores são -expressos em termos maiores) :: +Este método formata tamanhos de dados em formas legíveis para humanos. Ele fornece +um atalho para converter bytes em KB, MB, GB e TB. O tamanho é +exibido com um nível de precisão de dois dígitos, de acordo com o tamanho +dos dados fornecidos (ou seja, tamanhos maiores são expressos em termos +maiores):: - // Called as NumberHelper + // Chamado como NumberHelper echo $this->Number->toReadableSize(0); // 0 Byte echo $this->Number->toReadableSize(1024); // 1 KB echo $this->Number->toReadableSize(1321205.76); // 1.26 MB echo $this->Number->toReadableSize(5368709120); // 5 GB - // Called as Number + // Chamado como Number echo Number::toReadableSize(0); // 0 Byte echo Number::toReadableSize(1024); // 1 KB echo Number::toReadableSize(1321205.76); // 1.26 MB @@ -196,155 +197,157 @@ Formatando Números .. php:method:: format(mixed $value, array $options = []) -Este método fornece muito mais controle sobre a formatação de números -para uso em suas visualizações (e é usado como o método principal pela -maioria dos outros métodos NumberHelper). Usar este método pode ser -parecido com:: +Este método oferece muito mais controle sobre a formatação de +números para uso em suas views (e é usado como método principal por +a maioria dos outros métodos do NumberHelper). Usar este método pode +parecer assim:: - // Called as NumberHelper + // Chamado como NumberHelper $this->Number->format($value, $options); - // Called as Number + // Chamado como Number Number::format($value, $options); -O parâmetro ``$value`` é o número que você está planejando formatar para -saída. Sem o formatting for output. Sem o ``$options``, o número -1236.334 produzirá a saída 1,236. Observe que a precisão padrão -é zero casas decimais. +O parâmetro ``$value`` é o número que você está planejando +formatar para saída. Sem ``$options`` fornecidas, o número +1236.334 seria exibido como 1,236. Observe que a precisão padrão é +zero casas decimais. -O parâmetro ``$options`` é onde reside a verdadeira magia desse método. +O parâmetro ``$options`` é onde a verdadeira mágica deste método +reside. -- Se você passar um número inteiro, isso se tornará a quantidade de precisão ou casas para a função. -- Se você passar uma matriz associada, você pode usar as seguintes chaves: +- Se você passar um inteiro, então isso se torna a quantidade de precisão + ou casas para a função. +- Se você passar um array associativo, você pode usar as seguintes chaves: +---------------------+----------------------------------------------------+ -| Opção | Descrição | +| Opção | Descrição | +=====================+====================================================+ -| places | Número de casas decimais a serem usadas, ou seja, 2| +| places | Número de casas decimais a usar, ex: 2 | +---------------------+----------------------------------------------------+ -| precision | Número máximo de casas decimais a serem usadas, ou | -| | seja, 2 | +| precision | Número máximo de casas decimais a usar, ex: 2 | +---------------------+----------------------------------------------------+ -| pattern | Um padrão de número ICU a ser usado para formatar | -| | o número, ou seja. #, ###. 00 | +| pattern | Um padrão de número ICU a usar para formatar o | +| | número, ex: #,###.00 | +---------------------+----------------------------------------------------+ -| locale | O nome do local a ser usado para formatar o número,| -| | ou seja. “Fr_FR”. | +| locale | O nome da localidade a usar para formatar o | +| | número, ex: "fr_FR". | +---------------------+----------------------------------------------------+ -| before | Texto a ser exibido antes do número renderizado. | +| before | Texto a exibir antes do número renderizado. | +---------------------+----------------------------------------------------+ -| after | Texto a ser exibido após o número renderizado. | +| after | Texto a exibir após o número renderizado. | +---------------------+----------------------------------------------------+ Exemplo:: - // Called as NumberHelper + // Chamado como NumberHelper echo $this->Number->format('123456.7890', [ 'places' => 2, 'before' => '¥ ', 'after' => ' !' ]); - // Output '¥ 123,456.79 !' + // Saída '¥ 123,456.79 !' echo $this->Number->format('123456.7890', [ 'locale' => 'fr_FR' ]); - // Output '123 456,79 !' + // Saída '123 456,79 !' - // Called as Number + // Chamado como Number echo Number::format('123456.7890', [ 'places' => 2, 'before' => '¥ ', 'after' => ' !' ]); - // Output '¥ 123,456.79 !' + // Saída '¥ 123,456.79 !' echo Number::format('123456.7890', [ 'locale' => 'fr_FR' ]); - // Output '123 456,79 !' + // Saída '123 456,79 !' .. php:method:: ordinal(mixed $value, array $options = []) -Este método irá gerar um número ordinal. +Este método produzirá um número ordinal. Exemplos:: echo Number::ordinal(1); - // Output '1st' + // Saída '1st' echo Number::ordinal(2); - // Output '2nd' + // Saída '2nd' echo Number::ordinal(2, [ 'locale' => 'fr_FR' ]); - // Output '2e' + // Saída '2e' echo Number::ordinal(410); - // Output '410th' + // Saída '410th' -Diferenças de formato +Diferenças de Formato ===================== .. php:method:: formatDelta(mixed $value, array $options = []) -Este método exibe diferenças de valor como um número assinado:: +Este método exibe diferenças de valor como um número com sinal:: - // Called as NumberHelper + // Chamado como NumberHelper $this->Number->formatDelta($value, $options); - // Called as Number + // Chamado como Number Number::formatDelta($value, $options); -O parâmetro ``$value`` é o número que você está planejando formatar -para saída. Sem o ``$options`` , 1236.334 produziria como saída 1,236. -Observe que a precisão padrão é zero casas decimais. +O parâmetro ``$value`` é o número que você está planejando +formatar para saída. Sem ``$options`` fornecidas, o número +1236.334 seria exibido como 1,236. Observe que a precisão padrão é +zero casas decimais. -O parâmetro ``$options`` usa as mesmas chaves que :php:meth:`Number::format()`: +O parâmetro ``$options`` recebe as mesmas chaves que :php:meth:`Number::format()`: +---------------------+----------------------------------------------------+ -| Opção | Descrição | +| Opção | Descrição | +=====================+====================================================+ -| places | Número de casas decimais a serem usadas, ou seja, 2| +| places | Número de casas decimais a usar, ex: 2 | +---------------------+----------------------------------------------------+ -| precision | Número máximo de casas decimais a serem usadas, ou | -| | seja, 2 | +| precision | Número máximo de casas decimais a usar, ex: 2 | +---------------------+----------------------------------------------------+ -| locale | O nome do local a ser usado para formatar o número,| -| | ou seja. “Fr_FR”. | +| locale | O nome da localidade a usar para formatar o | +| | número, ex: "fr_FR". | +---------------------+----------------------------------------------------+ -| before | Texto a ser exibido antes do número renderizado. | +| before | Texto a exibir antes do número renderizado. | +---------------------+----------------------------------------------------+ -| after | Texto a ser exibido após o número renderizado. | +| after | Texto a exibir após o número renderizado. | +---------------------+----------------------------------------------------+ Exemplo:: - // Called as NumberHelper + // Chamado como NumberHelper echo $this->Number->formatDelta('123456.7890', [ 'places' => 2, 'before' => '[', 'after' => ']' ]); - // Output '[+123,456.79]' + // Saída '[+123,456.79]' - // Called as Number + // Chamado como Number echo Number::formatDelta('123456.7890', [ 'places' => 2, 'before' => '[', 'after' => ']' ]); - // Output '[+123,456.79]' + // Saída '[+123,456.79]' .. end-cakenumber -Configurar formatadores +Configurar Formatadores ======================= .. php:method:: config(string $locale, int $type = NumberFormatter::DECIMAL, array $options = []) -Este método permite configurar padrões do formatador que persistem nas chamadas para vários métodos. +Este método permite configurar padrões de formatador que persistem entre chamadas +para vários métodos. Exemplo:: @@ -354,5 +357,5 @@ Exemplo:: .. meta:: :title lang=pt: NumberHelper - :description lang=pt: O Helper Number contém métodos convenientes que permitem a exibição de números em formatos comuns em suas visualizações. - :keywords lang=pt: number helper, moeda, formato de número, precisão de número, tamanho do arquivo de formato, números de formato + :description lang=pt: O Number Helper contém métodos de conveniência que permitem exibir números em formatos comuns em suas views. + :keywords lang=pt: number helper,currency,number format,number precision,format file size,format numbers diff --git a/pt/core-libraries/plugin.rst b/pt/core-libraries/plugin.rst new file mode 100644 index 0000000000..77773fab6b --- /dev/null +++ b/pt/core-libraries/plugin.rst @@ -0,0 +1,53 @@ +Classe Plugin +############# + +.. php:namespace:: Cake\Core + +.. php:class:: Plugin + +A classe Plugin é responsável pela localização de recursos e gerenciamento de caminhos de plugins. + +Localizando Plugins +=================== + +.. php:staticmethod:: path(string $plugin) + +Plugins podem ser localizados com Plugin. Usar ``Plugin::path('DebugKit');`` +por exemplo, lhe dará o caminho completo para o plugin DebugKit:: + + $path = Plugin::path('DebugKit'); + +Verificar se um Plugin está Carregado +====================================== + +Você pode verificar dinamicamente dentro do seu código se um plugin específico foi carregado:: + + $isLoaded = Plugin::isLoaded('DebugKit'); + +Use ``Plugin::loaded()`` se você quiser obter uma lista de todos os plugins atualmente carregados. + +Encontrando Caminhos para Namespaces +===================================== + +.. php:staticmethod:: classPath(string $plugin) + +Usado para obter a localização dos arquivos de classe do plugin:: + + $path = App::classPath('DebugKit'); + +Encontrando Caminhos para Recursos +=================================== + +.. php:staticmethod:: templatePath(string $plugin) + +O método retorna o caminho para os templates do plugin:: + + $path = Plugin::templatePath('DebugKit'); + +O mesmo vale para o caminho de config:: + + $path = Plugin::configPath('DebugKit'); + +.. meta:: + :title lang=en: Plugin Class + :keywords lang=en: compatible implementation,model behaviors,path management,loading files,php class,class loading,model behavior,class location,component model,management class,autoloader,classname,directory location,override,conventions,lib,textile,cakephp,php classes,loaded diff --git a/pt/core-libraries/registry-objects.rst b/pt/core-libraries/registry-objects.rst index 4dc81b6d1f..e8f1accb3d 100644 --- a/pt/core-libraries/registry-objects.rst +++ b/pt/core-libraries/registry-objects.rst @@ -1,12 +1,57 @@ Objetos de Registro ################### -.. note:: - Atualmente, a documentação desta página não é suportada em português. +As classes de registro fornecem uma maneira simples de criar e recuperar instâncias +carregadas de um determinado tipo de objeto. Existem classes de registro para Components, +Helpers, Tasks e Behaviors. - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. +Embora os exemplos abaixo usem Components, o mesmo comportamento pode ser esperado +para Helpers, Behaviors e Tasks, além de Components. - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. \ No newline at end of file +Carregando Objetos +================== + +Objetos podem ser carregados dinamicamente usando add() +Exemplo:: + + $this->loadComponent('Acl.Acl'); + $this->addHelper('Flash') + +Isso resultará no carregamento da propriedade ``Acl`` e do helper ``Flash``. +A configuração também pode ser definida dinamicamente. Exemplo:: + + $this->loadComponent('Cookie', ['name' => 'sweet']); + +Quaisquer chaves e valores fornecidos serão passados para o construtor do Component. A +única exceção a esta regra é ``className``. Classname é uma chave especial que é +usada para criar aliases de objetos em um registro. Isso permite que você tenha nomes de components +que não refletem os nomes de classe, o que pode ser útil ao estender components +do núcleo:: + + $this->Flash = $this->loadComponent('Flash', ['className' => 'MyCustomFlash']); + $this->Flash->error(); // Actually using MyCustomFlash::error(); + +Acionando Callbacks +=================== + +Callbacks não são fornecidos por objetos de registro. Você deve usar o +:doc:`sistema de eventos ` para disparar quaisquer eventos/callbacks +para sua aplicação. + +Desabilitando Callbacks +======================== + +Em versões anteriores, objetos de coleção forneciam um método ``disable()`` para desabilitar +objetos de receber callbacks. Você deve usar os recursos do sistema de eventos para +fazer isso agora. Por exemplo, você poderia desabilitar callbacks de components da +seguinte maneira:: + + // Remove MyComponent from callbacks. + $this->getEventManager()->off($this->MyComponent); + + // Re-enable MyComponent for callbacks. + $this->getEventManager()->on($this->MyComponent); + +.. meta:: + :title lang=pt: Objetos de Registro + :keywords lang=pt: array name,loading components,several different kinds,unified api,loading objects,component names,special key,core components,callbacks,prg,callback,alias,fatal error,collections,memory,priority,priorities diff --git a/pt/core-libraries/security.rst b/pt/core-libraries/security.rst index f1bd39ae1f..4e71f13642 100644 --- a/pt/core-libraries/security.rst +++ b/pt/core-libraries/security.rst @@ -1,92 +1,70 @@ -Segurança -######### +Utilitário de Segurança +####################### .. php:namespace:: Cake\Utility .. php:class:: Security A `biblioteca de segurança -`_ -trabalha com medidas básicas de segurança fornecendo métodos para -`hash` e criptografia de dados. +`_ +lida com medidas básicas de segurança, como fornecer métodos para +fazer hash e criptografar dados. Criptografando e Descriptografando Dados -========================================== +========================================= .. php:staticmethod:: encrypt($text, $key, $hmacSalt = null) .. php:staticmethod:: decrypt($cipher, $key, $hmacSalt = null) -Criptografando ``$text`` usando AES-256. A ``$key`` deve ser um valor com -dados variados como uma senha forte. O resultado retornado será o valor -criptografado com um `HMAC checksum`. +Criptografa ``$text`` usando AES-256. A ``$key`` deve ser um valor com muita +variância nos dados, muito parecido com uma boa senha. O resultado retornado +será o valor criptografado com uma soma de verificação HMAC. -Este método irá usar `openssl `_ ou `mcrypt -`_ dependendo de qual deles estiver disponível em seu sistema. Dados criptografados em uma implementação são portáveis para a outra. +A extensão `openssl `_ é necessária para criptografar/descriptografar. -.. warning:: - A extensão `mcrypt `_ foi considerada obsoleta no PHP7.1 - -Este método **nunca** deve ser usado para armazenar senhas. Em vez disso, você deve usar -o método de ``hash`` de mão única fornecidos por -:php:meth:`~Cake\\Utility\\Security::hash()`. Um exemplo de uso pode ser:: +Um exemplo de uso seria:: - // Assumindo que $key está gravada em algum lugar, ela pode ser reusada para - // descriptografar depois. + // Assumindo que a chave está armazenada em algum lugar onde pode ser reutilizada para + // descriptografia posteriormente. $key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA'; $result = Security::encrypt($value, $key); -Se você não fornecer um ``HMAC salt``, o valor em ``Security.salt`` será usado. -Os valores criptografados podem ser descriptografados usando +Se você não fornecer um sal HMAC, o valor de ``Security::getSalt()`` será usado. +Valores criptografados podem ser descriptografados usando :php:meth:`Cake\\Utility\\Security::decrypt()`. -Descriptografando um valor criptografado anteriormente. Os parametros ``$key`` e ``$hmacSalt`` -devem corresponder aos valores utilizados para a criptografia senão o processo falhará. +Este método **nunca** deve ser usado para armazenar senhas. -Exemplo:: +Descriptografa um valor criptografado anteriormente. Os parâmetros ``$key`` e ``$hmacSalt`` +devem corresponder aos valores usados para criptografar ou a descriptografia falhará. Um +exemplo de uso seria:: - // Assumindo que $key está gravada em algum lugar, ela pode ser reusada para - // descriptografar depois. + // Assumindo que a chave está armazenada em algum lugar onde pode ser reutilizada para + // Descriptografia posteriormente. $key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA'; $cipher = $user->secrets; $result = Security::decrypt($cipher, $key); -Se o valor não puder ser descriptografado por mudanças em ``$key`` ou ``HMAC salt`` -o método retornará ``false``. - -.. _force-mcrypt: - -Escolhendo uma implementação de criptografia --------------------------------------------- - -Se você está atualizando sua aplicação do CakePHP 2.x, os dados criptografados -não serão compatíveis com openssl por que seus dados criptografados não são totalmente -compatíveis com AES. Se você não quiser ter o trabalho de refazer a criptografia dos seus -dados, você pode forçar o CakePHP a usar ``mcrypt`` através do método ``engine()``:: +Se o valor não puder ser descriptografado devido a alterações na chave ou sal HMAC, +``false`` será retornado. - // Em config/bootstrap.php - use Cake\Utility\Crypto\Mcrypt; - - Security::engine(new Mcrypt()); - -O código acima permitirá que você leia dados de versões anteriores do CakePHP -e criptografar novos dados para serem compatíveis com OpenSSL. - -Fazendo Hash de dados -===================== +Fazendo Hash de Dados +====================== .. php:staticmethod:: hash( $string, $type = NULL, $salt = false ) -Criando um hash de uma string usando o método acima. Se ``$salt`` estiver -setado como ``true`` o salt da aplicação será utilizado:: +Cria um hash de string usando o método fornecido. Retorna ao próximo +método disponível. Se ``$salt`` for definido como ``true``, o valor de sal da +aplicação será usado:: - // Usando salt definido na aplicação + // Usando o valor de sal da aplicação $sha1 = Security::hash('CakePHP Framework', 'sha1', true); - // Usando um salt customizado + // Usando um valor de sal personalizado $sha1 = Security::hash('CakePHP Framework', 'sha1', 'my-salt'); - // Usando o padrão do algoritmo de hash + // Usando o algoritmo de hash padrão $hash = Security::hash('CakePHP Framework'); O método ``hash()`` suporta as seguintes estratégias de hash: @@ -95,27 +73,34 @@ O método ``hash()`` suporta as seguintes estratégias de hash: - sha1 - sha256 -E qualquer outro algoritmo de hash que a função ``hash()`` do PHP suporta. +E qualquer outro algoritmo de hash que a função ``hash()`` do PHP suporte. .. warning:: - Você não deve usar ``hash()`` para senhas em novas aplicações, o ideal - é usar a classe ``DefaultPasswordHasher`` que usa ``bcrypt`` por padrão. + Você não deve usar ``hash()`` para senhas em novas aplicações. + Em vez disso, você deve usar a classe ``DefaultPasswordHasher`` que usa bcrypt + por padrão. -Gerando dados aleatórios seguros -================================ +Obtendo Dados Aleatórios Seguros +================================= .. php:staticmethod:: randomBytes($length) -Obter ``$length`` número de bytes de uma fonte segura aleatória. Esta função -utiliza um dos seguntes métodos: +Obtenha ``$length`` número de bytes de uma fonte aleatória segura. Esta função extrai +dados de uma das seguintes fontes: * Função ``random_bytes`` do PHP. -* Função ``openssl_random_pseudo_bytes`` da extensão SSL. +* ``openssl_random_pseudo_bytes`` da extensão SSL. + +Se nenhuma fonte estiver disponível, um aviso será emitido e um valor +inseguro será usado por motivos de compatibilidade com versões anteriores. + +.. php:staticmethod:: randomString($length) -Se nenhuma das opções estiverem disponíveis um ``warning`` será emitido e um -valor não seguro será usado por motivos de compatibilidade. +Obtenha uma string aleatória com ``$length`` de comprimento de uma fonte aleatória segura. Este método +extrai da mesma fonte aleatória que ``randomBytes()`` e codificará os dados +como uma string hexadecimal. .. meta:: - :title lang=pt: Segurança - :keywords lang=pt: api segurança,senha,cipher text,php class,class security,text key,security library,object instance,security measures,basic security,security level,string type,fallback,hash,data security,singleton,inactivity,php encrypt,implementation,php security + :title lang=pt: Security + :keywords lang=pt: security api,secret password,cipher text,php class,class security,text key,security library,object instance,security measures,basic security,security level,string type,fallback,hash,data security,singleton,inactivity,php encrypt,implementation,php security diff --git a/pt/core-libraries/text.rst b/pt/core-libraries/text.rst index 08986f1e21..21c2df0d69 100644 --- a/pt/core-libraries/text.rst +++ b/pt/core-libraries/text.rst @@ -1,12 +1,385 @@ Texto ##### -.. note:: - Atualmente, a documentação desta página não é suportada em português. +.. php:namespace:: Cake\Utility - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. +.. php:class:: Text - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. \ No newline at end of file +A classe Text inclui métodos de conveniência para criar e manipular +strings e é normalmente acessada estaticamente. Exemplo: +``Text::uuid()``. + +Se você precisa das funcionalidades do :php:class:`Cake\\View\\Helper\\TextHelper` fora +de uma ``View``, use a classe ``Text``:: + + namespace App\Controller; + + use Cake\Utility\Text; + + class UsersController extends AppController + { + public function initialize(): void + { + parent::initialize(); + $this->loadComponent('Auth') + }; + + public function afterLogin() + { + $message = $this->Users->find('new_message')->first(); + if (!empty($message)) { + // Notificar usuário sobre nova mensagem + $this->Flash->success(__( + 'Você tem uma nova mensagem: {0}', + Text::truncate($message['Message']['body'], 255, ['html' => true]) + )); + } + } + } + +Converter Strings para ASCII +============================= + +.. php:staticmethod:: transliterate($string, $transliteratorId = null) + +Transliterate por padrão converte todos os caracteres na string fornecida em +caracteres ASCII equivalentes. O método espera codificação UTF-8. A conversão de caracteres +pode ser controlada usando identificadores de transliteração que você pode +passar usando o argumento ``$transliteratorId`` ou alterar a string de identificador padrão +usando ``Text::setTransliteratorId()``. Identificadores de transliteração ICU +são basicamente da forma `` + +Você pode linkar arquivos com caminhos absolutos também para linkar arquivos +que não estão em **webroot/js**:: + + echo $this->Html->script('/otherdir/script_file'); + +Você também pode linkar para uma URL remota:: + + echo $this->Html->script('https://code.jquery.com/jquery.min.js'); + +Vai produzir: + +.. code-block:: html + + + +O primeiro parâmetro pode ser um array para incluir múltiplos arquivos. :: + + echo $this->Html->script(['jquery', 'wysiwyg', 'scripts']); + +Vai produzir: + +.. code-block:: html + + + + + +Você pode anexar a tag de script a um bloco específico usando a opção ``block``:: + + $this->Html->script('wysiwyg', ['block' => 'scriptBottom']); + +No seu layout, você pode produzir todas as tags de script adicionadas a 'scriptBottom':: + + echo $this->fetch('scriptBottom'); + +Você pode incluir arquivos de script de qualquer plugin carregado usando +:term:`sintaxe de plugin`. Para incluir **plugins/DebugKit/webroot/js/toolbar.js** +você poderia usar o seguinte:: + + echo $this->Html->script('DebugKit.toolbar.js'); + +Se você quiser incluir um arquivo de script que compartilha um nome com um plugin carregado, +você pode fazer o seguinte. Por exemplo, se você tivesse um plugin ``Blog``, +e também quisesse incluir **webroot/js/Blog.plugins.js**, você faria:: + + echo $this->Html->script('Blog.plugins.js', ['plugin' => false]); + +Criando Blocos Javascript Inline +--------------------------------- + +.. php:method:: scriptBlock(string $code, array $options = []) + +Para gerar blocos Javascript a partir do código de view PHP, você pode usar um dos métodos +de bloco de script. Scripts podem ser produzidos no lugar, ou armazenados em buffer em um bloco:: + + // Define um bloco de script de uma vez, com o atributo defer. + $this->Html->scriptBlock('alert("hi")', ['defer' => true]); + + // Armazena em buffer um bloco de script para ser produzido mais tarde. + $this->Html->scriptBlock('alert("hi")', ['block' => true]); + +.. php:method:: scriptStart(array $options = []) +.. php:method:: scriptEnd() + +Você pode usar o método ``scriptStart()`` para criar um bloco de captura que será +produzido em uma tag `` + +Gerando mapas com imports, scopes e integrity:: + + echo $this->Html->importmap([ + 'imports' => [ + 'jquery' => 'jquery-3.7.1.min.js', + 'wysiwyg' => '/editor/wysiwyg.js' + ], + 'scopes' => [ + 'scoped/' => [ + 'foo' => 'inner/foo', + ], + ], + 'integrity' => [ + 'jquery' => 'sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=', + ], + ]); + +Vai produzir: + +.. code-block:: html + + + +Criando Listas Aninhadas +------------------------- + +.. php:method:: nestedList(array $list, array $options = [], array $itemOptions = []) + +Constrói uma lista aninhada (UL/OL) a partir de um array associativo:: + + $list = [ + 'Idiomas' => [ + 'Inglês' => [ + 'Americano', + 'Canadense', + 'Britânico', + ], + 'Espanhol', + 'Alemão', + ] + ]; + echo $this->Html->nestedList($list); + +Saída: + +.. code-block:: html + + // Saída (menos os espaços em branco) +
    +
  • Idiomas +
      +
    • Inglês +
        +
      • Americano
      • +
      • Canadense
      • +
      • Britânico
      • +
      +
    • +
    • Espanhol
    • +
    • Alemão
    • +
    +
  • +
+ +Criando Cabeçalhos de Tabela +----------------------------- + +.. php:method:: tableHeaders(array $names, array $trOptions = null, array $thOptions = null) + +Cria uma linha de células de cabeçalho de tabela para ser colocada dentro de tags . :: + + echo $this->Html->tableHeaders(['Data', 'Título', 'Ativo']); + +Saída: + +.. code-block:: html + + + + + + + +:: + + echo $this->Html->tableHeaders( + ['Data', 'Título','Ativo'], + ['class' => 'status'], + ['class' => 'product_table'] + ); + +Saída: + +.. code-block:: html + + + + + + + +Você pode definir atributos por coluna, estes são usados em vez dos +padrões fornecidos no ``$thOptions``:: + + echo $this->Html->tableHeaders([ + 'id', + ['Nome' => ['class' => 'highlight']], + ['Data' => ['class' => 'sortable']] + ]); + +Saída: + +.. code-block:: html + + + + + + + +Criando Células de Tabela +-------------------------- + +.. php:method:: tableCells(array $data, array $oddTrOptions = null, array $evenTrOptions = null, $useCount = false, $continueOddEven = true) + +Cria células de tabela, em linhas, atribuindo atributos de forma diferente +para linhas ímpares e pares. Envolva uma única célula de tabela dentro de um +[] para atributos + + + +:: + + echo $this->Html->tableCells([ + ['7 de Jul, 2007', ['Melhores Brownies', ['class' => 'highlight']] , 'Sim'], + ['21 de Jun, 2007', 'Cookies Inteligentes', 'Sim'], + ['1 de Ago, 2006', 'Bolo Anti-Java', ['Não', ['id' => 'special']]], + ]); + +Saída: + +.. code-block:: html + + + + + + + + + + + + + + + + + +:: + + echo $this->Html->tableCells( + [ + ['Vermelho', 'Maçã'], + ['Laranja', 'Laranja'], + ['Amarelo', 'Banana'], + ], + ['class' => 'darker'] + ); + +Saída: + +.. code-block:: html + + + + + +Alterando as Tags Produzidas pelo HtmlHelper +============================================= + +.. php:method:: setTemplates(array $templates) + +Carrega um array de templates para adicionar/substituir templates:: + + // Carrega templates específicos. + $this->Html->setTemplates([ + 'javascriptlink' => '' + ]); + +Você pode carregar um arquivo de configuração contendo templates usando o templater +diretamente:: + + // Carrega um arquivo de configuração com templates. + $this->Html->templater()->load('my_tags'); + +Ao carregar arquivos de templates, seu arquivo deve se parecer com:: + + '' + ]; + +.. warning:: + + Strings de template contendo um sinal de porcentagem (``%``) precisam de atenção especial, + você deve prefixar este caractere com outro sinal de porcentagem para que pareça + ``%%``. A razão é que internamente os templates são compilados para serem usados com + ``sprintf()``. Exemplo: ``
{{content}}
`` + +.. meta:: + :title lang=pt: HtmlHelper + :description lang=pt: O papel do HtmlHelper no CakePHP é tornar as opções relacionadas ao HTML mais fáceis, rápidas e resilientes a mudanças. + :keywords lang=pt: html helper,cakephp css,cakephp script,tipo de conteúdo,imagem html,link html,tag html,bloco de script,início de script,url html,estilo cakephp,breadcrumbs cakephp diff --git a/pt/views/helpers/number.rst b/pt/views/helpers/number.rst index 03a30e3e7c..96aca1cea3 100644 --- a/pt/views/helpers/number.rst +++ b/pt/views/helpers/number.rst @@ -5,12 +5,21 @@ Number .. php:class:: NumberHelper(View $view, array $config = []) -.. note:: - Atualmente, a documentação desta página não é suportada em português. +O NumberHelper contém métodos convenientes que permitem exibir +números em formatos comuns em suas views. Esses métodos incluem formas +de formatar moeda, porcentagens, tamanhos de dados, formatar números para +precisões específicas e também oferecem mais flexibilidade com +a formatação de números. - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. +.. include:: /core-libraries/number.rst + :start-after: start-cakenumber + :end-before: end-cakenumber - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. +.. warning:: + + Todos os símbolos são UTF-8. + +.. meta:: + :title lang=pt: NumberHelper + :description lang=pt: O NumberHelper contém métodos de conveniência que permitem exibir números em formatos comuns em suas views. + :keywords lang=pt: number helper,currency,number format,number precision,format file size,format numbers diff --git a/pt/views/helpers/paginator.rst b/pt/views/helpers/paginator.rst index c3366d0871..9d15d9de54 100644 --- a/pt/views/helpers/paginator.rst +++ b/pt/views/helpers/paginator.rst @@ -5,17 +5,578 @@ Paginator .. php:class:: PaginatorHelper(View $view, array $config = []) +O PaginatorHelper é usado para gerar controles de paginação como números de página +e links de próximo/anterior. + +Veja também :doc:`/controllers/pagination` para informações sobre como +criar datasets paginados e fazer consultas paginadas. + +Definindo o conjunto de resultados paginado +-------------------------------------------- + +.. php:method:: setPaginated($paginated, $options) + +Por padrão, o helper usa a primeira instância de ``Cake\Datasource\Paging\PaginatedInterface`` +que ele encontra nas variáveis de view. (Geralmente o resultado de ``Controller::paginate()``). + +Você pode usar ``PaginatorHelper::setPaginated()`` para definir explicitamente o conjunto +de resultados paginado que o helper deve usar. + .. _paginator-templates: -PaginatorHelper Templates -========================= +Templates do PaginatorHelper +============================ + +Internamente o PaginatorHelper usa uma série de templates HTML simples para gerar +marcação. Você pode modificar esses templates para personalizar o HTML gerado pelo +PaginatorHelper. + +Os templates usam placeholders no estilo ``{{var}}``. É importante não adicionar +espaços ao redor de ``{{}}`` ou as substituições não funcionarão. + +Carregando Templates de um Arquivo +----------------------------------- + +Ao adicionar o PaginatorHelper em seu controller, você pode definir a +configuração 'templates' para definir um arquivo de template a ser carregado. Isso permite que você +personalize vários templates e mantenha seu código DRY:: + + // No seu AppView.php + public function initialize(): void + { + ... + $this->loadHelper('Paginator', ['templates' => 'paginator-templates']); + } + +Isso carregará o arquivo localizado em **config/paginator-templates.php**. Veja o +exemplo abaixo de como o arquivo deve ser. Você também pode carregar templates +de um plugin usando :term:`sintaxe de plugin`:: + + // No seu AppView.php + public function initialize(): void + { + ... + $this->loadHelper('Paginator', ['templates' => 'MyPlugin.paginator-templates']); + } + +Seja seus templates na aplicação principal ou em um plugin, seu +arquivo de templates deve se parecer com algo assim:: + + return [ + 'number' => '{{text}}', + ]; + +Alterando Templates em Tempo de Execução +----------------------------------------- + +.. php:method:: setTemplates($templates) + +Este método permite que você altere os templates usados pelo PaginatorHelper em +tempo de execução. Isso pode ser útil quando você quer personalizar templates para uma +chamada de método específica:: + + // Lê o valor do template atual. + $result = $this->Paginator->getTemplates('number'); + + // Altera um template + $this->Paginator->setTemplates([ + 'number' => '{{text}}' + ]); + +.. warning:: + + Strings de template contendo um sinal de porcentagem (``%``) precisam de atenção + especial, você deve prefixar este caractere com outra porcentagem para que + pareça ``%%``. A razão é que internamente os templates são compilados para + serem usados com ``sprintf()``. + Exemplo: '
{{content}}
' + +Nomes de Template +----------------- + +O PaginatorHelper usa os seguintes templates: + +- ``nextActive`` O estado ativo para um link gerado por next(). +- ``nextDisabled`` O estado desabilitado para next(). +- ``prevActive`` O estado ativo para um link gerado por prev(). +- ``prevDisabled`` O estado desabilitado para prev() +- ``counterRange`` O template que counter() usa quando format == range. +- ``counterPages`` O template que counter() usa quando format == pages. +- ``first`` O template usado para um link gerado por first(). +- ``last`` O template usado para um link gerado por last() +- ``number`` O template usado para um link gerado por numbers(). +- ``current`` O template usado para a página atual. +- ``ellipsis`` O template usado para reticências geradas por numbers(). +- ``sort`` O template para um link de ordenação sem direção. +- ``sortAsc`` O template para um link de ordenação com direção ascendente. +- ``sortDesc`` O template para um link de ordenação com direção descendente. + +Criando Links de Ordenação +=========================== + +.. php:method:: sort($key, $title = null, $options = []) + + :param string $key: O nome da coluna pela qual o conjunto de registros deve ser ordenado. + :param string $title: Título para o link. Se $title for null, $key será + usado convertido para o formato "Title Case" e usado como título. + :param array $options: Opções para link de ordenação. + +Gera um link de ordenação. Define parâmetros querystring para a ordenação e +direção. Os links serão padrão para ordenar por asc. Após o primeiro clique, links +gerados com ``sort()`` irão lidar com a troca de direção automaticamente. Se o +conjunto de resultados está ordenado 'asc' pela chave especificada, o link retornado irá ordenar por +'desc'. Usa os templates ``sort``, ``sortAsc``, ``sortDesc``, ``sortAscLocked`` e +``sortDescLocked``. + +Chaves aceitas para ``$options``: + +* ``escape`` Se você quer o conteúdo codificado como entidade HTML, padrão é + ``true``. +* ``direction`` A direção padrão a usar quando este link não está ativo. +* ``lock`` Bloquear direção. Só usará a direção padrão então, padrão é ``false``. + +Assumindo que você está paginando alguns posts, e está na página um:: + + echo $this->Paginator->sort('user_id'); + +Saída: + +.. code-block:: html + + User Id + +Você pode usar o parâmetro title para criar texto personalizado para seu link:: + + echo $this->Paginator->sort('user_id', 'User account'); + +Saída: + +.. code-block:: html + + User account + +Se você está usando HTML como imagens em seus links, lembre-se de desativar o escape:: + + echo $this->Paginator->sort( + 'user_id', + 'User account', + ['escape' => false] + ); + +Saída: + +.. code-block:: html + + User account + +A opção direction pode ser usada para definir a direção padrão para um link. Uma vez que um +link está ativo, ele irá trocar de direção automaticamente como normal:: + + echo $this->Paginator->sort('user_id', null, ['direction' => 'desc']); + +Saída: + +.. code-block:: html + + User Id + +A opção lock pode ser usada para bloquear a ordenação na direção especificada:: + + echo $this->Paginator->sort('user_id', null, ['direction' => 'asc', 'lock' => true]); + +.. php:method:: sortDir(string $model = null, mixed $options = []) + + Obtém a direção atual pela qual o conjunto de registros está ordenado. + +.. php:method:: sortKey(string $model = null, mixed $options = []) + + Obtém a chave atual pela qual o conjunto de registros está ordenado. + +Criando Links de Números de Página +=================================== + +.. php:method:: numbers($options = []) + +Retorna um conjunto de números para o conjunto de resultados paginado. Usa um módulo para +decidir quantos números mostrar em cada lado da página atual. Por padrão, +8 links em cada lado da página atual serão criados se essas páginas existirem. +Links não serão gerados para páginas que não existem. A página atual também +não é um link. Os templates ``number``, ``current`` e ``ellipsis`` serão +usados. + +Opções suportadas são: + +* ``before`` Conteúdo a ser inserido antes dos números. +* ``after`` Conteúdo a ser inserido depois dos números. +* ``modulus`` quantos números incluir em cada lado da página atual, + padrão é 8. +* ``first`` Se você quer links primeiro gerados, defina como um inteiro para + definir o número de links 'primeiro' a gerar. Padrão é ``false``. Se uma + string for definida, um link para a primeira página será gerado com o valor como + título:: + + echo $this->Paginator->numbers(['first' => 'First page']); + +* ``last`` Se você quer links último gerados, defina como um inteiro para definir + o número de links 'último' a gerar. Padrão é ``false``. Segue a mesma + lógica que a opção ``first``. Há um + método :php:meth:`~PaginatorHelper::last()` para ser usado separadamente também se + você desejar. + +Embora este método permita muita personalização para sua saída, também é +ok apenas chamar o método sem nenhum parâmetro. :: + + echo $this->Paginator->numbers(); + +Usando as opções first e last você pode criar links para o início +e fim do conjunto de páginas. O seguinte criaria um conjunto de links de página que +incluem links para as primeiras 2 e últimas 2 páginas nos resultados paginados:: + + echo $this->Paginator->numbers(['first' => 2, 'last' => 2]); + +Criando Links de Salto +======================= + +Além de gerar links que vão diretamente para números de página específicos, +você frequentemente vai querer links que vão para os links anterior e próximo, primeira e última +páginas no conjunto de dados paginado. + +.. php:method:: prev($title = '<< Previous', $options = []) + + :param string $title: Título para o link. + :param mixed $options: Opções para link de paginação. + + Gera um link para a página anterior em um conjunto de registros paginados. Usa + os templates ``prevActive`` e ``prevDisabled``. + + ``$options`` suporta as seguintes chaves: + + * ``escape`` Se você quer o conteúdo codificado como entidade HTML, + padrão é ``true``. + * ``disabledTitle`` O texto a usar quando o link está desabilitado. Padrão é + o parâmetro ``$title``. + + Um exemplo simples seria:: + + echo $this->Paginator->prev(' << ' . __('previous')); + + Se você estivesse atualmente na segunda página de posts, você obteria o seguinte: + + .. code-block:: html + + + + Se não houver páginas anteriores, você obteria: + + .. code-block:: html + + + + Para alterar os templates usados por este método, veja :ref:`paginator-templates`. + +.. php:method:: next($title = 'Next >>', $options = []) + + Este método é idêntico a :php:meth:`~PaginatorHelper::prev()` com algumas exceções. Ele + cria links apontando para a próxima página em vez da anterior. Ele também + usa ``next`` como o valor do atributo rel em vez de ``prev``. Usa os + templates ``nextActive`` e ``nextDisabled``. + +.. php:method:: first($first = '<< first', $options = []) + + Retorna um primeiro ou conjunto de números para as primeiras páginas. Se uma string for fornecida, + então apenas um link para a primeira página com o texto fornecido será criado:: + + echo $this->Paginator->first('< first'); + + O código acima cria um único link para a primeira página. Não produzirá nada se você + estiver na primeira página. Você também pode usar um inteiro para indicar quantos primeiros + links de paginação você quer gerados:: + + echo $this->Paginator->first(3); + + O código acima criará links para as primeiras 3 páginas, uma vez que você chegue à terceira ou + página maior. Antes disso, nada será produzido. Usa o template ``first``. + + O parâmetro options aceita o seguinte: + + - ``escape`` Se o texto deve ou não ser escapado. Defina como ``false`` se seu + conteúdo contém HTML. + +.. php:method:: last($last = 'last >>', $options = []) + + Este método funciona muito como o método :php:meth:`~PaginatorHelper::first()`. + Mas tem algumas diferenças. Ele não gerará nenhum link se você + estiver na última página para valores string de ``$last``. Para um valor inteiro de + ``$last``, nenhum link será gerado uma vez que o usuário esteja dentro do intervalo de últimas + páginas. Usa o template ``last``. + +Criando Tags de Link de Cabeçalho +================================== + +O PaginatorHelper pode ser usado para criar tags de link de paginação em seus elementos +```` da página:: + + // Cria links próximo/anterior para o model atual. + echo $this->Paginator->meta(); + + // Cria links próximo/anterior e primeiro/último para o model atual. + echo $this->Paginator->meta(['first' => true, 'last' => true]); + +Verificando o Estado da Paginação +================================== + +.. php:method:: current() + + Obtém a página atual do conjunto de registros:: + + // Nossa URL é: /comments?page=3 + echo $this->Paginator->current(); + // A saída é 3 + + Usa o template ``current``. + +.. php:method:: hasNext(string $model = null) + + Retorna ``true`` se o conjunto de resultados fornecido não estiver na última página. + +.. php:method:: hasPrev() + + Retorna ``true`` se o conjunto de resultados fornecido não estiver na primeira página. + +.. php:method:: hasPage(int $page = 1) + + Retorna ``true`` se o conjunto de resultados fornecido tiver o número de página fornecido por ``$page``. + +.. php:method:: total() + + Retorna o número total de páginas para o model fornecido. + +Criando um Contador de Página +============================== + +.. php:method:: counter(string $format = 'pages', array $options = []) + +Retorna uma string de contador para o conjunto de resultados paginado. Usando uma string de formato +fornecida e várias opções, você pode criar indicadores localizados e específicos da aplicação +de onde um usuário está no conjunto de dados paginado. Usa os +templates ``counterRange`` e ``counterPages``. + +Formatos suportados são 'range', 'pages' e custom. O padrão é pages, que +geraria uma saída como '1 of 10'. No modo custom, a string fornecida é analisada e +tokens são substituídos por valores reais. Os tokens disponíveis são: + +- ``{{page}}`` - a página atual exibida. +- ``{{pages}}`` - número total de páginas. +- ``{{current}}`` - número atual de registros sendo mostrados. +- ``{{count}}`` - o número total de registros no conjunto de resultados. +- ``{{start}}`` - número do primeiro registro sendo exibido. +- ``{{end}}`` - número do último registro sendo exibido. +- ``{{model}}`` - A forma humana pluralizada do nome do model. + Se seu model fosse 'RecipePage', ``{{model}}`` seria 'recipe pages'. + +Você também pode fornecer apenas uma string para o método counter usando os tokens +disponíveis. Por exemplo:: + + echo $this->Paginator->counter( + 'Page {{page}} of {{pages}}, showing {{current}} records out of + {{count}} total, starting on record {{start}}, ending on {{end}}' + ); + +Definir 'format' para range geraria uma saída como '1 - 3 of 13':: + + echo $this->Paginator->counter('range'); + +Gerando URLs de Paginação +========================== + +.. php:method:: generateUrl(array $options = [], ?string $model = null, array $url = [], array $urlOptions = []) + +Por padrão, retorna uma string de URL de paginação completa para uso em contextos não-padrão +(ou seja, JavaScript). :: + + // Gera uma URL similar a: /articles?sort=title&page=2 + echo $this->Paginator->generateUrl(['sort' => 'title']); + + // Gera uma URL para um model diferente + echo $this->Paginator->generateUrl(['sort' => 'title'], 'Comments'); + + // Gera uma URL para um controller diferente. + echo $this->Paginator->generateUrl( + ['sort' => 'title'], + null, + ['controller' => 'Comments'] + ); + +Criando um Controle Selectbox de Limite +======================================== + +.. php:method:: limitControl(array $limits = [], $default = null, array $options = []) + +Cria um controle dropdown que altera o parâmetro de consulta ``limit``:: + + // Usa os padrões. + echo $this->Paginator->limitControl(); + + // Define quais opções de limite você quer. + echo $this->Paginator->limitControl([25 => 25, 50 => 50]); + + // Limites personalizados e define a opção selecionada + echo $this->Paginator->limitControl([25 => 25, 50 => 50], $user->perPage); + +O formulário e controle gerados serão enviados automaticamente ao mudar. + +Configurando Opções de Paginação +================================= + +.. php:method:: options($options = []) + +Define todas as opções para o PaginatorHelper. Opções suportadas são: + +* ``url`` A URL da action de paginação. + + A opção permite que você defina/sobrescreva qualquer elemento para URLs geradas pelo + helper:: + + $this->Paginator->options([ + 'url' => [ + 'lang' => 'en', + '?' => [ + 'sort' => 'email', + 'direction' => 'desc', + 'page' => 6, + ], + ] + ]); + + O exemplo acima adiciona o parâmetro de rota ``en`` a todos os links que o helper irá + gerar. Ele também criará links com valores específicos de sort, direction e page. + Por padrão, ``PaginatorHelper`` irá mesclar todos os argumentos passados + atualmente e parâmetros de query string. + +* ``escape`` Define se o campo de título para links deve ser escapado em HTML. + Padrão é ``true``. + +Exemplo de Uso +============== + +Cabe a você decidir como mostrar registros ao usuário, mas na maioria das vezes isso +será feito dentro de tabelas HTML. Os exemplos abaixo assumem um layout tabular, mas +o PaginatorHelper disponível em views nem sempre precisa ser restrito +assim. + +Veja os detalhes sobre +`PaginatorHelper `_ na +API. Como mencionado, o PaginatorHelper também oferece recursos de ordenação que +podem ser integrados aos cabeçalhos das colunas da sua tabela: + +.. code-block:: php + + +
DataTítuloAtivo
DataTítuloAtivo
idNomeData
específicos. :: + + echo $this->Html->tableCells([ + ['7 de Jul, 2007', 'Melhores Brownies', 'Sim'], + ['21 de Jun, 2007', 'Cookies Inteligentes', 'Sim'], + ['1 de Ago, 2006', 'Bolo Anti-Java', 'Não'], + ]); + +Saída: + +.. code-block:: html + +
7 de Jul, 2007Melhores BrowniesSim
21 de Jun, 2007Cookies InteligentesSim
1 de Ago, 2006Bolo Anti-JavaNão
+ 7 de Jul, 2007 + + Melhores Brownies + + Sim +
+ 21 de Jun, 2007 + + Cookies Inteligentes + + Sim +
+ 1 de Ago, 2006 + + Bolo Anti-Java + + Não +
VermelhoMaçã
LaranjaLaranja
AmareloBanana
+ + + + + + + + + + +
Paginator->sort('id', 'ID') ?>Paginator->sort('title', 'Title') ?>
id ?> title) ?>
+ +Os links gerados pelo método ``sort()`` do ``PaginatorHelper`` permitem que +usuários cliquem nos cabeçalhos da tabela para alternar a ordenação dos dados por um +campo específico. + +Também é possível ordenar uma coluna com base em associações: + +.. code-block:: php + + + + + + + + + + + + +
Paginator->sort('title', 'Title') ?>Paginator->sort('Authors.name', 'Author') ?>
title) ?> name) ?>
.. note:: - Atualmente, a documentação desta página não é suportada em português. - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. + Ordenar por colunas em models associados requer definir estas na + propriedade ``PaginationComponent::paginate``. Usando o exemplo acima, o + controller que lida com a paginação precisaria definir sua chave ``sortableFields`` + da seguinte forma: + + .. code-block:: php + + $this->paginate = [ + 'sortableFields' => [ + 'Posts.title', + 'Authors.name', + ], + ]; + + Para mais informações sobre o uso da opção ``sortableFields``, por favor veja + :ref:`control-which-fields-used-for-ordering`. + +O ingrediente final para exibição de paginação em views é a adição de +navegação de página, também fornecida pelo PaginationHelper:: + + // Mostra os números de página + Paginator->numbers() ?> + + // Mostra os links próximo e anterior + Paginator->prev('« Previous') ?> + Paginator->next('Next »') ?> + + // Imprime X de Y, onde X é a página atual e Y é o número de páginas + Paginator->counter() ?> + +A redação da saída do método counter() também pode ser personalizada usando +marcadores especiais:: + + Paginator->counter([ + 'format' => 'Page {{page}} of {{pages}}, showing {{current}} records out of + {{count}} total, starting on record {{start}}, ending on {{end}}' + ]) ?> + +.. _paginator-helper-multiple: + +Paginando Múltiplos Resultados +=============================== + +Se você está :ref:`paginando múltiplas consultas ` +você precisará usar ``PaginatorHelper::setPaginated()`` primeiro antes de chamar +outros métodos do helper, para que eles gerem a saída esperada. + +``PaginatorHelper`` usará automaticamente o ``scope`` definido quando a +consulta foi paginada. Para definir parâmetros de URL adicionais para paginação múltipla +você pode incluir os nomes de scope em ``options()``:: + + $this->Paginator->options([ + 'url' => [ + // Parâmetros de URL adicionais para o scope 'articles' + 'articles' => [ + '?' => ['articles' => 'yes'] + ], + // Parâmetros de URL adicionais para o scope 'comments' + 'comments' => [ + 'articleId' => 1234, + ], + ], + ]); - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. +.. meta:: + :title lang=pt: PaginatorHelper + :description lang=pt: O PaginatorHelper é usado para gerar controles de paginação como números de página e links de próximo/anterior. + :keywords lang=pt: helper paginator,paginação,ordenar,links de número de página,paginação em views,link anterior,link próximo,link último,link primeiro,contador de página diff --git a/pt/views/helpers/text.rst b/pt/views/helpers/text.rst index 3680fc6b8a..dfa898b47c 100644 --- a/pt/views/helpers/text.rst +++ b/pt/views/helpers/text.rst @@ -5,12 +5,90 @@ Text .. php:class:: TextHelper(View $view, array $config = []) -.. note:: - Atualmente, a documentação desta página não é suportada em português. +O TextHelper contém métodos para tornar o texto mais utilizável e +amigável em suas views. Ele auxilia na criação de links, formatação de URLs, +criação de trechos de texto em torno de palavras ou frases escolhidas, +destacando palavras-chave em blocos de texto, e truncando graciosamente +longos trechos de texto. - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. +Vinculando Endereços de E-mail +=============================== - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. +.. php:method:: autoLinkEmails(string $text, array $options = []) + +Adiciona links aos endereços de e-mail bem formados em $text, de acordo +com quaisquer opções definidas em ``$options`` (consulte +:php:meth:`HtmlHelper::link()`). :: + + $myText = 'Para mais informações sobre nossas sobremesas e doces ' . + 'mundialmente famosos, entre em contato info@example.com'; + $linkedText = $this->Text->autoLinkEmails($myText); + +Saída:: + + Para mais informações sobre nossas sobremesas e doces mundialmente famosos, + entre em contato info@example.com + +Este método automaticamente escapa sua entrada. Use a opção ``escape`` +para desabilitar isso se necessário. + +Vinculando URLs +=============== + +.. php:method:: autoLinkUrls(string $text, array $options = []) + +Igual a ``autoLinkEmails()``, apenas este método procura por +strings que começam com https, http, ftp, ou nntp e as vincula +apropriadamente. + +Este método automaticamente escapa sua entrada. Use a opção ``escape`` +para desabilitar isso se necessário. + +Vinculando Tanto URLs quanto Endereços de E-mail +================================================= + +.. php:method:: autoLink(string $text, array $options = []) + +Executa a funcionalidade tanto de ``autoLinkUrls()`` quanto de +``autoLinkEmails()`` no ``$text`` fornecido. Todas as URLs e e-mails +são vinculados apropriadamente de acordo com as ``$options`` fornecidas. + +Este método automaticamente escapa sua entrada. Use a opção ``escape`` +para desabilitar isso se necessário. + +Opções adicionais: + +* ``stripProtocol``: Remove ``http://`` e ``https://`` do início do + rótulo do link. Padrão desligado. +* ``maxLength``: O comprimento máximo do rótulo do link. Padrão desligado. +* ``ellipsis``: A string a ser anexada ao final do rótulo do link. Padrão é + reticências UTF8. + +Convertendo Texto em Parágrafos +================================ + +.. php:method:: autoParagraph(string $text) + +Adiciona

apropriados ao redor do texto onde retornos de linha duplos são encontrados, e
onde +retornos de linha simples são encontrados. :: + + $myText = 'Para mais informações + sobre nossas sobremesas e doces mundialmente famosos. + + entre em contato info@example.com'; + $formattedText = $this->Text->autoParagraph($myText); + +Saída:: + +

Para mais informações
+ sobre nossas sobremesas e doces mundialmente famosos.

+

entre em contato info@example.com

+ +.. include:: /core-libraries/text.rst + :start-after: start-text + :end-before: end-text + +.. meta:: + :title lang=pt: TextHelper + :description lang=pt: O TextHelper contém métodos para tornar o texto mais utilizável e amigável em suas views. + :keywords lang=pt: text helper,autoLinkEmails,autoLinkUrls,autoLink,excerpt,highlight,stripLinks,truncate,string text diff --git a/pt/views/helpers/time.rst b/pt/views/helpers/time.rst index 51dbf9babf..2eef18dfa6 100644 --- a/pt/views/helpers/time.rst +++ b/pt/views/helpers/time.rst @@ -5,12 +5,47 @@ Time .. php:class:: TimeHelper(View $view, array $config = []) -.. note:: - Atualmente, a documentação desta página não é suportada em português. +O TimeHelper permite o processamento rápido de informações relacionadas ao tempo. +O TimeHelper tem duas tarefas principais que pode realizar: - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. +#. Ele pode formatar strings de tempo. +#. Ele pode testar tempo. - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. +Usando o Helper +=============== + +Um uso comum do TimeHelper é compensar a data e hora para corresponder ao fuso +horário de um usuário. Vamos usar um fórum como exemplo. Seu fórum tem muitos usuários que +podem postar mensagens a qualquer momento de qualquer parte do mundo. Uma maneira de +gerenciar o tempo é salvar todas as datas e horas como GMT+0 ou UTC. Descomente a +linha ``date_default_timezone_set('UTC');`` em **config/bootstrap.php** para garantir +que o fuso horário da sua aplicação esteja definido como GMT+0. + +Em seguida, adicione um campo de fuso horário à sua tabela de usuários e faça as modificações necessárias +para permitir que seus usuários definam seu fuso horário. Agora que sabemos +o fuso horário do usuário logado, podemos corrigir a data e hora em nossas +postagens usando o TimeHelper:: + + echo $this->Time->format( + $post->created, + \IntlDateFormatter::FULL, + false, + $user->time_zone + ); + // Exibirá 'Saturday, August 22, 2011 at 11:53:00 PM GMT' + // para um usuário em GMT+0. Enquanto exibe, + // 'Saturday, August 22, 2011 at 03:53 PM GMT-8:00' + // para um usuário em GMT-8 + +A maioria dos recursos do TimeHelper são destinados como interfaces compatíveis com versões anteriores +para aplicações que estão atualizando de versões mais antigas do CakePHP. Porque o +ORM retorna instâncias de :php:class:`Cake\\I18n\\Time` para cada coluna ``timestamp`` +e ``datetime``, você pode usar os métodos lá para fazer a maioria das tarefas. +Por exemplo, para ler sobre as strings de formatação aceitas, dê uma olhada no método +`Cake\\I18n\\Time::i18nFormat() +`_. + +.. meta:: + :title lang=pt: TimeHelper + :description lang=pt: O TimeHelper ajudará você a formatar tempo e testar tempo. + :keywords lang=pt: time helper,format time,timezone,unix epoch,time strings,time zone offset,utc,gmt diff --git a/pt/views/helpers/url.rst b/pt/views/helpers/url.rst index 5565c9880b..38d76aafa7 100644 --- a/pt/views/helpers/url.rst +++ b/pt/views/helpers/url.rst @@ -5,12 +5,159 @@ Url .. php:class:: UrlHelper(View $view, array $config = []) -.. note:: - Atualmente, a documentação desta página não é suportada em português. +O UrlHelper ajuda você a gerar URLs de seus outros helpers. +Ele também oferece um único lugar para personalizar como as URLs são geradas +sobrescrevendo o helper principal com um da aplicação. Veja a +seção :ref:`aliasing-helpers` para saber como fazer isso. - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. +Gerando URLs +============ - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. +.. php:method:: build($url = null, array $options = []) + +Retorna uma URL apontando para uma combinação de controller e action. +Se ``$url`` estiver vazia, retorna o ``REQUEST_URI``, caso contrário +gera a URL para a combinação de controller e action. Se ``fullBase`` for +``true``, a URL base completa será anexada ao resultado:: + + echo $this->Url->build([ + 'controller' => 'Posts', + 'action' => 'view', + 'bar', + ]); + + // Saída + /posts/view/bar + +Aqui estão mais alguns exemplos de uso: + +URL com extensão:: + + echo $this->Url->build([ + 'controller' => 'Posts', + 'action' => 'list', + '_ext' => 'rss', + ]); + + // Saída + /posts/list.rss + +URL com prefixo:: + + echo $this->Url->build([ + 'controller' => 'Posts', + 'action' => 'list', + 'prefix' => 'Admin', + ]); + + // Saída + /admin/posts/list + +URL (começando com '/') com a URL base completa anexada:: + + echo $this->Url->build('/posts', ['fullBase' => true]); + + // Saída + http://somedomain.com/posts + +URL com parâmetros GET e âncora de fragmento:: + + echo $this->Url->build([ + 'controller' => 'Posts', + 'action' => 'search', + '?' => ['foo' => 'bar'], + '#' => 'first', + ]); + + // Saída + /posts/search?foo=bar#first + +O exemplo acima usa a chave especial ``?`` para especificar parâmetros de query string +e a chave ``#`` para fragmento de URL. + +URL para rota nomeada:: + + // Assumindo que uma rota está configurada como rota nomeada: + // $router->connect( + // '/products/{slug}', + // [ + // 'controller' => 'Products', + // 'action' => 'view', + // ], + // [ + // '_name' => 'product-page', + // ] + // ); + + echo $this->Url->build(['_name' => 'product-page', 'slug' => 'i-m-slug']); + // Resultará em: + /products/i-m-slug + +O 2º parâmetro permite que você defina opções controlando o escape de HTML e +se o caminho base deve ser adicionado ou não:: + + $this->Url->build('/posts', [ + 'escape' => false, + 'fullBase' => true, + ]); + +.. php:method:: buildFromPath(string $path, array $params = [], array $options = []) + +Se você quiser usar strings de caminho de rota, pode fazer isso usando este método:: + + echo $this->Url->buildFromPath('Articles::index'); + // saída: /articles + + echo $this->Url->buildFromPath('MyBackend.Admin/Articles::view', [3]); + // saída: /admin/my-backend/articles/view/3 + +URL com timestamp de asset envolvida por ````, aqui pré-carregando +uma fonte. Nota: O arquivo deve existir e ``Configure::read('Asset.timestamp')`` +deve retornar ``true`` ou ``'force'`` para que o timestamp seja anexado:: + + echo $this->Html->meta([ + 'rel' => 'preload', + 'href' => $this->Url->assetUrl( + '/assets/fonts/your-font-pack/your-font-name.woff2' + ), + 'as' => 'font', + ]); + +Se você está gerando URLs para arquivos CSS, Javascript ou de imagem, existem métodos +helper para cada um desses tipos de assets:: + + // Saída /img/icon.png + $this->Url->image('icon.png'); + + // Saída /js/app.js + $this->Url->script('app.js'); + + // Saída /css/app.css + $this->Url->css('app.css'); + + // Força timestamps para uma chamada de método. + $this->Url->css('app.css', ['timestamp' => 'force']); + + // Ou desabilita timestamps para uma chamada de método. + $this->Url->css('app.css', ['timestamp' => false]); + +Personalizando a Geração de URL de Assets +========================================== + +Se você precisar personalizar como as URLs de assets são geradas, ou deseja usar parâmetros +personalizados de cache busting de assets, pode usar a opção ``assetUrlClassName``:: + + // Em view initialize + $this->loadHelper('Url', ['assetUrlClassName' => AppAsset::class]); + +Ao usar ``assetUrlClassName`` você deve implementar os mesmos métodos que +``Cake\Routing\Asset`` implementa. + +Para mais informações, consulte +`Router::url `_ +na API. + +.. meta:: + :title lang=pt: UrlHelper + :description lang=pt: O papel do UrlHelper no CakePHP é ajudar a construir urls. + :keywords lang=pt: url helper,url diff --git a/pt/views/json-and-xml-views.rst b/pt/views/json-and-xml-views.rst index ea762ac3ce..e6a19cd602 100644 --- a/pt/views/json-and-xml-views.rst +++ b/pt/views/json-and-xml-views.rst @@ -1,12 +1,249 @@ -Views JSON & XML +Views JSON e XML ################ -.. note:: - Atualmente, a documentação desta página não é suportada em português. +A integração de ``JsonView`` e ``XmlView`` com os recursos de +:ref:`controller-viewclasses` do CakePHP permitem que você crie respostas JSON e XML. - Por favor, sinta-se a vontade para nos enviar um *pull request* para o - `Github `_ ou use o botão - **IMPROVE THIS DOC** para propor suas mudanças diretamente. +Essas classes de view são mais comumente usadas com :php:meth:`Cake\\Controller\\Controller::viewClasses()`. - Você pode consultar a versão em inglês deste tópico através do seletor de - idiomas localizado ao lado direito do campo de buscas da documentação. \ No newline at end of file +Existem duas maneiras de gerar views de dados. A primeira é usando a +opção ``serialize`` e a segunda é criando arquivos de template normais. + +Definindo Classes de View para Negociar +======================================== + +No seu ``AppController`` ou em um controller individual, você pode implementar o +método ``viewClasses()`` e fornecer todas as views que deseja suportar:: + + use Cake\View\JsonView; + use Cake\View\XmlView; + + public function viewClasses(): array + { + return [JsonView::class, XmlView::class]; + } + +Você pode opcionalmente habilitar as extensões json e/ou xml com +:ref:`file-extensions`. Isso permitirá que você acesse as views ``JSON``, ``XML`` ou +qualquer outro formato especial usando uma URL personalizada terminando com o nome do +tipo de resposta como uma extensão de arquivo, como ``http://example.com/articles.json``. + +Por padrão, quando não estiver habilitando :ref:`file-extensions`, o cabeçalho ``Accept`` +na requisição é usado para selecionar qual tipo de formato deve ser renderizado para o +usuário. Um exemplo de formato ``Accept`` usado para renderizar respostas ``JSON`` é +``application/json``. + +Usando Views de Dados com a Chave Serialize +============================================ + +A opção ``serialize`` indica qual(is) variável(is) de view deve(m) ser +serializada(s) ao usar uma view de dados. Isso permite que você pule a definição de arquivos de template +para as ações do seu controller se não precisar fazer nenhuma formatação personalizada antes +de seus dados serem convertidos em json/xml. + +Se você precisar fazer qualquer formatação ou manipulação de suas variáveis de view antes +de gerar a resposta, deve usar arquivos de template. O valor de +``serialize`` pode ser tanto uma string quanto um array de variáveis de view para +serializar:: + + + namespace App\Controller; + + use Cake\View\JsonView; + + class ArticlesController extends AppController + { + public function viewClasses(): array + { + return [JsonView::class]; + } + + public function index() + { + // Define as variáveis de view + $this->set('articles', $this->paginate()); + // Especifica quais variáveis de view o JsonView deve serializar. + $this->viewBuilder()->setOption('serialize', 'articles'); + } + } + +Você também pode definir ``serialize`` como um array de variáveis de view para combinar:: + + namespace App\Controller; + + use Cake\View\JsonView; + + class ArticlesController extends AppController + { + public function viewClasses(): array + { + return [JsonView::class]; + } + + public function index() + { + // Algum código que criou $articles e $comments + + // Define as variáveis de view + $this->set(compact('articles', 'comments')); + + // Especifica quais variáveis de view o JsonView deve serializar. + $this->viewBuilder()->setOption('serialize', ['articles', 'comments']); + } + } + +Definir ``serialize`` como um array tem o benefício adicional de anexar automaticamente +um elemento ```` de nível superior ao usar :php:class:`XmlView`. +Se você usar um valor string para ``serialize`` e XmlView, certifique-se de que sua +variável de view tenha um único elemento de nível superior. Sem um único elemento de nível +superior, o Xml falhará ao gerar. + +Usando uma View de Dados com Arquivos de Template +================================================== + +Você deve usar arquivos de template se precisar manipular o conteúdo de sua view +antes de criar a saída final. Por exemplo, se tivéssemos articles com um campo contendo HTML gerado, provavelmente gostaríamos de omitir isso de uma +resposta JSON. Esta é uma situação onde um arquivo de view seria útil:: + + // Código do Controller + class ArticlesController extends AppController + { + public function index() + { + $articles = $this->paginate('Articles'); + $this->set(compact('articles')); + } + } + + // Código da View - templates/Articles/json/index.php + foreach ($articles as $article) { + unset($article->generated_html); + } + echo json_encode(compact('articles')); + +Você pode fazer manipulações mais complexas, ou usar helpers para formatação também. +As classes de view de dados não suportam layouts. Elas assumem que o arquivo de view irá +gerar o conteúdo serializado. + +Criando Views XML +================= + +.. php:class:: XmlView + +Por padrão, ao usar ``serialize``, o XmlView envolverá suas variáveis +de view serializadas com um nó ````. Você pode definir um nome personalizado para +este nó usando a opção ``rootNode``. + +A classe XmlView suporta a opção ``xmlOptions`` que permite personalizar +as opções, como ``tags`` ou ``attributes``, usadas para gerar XML. + +Um exemplo de uso de ``XmlView`` seria gerar um `sitemap.xml +`_. Este tipo de documento requer que você +altere ``rootNode`` e defina atributos. Atributos são definidos usando o prefixo ``@``:: + + use Cake\View\XmlView; + + public function viewClasses(): array + { + return [XmlView::class]; + } + + public function sitemap() + { + $pages = $this->Pages->find()->all(); + $urls = []; + foreach ($pages as $page) { + $urls[] = [ + 'loc' => Router::url(['controller' => 'Pages', 'action' => 'view', $page->slug, '_full' => true]), + 'lastmod' => $page->modified->format('Y-m-d'), + 'changefreq' => 'daily', + 'priority' => '0.5', + ]; + } + + // Define um nó raiz personalizado no documento gerado. + $this->viewBuilder() + ->setOption('rootNode', 'urlset') + ->setOption('serialize', ['@xmlns', 'url']); + $this->set([ + // Define um atributo no nó raiz. + '@xmlns' => 'http://www.sitemaps.org/schemas/sitemap/0.9', + 'url' => $urls, + ]); + } + +Criando Views JSON +================== + +.. php:class:: JsonView + +A classe JsonView suporta a opção ``jsonOptions`` que permite personalizar +a máscara de bits usada para gerar JSON. Veja a documentação do +`json_encode `_ para os valores +válidos desta opção. + +Por exemplo, para serializar a saída de erros de validação de entidades CakePHP em uma forma consistente de JSON faça:: + + // Na action do seu controller quando o salvamento falhou + $this->set('errors', $articles->errors()); + $this->viewBuilder() + ->setOption('serialize', ['errors']) + ->setOption('jsonOptions', JSON_FORCE_OBJECT); + +Respostas JSONP +--------------- + +Ao usar ``JsonView`` você pode usar a variável de view especial ``jsonp`` para +habilitar o retorno de uma resposta JSONP. Defini-la como ``true`` faz com que a classe de view +verifique se o parâmetro de query string chamado "callback" está definido e, se estiver, envolve a +resposta json no nome da função fornecida. Se você quiser usar um nome de parâmetro de query string +personalizado em vez de "callback", defina ``jsonp`` para o nome requerido em vez de +``true``. + +Escolhendo uma Classe de View +============================== + +Embora você possa usar o método hook ``viewClasses`` na maioria das vezes, se você quiser +controle total sobre a seleção da classe de view, pode escolher diretamente a classe de view:: + + // src/Controller/VideosController.php + namespace App\Controller; + + use App\Controller\AppController; + use Cake\Http\Exception\NotFoundException; + + class VideosController extends AppController + { + public function export($format = '') + { + $format = strtolower($format); + + // Mapeamento de formato para view + $formats = [ + 'xml' => 'Xml', + 'json' => 'Json', + ]; + + // Erro em tipo desconhecido + if (!isset($formats[$format])) { + throw new NotFoundException(__('Unknown format.')); + } + + // Define a View do Formato de Saída + $this->viewBuilder()->setClassName($formats[$format]); + + // Obtém dados + $videos = $this->Videos->find('latest')->all(); + + // Define a View de Dados + $this->set(compact('videos')); + $this->viewBuilder()->setOption('serialize', ['videos']); + + // Define Download Forçado + return $this->response->withDownload('report-' . date('YmdHis') . '.' . $format); + } + } + +.. meta:: + :title lang=pt: Views JSON e XML + :keywords lang=pt: json,xml,presentation layer,view,ajax,logic,syntax,templates,cakephp diff --git a/pt/views/themes.rst b/pt/views/themes.rst index c273a2a1b6..29cb019b11 100644 --- a/pt/views/themes.rst +++ b/pt/views/themes.rst @@ -6,7 +6,7 @@ Veja a seção em :ref:`plugin-create-your-own`. Você pode tirar vantagem de temas, deixando fácil a troca da aparência da dua página rapidamente. Além de arquivos de templates, eles também podem provers `helpers` e 'cells' se o seu tema assim requerer. Quando usado ``cells`` e ``helpes`` no seu tema, -você precisará continuar usando a :term:`sintaxe plugin`. +você precisará continuar usando a :term:`sintaxe de plugin`. Para usar temas, defina o tema na `action` do seu `controller` ou no método ``beforeRender()``::