You are on page 1of 371

CakePHP Cookbook Documentation

Release 3.next

Cake Software Foundation

ago 03, 2017


Sumrio

1 CakePHP num piscar de olhos 1


Convenes Sobre Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
A camada Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
A camada View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
A camada Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Ciclo de Requisies do CakePHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Apenas o Comeo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Leitura adicional . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

2 Guia de Incio Rpido 11


Tutorial - Criando um Bookmarker - Parte 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Tutorial - Criando um Bookmarker - Parte 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

3 3.0 - Guia de migrao 25


Requerimentos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Ferramenta de atualizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Layout do diretrio da aplicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
O CakePHP deve ser instalado via Composer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Namespaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Constantes removidas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Novo ORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Bsico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Debug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Especificaes/Configuraes de objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Cache . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Core . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Shell / Tarefa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Eventos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Log . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Roteamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Rede . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Sesses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

i
Network\Http . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Network\Email . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Controller\Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Sute de Testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
View\Helper . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
I18n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Localizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Testes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Utilitrios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

4 Tutoriais & Exemplos 51


Tutorial - Criando um Bookmarker - Parte 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Tutorial - Criando um Bookmarker - Parte 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
Tutorial - Criando um Blog - Parte 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Tutorial - Criando um Blog - Parte 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Tutorial - Criando um Blog - Parte 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
Tutorial - Criando um Blog - Autenticao e Autorizao . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

5 Contribuindo 91
Documentao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Tickets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Cdigo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Padres de codificao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
Guia de retrocompatibilidade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

6 Instalao 115
Requisitos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Instalando o CakePHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Permisses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Servidor de Desenvolvimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
Produo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Aquecendo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
Reescrita de URL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118

7 Configurao 123
Configurando sua Aplicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Caminhos adicionais de classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
Configurao de Inflexo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Configurar classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
Lendo e escreveendo arquivos de configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
Criando seus prprios mecanismos de configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
Motores de Configurao Integrados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
Bootstrapping CakePHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
Variveis de Ambiente . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
Desabilitando tabelas genricas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134

8 Roteamento 135
Connecting Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135

9 Objetos de requisio e resposta 137


Requisio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

ii
10 Controllers (Controladores) 139
O App Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
Fluxo de requisies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Mtodos (actions) de controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
Redirecionando para outras pginas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
Carregando models adicionais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
Paginando um model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Configurando components para carregar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
Configurando helpers para carregar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Ciclo de vida de callbacks em uma requisio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
Mais sobre controllers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147

11 Views (Visualizao) 151


A App View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
View Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
Usando View Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
Eventos da View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Criando suas prprias Classes View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
Mais sobre Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163

12 Models (Modelos) 171


Exemplo rpido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Mais informao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173

13 Bake Console 229


Instalao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229

14 Caching 231
Configuring Cache Class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231

15 Console e Shells 233


O Console do CakePHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
Criando uma Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
Tasks de Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
Invocando outras Shells a partir da sua Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
Recenendo Input de usurios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Criando Arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Sada de dados do Console . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
Opes de configurao e Gerao de ajuda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 240
Roteamento em Shells / CLI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
Mtodos enganchados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
Mais tpicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248

16 Depurao 251
Depurao Bsica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Usando a Classe Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Valores de sada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Criando Logs com Pilha de Execuo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Gerando Pilhas de Execuo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Pegando Trechos de Arquivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Usando Logging para Depurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Debug Kit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254

iii
17 Implantao 255
Atualizar config/app.php . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
Checar a segurana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
Definir a raiz do documento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
Aprimorar a performance de sua aplicao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256

18 Email 257
Uso Bsico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Definindo Cabealho . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Enviando E-mail com Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Envio de Anexos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Usando Transportes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263

19 Erros & Excees 265


Error & Exception Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265

20 Sistema de eventos 267

21 Internacionalizao e Localizao 269


Configurando Tradues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
Usando funes de traduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
Criar seus prprios Tradutores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275

22 Logging 277
Logging Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277

23 Criando o Formulrio 279

24 Processando Requisio de Dados 281

25 Definindo os Valores do Formulrio 283

26 Pegando os Erros do Formulrio 285

27 Invalidando Campos Individuais do Formulrio no Controller 287

28 Criando o HTML com FormHelper 289

29 Plugins 291

30 REST 293

31 Segurana 295
Segurana . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

32 Sessions 297
Session Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297

33 Testing 299
Instalando o PHPUnit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Configurao do banco de dados test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Running Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Fixtures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Controller Integration Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Testing Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300

iv
34 Validao 301

35 App Class 303

36 Collections (Colees) 305

37 Arquivos & Pastas 307

38 Hash 309

39 Http Client 311

40 Inflector 313
Resumo dos mtodos de Inflexo e Suas Sadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
Criando as formas singulares e plurais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Criando as formas CamelCase e nome_sublinhado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Criando formas legveis para humanos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
Criando formatos para nomes de tabelas e classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Criando nomes de variveis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Criando strings de URL seguras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Configurao da inflexo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315

41 Nmero 317

42 Objetos de Registro 319

43 Texto 321

44 Tempo 323

45 Xml 325

46 Constantes e Funes 327


Funes globais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 327
Constantes de definio do Core . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329
Constantes de definio de tempo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 329

47 Debug Kit 331


Instalao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Armazenamento do DebugKit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
Uso da barra de ferramentas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Usando o painel History . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
Desenvolvendo seus prprios painis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333

48 Migrations 337
Instalao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
Viso Geral . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
Criando migrations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339
Gerando migraes a partir de uma base de dados existente . . . . . . . . . . . . . . . . . . . . . . . . . . 343
Os Comandos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 344
Usando migrations em plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
Executando migrations em ambientes fora da linha de comando . . . . . . . . . . . . . . . . . . . . . . . . 347
Dicas e truques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349

49 Apndices 353
Guia de Migrao para a verso 3.x . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353

v
Informaes Gerais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355

PHP Namespace Index 359

ndice 361

vi
CAPTULO 1

CakePHP num piscar de olhos

O CakePHP concebido para tornar tarefas de desenvolvimento web mais simples e fceis. Por fornecer uma caixa
de ferramentas completa para voc poder comear, o CakePHP funciona bem em conjunto ou isoladamente.
O objetivo desta anlise introduzir os conceitos gerais presentes no CakePHP, e lhe dar uma rpida viso geral de
como estes conceitos so implementados. Se voc est vido para comear um projeto, voc pode comear com o
tutorial, ou mergulhar na documentao.

Convenes Sobre Configurao

O CakePHP prov uma estrutura organizacional bsica que cobre nomenclaturas de classes, nomenclaturas de arqui-
vos, nomenclaturas de banco de dados, e outras convenes. Apesar das convenes levarem algum tempo para serem
assimiladas, ao segu-las o CakePHP evita configurao desnecessrio e cria uma estrutura de aplicao uniforme que
faz trabalhar com vrios projetos uma tarefa suave. O captulo de convenes cobre as variadas convenes que o
CakePHP utiliza.

A camada Model

A camada Model representa a parte da sua aplicao que implementa a lgica de negcio. Ela responsvel por
recuperar dados e convert-los nos conceitos significativos primrios na sua aplicao. Isto inclui processar, validar,
associar ou qualquer outra tarefa relacionada manipulao de dados.
No caso de uma rede social, a camada Model deveria tomar cuidado de tarefas como salvar os dados do usurio,
salvar as associaes entre amigos, salvar e recuperar fotos de usurios, localizar sugestes para novos amigos, etc. Os
objetos de modelo podem ser pensados como Friend, User, Comment, ou Photo. Se ns quisssemos carregar
alguns dados da nossa tabela users poderiamos fazer:

use Cake\ORM\TableRegistry;

$users = TableRegistry::get('Users');
$query = $users->find();
foreach ($query as $row) {
echo $row->username;
}

1
CakePHP Cookbook Documentation, Release 3.next

Voc pode notar que no precisamos escrever nenhum cdigo antes de podermos comear a trabalhar com nossos
dados. Por usar convenes, o CakePHP ir utilizar classes padro para tabelas e entidades ainda no definidas.
Se ns quisssemos criar um usurio e salv-lo (com validao) fariamos algo assim:

use Cake\ORM\TableRegistry;

$users = TableRegistry::get('Users');
$user = $users->newEntity(['email' => 'mark@example.com']);
$users->save($user);

A camada View

A View renderiza uma apresentao de dados modelados. Estando separada dos objetos da Model, responsvel por
utilizar a informao que tem disponvel para produzir qualquer interface de apresentao que a sua aplicao possa
precisar.
Por exemplo, a view pode usar dados da model para renderizar uma pgina HTML que os conhtenha, ou um resultado
formatado como XML:

// No arquivo view, ns renderizaremos um 'elemento' para cada usurio.


<?php foreach ($users as $user): ?>
<div class="user">
<?= $this->element('user', ['user' => $user]) ?>
</div>
<?php endforeach; ?>

A camada View prov alguma variedade de extenses como Elements e View Cells (Clulas de Visualizao) para
permitir que voc reutilize sua lgica de apresentao.
A camada View no est limitada somente a HTML ou apresentao textual dos dados. Ela pode ser usada para
entregar formatos de dado comuns como JSON, XML, e atravs de uma arquitetura encaixvel qualquer outro formato
que voc venha precisar.

A camada Controller

A camada Controller manipula requisies dos usurios. responsvel por renderizar uma resposta com o auxlio de
ambas as camadas, Model e View respectivamente.
Um controller pode ser visto como um gerente que certifica-se que todos os recursos necessrios para completar uma
tarefa sejam delegados aos trabalhadores corretos. Ele aguarda por peties dos clientes, checa suas validades de
acordo com autenticao ou regras de autorizao, delega requisies ou processamento de dados da camada Mo-
del, selecciona o tipo de dados de apresentao que os clientes esto aceitando, e finalmente delega o processo de
renderizao para a camada View. Um exemplo de controller para registro de usurio seria:

public function add()


{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->getData());
if ($this->Users->save($user, ['validate' => 'registration'])) {
$this->Flash->success(__('Voc est registrado.'));
} else {
$this->Flash->error(__('Houve algum problema.'));

2 Captulo 1. CakePHP num piscar de olhos


CakePHP Cookbook Documentation, Release 3.next

}
}
$this->set('user', $user);
}

Voc pode perceber que ns nunca renderizamos uma view explicitamente. As convenes do CakePHP tomaro
cuidado de selecionar a view correta e renderiz-la como os dados definidos com set().

Ciclo de Requisies do CakePHP

Agora que voc familiar com as diferentes camadas no CakePHP, vamos revisar como um cclo de requisio funci-
ona no CakePHP:

O cclo de requisio do CakePHP comea com a solicitao de uma pgina ou recurso da sua aplicao, seguindo a
cadncia abaixo:
1. As regras de reescrita do servidor encaminham a requisio para webroot/index.php.
2. Sua aplicao carregada e vinculada a um HttpServer.
3. O middleware da sua aplicao inicializado.

Ciclo de Requisies do CakePHP 3


CakePHP Cookbook Documentation, Release 3.next

4. A requisio e a resposta so processados atravs do PSR-7 Middleware que sua aplicao utiliza. Normalmente
isso inclui captura de erros e roteamento.
5. Se nenhuma resposta for retornada do middleware e a requisio contiver informaes de rota, um Controller e
uma action so acionados.
6. A action do Controller chamada e o mesmo interage com os Models e Components requisitados.
7. O controller delega a responsabilidade de criar respostas view, para assim gerar a sada de dados resultante do
Model.
8. A View utiliza Helpers e Cells para gerar o corpo e cabealho das respostas.
9. A resposta enviada de volta atravs do /controllers/middleware.
10. O HttpServer emite a resposta para o servidor web.

Apenas o Comeo

Esperamos que essa rpida viso geral tenha despertado seu interesse. Alguns outros grandes recursos no CakePHP
so:
Framework de cache que integra com Memcached, Redis e outros backends.
Poderosas ferramentas de gerao de cdigo para voc sair em disparada.
Framework de teste integrado para voc assegurar-se que seu cdigo funciona perfeitamente.
Os prximos passos bvios so baixar o CakePHP, ler o tutorial e construir algo fantstico.

Leitura adicional

Onde Conseguir Ajuda

O website oficial do CakePHP

https://cakephp.org
O website oficial do CakePHP sempre um timo lugar para visitar. Ele prov links para ferramentas comunmente
utilizadas por desenvolvedores, screencasts, oportunidades de doao e downloads.

O Cookbook

https://book.cakephp.org
Esse manual deveria ser o primeiro lugar para onde voc iria afim de conseguir respostas. Assim como muitos outros
projetos de cdigo aberto, ns conseguimos novos colaboradores regularmente. Tente o seu melhor para responder
suas questes por si s. Respostas vo vir lentamente, e provavelmente continuaro longas. Voc pode suavizar nossa
carga de suporte. Tanto o manual quanto a API possuem um componente online.

4 Captulo 1. CakePHP num piscar de olhos


CakePHP Cookbook Documentation, Release 3.next

A Bakery

https://bakery.cakephp.org
A padaria do CakePHP um local para todas as coisas relacionadas ao CakePHP. Visite-a para tutoriais, estudos de
caso e exemplos de cdigo. Uma vez que voc tenha se familiarizado com o CakePHP, autentique-se e compartilhe
seu conhecimento com a comunidade, ganhe instantaneamente fama e fortuna.

A API

https://api.cakephp.org/
Diretamente ao ponto, dos desenvolvedores do ncleo do CakePHP, a API (Application Programming Interface) do
CakePHP a mais compreensiva documentao sobre os detalhes tcnicos e minuciosos sobre do funcionamento
interno do framework.

Os Testes de Caso

Se voc sente que a informao provida pela API no suficiente, verifique os cdigos de testes de caso do CakePHP.
Eles podem servir como exemplos prticos para funes e e utilizao de dados referentes a uma classe.:

tests/TestCase/

O canal de IRC

Canal de IRC na irc.freenode.net:


#cakephp Discusso geral
#cakephp-docs Documentao
#cakephp-bakery Bakery
#cakephp-fr Canal francs.
Se voc est travado, nos faa uma visita no canal de IRC do CakePHP. Algum do time de desenvolvimento4 normal-
mente est conectado, especiamente nos horrios diurnos da Amrica do Sul e Amrica do Norte. Ns apreciaramos
ouv-lo se voc precisar de ajuda, se quiser encontrar usurios da sua rea ou ainda se quiser doar seu novo carro
esporte.

Stackoverflow

https://stackoverflow.com/5
Marque suas questes com a tag cakephp e especifique a verso que voc est utilizando para permitir que usurios
do stackoverflow achem suas questes.
4 https://github.com/cakephp?tab=members
5 https://stackoverflow.com/questions/tagged/cakephp/

Leitura adicional 5
CakePHP Cookbook Documentation, Release 3.next

Onde conseguir ajuda em sua lngua

Francs

Comunidade CakePHP francesa6

Portugus brasileiro

Comunidade CakePHP brasileira7

Convenes do CakePHP

Ns somos grandes fs de conveno sobre configurao. Apesar de levar um pouco de tempo para aprender as
convenes do CakePHP, voc economiza tempo a longo prazo. Ao seguir as convenes, voc ganha funcionalidades
instantaneamente e liberta-se do pesadelo de manuteno e rastreamento de arquivos de configurao. Convenes
tambm prezam por uma experincia de desenvolvimento uniforme, permitindo que outros desenvolvedores ajudem
mais facilmente.

Convenes para Controllers

Os nomes das classes de Controllers so pluralizados, CamelCased, e terminam em Controller.


PeopleController e LatestArticlesController so exemplos de nomes convencionais para control-
lers.
Mtodos pblicos nos Controllers so frequentemente referenciados como actions acessveis atravs de um nave-
gador web. Por exemplo, o /articles/view mapeia para o mtodo view() do ArticlesController sem
nenhum esforo. Mtodos privados ou protegidos no podem ser acessados pelo roteamento.

Consideraes de URL para nomes de Controller

Como voc acabou de ver, controllers singulares mapeiam facilmente um caminho simples, todo em minsculo. Por
exemplo, ApplesController (o qual deveria ser definido no arquivo de nome ApplesController.php) acessado
por http://example.com/apples.
Controllers com mltiplas palavras podem estar em qualquer forma flexionada igual ao nome do controller, ento:
/redApples
/RedApples
/Red_apples
/red_apples
Todos resolvero para o index do controller RedApples. Porm, a forma correta que suas URLs sejam
minsculas e separadas por sublinhado, portanto /red_apples/go_pick a forma correta de acessar a action
RedApplesController::go_pick.
Quando voc cria links usando this->Html->link(), voc pode usar as seguintes convenes para a array de
url:
6 http://cakephp-fr.org
7 http://cakephp-br.org

6 Captulo 1. CakePHP num piscar de olhos


CakePHP Cookbook Documentation, Release 3.next

$this->Html->link('link-title', [
'prefix' => 'MyPrefix' // CamelCased
'plugin' => 'MyPlugin', // CamelCased
'controller' => 'ControllerName', // CamelCased
'action' => 'actionName' // camelBacked
]

Para mais informaes sobre o manuseio de URLs e parmetros do CakePHP, veja Connecting Routes.

Convenes para nomes de Classes e seus nomes de arquivos

No geral, nomes de arquivos correspondem aos nomes das classes, e seguem os padres PSR-0 ou PSR-4 para auto-
carregamento. A seguir seguem exemplos de nomes de classes e de seus arquivos:
A classe de Controller KissesAndHugsController deveria ser encontrada em um arquivo nomeado Kisse-
sAndHugsController.php
A classe de Component MyHandyComponent deveria ser encontrada em um arquivo nomeado MyHandy-
Component.php
A classe de Table OptionValuesTable deveria ser encontrada em um arquivo nomeado OptionValuesTa-
ble.php.
A classe de Entity OptionValue deveria ser encontrada em um arquivo nomeado OptionValue.php.
A classe de Behavior EspeciallyFunkableBehavior deveria ser encontrada em um arquivo nomeado Especi-
allyFunkableBehavior.php
A classe de View SuperSimpleView deveria ser encontrada em um arquivo nomeado SuperSimpleView.php
A classe de Helper BestEverHelper deveria ser encontrada em um arquivo nomeado BestEverHelper.php
Cada arquivo deveria estar localizado no diretrio/namespace apropriado de sua aplicao.

Convenes para Models e Databases

Os nomes de classe de Tables so pluralizadas e CamelCased. People, BigPeople, and ReallyBigPeople so todos
exemplos convencionais de models.
Os nomes de Tables correspondentes aos models do CakePHP so pluralizadas e separadas por sublinhado. As ta-
bles sublinhadas para os models mencionados acima seriam people, big_people, e really_big_people,
respectively.
Voc pode utilizar a biblioteca utility Cake\Utility\Inflector para checar o singular/plural de palavras. Veja
o Inflector para mais informaes. Recomenda-se que as tables sejam criadas e mantidas na lngua inglesa.
Campos com duas ou mais palavras so separados por sublinhado: first_name.
Chaves estrangeiras nos relacionamentos hasMany, belongsTo ou hasOne so reconhecidas por padro como o nome
(singular) da table relacionada seguida por _id. Ento se Bakers hasMany Cakes, a table cakes ir referenciar-se para a
table bakers atravs da chave estrangeira baker_id. Para uma tabela como category_types a qual o nome contm mais
palavras, a chave estrangeira seria a category_type_id.
tables de unio, usadas no relacionamento BelongsToMany entre models, devem ser nomeadas depois das tables que
ela est unindo, ordenadas em ordem alfabtica (apples_zebras ao invs de zebras_apples).

Leitura adicional 7
CakePHP Cookbook Documentation, Release 3.next

Convenes para Views

Arquivos de template views so nomeadas seguindo as funes que a exibem do controller, separa-
das por sublinhado. A funo getReady() da classe PeopleController buscar por um template view em
src/Template/People/get_ready.ctp. O padro src/Template/Controller/underscored_function_name.ctp.
Por nomear as partes de sua aplicao utilizando as convenes do CakePHP, voc ganha funcionalidades sem luta e
sem amarras de configurao. Aqui est um exemplo final que enlaa as convenes juntas:
Table: people
Classe Table: PeopleTable, encontrada em src/Model/Table/PeopleTable.php
Classe Entity: Person, encontrada em src/Model/Entity/Person.php
Classe Controller: PeopleController, encontrada em src/Controller/PeopleController.php
View template, encontrado em src/Template/People/index.ctp
Utilizando estas convenes, o CakePHP sabe que uma requisio para http://example.com/people/ mapeia para uma
chamada da funo index() do PeopleController, onde o model Person automaticamente disponbilizado (e auto-
maticamente amarrado table people no banco de dados), e ento renderiza-se um arquivo view template. Nenhuma
destes relacionamentos foi configurado de qualquer forma se no por criar classes e arquivos que voc precisaria criar
de qualquer forma.
Agora que voc foi introduzido aos fundamentos do CakePHP, voc pode tentar seguir atravs do Tutorial - Criando
um Blog - Parte 1 para ver como as coisas se encaixam juntas.

Estrutura de pastas do CakePHP

Depois de voc ter baixado e extrado o CakePHP, a esto os arquivos e pastas que voc deve ver:
bin
config
logs
plugins
src
tests
tmp
vendor
webroot
.htaccess
composer.json
index.php
README.md
Voc notar alguns diretrios principais:
The bin folder holds the Cake console executables.
O diretrio config contem os (poucos) Configurao arquivos de configurao que o CakePHP utiliza. Detalhes
de conexo com banco de dados, inicializao, arquivos de configurao do ncleo da aplicao, e relacionados
devem ser postos aqui.

8 Captulo 1. CakePHP num piscar de olhos


CakePHP Cookbook Documentation, Release 3.next

O diretrio logs ser normalmente onde seus arquivos de log ficaro, dependendo das suas configuraes.
O diretrio plugins ser onde Plugins que sua aplicao utiliza sero armazenados.
O diretrio src ser onde voc far sua mgica: onde os arquivos da sua aplicao sero colocados.
O diretrio tests ser onde voc colocar os testes de caso para sua aplicao.
O diretrio tmp ser onde o CakePHP armazenar dados temporrios. O modo como os dados sero armazena-
dos depende da configurao do CakePHP, mas esse diretrio comunmente usado para armazenar descries
de modelos e algumas vezes informao de sesso.
O diretrio vendor ser onde o CakePHP e outras dependncias da aplicao sero instalados. Faa uma nota
pessoal para no editar arquivos deste diretrio. Ns no podemos ajudar se voc tiv-lo feito.
O diretrio webroot ser a raz pblica de documentos da sua aplicao. Ele contem todos os arquivos que voc
gostaria que fossem pblicos.
Certifique-se que os diretrios tmp e logs existem e so passveis de escrita, seno a performance de sua aplicao
ser severamente impactada. Em modo de debug, o CakePHP ir alert-lo se este for o caso.

O diretrio src

O diretrio src do CakePHP onde voc far a maior parte do desenvolvimento de sua aplicao. Vamos ver mais de
perto a estrutura de pastas dentro de src.
Console Contm os comandos e tarefas de console para sua aplicao. Para mais informaes veja Console e Shells.
Controller Contm os controllers de sua aplicao e seus componentes.
Locale Armazena arquivos textuais para internacionalizao.
Model Contm as tables, entities e behaviors de sua aplicao.
View Classes de apresentao so alocadas aqui: cells, helpers, e arquivos view.
Template Arquivos de apresentao so alocados aqui: elements, pginas de erro, layouts, e templates view.

Leitura adicional 9
CakePHP Cookbook Documentation, Release 3.next

10 Captulo 1. CakePHP num piscar de olhos


CAPTULO 2

Guia de Incio Rpido

A melhor forma de viver experincias e aprender sobre CakePHP sentar e construir algo. Para comear ns iremos
construir uma aplicao simples de blog.

Tutorial - Criando um Bookmarker - Parte 1

Esse tutorial vai guiar voc atravs da criao de uma simples aplicao de marcao (bookmarker). Para comear,
ns vamos instalar o CakePHP, criar nosso banco de dados, e usar as ferramentas que o CakePHP fornece para obter
nossa aplicao de p rpido.
Aqui est o que voc vai precisar:
1. Um servidor de banco de dados. Ns vamos usar o servidor MySQL neste tutorial. Voc precisa saber o
suficiente sobre SQL para criar um banco de dados: O CakePHP vai tomar as rdeas a partir da. Por ns
estarmos usando o MySQL, tambm certifique-se que voc tem a extenso pdo_mysql habilitada no PHP.
2. Conhecimento bsico sobre PHP.
Vamos comear!

Instalao do CakePHP

A maneira mais fcil de instalar o CakePHP usando Composer, um gerenciador de dependncias para o PHP. uma
forma simples de instalar o CakePHP a partir de seu terminal ou prompt de comando. Primeiro, voc precisa baixar e
instalar o Composer. Se voc tiver instalada a extenso cURL do PHP, execute o seguinte comando:

curl -s https://getcomposer.org/installer | php

Ao invs disso, voc tambm pode baixar o arquivo composer.phar do site8 oficial.
Em seguida, basta digitar a seguinte linha no seu terminal a partir do diretrio onde se localiza o arquivo
composer.phar para instalar o esqueleto de aplicaes do CakePHP no diretrio bookmarker.

php composer.phar create-project --prefer-dist cakephp/app bookmarker

8 https://getcomposer.org/download/

11
CakePHP Cookbook Documentation, Release 3.next

A vantagem de usar Composer que ele ir completar automaticamente um conjunto importante de tarefas, como
configurar as permisses de arquivo e criar a sua config/app.php.
H outras maneiras de instalar o CakePHP. Se voc no puder ou no quiser usar Composer, veja a seo Instalao.
Independentemente de como voc baixou o CakePHP, uma vez que sua instalao for concluda, a estrutura dos
diretrios deve ficar parecida com o seguinte:
/bookmarker
/bin
/config
/logs
/plugins
/src
/tests
/tmp
/vendor
/webroot
.editorconfig
.gitignore
.htaccess
.travis.yml
composer.json
index.php
phpunit.xml.dist
README.md

Agora pode ser um bom momento para aprender sobre como a estrutura de diretrios do CakePHP funciona: Confira
a seo Estrutura de pastas do CakePHP.

Verificando nossa instalao

Podemos checar rapidamente que a nossa instalao est correta, verificando a pgina inicial padro. Antes que voc
possa fazer isso, voc vai precisar iniciar o servidor de desenvolvimento:
bin/cake server

Isto ir iniciar o servidor embutido do PHP na porta 8765. Abra http://localhost:8765 em seu navegador
para ver a pgina de boas-vindas. Todas as verificaes devem estar checadas corretamente, a no ser a conexo com
banco de dados do CakePHP. Se no, voc pode precisar instalar extenses do PHP adicionais, ou definir permisses
de diretrio.

Criando o banco de dados

Em seguida, vamos criar o banco de dados para a nossa aplicao. Se voc ainda no tiver feito isso, crie um banco
de dados vazio para uso nesse tutorial, com um nome de sua escolha, por exemplo, cake_bookmarks. Voc pode
executar o seguinte SQL para criar as tabelas necessrias:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
created DATETIME,
modified DATETIME
);

12 Captulo 2. Guia de Incio Rpido


CakePHP Cookbook Documentation, Release 3.next

CREATE TABLE bookmarks (


id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(50),
description TEXT,
url TEXT,
created DATETIME,
modified DATETIME,
FOREIGN KEY user_key (user_id) REFERENCES users(id)
);

CREATE TABLE tags (


id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
created DATETIME,
modified DATETIME,
UNIQUE KEY (title)
);

CREATE TABLE bookmarks_tags (


bookmark_id INT NOT NULL,
tag_id INT NOT NULL,
PRIMARY KEY (bookmark_id, tag_id),
INDEX tag_idx (tag_id, bookmark_id),
FOREIGN KEY tag_key(tag_id) REFERENCES tags(id),
FOREIGN KEY bookmark_key(bookmark_id) REFERENCES bookmarks(id)
);

Voc deve ter notado que a tabela bookmarks_tags utilizada uma chave primria composta. O CakePHP suporta
chaves primrias compostas quase todos os lugares, tornando mais fcil construir aplicaes multi-arrendados.
Os nomes de tabelas e colunas que usamos no foram arbitrrias. Usando convenes de nomenclatura do CakePHP,
podemos alavancar o desenvolvimento e evitar ter de configurar o framework. O CakePHP flexvel o suficiente para
acomodar at mesmo esquemas de banco de dados legados inconsistentes, mas aderir s convenes vai lhe poupar
tempo.

Configurando o banco de dados

Em seguida, vamos dizer ao CakePHP onde o nosso banco de dados est como se conectar a ele. Para muitos, esta
ser a primeira e ltima vez que voc vai precisar configurar qualquer coisa.
A configurao bem simples: basta alterar os valores do array Datasources.default no arquivo con-
fig/app.php pelos que se aplicam sua configurao. A amostra completa da gama de configuraes pode ser algo
como o seguinte:
return [
// Mais configurao acima.
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => 'cakephp',
'password' => 'AngelF00dC4k3~',
'database' => 'cake_bookmarks',
'encoding' => 'utf8',

Tutorial - Criando um Bookmarker - Parte 1 13


CakePHP Cookbook Documentation, Release 3.next

'timezone' => 'UTC',


'cacheMetadata' => true,
],
],
// Mais configurao abaixo.
];

Depois de salvar o seu arquivo config/app.php, voc deve notar que a mensagem CakePHP is able to connect to the
database tem uma marca de verificao.

Nota: Uma cpia do arquivo de configurao padro do CakePHP encontrado em config/app.default.php.

Gerando o cdigo base

Devido a nosso banco de dados seguir as convenes do CakePHP, podemos usar o bake console para gerar rapida-
mente uma aplicao bsica . Em sua linha de comando execute:

bin/cake bake all users


bin/cake bake all bookmarks
bin/cake bake all tags

Isso ir gerar os controllers, models, views, seus casos de teste correspondentes, e fixtures para os nossos users,
bookmarks e tags. Se voc parou seu servidor, reinicie-o e v para http://localhost:8765/bookmarks.
Voc dever ver uma aplicao que d acesso bsico, mas funcional a tabelas de banco de dados. Adicione alguns
users, bookmarks e tags.

Adicionando criptografia de senha

Quando voc criou seus users, voc deve ter notado que as senhas foram armazenadas como texto simples. Isso
muito ruim do ponto de vista da segurana, por isso vamos consertar isso.
Este tambm um bom momento para falar sobre a camada de modelo. No CakePHP, separamos os mtodos que
operam em uma coleo de objetos, e um nico objeto em diferentes classes. Mtodos que operam na recolha de
entidades so colocadas na classe Table, enquanto as caractersticas pertencentes a um nico registro so colocados na
classe Entity.
Por exemplo, a criptografia de senha feita no registro individual, por isso vamos implementar esse comportamento
no objeto entidade. Dada a circunstncia de ns querermos criptografar a senha cada vez que definida, vamos usar
um mtodo modificador/definidor. O CakePHP vai chamar mtodos de definio baseados em convenes a qualquer
momento que uma propriedade definida em uma de suas entidades. Vamos adicionar um definidor para a senha. Em
src/Model/Entity/User.php adicione o seguinte:

namespace App\Model\Entity;

use Cake\ORM\Entity;
use Cake\Auth\DefaultPasswordHasher;

class User extends Entity


{

// Code from bake.

14 Captulo 2. Guia de Incio Rpido


CakePHP Cookbook Documentation, Release 3.next

protected function _setPassword($value)


{
$hasher = new DefaultPasswordHasher();
return $hasher->hash($value);
}
}

Agora atualize um dos usurios que voc criou anteriormente, se voc alterar sua senha, voc deve ver um senha
criptografada ao invs do valor original nas pginas de lista ou visualizao. O CakePHP criptografa senhas com
bcrypt9 por padro. Voc tambm pode usar sha1 ou md5 caso venha a trabalhar com um banco de dados existente.

Recuperando bookmarks com uma tag especfica

Agora que estamos armazenando senhas com segurana, podemos construir algumas caractersticas mais interessantes
em nossa aplicao. Uma vez que voc acumulou uma coleo de bookmarks, til ser capaz de pesquisar atravs
deles por tag. Em seguida, vamos implementar uma rota, a ao do controller, e um mtodo localizador para pesquisar
atravs de bookmarks por tag.
Idealmente, ns teramos uma URL que se parece com http://localhost:8765/bookmarks/tagged/funny/cat/gifs.
Isso deveria nos permitir a encontrar todos os bookmarks que tm as tags funny, cat e gifs. Antes de podermos
implementar isso, vamos adicionar uma nova rota. Em config/routes.php, adicione o seguinte na parte superior do
arquivo:

Router::scope(
'/bookmarks',
['controller' => 'Bookmarks'],
function ($routes) {
$routes->connect('/tagged/*', ['action' => 'tags']);
}
);

O acima define uma nova rota que liga o caminho /bookmarks/tagged/*, a


BookmarksController::tags(). Ao definir rotas, voc pode isolar como suas URLs parecero, de
como eles so implementadas. Se fssemos visitar http://localhost:8765/bookmarks/tagged, de-
veriamos ver uma pgina de erro informativa do CakePHP. Vamos implementar esse mtodo ausente agora. Em
src/Controller/BookmarksController.php adicione o seguinte:

public function tags()


{
$tags = $this->request->getParam('pass');
$bookmarks = $this->Bookmarks->find('tagged', [
'tags' => $tags
]);
$this->set(compact('bookmarks', 'tags'));
}

Criando o mtodo localizador

No CakePHP ns gostamos de manter as nossas aes do controller enxutas, e colocar a maior parte da l-
gica de nossa aplicao nos modelos. Se voc fosse visitar a URL /bookmarks/tagged agora, voc
veria um erro sobre o mtodo findTagged no estar implementado ainda, ento vamos fazer isso. Em
src/Model/Table/BookmarksTable.php adicione o seguinte:
9 http://codahale.com/how-to-safely-store-a-password/

Tutorial - Criando um Bookmarker - Parte 1 15


CakePHP Cookbook Documentation, Release 3.next

public function findTagged(Query $query, array $options)


{
$bookmarks = $this->find()
->select(['id', 'url', 'title', 'description']);

if (empty($options['tags'])) {
$bookmarks
->leftJoinWith('Tags')
->where(['Tags.title IS' => null]);
} else {
$bookmarks
->innerJoinWith('Tags')
->where(['Tags.title IN ' => $options['tags']]);
}

return $bookmarks->group(['Bookmarks.id']);
}

Ns implementamos um mtodo localizador customizado. Este um conceito muito poderoso no CakePHP que lhe
permite construir consultas reutilizveis. Em nossa pesquisa, ns alavancamos o mtodo matching() que nos
habilita encontrar bookmarks que tm uma tag correspondente.

Criando a view

Agora, se voc visitar a URL /bookmarks/tagged, o CakePHP ir mostrar um erro e deix-lo saber que voc
ainda no fez um arquivo view. Em seguida, vamos construir o arquivo view para a nossa ao tags. Em
src/Template/Bookmarks/tags.ctp coloque o seguinte contedo:

<h1>
Bookmarks tagged with
<?= $this->Text->toList(h($tags)) ?>
</h1>

<section>
<?php foreach ($bookmarks as $bookmark): ?>
<article>
<h4><?= $this->Html->link($bookmark->title, $bookmark->url) ?></h4>
<small><?= h($bookmark->url) ?></small>
<?= $this->Text->autoParagraph(h($bookmark->description)) ?>
</article>
<?php endforeach; ?>
</section>

O CakePHP espera que os nossos templates sigam a conveno de nomenclatura onde o nome do template a verso
minscula e grifada do nome da ao do controller.
Voc pode perceber que fomos capazes de utilizar as variveis $tags e bookmarks em nossa view. Quando usamos
o mtodo set() em nosso controller, automaticamente definimos variveis especficas que devem ser enviadas para
a view. A view vai tornar todas as variveis passadas disponveis nos templates como variveis locais.
Em nossa view, usamos alguns dos helpers nativos do CakePHP. Helpers so usados para criar lgica re-utilizvel para
a formatao de dados, a criao de HTML ou outra sada da view.
Agora voc deve ser capaz de visitar a URL /bookmarks/tagged/funny e ver todas os bookmarks com a tag
funny.

16 Captulo 2. Guia de Incio Rpido


CakePHP Cookbook Documentation, Release 3.next

At agora, ns criamos uma aplicao bsica para gerenciar bookmarks, tags e users. No entanto, todos podem ver as
tags de toda a gente. No prximo captulo, vamos implementar a autenticao e restringir os bookmarks visveis para
somente aqueles que pertencem ao usurio atual.
Agora v a Tutorial - Criando um Bookmarker - Parte 2 para continuar a construir sua aplicao ou mergulhe na
documentao para saber mais sobre o que CakePHP pode fazer por voc.

Tutorial - Criando um Bookmarker - Parte 2

Depois de terminar a primeira parte deste tutorial, voc deve ter uma aplicao muito bsica. Neste captulo iremos
adicionar autenticao e restringir as bookmarks para que cada usurio possa ver/modificar somente aquelas que
possuam.

Adicionando login

No CakePHP, a autenticao feita por Components (Componentes). Os Components podem ser considerados como
formas de criar pedaos reutilizveis de cdigo relacionado a controllers com uma caracterstica especfica ou conceito.
Os components tambm podem ligar-se ao evento do ciclo de vida do controller e interagir com a sua aplicao. Para
comear, vamos adicionar o AuthComponent a nossa aplicao. Ns vamos querer muito que cada mtodo exija
autenticao, por isso vamos acrescentar o AuthComponent em nosso AppController:

// Em src/Controller/AppController.php
namespace App\Controller;

use Cake\Controller\Controller;

class AppController extends Controller


{
public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
]
]);

// Permite a ao display, assim nosso pages controller


// continua a funcionar.
$this->Auth->allow(['display']);
}
}

Acabamos de dizer ao CakePHP que queremos carregar os components Flash e Auth. Alm disso, temos a confi-
gurao personalizada do AuthComponent, assim a nossa tabela users pode usar email como username. Agora, se

Tutorial - Criando um Bookmarker - Parte 2 17


CakePHP Cookbook Documentation, Release 3.next

voc for a qualquer URL, voc vai ser chutado para /users/login, que ir mostrar uma pgina de erro j que no
escrevemos o cdigo ainda. Ento, vamos criar a ao de login:

// Em src/Controller/UsersController.php

public function login()


{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error('Your username or password is incorrect.');
}
}

E em src/Template/Users/login.ctp adicione o seguinte:

<h1>Login</h1>
<?= $this->Form->create() ?>
<?= $this->Form->input('email') ?>
<?= $this->Form->input('password') ?>
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

Agora que temos um simples formulrio de login, devemos ser capazes de efetuar login com um dos users que tenham
senha criptografada.

Nota: Se nenhum de seus users tem senha criptografada, comente a linha loadComponent('Auth'). Ento v
e edite o user, salvando uma nova senha para ele.

Agora voc deve ser capaz de entrar. Se no, certifique-se que voc est usando um user que tenha senha criptografada.

Adicionando logout

Agora que as pessoas podem efetuar o login, voc provavelmente vai querer fornecer uma maneira de encerrar a sesso
tambm. Mais uma vez, no UsersController, adicione o seguinte cdigo:

public function logout()


{
$this->Flash->success('You are now logged out.');
return $this->redirect($this->Auth->logout());
}

Agora voc pode visitar /users/logout para sair e ser enviado pgina de login.

Ativando inscries

Se voc no estiver logado e tentar visitar / usurios / adicionar voc vai ser expulso para a pgina de login. Devemos
corrigir isso se quisermos que as pessoas se inscrevam em nossa aplicao. No UsersController adicione o seguinte:

public function beforeFilter(\Cake\Event\Event $event)


{

18 Captulo 2. Guia de Incio Rpido


CakePHP Cookbook Documentation, Release 3.next

$this->Auth->allow(['add']);
}

O texto acima diz ao AuthComponent que a ao add no requer autenticao ou autorizao. Voc pode querer
dedicar algum tempo para limpar a /users/add e remover os links enganosos, ou continuar para a prxima se-
o. Ns no estaremos construindo a edio do usurio, visualizao ou listagem neste tutorial, ento eles no vo
funcionar, j que o AuthComponent vai negar-lhe acesso a essas aes do controller.

Restringindo acesso

Agora que os usurios podem conectar-se, ns vamos querer limitar os bookmarks que podem ver para aqueles que
fizeram. Ns vamos fazer isso usando um adaptador de autorizao. Sendo os nossos requisitos bastante simples,
podemos escrever um cdigo em nossa BookmarksController. Mas antes de fazer isso, vamos querer dizer ao
AuthComponent como nossa aplicao vai autorizar aes. Em seu AppController adicione o seguinte:
public function isAuthorized($user)
{
return false;
}

Alm disso, adicione o seguinte configurao para Auth em seu AppController:


'authorize' => 'Controller',

Seu mtodo initialize agora deve parecer com:


public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize'=> 'Controller',//added this line
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
'unauthorizedRedirect' => $this->referer()
]);

// Permite a ao display, assim nosso pages controller


// continua a funcionar.
$this->Auth->allow(['display']);
}

Vamos usar como padro, negao do acesso, e de forma incremental conceder acesso onde faa sentido. Primeiro,
vamos adicionar a lgica de autorizao para os bookmarks. Em seu BookmarksController adicione o seguinte:
public function isAuthorized($user)
{

Tutorial - Criando um Bookmarker - Parte 2 19


CakePHP Cookbook Documentation, Release 3.next

$action = $this->request->params['action'];

// As aes add e index so permitidas sempre.


if (in_array($action, ['index', 'add', 'tags'])) {
return true;
}
// Todas as outras aes requerem um id.
if (!$this->request->getParam('pass.0')) {
return false;
}

// Checa se o bookmark pertence ao user atual.


$id = $this->request->getParam('pass.0');
$bookmark = $this->Bookmarks->get($id);
if ($bookmark->user_id == $user['id']) {
return true;
}
return parent::isAuthorized($user);
}

Agora, se voc tentar visualizar, editar ou excluir um bookmark que no pertena a voc, voc deve ser redirecionado
para a pgina de onde veio. No entanto, no h nenhuma mensagem de erro sendo exibida, ento vamos corrigir isso
a seguir:

// In src/Template/Layout/default.ctp
// Under the existing flash message.
<?= $this->Flash->render('auth') ?>

Agora voc deve ver as mensagens de erro de autorizao.

Corrigindo a view de listagem e formulrios

Enquanto view e delete esto trabalhando, edit, add e index tem alguns problemas:
1. Ao adicionar um bookmark, voc pode escolher o user.
2. Ao editar um bookmark, voc pode escolher o user.
3. A pgina de listagem mostra os bookmarks de outros users.
Vamos enfrentar o formulrio de adio em primeiro lugar. Para comear remova o input('user_id') a partir
de src/Template/Bookmarks/add.ctp. Com isso removido, ns tambm vamos atualizar o mtodo add:

public function add()


{
$bookmark = $this->Bookmarks->newEntity();
if ($this->request->is('post')) {
$bookmark = $this->Bookmarks->patchEntity($bookmark, $this->request->
getData());

$bookmark->user_id = $this->Auth->user('id');
if ($this->Bookmarks->save($bookmark)) {
$this->Flash->success('The bookmark has been saved.');
return $this->redirect(['action' => 'index']);
}
$this->Flash->error('The bookmark could not be saved. Please, try again.');
}
$tags = $this->Bookmarks->Tags->find('list');

20 Captulo 2. Guia de Incio Rpido


CakePHP Cookbook Documentation, Release 3.next

$this->set(compact('bookmark', 'tags'));
}

Ao definir a propriedade da entidade com os dados da sesso, ns removemos qualquer possibilidade do user modificar
de que outro user um bookmark seja. Ns vamos fazer o mesmo para o formulrio edit e action edit. Sua ao edit
deve ficar assim:

public function edit($id = null)


{
$bookmark = $this->Bookmarks->get($id, [
'contain' => ['Tags']
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$bookmark = $this->Bookmarks->patchEntity($bookmark, $this->request->
getData());

$bookmark->user_id = $this->Auth->user('id');
if ($this->Bookmarks->save($bookmark)) {
$this->Flash->success('The bookmark has been saved.');
return $this->redirect(['action' => 'index']);
}
$this->Flash->error('The bookmark could not be saved. Please, try again.');
}
$tags = $this->Bookmarks->Tags->find('list');
$this->set(compact('bookmark', 'tags'));
}

View de listagem

Agora, ns precisamos apenas exibir bookmarks para o user logado. Ns podemos fazer isso ao atualizar a chamada
para paginate(). Altere sua ao index:

public function index()


{
$this->paginate = [
'conditions' => [
'Bookmarks.user_id' => $this->Auth->user('id'),
]
];
$this->set('bookmarks', $this->paginate($this->Bookmarks));
}

Ns tambm devemos atualizar a action tags() e o mtodo localizador relacionado, mas vamos deixar isso como
um exerccio para que voc conclua por s.

Melhorando a experincia com as tags

Agora, adicionar novas tags um processo difcil, pois o TagsController probe todos os acessos. Em vez de
permitir o acesso, podemos melhorar a interface do usurio para selecionar tags usando um campo de texto separado
por vrgulas. Isso permitir dar uma melhor experincia para os nossos usurios, e usar mais alguns grandes recursos
no ORM.

Tutorial - Criando um Bookmarker - Parte 2 21


CakePHP Cookbook Documentation, Release 3.next

Adicionando um campo computado

Porque ns queremos uma maneira simples de acessar as tags formatados para uma entidade, podemos adicionar um
campo virtual/computado para a entidade. Em src/Model/Entity/Bookmark.php adicione o seguinte:

use Cake\Collection\Collection;

protected function _getTagString()


{
if (isset($this->_properties['tag_string'])) {
return $this->_properties['tag_string'];
}
if (empty($this->tags)) {
return '';
}
$tags = new Collection($this->tags);
$str = $tags->reduce(function ($string, $tag) {
return $string . $tag->title . ', ';
}, '');
return trim($str, ', ');
}

Isso vai nos deixar acessar a propriedade computada $bookmark->tag_string. Vamos usar essa propriedade
em inputs mais tarde. Lembre-se de adicionar a propriedade tag_string a lista _accessible em sua entidade.
Em src/Model/Entity/Bookmark.php adicione o tag_string ao _accessible desta forma:

protected $_accessible = [
'user_id' => true,
'title' => true,
'description' => true,
'url' => true,
'user' => true,
'tags' => true,
'tag_string' => true,
];

Atualizando as views

Com a entidade atualizado, podemos adicionar uma nova entrada para as nossas tags. Nas views add e edit, substitua
tags._ids pelo seguinte:

<?= $this->Form->input('tag_string', ['type' => 'text']) ?>

Persistindo a string tag

Agora que podemos ver as tags como uma string existente, vamos querer salvar os dados tambm. Por marcar o
tag_string como acessvel, o ORM ir copiar os dados do pedido em nossa entidade. Podemos usar um mtodo
beforeSave para analisar a cadeia tag e encontrar/construir as entidades relacionadas. Adicione o seguinte em
src/Model/Table/BookmarksTable.php:

public function beforeSave($event, $entity, $options)


{
if ($entity->tag_string) {
$entity->tags = $this->_buildTags($entity->tag_string);

22 Captulo 2. Guia de Incio Rpido


CakePHP Cookbook Documentation, Release 3.next

}
}

protected function _buildTags($tagString)


{
$new = array_unique(array_map('trim', explode(',', $tagString)));
$out = [];
$query = $this->Tags->find()
->where(['Tags.title IN' => $new]);

// Remove tags existentes da lista de novas tags.


foreach ($query->extract('title') as $existing) {
$index = array_search($existing, $new);
if ($index !== false) {
unset($new[$index]);
}
}
// Adiciona tags existentes.
foreach ($query as $tag) {
$out[] = $tag;
}
// Adiciona novas tags.
foreach ($new as $tag) {
$out[] = $this->Tags->newEntity(['title' => $tag]);
}
return $out;
}

Embora esse cdigo seja um pouco mais complicado do que o que temos feito at agora, ele ajuda a mostrar o quo
poderosa a ORM do CakePHP . Voc pode facilmente manipular resultados da consulta usando os mtodos de
Collections (Colees), e lidar com situaes em que voc est criando entidades sob demanda com facilidade.

Terminando

Ns expandimos nossa aplicao bookmarker para lidar com situaes de autenticao e controle de autorizao/acesso
bsico. Ns tambm adicionamos algumas melhorias agradveis UX, aproveitando os recursos FormHelper e ORM.
Obrigado por dispor do seu tempo para explorar o CakePHP. Em seguida, voc pode saber mais sobre o Models
(Modelos), ou voc pode ler os /topics.

Tutorial - Criando um Bookmarker - Parte 2 23


CakePHP Cookbook Documentation, Release 3.next

24 Captulo 2. Guia de Incio Rpido


CAPTULO 3

3.0 - Guia de migrao

Esta pgina resume as alteraes do CakePHP 2.x e ir auxiliar na migrao do seu projeto para a verso 3.0, e tambm
ser uma referncia para atualiz-lo quanto s principais mudanas do branch 2.x. Certifique-se de ler tambm as
outras pginas nesse guia para conhecer todas as novas funcionalidades e mudanas na API.

Requerimentos

O CakePHP 3.x suporta o PHP 5.4.16 e acima.


O CakePHP 3.x precisa da extenso mbstring.
O CakePHP 3.x precisa da extenso intl.

Aviso: O CakePHP 3.0 no ir funcionar se voc no atender aos requisitos acima.

Ferramenta de atualizao

Enquanto este documento cobre todas as alteraes e melhorias feitas no CakePHP 3.0, ns tambm criamos uma
aplicao de console para ajudar voc a completar mais facilmente algumas das alteraes mecnicas que consomem
tempo. Voc pode pegar a ferramenta de atualizao no GitHub10 .

Layout do diretrio da aplicao

O Layout do diretrio da aplicao mudou e agora segue o PSR-411 . Voc deve usar o projeto do esqueleto da
aplicao12 como um ponto de referncia quando atualizar sua aplicao.
10 https://github.com/cakephp/upgrade
11 http://www.php-fig.org/psr/psr-4/
12 https://github.com/cakephp/app

25
CakePHP Cookbook Documentation, Release 3.next

O CakePHP deve ser instalado via Composer

Como o CakePHP no pode mais ser instalado facilmente via PEAR, ou em um diretrio compartilhado, essas opes
no so mais suportadas. Ao invs disso, voc deve usar o Composer13 para instalar o CakePHP em sua aplicao.

Namespaces

Todas as classes do core do CakePHP agora usam namespaces e seguem as especificaes de autoload (auto-
carregamento) do PSR-4. Por exemplo src/Cache/Cache.php tem o namespace Cake\Cache\Cache. Constantes
globais e mtodos de helpers como __() e debug() no usam namespaces por questes de convenincia.

Constantes removidas

As seguintes constantes obsoletas foram removidas:


IMAGES
CSS
JS
IMAGES_URL
JS_URL
CSS_URL
DEFAULT_LANGUAGE

Configurao

As configuraes no CakePHP 3.0 esto significativamente diferentes que nas verses anteriores. Voc deve ler a
documentao Configurao para ver como a configurao feita.
Voc no pode mais usar o App::build() para configurar caminhos adicionais de classes. Ao invs disso, voc
deve mapear caminhos adicionais usando o autoloader da sua aplicao. Veja a seo Caminhos de Classes Adicionais
para mais informaes.
Trs novas variveis de configurao fornecem o caminho de configurao para plugins, views e arquivos de
localizao. Voc pode adicionar vrios caminhos em App.paths.templates, App.paths.plugins,
App.paths.locales para configurar mltiplos caminhos para templates, plugins e arquivos de localizao res-
pectivamente.
A chave de configurao www_root mudou para wwwRoot devido a consistncia. Por favor, ajuste seu arquivo de
configurao app.php assim como qualquer uso de Configure::read('App.wwwRoot').
13 http://getcomposer.org

26 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

Novo ORM

O CakePHP 3.0 possui um novo ORM que foi refeito do zero. O novo ORM significativamente diferente e incom-
patvel com o anterior. Migrar para o novo ORM necessita de alteraes extensas em qualquer aplicao que esteja
sendo atualizada. Veja a nova documentao Models (Modelos) para informaes de como usar o novo ORM.

Bsico

O LogError() foi removido, ele no tinha vantagens e era raramente ou mesmo, nunca usado.
As seguintes funes globais foram removidas: config(), cache(), clearCache(),
convertSlashes(), am(), fileExistsInPath(), sortByKey().

Debug

A funo Configure::write('debug',$bool) no suporta mais 0/1/2. Um boleano simples usado


para mudar o modo de debug para ligado ou desligado.

Especificaes/Configuraes de objetos

Os objetos usados no CakePHP agora tem um sistema consistente de armazenamento/recuperao de


configurao-de-instncia. Os cdigos que anteriormente acessavam, por exemplo $object->settings,
devem ser atualizados para usar $object->config() alternativamente.

Cache

Memcache foi removido, use Cake\Cache\Cache\Engine\Memcached alternativamente.


Cache engines so carregados sob demanda no primeiro uso.
Cake\Cache\Cache::engine() foi adicionado.
Cake\Cache\Cache::enabled() foi adicionado. Substituindo a opo de configurao
Cache.disable.
Cake\Cache\Cache::enable() foi adicionado.
Cake\Cache\Cache::disable() foi adicionado.
Configurao de cache agora imutvel. Se voc precisa alterar a configurao, ser necessrio desfazer-se da
configurao e recri-la. Isso previne problemas de sincronizao com as opes de configurao.
Cache::set() foi removido. recomendado criar mltiplas configuraes de cache para substituir ajustes
de configurao em tempo de execuo anteriormente possveis com Cache::set().
Todas as subclasses CacheEngine agora implementam um mtodo config().
Cake\Cache\Cache::readMany(), Cake\Cache\Cache::deleteMany(), e
Cake\Cache\Cache::writeMany() foram adicionados.

Novo ORM 27
CakePHP Cookbook Documentation, Release 3.next

Todos os mtodos Cake\Cache\Cache\CacheEngine agora so responsveis por manipular o prefixo chave


configurado. O Cake\Cache\CacheEngine::write() no mais permite definir a durao na escrita, a durao
captada pela configurao de tempo de execuo do mecanismo de cache. Chamar um mtodo cache com uma chuva
vazia ir lanar uma InvalidArgumentException ao invs de retornar false.

Core

App

App::pluginPath() foi removido. Use CakePlugin::path() alternativamente.


App::build() foi removido.
App::location() foi removido.
App::paths() foi removido.
App::load() foi removido.
App::objects() foi removido.
App::RESET foi removido.
App::APPEND foi removido.
App::PREPEND foi removido.
App::REGISTER foi removido.

Plugin

O Cake\Core\Plugin::load() no configura a carga automtica a menos que voc defina a opo


autoload como true.
Quanto estiver carregando plugins voc no pode mais fornecer um callable.
Quanto estiver carregando plugins voc no pode mais fornecer um array de arquivos de configurao para
carregar.

Configure

O Cake\Configure\PhpReader foi renomeado para Cake\Core\Configure\EnginePhpConfig


O Cake\Configure\IniReader foi renomeado para Cake\Core\Configure\EngineIniConfig
O Cake\Configure\ConfigReaderInterface foi renomeado para
Cake\Core\Configure\ConfigEngineInterface
O Cake\Core\Configure::consume() foi adicionado.
O Cake\Core\Configure::load() agora espera o nome de arquivo sem o sufixo de extenso como isso
pode ser derivado do mecanismo. Ex.: para usar o PhpConfig use app para carregar app.php.
Definir uma varivel $config no arquivo PHP config est obsoleto.
Cake\Core\Configure\EnginePhpConfig agora espera que o arquivo de configurao retorne
um array.
Um novo mecanismo de configurao Cake\Core\Configure\EngineJsonConfig foi adicionado.

28 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

Object

A classe Object foi removida. Ela anteriormente continha um monte de mtodos que eram utilizados em
vrios locais no framework. O mais til destes mtodos foi extraido como um trait. Voc pode usar o
Cake\Log\LogTrait para acessar o mtodo log(). O Cake\Routing\RequestActionTrait fornece
o mtodo requestAction().

Console

O executvel cake foi movido do diretrio app/Console para o diretrio bin dentro do esqueleto da aplicao.
Voc pode agora invocar o console do CakePHP com bin/cake.

TaskCollection Substitudo

Essa classe foi renomeada para Cake\Console\TaskRegistry. Veja a seo em Objetos de Registro
para mais informaes sobre funcionalidades fornecidas pela nova classe. Voc pode usar o cake upgrade
rename_collections para ajuda ao atualizar seu cdigo. Tarefas no tem mais acesso a callbacks, como nunca
houve nenhum callback para se usar.

Shell

O Shell::__construct() foi alterado. Ele agora usa uma instncia de Cake\Console\ConsoleIo.


O Shell::param() foi adicionado como um acesso conveniente aos parmetros.
Adicionalmente todos os mtodos shell sero transformados em camel case quando invocados. Por exemplo, se voc
tem um mtodo hello_world() dentro de um shell e chama ele com bin/cake my_shell hello_world,
voc ter que renomear o mtodo para helloWorld. No h necessidade de mudanas no modo que voc chama os
mtodos/comandos.

ConsoleOptionParser

O ConsoleOptionParser::merge() foi adicionado para mesclar os parsers.

ConsoleInputArgument

O ConsoleInputArgument::isEqualTo() foi adicionado para comparar dois argumentos.

Shell / Tarefa

Os Shells e Tarefas foram movidas de Console/Command e Console/Command/Task para Shell e


Shell/Task, respectivamente.

Console 29
CakePHP Cookbook Documentation, Release 3.next

ApiShell Removido

O ApiShell foi removido pois ele no fornecia nenhum beneficio alm do prprio arquivo fonte e da documenta-
o/API14 online.

SchemaShell Removido

O SchemaShell foi removido como ele nunca foi uma implementao completa de migrao de banco de dados e
surgiram ferramentas melhores como o Phinx15 . Ele foi substitudo pelo CakePHP Migrations Plugin16 que funciona
como um empacotamento entre o CakePHP e o Phinx17 .

ExtractTask

O bin/cake i18n extract no inclui mais mensagens de validao sem traduo. Se voc quiser men-
sagens de validao traduzidas voc deve encapsula-las com chamadas __() como qualquer outro contedo.

BakeShell / TemplateTask

O Bake no faz mais parte do fonte do ncleo e suplantado pelo CakePHP Bake Plugin18
Os templates do Bake foram movidos para src/Template/Bake.
A sintaxe dos templates do Bake agora usam tags estilo erb (<% %>) para denotar lgica de template, permitindo
cdigo php ser tratado como texto plano.
O comando bake view foi renomeado para bake template.

Eventos

O mtodo getEventManager(), foi removido de todos os objetos que continham. Um mtodo


eventManager() agora fornecido pelo EventManagerTrait. O EventManagerTrait contm a lgica
de instanciao e manuteno de uma referncia para um gerenciador local de eventos.
O subsistema Event teve um monte de funcionalidades opcionais removidas. Quando despachar eventos voc no
poder mais usar as seguintes opes:
passParams Essa opo est agora ativada sempre implicitamente. Voc no pode desliga-la.
break Essa opo foi removida. Voc deve agora parar os eventos.
breakOn Essa opo foi removida. Voc deve agora parar os eventos.

Log

As configuraes do Log agora no imutveis. Se voc precisa alterar a configurao voc deve primeiro derru-
bar a configurao e ento recria-la. Isso previne problemas de sincronizao com opes de configurao.
14 https://api.cakephp.org/
15 https://phinx.org/
16 https://github.com/cakephp/migrations
17 https://phinx.org/
18 https://github.com/cakephp/bake

30 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

Os mecanismos de Log agora so carregados tardiamente aps a primeira escrita nos logs.
O Cake\Log\Log::engine() foi adicionado.
Os seguintes mtodos foram removidos de Cake\Log\Log :: defaultLevels(), enabled(),
enable(), disable().
Voc no pode mais criar nveis personalizados usando Log::levels().
Quando configurar os loggers voc deve usar 'levels' ao invs de 'types'.
Voc no pode mais especificar nveis personalizados de log. Voc deve usar o conjunto padro de nveis de
log. Voc deve usar escopos de log para criar arquivos de log personalizados ou manipulaes especficas para
diferentes sees de sua aplicao. Usando um nvel de log no padro ir lanar uma exceo.
O Cake\Log\LogTrait foi adicionado. Voc pode usar este trait em suas classes para adicionar o mtodo
log().
O escopo de log passado para Cake\Log\Log::write() agora encaminhado para o mtodo write()
dos mecanismos de log de maneira a fornecer um melhor contexto para os mecanismos.
Os mecanismos de Log agora so necessrios para implementar Psr\Log\LogInterface invs do prprio
LogInterface do Cake. Em geral, se voc herdou o Cake\Log\Engine\BaseEngine voc s precisa
renomear o mtodo write() para log().
O Cake\Log\Engine\FileLog agora grava arquivos em ROOT/logs no lugar de ROOT/tmp/logs.

Roteamento

Parmetros Nomeados

Os parmetros nomeados foram removidos no 3.0. Os parmetros nomeados foram adicionados no 1.2.0 como uma
verso bonita de parmetros de requisio. Enquanto o benefcio visual discutvel, os problemas criados pelos
parmetros nomeados no so.
Os parmetros nomeados necessitam manipulao especial no CakePHP assim como em qualquer biblioteca PHP ou
JavaScript que necessite interagir com eles, os parmetros nomeados no so implementados ou entendidos por qual-
quer biblioteca exceto o CakePHP. A complexidade adicionada e o cdigo necessrio para dar suporte aos parmetros
nomeados no justificam a sua existncia, e eles foram removidos. No lugar deles, voc deve agora usar o padro
de parmetros de requisio (querystring) ou argumentos passados configurados nas rotas. Por padro o Router ir
tratar qualquer parmetro adicional ao Router::url() como argumentos de requisio.
Como muitas aplicaes ainda precisaro analisar URLs contendo parmetros nomeados, o
Cake\Routing\Router::parseNamedParams() foi adicionado para permitir compatibilidade com
URLs existentes.

RequestActionTrait

O Cake\Routing\RequestActionTrait::requestAction() teve algumas de suas opes extras


alteradas:
o options[url] agora options[query].
o options[data] agora options[post].
os parmetros nomeados no so mais suportados.

Roteamento 31
CakePHP Cookbook Documentation, Release 3.next

Roteador

Os parmetros nomeados foram removidos, veja acima para mais informaes.


A opo full_base foi substituda com a opo _full.
A opo ext foi substituda com a opo _ext.
As opes _scheme, _port, _host, _base, _full, _ext foram adicionadas.
As URLs em strings no so mais modificados pela adio de plugin/controller/nomes de prefixo.
A manipulao da rota padro de fallback foi removida. Se nenhuma rota combinar com o conjunto de
parmetros, o / ser retornado.
As classes de rota so responsveis por toda gerao de URLs incluindo parmetros de requisio (query string).
Isso faz com que as rotas sejam muito mais poderosas e flexveis.
Parmetros persistentes foram removidos. Eles foram substitudos pelo
Cake\Routing\Router::urlFilter() que permite um jeito mais flexvel para mudar URLs
sendo roteadas reversamente.
O Router::parseExtensions() foi removido. Use o Cake\Routing\Router::extensions()
no lugar. Esse mtodo deve ser chamado antes das rotas serem conectadas. Ele no ir modificar rotas existentes.
O Router::setExtensions() foi removido. Use o Cake\Routing\Router::extensions() no
lugar.
O Router::resourceMap() foi removido.
A opo [method] foi renomeada para _method.
A habilidade de combinar cabealhos arbitrrios com parmetros no estilo [] foi removida. Se voc precisar
combinar/analisar em condies arbitrrias considere usar classes personalizadas de roteamento.
O Router::promote() foi removido.
O Router::parse() ir agora lanar uma exceo quando uma URL no puder ser atendida por nenhuma
rota.
O Router::url() agora ir lanar uma exceo quando nenhuma rota combinar com um conjunto de par-
metros.
Os escopos de rotas foram adicionados. Escopos de rotas permitem voc manter seu arquivo de rotas limpo e
dar dicas de rotas em como otimizar anlise e reverso de rotas de URL.

Route

O CakeRoute foi renomeado para Route.


A assinatura de match() mudou para match($url,$context = []). Veja
Cake\Routing\Route::match() para mais informaes sobre a nova assinatura.

Configurao de Filtros do Despachante Mudaram

Os filtros do despachante no so mais adicionados em sua aplicao usando o Configure. Voc deve
agora anexa-los com Cake\Routing\DispatcherFactory. Isso significa que sua aplicao usava
Dispatcher.filters, voc deve usar agora o mtodo Cake\Routing\DispatcherFactory::add().
Alm das mudanas de configurao, os filtros do despachante tiveram algumas convenes atualizadas e novas fun-
cionalidades. Veja a documentao em Filtros do Dispatcher para mais informaes.

32 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

FilterAssetFilter

Os itens de plugins e temas manipulados pelo AssetFilter no so mais lidos via include, ao invs disso eles
so tratados como arquivos de texto plano. Isso corrige um nmero de problemas com bibliotecas javascript
como TinyMCE e ambientes com short_tags ativadas.
O suporte para a configurao Asset.filter e ganchos foram removidos. Essa funcionalidade pode ser
facilmente substituda com um plugin ou filtro de despachante.

Rede

Requisio

O CakeRequest foi renomeada para Cake\Network\Request.


O Cake\Network\Request::port() foi adicionado.
O Cake\Network\Request::scheme() foi adicionado.
O Cake\Network\Request::cookie() foi adicionado.
O Cake\Network\Request::$trustProxy foi adicionado. Isso torna mais fcil colocar aplicaes
CakePHP atrs de balanceadores de carga.
O Cake\Network\Request::$data no mais mesclado com a chave de dados prefixada, pois esse
prefixo foi removido.
O Cake\Network\Request::env() foi adicionado.
O Cake\Network\Request::acceptLanguage() mudou de um mtodo esttico para no-esttico.
O detector de requisio para dispositivos mveis foi removido do ncleo. Agora o app template adiciona
detectores para dispositivos mveis usando a biblioteca MobileDetect.
O mtodo onlyAllow() foi renomeado para allowMethod() e no aceita mais argumentos var. Todos
os nomes de mtodos precisam ser passados como primeiro argumento, seja como string ou como array de
strings.

Resposta

O mapeamento do mimetype text/plain para extenso csv foi removido. Como consequncia o
Cake\Controller\Component\RequestHandlerComponent no define a extenso para csv se o
cabealho Accept tiver o mimetype text/plain que era um problema comum quando recebia uma requi-
sio XHR do jQuery.

Sesses

A classe de sesso no mais esttica, agora a sesso (session) pode ser acessada atravs do objeto de requisio
(request). Veja a documentao em Sessions para ver como usar o objeto de sesso.
O Cake\Network\Session e classes de sesso relacionadas foram movidas para o namespace
Cake\Network.
O SessionHandlerInterface foi removido em favor ao fornecido pelo prprio PHP.
A propriedade Session::$requestCountdown foi removida.

Rede 33
CakePHP Cookbook Documentation, Release 3.next

O funcionalidade de sesso checkAgent foi removida. Ela causava um monte de bugs quando quadros do
chrome e o flash player estavam envolvidos.
A conveno de nome para a tabela de sesso no banco de dados agora sessions ao invs de
cake_sessions.
O cookie de tempo limite da sesso atualizado automaticamente em conjunto com o tempo limite dos dados
de sesso.
O caminho padro para o cookie de sesso agora o caminho base da aplicao, ao invs de /. Alm disso,
uma nova varivel de configurao Session.cookiePath foi adicionada para facilitar a personalizao do
caminho para os cookies.
Um novo mtodo conveniente Cake\Network\Session::consume() foi adicionado para permitir a lei-
tura e excluso de dados de sesso em um nico passo.
O valor padro do argumento $renew de Cake\Network\Session::clear() mudou de true para
false.

Network\Http

O HttpSocket agora Cake\Network\Http\Client.


O HttpClient foi reescrito do zero. Ele tem uma API mais simples/fcil de usar, suporta novos sistemas de
autenticao como OAuth, e uploads de arquivos. Ele usa as API de stream do PHP de modo que no h
requerimentp para o cURL. Veja a documentao Http Client para mais informaes.

Network\Email

O Cake\Network\Email\Email::config() agora usado para definir perfis de configurao. Isso


substitui as classes EmailConfig nas verses anteriores.
O Cake\Network\Email\Email::profile() substitui o config() como modo de modificar opes
de configurao por instncia.
O Cake\Network\Email\Email::drop() foi adicionado para permitir a remoo de configuraes de
email.
O Cake\Network\Email\Email::configTransport() foi adicionado para permitir a definio de
configuraes de transporte. Essa mudana retira as opes de transporte dos perfis de entrega e permite a voc
reusar facilmente os transportes atravs de perfis de e-mails.
O Cake\Network\Email\Email::dropTransport() foi adicionado para permitir a remoo de con-
figuraes de transporte.

Controller

Controller

As propriedades $helpers e $components agora esto mescladas com todas classes pai, no apenas a
AppController e o plugin de AppController. As propriedades so mescladas de modo diferente agora
tambm. No lugar de todas as configuraes em todas as classes serem mescladas juntas, as configuraes
definidas nas classes filho sero usadas. Isso quer dizer que se voc tem alguma configuraes definida no seu

34 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

AppController, e alguma configurao definida em uma a subclasse, apenas a configurao na subclasse ser
usada.
O Controller::httpCodes() foi removido, use o Cake\Network\Response::httpCodes() no
lugar.
O Controller::disableCache() foi removido, use o Cake\Network\Response::disableCache()
no lugar.
O Controller::flash() foi removido. Esse mtodo era raramente usado em aplicaes reais e no tinha
mais propsito algum.
O Controller::validate() e Controller::validationErrors() foram removidos. Eles eram
restos dos dias do 1.x onde as preocupaes com os models + controllers eram muito mais entrelaados.
O Controller::loadModel() agora carrega uma tabela de objetos.
A propriedade Controller::$scaffold foi removida. O scaffolding dinmico foi removido do ncleo do
CakePHP. Um plugin de scaffolding melhorado, chamado CRUD, pode ser encontrado em: https://github.com/
FriendsOfCake/crud
A propriedade Controller::$ext foi removida. Voc deve agora estender e sobrescrever a propriedade
View::$_ext se voc deseja usar uma extenso de arquivo de viso no padro.
A propriedade Controller::$methods foi removida. Voc deve usar o Controller::isAction()
para determinar quando ou no um nome de mtodo uma ao. Essa mudana foi feita para permitir persona-
lizaes mais fceis do que vai contar ou no como uma ao.
A propriedade Controller::$Components foi removida e substituda pelo _components. Se voc
precisar carregar componentes em tempo de execuo voc deve usar o $this->loadComponent() em
seu controller.
A assinatura do Cake\Controller\Controller::redirect() mudou para
Controller::redirect(string|array $url,int $status = null). O terceiro argu-
mento $exit foi removido. O mtodo no pode mais enviar resposta e sair do script, no lugar ele retorna uma
instncia de Response com os cabealhos apropriados definidos.
As propriedades mgicas base, webroot, here, data, action, e params foram removidas. Voc deve
acessar todas essas propriedades em $this->request no lugar.
Mtodos de controlar prefixados com sublinhado como _someMethod() no so mais tratados como mtodos
privados. Use as palavras chaves de visibilidade apropriadas no lugar. Somente mtodos pblicos podem ser
usados como ao de controllers.

Scaffold Removido

O scaffolding dinmico no CakePHP foi removido do ncleo do CakePHP. Ele no era usado com frequncia, e no
era voltado para uso em produo. Um plugin melhorado de scaffolding, chamado CRUD, pode ser encontrado em:
https://github.com/FriendsOfCake/crud

ComponentCollection Substitudo

Essa classe foi renomeada para Cake\Controller\ComponentRegistry. Veja a seo em Objetos de Registro
para mais informaes sobre as funcionalidades fornecidas pela nova classe. Voc pode usar o cake upgrade
rename_collections para ajudar voc a atualizar o seu cdigo.

Controller 35
CakePHP Cookbook Documentation, Release 3.next

Components

A propriedade _Collection agora _registry. Ela contm uma instncia do


Cake\Controller\ComponentRegistry agora.
Todos components devem agora usar o mtodo config() para obter/definir configuraes.
A configurao padro para components deve ser definido na propriedade $_defaultConfig. Essa proprie-
dade automaticamente mesclada com qualquer configurao fornecida pelo construtor.
Opes de configurao no so mais definidas como propriedades pblicas.
O mtodo Component::initialize() no mais um event listener (ouvinte de even-
tos). Ao invs disso, ele um gancho ps-construtor como o Table::initialize() e
Controller::initialize(). O novo mtodo Component::beforeFilter() ligado ao mesmo
evento que o Component::initialize() costumava ser. O mtodo de inicializao deve ter a seguinte
assinatura initialize(array $config).

Controller\Components

CookieComponent

Ele usa o Cake\Network\Request::cookie() para ler os dados de cookies, isso facilita os testes, e
permite o ControllerTestCase definir os cookies.
Os Cookies encriptados pelas verses anteriores do CakePHP usando o mtodo cipher(), agora no podem
ser lidos, pois o Security::cipher() foi removido. Voc precisar reencriptar os cookies com o mtodo
rijndael() ou aes() antes de atualizar.
O CookieComponent::type() foi removido e substitudo com dados de configurao acessados atravs
de config().
O write() no aceita mais os parmetros encryption ou expires. Os dois agora so gerenciados atravs
de dados de configurao. Veja CookieComponent para mais informaes.
O caminho padro para os cookies agora o caminho base da aplicao, ao invs de /.

AuthComponent

O Default agora o hasher de senhas padro usado pelas classes de autenticao. Ele usa exclusiva-
mente o algoritmo de hash bcrypt. Se voc desejar continuar usando o hash SHA1 usado no 2.x, use
'passwordHasher' => 'Weak' nas configuraes de seu autenticador.
O novo FallbackPasswordHasher foi adicionado para ajudar os usurios migrar senhas antigas de um
algoritmo para o outro. Veja a documentao do AuthComponent para mais informaes.
A classe BlowfishAuthenticate foi removida. Apenas use FormAuthenticate.
A classe BlowfishPasswordHasher foi removida. Use o DefaultPasswordHasher no lugar.
O mtodo loggedIn() foi removido. Use o user() no lugar.
As opes de configurao no so mais definidas como propriedades pblicas.
Os mtodos allow() e deny() no aceitam mais var args. Todos os nomes de mtodos precisam ser
passados como primeiro argumento, seja como string ou array de strings.

36 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

O mtodo login() foi removido e substitudo por setUser(). Para logar um usurio agora voc deve
chamar identify() que retorna as informaes do usurio caso identificado com sucesso e ento usar
setUser() para salvar as informaes na sesso de maneira persistente entre as requisies.
O BaseAuthenticate::_password() foi removido. Use a classe PasswordHasher no lugar.
O BaseAuthenticate::logout() foi removido.
O AuthComponent agora dispara dois eventos Auth.afterIdentify e Auth.logout aps um usu-
rio ser identificado e antes de um usurio ser deslogado respectivamente. Voc pode definir funes de callback
para esses eventos retornando um array mapeado no mtodo implementedEvents() de sua classe de au-
tenticao.
Classes relacionadas a ACL foram movidas para um plugin separado. Hashers de senha, fornecedores de Autenticao
e Autorizao foram movidos para o namespace \Cake\Auth. Voc DEVE mover seus fornecedores e hashers para
o namespace App\Auth tambm.

RequestHandlerComponent

Os seguintes mtodos foram removidos do componente RequestHandler: isAjax(),


isFlash(), isSSL(), isPut(), isPost(), isGet(), isDelete(). Use o mtodo
Cake\Network\Request::is() no lugar com o argumento relevante.
O RequestHandler::setContent() foi removido, use Cake\Network\Response::type() no
lugar.
O RequestHandler::getReferer() foi removido, use Cake\Network\Request::referer()
no lugar.
O RequestHandler::getClientIP() foi removido, use Cake\Network\Request::clientIp()
no lugar.
O RequestHandler::getAjaxVersion() foi removido.
O RequestHandler::mapType() foi removido, use Cake\Network\Response::mapType() no
lugar.
As opes de configurao no so mais definidas como propriedades pblicas.

SecurityComponent

Os seguintes mtodos e as propriedades relacionadas foram removidas do componente Secu-


rity: requirePost(), requireGet(), requirePut(), requireDelete(). Use o
Cake\Network\Request::allowMethod() no lugar.
SecurityComponent::$disabledFields() foi removido, use o
SecurityComponent::$unlockedFields().
As funes relacionadas ao CSRF no SecurityComponent foram extradas e movidas em separado no CsrfCom-
ponent. Isso permite que voc use a proteo CSRF facilmente sem ter que usar preveno de adulterao de
formulrios.
As opes de configurao no so mais definidas como propriedades pblicas.
Os mtodos requireAuth() e requireSecure() no aceitam mais var args. Todos os nomes de
mtodos precisam ser passados como primeiro argumento, seja como string ou array de strings.

Controller\Components 37
CakePHP Cookbook Documentation, Release 3.next

SessionComponent

O SessionComponent::setFlash() est obsoleto. Voc deve usar o Flash no lugar.

Error

ExceptionRenderers personalizados agora espera-se que retornem ou um objeto Cake\Network\Response ou


uma string quando renderizando erros. Isso significa que qualquer mtodo que manipule excees especficas devem
retornar uma resposta ou valor de string.

Model

A camada de model do 2.x foi completamente reescrita e substituda. Voc deve revisar o Guia de atualizao para o
novo ORM para saber como usar o novo ORM.
A classe Model foi removida.
A classe BehaviorCollection foi removida.
A classe DboSource foi removida.
A classe Datasource foi removida.
As vrias classes de fonte de dados foram removidas.

ConnectionManager

O ConnectionManager (gerenciador de conexo) foi movido para o namespace Cake\Datasource.


O ConnectionManager teve os seguintes mtodos removidos:
sourceList
getSourceName
loadDataSource
enumConnectionObjects
O Database\ConnectionManager::config() foi adicionado e agora o nico jeito de configurar
conexes.
O Database\ConnectionManager::get() foi adicionado. Ele substitui o getDataSource().
O Database\ConnectionManager::configured() foi adicionado. Ele junto com config() subs-
titui o sourceList() e enumConnectionObjects() com uma API mais padro e consistente.
O ConnectionManager::create() foi removido. Ele pode ser substitudo por
config($name,$config) e get($name).

Behaviors

Os mtodos de comportamentos (behaviors) prefixados com sublinhado como _someMethod() no so mais


tratados como mtodos privados. Use as palavras chaves de visibilidade.

38 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

TreeBehavior

O TreeBehavior foi completamente reescrito para usar o novo ORM. Embora ele funcione do mesmo modo que no
2.x, alguns mtodos foram renomeados ou removidos:
TreeBehavior::children() agora uma busca personalizada find('children').
TreeBehavior::generateTreeList() agora uma busca personalizada find('treeList').
TreeBehavior::getParentNode() foi removido.
TreeBehavior::getPath() agora uma busca personalizada find('path').
TreeBehavior::reorder() foi removido.
TreeBehavior::verify() foi removido.

Sute de Testes

Casos de Teste

O _normalizePath() foi adicionado para permitir testes de comparao de caminhos para executar em
todos os sistemas operacionais, independente de sua configurao (\ no Windows vs / no UNIX, por exemplo).
Os seguintes mtodos de assero foram removidos j que eles estavam h muito obsoletos e foram substitudos pelo
seu equivalente no PHPUnit:
assertEqual() substitudo por assertEquals()
assertNotEqual() substitudo por assertNotEquals()
assertIdentical() substitudo por assertSame()
assertNotIdentical() substitudo por assertNotSame()
assertPattern() substitudo por assertRegExp()
assertNoPattern() substitudo por assertNotRegExp()
assertReference() substitudo por assertSame()
assertIsA() substitudo por assertInstanceOf()
Note que alguns mtodos tiveram a ordem dos argumentos trocada, ex. assertEqual($is,$expected) deve
ser agora assertEquals($expected,$is).
Os seguintes mtodos de assero esto obsoletos e sero removidos no futuro:
assertWithinMargin() substitudo por assertWithinRange()
assertTags() substitudo por assertHtml()
Em ambas as substituies dos mtodos tambm mudaram a ordem dos argumentos para manter a consistncia na API
com $expected como primeiro argumento.
Os seguintes mtodos de assero foram adicionados:
assertNotWithinRange() em contrapartida ao assertWithinRange()

Sute de Testes 39
CakePHP Cookbook Documentation, Release 3.next

View

Temas so agora Plugins Bsicos

Ter os temas e plugins de modo a criar components modulares da aplicao se provou limitado e confuso. No CakePHP
3.0, temas no residem mais dentro da aplicao. Ao invs disso, eles so plugins independentes. Isso resolveu alguns
problemas com temas:
Voc no podia colocar temas nos plugins.
Temas no podiam fornecer helpers (helpers), ou classes de viso personalizadas.
Esses dois problemas foram resolvidos ao converter os temas em plugins.

Pasta das views renomeada

As pastas contendo os arquivos de views agora ficam em src/Template no lugar de src/View. Isso foi feito para separar
os arquivos de viso dos arquivos contendo classes php. (ex. helpers, Classes de viso).
As seguintes pastas de Viso foram renomeadas para evitar coliso de nomes com nomes de controllers:
Layouts agora Layout
Elements agora Element
Errors agora Error
Emails agora Email (o mesmo para Email dentro de Layout)

Coleo de Helpers Substituda

Essa classe foi renomeada para Cake\View\HelperRegistry. Veja a seo em Objetos de Registro para
mais informaes sobre as funcionalidades fornecidas pela nova classe. Voc pode usar o cake upgrade
rename_collections para ajudar voc a atualizar seu cdigo.

Classe View

A chave plugin foi removida do argumento $options de Cake\View\View::element(). Especifique


o nome do elemento como AlgumPlugin.nome_do_elemento no lugar.
O View::getVar() foi removido, use o Cake\View\View::get() no lugar.
O View::$ext foi removido e no lugar uma propriedade protegida View::$_ext foi adicionada.
O View::addScript() foi removido. Use o Usando View Blocks no lugar.
As propriedades mgicas base, webroot, here, data, action, e params foram removidas. Ao invs
disso, voc deve acessar todas essas propriedades no $this->request.
O View::start() no se liga mais a um bloco existente. Ao invs disso ele ir sobrescrever o contedo do
bloco quando o end() for chamado. Se voc precisa combinar o contedo de um bloco voc dever buscar o
contedo do bloco quando chamar o start uma segunda vez, ou usar o modo de captura de append().
O View::prepend() no tem mais um modo de captura.
O View::startIfEmpty() foi removido. Agora que o start() sempre sobrescreve, o startIfEmpty no tem
mais propsito.

40 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

A propriedade View::$Helpers foi removida e substituda com _helpers. Se voc precisar carregar
helpers em tempo de execuo voc deve usar o $this->addHelper() em seus arquivos de viso.
O View agora ir lanar Cake\View\Exception\MissingTemplateException quando templates
estiverem faltando, ao invs de MissingViewException.

ViewBlock

O ViewBlock::append() foi removido, use o Cake\ViewViewBlock::concat() no lugar. Entre-


tanto o View::append() ainda existe.

JsonView

Agora os dados JSON tero as entidades HTML codificadas por padro. Isso previne possveis problemas de
XSS quando o contedo de viso JSON est encapsulado em arquivos HTML.
O Cake\View\JsonView agora suporta a varivel de viso _jsonOptions. Isso permite a voc configurar
as opes de mscara de bits usadas ao gerar JSON.

XmlView

A Cake\View\XmlView agora suporta a varivel de viso _xmlOptions. Isso permite a voc configurar
as opes usadas quando gerar XML.

View\Helper

A propriedade $settings agora chamada $_config e deve ser acessada atravs do mtodo config().
As opes de configurao no so mais definidas como propriedades pblicas.
O Helper::clean() foi removido. Ele nunca foi robusto o suficiente para prevenir completamente XSS.
Ao invs disso voc deve escapar o contedo com h ou ou usar uma biblioteca dedicada como o htmlPurifier.
O Helper::output() foi removido. Esse mtodo estava obsoleto no 2.x.
Os mtodos Helper::webroot(), Helper::url(), Helper::assetUrl(),
Helper::assetTimestamp() foram movidos para o novo ajudante
Cake\View\Helper\UrlHelper. O Helper::url() est agora disponvel como
Cake\View\Helper\UrlHelper::build().
Os Assessores Mgicos a propriedades obsoletas foram removidos. A seguinte propriedade agora deve ser
acessada a partir do objeto de requisio:
base
here
webroot
data
action
params

View\Helper 41
CakePHP Cookbook Documentation, Release 3.next

Helpers

A classe Helper teve os seguintes mtodos removidos:


Helper::setEntity()
Helper::entity()
Helper::model()
Helper::field()
Helper::value()
Helper::_name()
Helper::_initInputField()
Helper::_selectedArray()
Esses mtodos eram partes usadas apenas pelo FormHelper, e parte de uma funcionalidade de persistncia de campos
que se mostrou problemtica com o tempo. O FormHelper no precisa mais destes mtodos e a complexidades que
eles provm no mais necessria.
Os seguintes mtodos foram removidos:
Helper::_parseAttributes()
Helper::_formatAttribute()
Esses mtodos podem agora ser encontrados na classe StringTemplate que os helpers usam com frequncia. Veja
o StringTemplateTrait para um jeito fcil de integrar os templates de string em seus prprios helpers.

FormHelper

O FormHelper foi completamente reescrito para o 3.0. Ele teve algumas grandes mudanas:
O FormHelper trabalha junto com o novo ORM. Mas tambm possui um sistema extensvel para integrar com
outros ORMs e fontes de dados.
O FormHelper possui um sistema de widgets extensvel que permite a voc criar novos widgets de entrada
personalizados e expandir facilmente aqueles inclusos no framework.
Os Templates de String so a fundao deste ajudante. Ao invs de encher de arrays por toda parte, a maioria
do HTML que o FormHelper gera pode ser personalizado em um lugar central usando conjuntos de templates.
Alm dessas grandes mudanas, foram feitas algumas mudanas menores que causaram rompendo algumas coisas da
verso anterior. Essas mudanas devem simplificar o HTML que o FormHelper gera e reduzir os problemas que as
pessoas tinham no passado:
O prefixo data[ foi removido de todas as entradas geradas. O prefixo no tem mais propsito.
Os vrios mtodos de entradas independentes, como text(), select() e outros, no geram mais atributos
id.
A opo inputDefaults foi removida de create().
As opes default e onsubmit do create() foram removidas. No lugar voc deve usar JavaScript event
binding ou definir todos os cdigos js necessrios para o onsubmit.
O end() no gerar mais botes. Voc deve criar botes com button() ou submit().
O FormHelper::tagIsInvalid() foi removido. Use isFieldError() no lugar.

42 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

O FormHelper::inputDefaults() foi removido. Voc pode usar templates() para definir/expandir


os templates que o FormHelper usa.
As opes wrap e class foram removidas do mtodo error().
A opo showParents foi removida do select().
As opes div, before, after, between e errorMessage foram removidas do input(). Voc pode
usar templates para atualizar o HTML envoltrio. A opo templates permite voc sobrescrever os templates
carregados para uma entrada.
As opes separator, between, e legend foram removidas do radio(). Voc pode usar templates para
mudar o HTML envoltrio agora.
O parmetro format24Hours foi removido de hour(). Ele foi substitudo pela opo format.
Os parmetros minYear e maxYear foram removidos do year(). Ambos podem ser fornecidos como
opes.
Os parmetros dateFormat e timeFormat foram removidos do datetime(). Voc pode usar o template
para definir a ordem que as entradas devem ser exibidas.
O submit() teve as opes div, before e after removidas. Voc pode personalizar o template
submitContainer para modificar esse contedo.
O mtodo inputs() no aceita mais legend e fieldset no parmetro $fields, voc deve usar o par-
metro $options. Ele tambm exige que o parmetro $fields seja um array. O parmetro $blacklist
foi removido, a funcionalidade foi substituda pela especificao de 'field' => false no parmetro
$fields.
O parmetro inline foi removido do mtodo postLink(). Voc deve usar a opo block no lugar. Definindo
block => true ir emular o comportamento anterior.
O parmetro timeFormat para hour(), time() e dateTime() agora 24 por padro, em cumprimento
ao ISO 8601.
O argumento $confirmMessage de Cake\View\Helper\FormHelper::postLink() foi remo-
vido. Voc deve usar agora a chave confirm no $options para especificar a mensagem.
As entradas do tipo Checkbox e radio so agora renderizadas dentro de elementos do tipo label por padro. Isso
ajuda a aumentar a compatibilidade com bibliotecas CSS populares como Bootstrap19 e Foundation20 .
As tags de template agora so todas camelBacked (primeira letra minscula e inicio de novas palavras em mais-
culo). As tags pr-3.0 formstart, formend, hiddenblock e inputsubmit so agora formStart,
formEnd, hiddenBlock e inputSubmit. Certifique-se de altera-las se elas estiverem personalizando sua
aplicao.
recomendado que voc revise a documentao Form para mais detalhes sobre como usar o FormHelper no 3.0.

HtmlHelper

O HtmlHelper::useTag() foi removido, use tag() no lugar.


O HtmlHelper::loadConfig() foi removido. As tags podem ser personalizadas usando templates()
ou as configuraes de templates.
O segundo parmetro $options para HtmlHelper::css() agora sempre ir exigir um array.
O primeiro parmetro $data para HtmlHelper::style() agora sempre ir exigir um array.
19 http://getbootstrap.com/
20 http://foundation.zurb.com/

View\Helper 43
CakePHP Cookbook Documentation, Release 3.next

O parmetro inline foi removido dos mtodos meta(), css(), script() e scriptBlock(). Ao invs disso, voc
deve usar a opo block. Definindo block => true ir emular o comportamento anterior.
O HtmlHelper::meta() agora exige que o $type seja uma string. Opes adicionais podem ser passadas
como $options.
O HtmlHelper::nestedList() agora exige que o $options seja um array. O quarto argumento para o
tipo tag foi removido e incluido no array $options.
O argumento $confirmMessage de Cake\View\Helper\HtmlHelper::link() foi removido.
Voc deve usar agora a chave confirm no $options para especificar a menssagem.

PaginatorHelper

O link() foi removido. Ele no era mais usado internamente pelo ajudante. Ele era pouco usado em cdigos
de usurios e no se encaixava mais nos objetivos do ajudante.
O next() no tem mais as opes class ou tag. Ele no tem mais argumentos desabilitados. Ao invs disso
so usados templates.
O prev() no tem mais as opes class ou tag. Ele no tem mais argumentos desabilitados. Ao invs disso
so usados templates.
O first() no tem mais as opes after, ellipsis, separator, class ou tag.
O last() no tem mais as opes after, ellipsis, separator, class ou tag.
O numbers() no tem mais as opes separator, tag, currentTag, currentClass, class, tag e ellipsis.
Essas opes so agora facilitadas pelos templates. Ele tambm exige que agora o parmetro $options seja
um array.
O espao reservado de estilo %page% foi removido de Cake\View\Helper\PaginatorHelper::counter().
Use o espao reservado de estilo {{page}} no lugar.
O url() foi renomeada para generateUrl() para evitar coliso de declarao de mtodo com
Helper::url().
Por padro todos os links e textos inativos so encapsulados em elementos <li>. Isso ajuda a fazer o CSS mais fcil
de escrever, e aumenta a compatibilidade com frameworks de CSS populares.
Ao invs de vrias opes em cada mtodo, voc deve usar a funcionalidade de templates. Veja a documentao
PaginatorHelper Templates para informaes de como se usar templates.

TimeHelper

TimeHelper::__set(), TimeHelper::__get(), e TimeHelper::__isset() foram removidos.


Eles eram mtodos mgicos para atributos obsoletos.
O TimeHelper::serverOffset() foi removido. Ele provia prticas incorretas de operaes com tempo.
O TimeHelper::niceShort() foi removido.

NumberHelper

O NumberHelper::format() agora exige que $options seja um array.

44 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

SessionHelper

O SessionHelper est obsoleto. Voc pode usar $this->request->session() diretamente, e a


funcionalidade de mensagens flash foi movida para Flash.

JsHelper

O JsHelper e todos motores associados foram removidos. Ele podia gerar somente um subconjunto muito
pequeno de cdigos JavaScript para biblioteca selecionada e consequentemente tentar gerar todo cdigo JavaS-
cript usando apenas o ajudante se tornava um impedimento com frequncia. recomendado usar diretamente
sua biblioteca JavaScript preferida.

CacheHelper Removido

O CacheHelper foi removido. A funcionalidade de cache que ele fornecia no era padro, limitada e incompatvel com
layouts no-HTML e views de dados. Essas limitaes significavam que uma reconstruo completa era necessria. O
ESI (Edge Side Includes) se tornou uma maneira padronizada para implementar a funcionalidade que o CacheHelper
costumava fornecer. Entretanto, implementando Edge Side Includes21 em PHP tem vrias limitaes e casos. Ao invs
de construir uma soluo ruim, recomendado que os desenvolvedores que precisem de cache de resposta completa
use o Varnish22 ou Squid23 no lugar.

I18n

O subsistema de internacionalizao foi completamente reescrito. Em geral, voc pode esperar o mesmo comporta-
mento que nas verses anteriores, especialmente se voc est usando a famlia de funes __().
Internamente, a classe I18n usa Aura\Intl, e mtodos apropriados so expostos para dar acesso a funes espec-
ficas da biblioteca. Por esta razo a maior parte dos mtodos dentro de I18n foram removidos ou renomeados.
Devido ao uso do ext/intl, a classe L10n foi removida completamente. Ela fornecia dados incompletos e desatu-
alizados em comparao com os dados disponveis na classe Locale do PHP.
O idioma padro da aplicao no ser mais alterado automaticamente pelos idiomas aceitos pelo navegador nem por
ter o valor Config.language definido na sesso do navegador. Voc pode, entretanto, usar um filtro no despa-
chante para trocar o idioma automaticamente a partir do cabealho Accept-Language enviado pelo navegador:

// No config/bootstrap.php
DispatcherFactory::addFilter('LocaleSelector');

No h nenhum substituto incluso para selecionar automaticamente o idioma a partir de um valor configurado na
sesso do usurio.
A funo padro para formatao de mensagens traduzidas no mais a sprintf, mas a mais avanada e funcional
classe MessageFormatter. Em geral voc pode reescrever os espaos reservados nas mensagens como segue:

// Antes:
__('Hoje um dia %s na %s', 'Ensolarado', 'Espanha');

// Depois:
__('Hoje um dia {0} na {1}', 'Ensolarado', 'Espanha');

21 http://en.wikipedia.org/wiki/Edge_Side_Includes
22 http://varnish-cache.org
23 http://squid-cache.org

I18n 45
CakePHP Cookbook Documentation, Release 3.next

Voc pode evitar ter de reescrever suas mensagens usando o antigo formatador sprintf:

I18n::defaultFormatter('sprintf');

Adicionalmente, o valor Config.language foi removido e ele no pode mais ser usado para controlar o idioma
atual da aplicao. Ao invs disso, voc pode usar a classe I18n:

// Antes
Configure::write('Config.language', 'fr_FR');

// Agora
I18n::locale('en_US');

Os mtodos abaixo foram movidos:


De Cake\I18n\Multibyte::utf8() para Cake\Utility\Text::utf8()
De Cake\I18n\Multibyte::ascii() para Cake\Utility\Text::ascii()
De Cake\I18n\Multibyte::checkMultibyte() para Cake\Utility\Text::isMultibyte()
Como agora o CakePHP requer a extenso mbstring, a classe Multibyte foi removida.
As mensagens de erro por todo o CakePHP no passam mais atravs das funes de internacionalizao. Isso foi
feito para simplificar o ncleo do CakePHP e reduzir a sobrecarga. As mensagens apresentadas aos desenvol-
vedores so raramente, isso quando, so de fato traduzidas - de modo que essa sobrecarga adicional trs pouco
beneficio.

Localizao

Agora o construtor de Cake\I18n\L10n recebe uma instncia de Cake\Network\Request como argu-


mento.

Testes

O TestShell foi removido. O CakePHP, o esqueleto da aplicao e novos plugins cozinhados, todos usam
o phpunit para rodar os testes.
O webrunner (webroot/test.php) foi removido. A adoo do CLI aumentou grandemente desde o release inicial
do 2.x. Adicionalmente, os CLI de execuo oferecem integrao superior com IDEs e outras ferramentas
automticas.
Se voc sentir necessidade de um jeito de executar os testes a partir de um navegador, voc deve verificar o
VisualPHPUnit24 . Ele oferece muitas funcionalidades adicionais que o antigo webrunner.
O ControllerTestCase est obsoleto e ser removido no CakePHP 3.0.0. Ao invs disso, voc deve usar
a nova funcionalidade Controller Integration Testing.
As Fixtures devem agora ser referenciadas usando sua forma no plural:

// No lugar de
$fixtures = ['app.artigo'];

// Voc deve usar


$fixtures = ['app.artigos'];

24 https://github.com/NSinopoli/VisualPHPUnit

46 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

Utilitrios

Classe Set Removida

A classe Set foi removida, agora voc deve usar a classe Hash no lugar dela.

Pastas & Arquivos

As classes de pastas e arquivos foram renomeadas:


O Cake\Utility\File foi renomeado para Cake\Filesystem\File
O Cake\Utility\Folder foi renomeado para Cake\Filesystem\Folder

Inflexo

O valor padro para o argumento $replacement do Cake\Utility\Inflector::slug() foi alterado


do sublinhado (_) para o trao (-). Usando traos para separar palavras nas URLs a escolha popular e tambm
recomendada pelo Google.
As transliteraes para Cake\Utility\Inflector::slug() foram alteradas. Se voc usa translitera-
es personalizadas voc ter que atualizar seu cdigo. No lugar de expresses regulares, as transliteraes
usam simples substituies de string. Isso rendeu melhorias de performance significativas:

// No lugar de
Inflector::rules('transliteration', [
'/|/' => 'ae',
'//' => 'aa'
]);

// Voc deve usar


Inflector::rules('transliteration', [
'' => 'ae',
'' => 'ae',
'' => 'aa'
]);

Os conjuntos distintos de regras de no-inflexes e irregulares para pluralizao e singulariza-


o foram removidos. No lugar agora temos uma lista comum para cada. Quando usar
Cake\Utility\Inflector::rules() com o tipo singular e plural voc no poder mais usar chaves
como uninflected e irregular no array de argumentos $rules.
Voc pode adicionar / sobrescrever a lista de regras de no-inflexionados e irregulares usando
Cake\Utility\Inflector::rules() com valores uninflected e irregular para o argumento $type.

Sanitize

A classe Sanitize foi removida.

Segurana

O Security::cipher() foi removido. Ele era inseguro e promovia prticas ruins de criptografia. Voc
deve usar o Security::encrypt() no lugar.

Utilitrios 47
CakePHP Cookbook Documentation, Release 3.next

O valor de configurao Security.cipherSeed no mais necessrio. Com a remoo de


Security::cipher() ele no tem utilidade.
A retrocompatibilidade do Cake\Utility\Security::rijndael() para valores encriptados antes do
CakePHP 2.3.1 foi removido. Voc deve reencriptar os valores usando Security::encrypt() e uma
verso recente do CakePHP 2.x antes de migrar.
A habilidade para gerar um hash do tipo blowfish foi removido. Voc no pode mais usar o tipo blowfish
em Security::hash(). Deve ser usado apenas o password_hash() do PHP e password_verify() para gerar
e verificar hashes blowfish. A compabilidade da biblioteca ircmaxell/password-compat25 que instalado junto
com o CakePHP fornece essas funes para verses de PHP menor que 5.5.
O OpenSSL usado agora no lugar do mcrypt ao encriptar/desencriptar dados. Esse alterao fornece uma
melhor performance e deixa o CakePHP a prova de futuros abandonos de suporte das distribuies ao mcrypt.
O Security::rijndael() est obsoleto e apenas disponvel quando se usa o mcrypt.

Aviso: Dados encriptados com Security::encrypt() em verses anteriores no so compatveis com a implementa-
o openssl. Voc deve definir a implementao como mcrypt quando fizer atualizao.

Data e Hora

O CakeTime foi renomeado para Cake\I18n\Time.


O CakeTime::serverOffset() foi removido. Ele provia prticas incorretas de operaes com tempo.
O CakeTime::niceShort() foi removido.
O CakeTime::convert() foi removido.
O CakeTime::convertSpecifiers() foi removido.
O CakeTime::dayAsSql() foi removido.
O CakeTime::daysAsSql() foi removido.
O CakeTime::fromString() foi removido.
O CakeTime::gmt() foi removido.
O CakeTime::toATOM() foi renomeado para toAtomString.
O CakeTime::toRSS() foi renomeado para toRssString.
O CakeTime::toUnix() foi renomeado para toUnixString.
O CakeTime::wasYesterday() foi renomeado para isYesterday para combinar com o resto da reno-
meao de mtodos.
O CakeTime::format() no usa mais o formato do sprintf, ao invs disso voc deve usar o formato
i18nFormat.
O Time::timeAgoInWords() agora exige que o $options seja um array.
A classe Time no mais uma coleo de mtodos estticos, ela estende o DateTime para herdar todos seus mtodos
e adicionar funes de formatao baseado em localizao com ajuda da extenso intl.
Em geral, expresses assim:
25 https://packagist.org/packages/ircmaxell/password-compat

48 Captulo 3. 3.0 - Guia de migrao


CakePHP Cookbook Documentation, Release 3.next

CakeTime::aMethod($date);

Podem ser migradas reescrevendo para:

(new Time($date))->aMethod();

Nmeros

A biblioteca Number foi reescrita para usar internamente a classe NumberFormatter.


O CakeNumber foi renomeada para Cake\I18n\Number.
O Number::format() agora exige que o $options seja um array.
O Number::addFormat() foi removido.
O Number::fromReadableSize() foi movido para Cake\Utility\Text::parseFileSize().

Validao

A faixa de valores para Validation::range() agora inclusiva se $lower e $upper forem fornecidos.
O Validation::ssn() foi removido.

Xml

O Xml::build() agora exige que o $options seja um array.


O Xml::build() no aceita mais uma URL. Se voc precisar criar um documento XML a partir de uma
URL, use Http\Client.

Utilitrios 49
CakePHP Cookbook Documentation, Release 3.next

50 Captulo 3. 3.0 - Guia de migrao


CAPTULO 4

Tutoriais & Exemplos

Nesta seo, voc poder caminhar atravs de tpicas aplicaes CakePHP para ver como todas as peas se encaixam.
Como alternativa, voc pode preferir visitar o repositrio no oficial de plugins para o CakePHP CakePackages26 e a
Bakery (Padaria)27 para conhecer aplicaes e componentes existentes.

Tutorial - Criando um Bookmarker - Parte 1

Esse tutorial vai guiar voc atravs da criao de uma simples aplicao de marcao (bookmarker). Para comear,
ns vamos instalar o CakePHP, criar nosso banco de dados, e usar as ferramentas que o CakePHP fornece para obter
nossa aplicao de p rpido.
Aqui est o que voc vai precisar:
1. Um servidor de banco de dados. Ns vamos usar o servidor MySQL neste tutorial. Voc precisa saber o
suficiente sobre SQL para criar um banco de dados: O CakePHP vai tomar as rdeas a partir da. Por ns
estarmos usando o MySQL, tambm certifique-se que voc tem a extenso pdo_mysql habilitada no PHP.
2. Conhecimento bsico sobre PHP.
Vamos comear!

Instalao do CakePHP

A maneira mais fcil de instalar o CakePHP usando Composer, um gerenciador de dependncias para o PHP. uma
forma simples de instalar o CakePHP a partir de seu terminal ou prompt de comando. Primeiro, voc precisa baixar e
instalar o Composer. Se voc tiver instalada a extenso cURL do PHP, execute o seguinte comando:

curl -s https://getcomposer.org/installer | php

Ao invs disso, voc tambm pode baixar o arquivo composer.phar do site28 oficial.
Em seguida, basta digitar a seguinte linha no seu terminal a partir do diretrio onde se localiza o arquivo
composer.phar para instalar o esqueleto de aplicaes do CakePHP no diretrio bookmarker.
26 https://plugins.cakephp.org/
27 https://bakery.cakephp.org/
28 https://getcomposer.org/download/

51
CakePHP Cookbook Documentation, Release 3.next

php composer.phar create-project --prefer-dist cakephp/app bookmarker

A vantagem de usar Composer que ele ir completar automaticamente um conjunto importante de tarefas, como
configurar as permisses de arquivo e criar a sua config/app.php.
H outras maneiras de instalar o CakePHP. Se voc no puder ou no quiser usar Composer, veja a seo Instalao.
Independentemente de como voc baixou o CakePHP, uma vez que sua instalao for concluda, a estrutura dos
diretrios deve ficar parecida com o seguinte:

/bookmarker
/bin
/config
/logs
/plugins
/src
/tests
/tmp
/vendor
/webroot
.editorconfig
.gitignore
.htaccess
.travis.yml
composer.json
index.php
phpunit.xml.dist
README.md

Agora pode ser um bom momento para aprender sobre como a estrutura de diretrios do CakePHP funciona: Confira
a seo Estrutura de pastas do CakePHP.

Verificando nossa instalao

Podemos checar rapidamente que a nossa instalao est correta, verificando a pgina inicial padro. Antes que voc
possa fazer isso, voc vai precisar iniciar o servidor de desenvolvimento:

bin/cake server

Isto ir iniciar o servidor embutido do PHP na porta 8765. Abra http://localhost:8765 em seu navegador
para ver a pgina de boas-vindas. Todas as verificaes devem estar checadas corretamente, a no ser a conexo com
banco de dados do CakePHP. Se no, voc pode precisar instalar extenses do PHP adicionais, ou definir permisses
de diretrio.

Criando o banco de dados

Em seguida, vamos criar o banco de dados para a nossa aplicao. Se voc ainda no tiver feito isso, crie um banco
de dados vazio para uso nesse tutorial, com um nome de sua escolha, por exemplo, cake_bookmarks. Voc pode
executar o seguinte SQL para criar as tabelas necessrias:

CREATE TABLE users (


id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
created DATETIME,

52 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

modified DATETIME
);

CREATE TABLE bookmarks (


id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(50),
description TEXT,
url TEXT,
created DATETIME,
modified DATETIME,
FOREIGN KEY user_key (user_id) REFERENCES users(id)
);

CREATE TABLE tags (


id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
created DATETIME,
modified DATETIME,
UNIQUE KEY (title)
);

CREATE TABLE bookmarks_tags (


bookmark_id INT NOT NULL,
tag_id INT NOT NULL,
PRIMARY KEY (bookmark_id, tag_id),
INDEX tag_idx (tag_id, bookmark_id),
FOREIGN KEY tag_key(tag_id) REFERENCES tags(id),
FOREIGN KEY bookmark_key(bookmark_id) REFERENCES bookmarks(id)
);

Voc deve ter notado que a tabela bookmarks_tags utilizada uma chave primria composta. O CakePHP suporta
chaves primrias compostas quase todos os lugares, tornando mais fcil construir aplicaes multi-arrendados.
Os nomes de tabelas e colunas que usamos no foram arbitrrias. Usando convenes de nomenclatura do CakePHP,
podemos alavancar o desenvolvimento e evitar ter de configurar o framework. O CakePHP flexvel o suficiente para
acomodar at mesmo esquemas de banco de dados legados inconsistentes, mas aderir s convenes vai lhe poupar
tempo.

Configurando o banco de dados

Em seguida, vamos dizer ao CakePHP onde o nosso banco de dados est como se conectar a ele. Para muitos, esta
ser a primeira e ltima vez que voc vai precisar configurar qualquer coisa.
A configurao bem simples: basta alterar os valores do array Datasources.default no arquivo con-
fig/app.php pelos que se aplicam sua configurao. A amostra completa da gama de configuraes pode ser algo
como o seguinte:
return [
// Mais configurao acima.
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => 'cakephp',

Tutorial - Criando um Bookmarker - Parte 1 53


CakePHP Cookbook Documentation, Release 3.next

'password' => 'AngelF00dC4k3~',


'database' => 'cake_bookmarks',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
],
],
// Mais configurao abaixo.
];

Depois de salvar o seu arquivo config/app.php, voc deve notar que a mensagem CakePHP is able to connect to the
database tem uma marca de verificao.

Nota: Uma cpia do arquivo de configurao padro do CakePHP encontrado em config/app.default.php.

Gerando o cdigo base

Devido a nosso banco de dados seguir as convenes do CakePHP, podemos usar o bake console para gerar rapida-
mente uma aplicao bsica . Em sua linha de comando execute:

bin/cake bake all users


bin/cake bake all bookmarks
bin/cake bake all tags

Isso ir gerar os controllers, models, views, seus casos de teste correspondentes, e fixtures para os nossos users,
bookmarks e tags. Se voc parou seu servidor, reinicie-o e v para http://localhost:8765/bookmarks.
Voc dever ver uma aplicao que d acesso bsico, mas funcional a tabelas de banco de dados. Adicione alguns
users, bookmarks e tags.

Adicionando criptografia de senha

Quando voc criou seus users, voc deve ter notado que as senhas foram armazenadas como texto simples. Isso
muito ruim do ponto de vista da segurana, por isso vamos consertar isso.
Este tambm um bom momento para falar sobre a camada de modelo. No CakePHP, separamos os mtodos que
operam em uma coleo de objetos, e um nico objeto em diferentes classes. Mtodos que operam na recolha de
entidades so colocadas na classe Table, enquanto as caractersticas pertencentes a um nico registro so colocados na
classe Entity.
Por exemplo, a criptografia de senha feita no registro individual, por isso vamos implementar esse comportamento
no objeto entidade. Dada a circunstncia de ns querermos criptografar a senha cada vez que definida, vamos usar
um mtodo modificador/definidor. O CakePHP vai chamar mtodos de definio baseados em convenes a qualquer
momento que uma propriedade definida em uma de suas entidades. Vamos adicionar um definidor para a senha. Em
src/Model/Entity/User.php adicione o seguinte:

namespace App\Model\Entity;

use Cake\ORM\Entity;
use Cake\Auth\DefaultPasswordHasher;

class User extends Entity


{

54 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

// Code from bake.

protected function _setPassword($value)


{
$hasher = new DefaultPasswordHasher();
return $hasher->hash($value);
}
}

Agora atualize um dos usurios que voc criou anteriormente, se voc alterar sua senha, voc deve ver um senha
criptografada ao invs do valor original nas pginas de lista ou visualizao. O CakePHP criptografa senhas com
bcrypt29 por padro. Voc tambm pode usar sha1 ou md5 caso venha a trabalhar com um banco de dados existente.

Recuperando bookmarks com uma tag especfica

Agora que estamos armazenando senhas com segurana, podemos construir algumas caractersticas mais interessantes
em nossa aplicao. Uma vez que voc acumulou uma coleo de bookmarks, til ser capaz de pesquisar atravs
deles por tag. Em seguida, vamos implementar uma rota, a ao do controller, e um mtodo localizador para pesquisar
atravs de bookmarks por tag.
Idealmente, ns teramos uma URL que se parece com http://localhost:8765/bookmarks/tagged/funny/cat/gifs.
Isso deveria nos permitir a encontrar todos os bookmarks que tm as tags funny, cat e gifs. Antes de podermos
implementar isso, vamos adicionar uma nova rota. Em config/routes.php, adicione o seguinte na parte superior do
arquivo:
Router::scope(
'/bookmarks',
['controller' => 'Bookmarks'],
function ($routes) {
$routes->connect('/tagged/*', ['action' => 'tags']);
}
);

O acima define uma nova rota que liga o caminho /bookmarks/tagged/*, a


BookmarksController::tags(). Ao definir rotas, voc pode isolar como suas URLs parecero, de
como eles so implementadas. Se fssemos visitar http://localhost:8765/bookmarks/tagged, de-
veriamos ver uma pgina de erro informativa do CakePHP. Vamos implementar esse mtodo ausente agora. Em
src/Controller/BookmarksController.php adicione o seguinte:
public function tags()
{
$tags = $this->request->getParam('pass');
$bookmarks = $this->Bookmarks->find('tagged', [
'tags' => $tags
]);
$this->set(compact('bookmarks', 'tags'));
}

Criando o mtodo localizador

No CakePHP ns gostamos de manter as nossas aes do controller enxutas, e colocar a maior parte da l-
gica de nossa aplicao nos modelos. Se voc fosse visitar a URL /bookmarks/tagged agora, voc
29 http://codahale.com/how-to-safely-store-a-password/

Tutorial - Criando um Bookmarker - Parte 1 55


CakePHP Cookbook Documentation, Release 3.next

veria um erro sobre o mtodo findTagged no estar implementado ainda, ento vamos fazer isso. Em
src/Model/Table/BookmarksTable.php adicione o seguinte:
public function findTagged(Query $query, array $options)
{
$bookmarks = $this->find()
->select(['id', 'url', 'title', 'description']);

if (empty($options['tags'])) {
$bookmarks
->leftJoinWith('Tags')
->where(['Tags.title IS' => null]);
} else {
$bookmarks
->innerJoinWith('Tags')
->where(['Tags.title IN ' => $options['tags']]);
}

return $bookmarks->group(['Bookmarks.id']);
}

Ns implementamos um mtodo localizador customizado. Este um conceito muito poderoso no CakePHP que lhe
permite construir consultas reutilizveis. Em nossa pesquisa, ns alavancamos o mtodo matching() que nos
habilita encontrar bookmarks que tm uma tag correspondente.

Criando a view

Agora, se voc visitar a URL /bookmarks/tagged, o CakePHP ir mostrar um erro e deix-lo saber que voc
ainda no fez um arquivo view. Em seguida, vamos construir o arquivo view para a nossa ao tags. Em
src/Template/Bookmarks/tags.ctp coloque o seguinte contedo:
<h1>
Bookmarks tagged with
<?= $this->Text->toList(h($tags)) ?>
</h1>

<section>
<?php foreach ($bookmarks as $bookmark): ?>
<article>
<h4><?= $this->Html->link($bookmark->title, $bookmark->url) ?></h4>
<small><?= h($bookmark->url) ?></small>
<?= $this->Text->autoParagraph(h($bookmark->description)) ?>
</article>
<?php endforeach; ?>
</section>

O CakePHP espera que os nossos templates sigam a conveno de nomenclatura onde o nome do template a verso
minscula e grifada do nome da ao do controller.
Voc pode perceber que fomos capazes de utilizar as variveis $tags e bookmarks em nossa view. Quando usamos
o mtodo set() em nosso controller, automaticamente definimos variveis especficas que devem ser enviadas para
a view. A view vai tornar todas as variveis passadas disponveis nos templates como variveis locais.
Em nossa view, usamos alguns dos helpers nativos do CakePHP. Helpers so usados para criar lgica re-utilizvel para
a formatao de dados, a criao de HTML ou outra sada da view.
Agora voc deve ser capaz de visitar a URL /bookmarks/tagged/funny e ver todas os bookmarks com a tag
funny.

56 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

At agora, ns criamos uma aplicao bsica para gerenciar bookmarks, tags e users. No entanto, todos podem ver as
tags de toda a gente. No prximo captulo, vamos implementar a autenticao e restringir os bookmarks visveis para
somente aqueles que pertencem ao usurio atual.
Agora v a Tutorial - Criando um Bookmarker - Parte 2 para continuar a construir sua aplicao ou mergulhe na
documentao para saber mais sobre o que CakePHP pode fazer por voc.

Tutorial - Criando um Bookmarker - Parte 2

Depois de terminar a primeira parte deste tutorial, voc deve ter uma aplicao muito bsica. Neste captulo iremos
adicionar autenticao e restringir as bookmarks para que cada usurio possa ver/modificar somente aquelas que
possuam.

Adicionando login

No CakePHP, a autenticao feita por Components (Componentes). Os Components podem ser considerados como
formas de criar pedaos reutilizveis de cdigo relacionado a controllers com uma caracterstica especfica ou conceito.
Os components tambm podem ligar-se ao evento do ciclo de vida do controller e interagir com a sua aplicao. Para
comear, vamos adicionar o AuthComponent a nossa aplicao. Ns vamos querer muito que cada mtodo exija
autenticao, por isso vamos acrescentar o AuthComponent em nosso AppController:

// Em src/Controller/AppController.php
namespace App\Controller;

use Cake\Controller\Controller;

class AppController extends Controller


{
public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
]
]);

// Permite a ao display, assim nosso pages controller


// continua a funcionar.
$this->Auth->allow(['display']);
}
}

Acabamos de dizer ao CakePHP que queremos carregar os components Flash e Auth. Alm disso, temos a confi-
gurao personalizada do AuthComponent, assim a nossa tabela users pode usar email como username. Agora, se

Tutorial - Criando um Bookmarker - Parte 2 57


CakePHP Cookbook Documentation, Release 3.next

voc for a qualquer URL, voc vai ser chutado para /users/login, que ir mostrar uma pgina de erro j que no
escrevemos o cdigo ainda. Ento, vamos criar a ao de login:

// Em src/Controller/UsersController.php

public function login()


{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error('Your username or password is incorrect.');
}
}

E em src/Template/Users/login.ctp adicione o seguinte:

<h1>Login</h1>
<?= $this->Form->create() ?>
<?= $this->Form->input('email') ?>
<?= $this->Form->input('password') ?>
<?= $this->Form->button('Login') ?>
<?= $this->Form->end() ?>

Agora que temos um simples formulrio de login, devemos ser capazes de efetuar login com um dos users que tenham
senha criptografada.

Nota: Se nenhum de seus users tem senha criptografada, comente a linha loadComponent('Auth'). Ento v
e edite o user, salvando uma nova senha para ele.

Agora voc deve ser capaz de entrar. Se no, certifique-se que voc est usando um user que tenha senha criptografada.

Adicionando logout

Agora que as pessoas podem efetuar o login, voc provavelmente vai querer fornecer uma maneira de encerrar a sesso
tambm. Mais uma vez, no UsersController, adicione o seguinte cdigo:

public function logout()


{
$this->Flash->success('You are now logged out.');
return $this->redirect($this->Auth->logout());
}

Agora voc pode visitar /users/logout para sair e ser enviado pgina de login.

Ativando inscries

Se voc no estiver logado e tentar visitar / usurios / adicionar voc vai ser expulso para a pgina de login. Devemos
corrigir isso se quisermos que as pessoas se inscrevam em nossa aplicao. No UsersController adicione o seguinte:

public function beforeFilter(\Cake\Event\Event $event)


{

58 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

$this->Auth->allow(['add']);
}

O texto acima diz ao AuthComponent que a ao add no requer autenticao ou autorizao. Voc pode querer
dedicar algum tempo para limpar a /users/add e remover os links enganosos, ou continuar para a prxima se-
o. Ns no estaremos construindo a edio do usurio, visualizao ou listagem neste tutorial, ento eles no vo
funcionar, j que o AuthComponent vai negar-lhe acesso a essas aes do controller.

Restringindo acesso

Agora que os usurios podem conectar-se, ns vamos querer limitar os bookmarks que podem ver para aqueles que
fizeram. Ns vamos fazer isso usando um adaptador de autorizao. Sendo os nossos requisitos bastante simples,
podemos escrever um cdigo em nossa BookmarksController. Mas antes de fazer isso, vamos querer dizer ao
AuthComponent como nossa aplicao vai autorizar aes. Em seu AppController adicione o seguinte:
public function isAuthorized($user)
{
return false;
}

Alm disso, adicione o seguinte configurao para Auth em seu AppController:


'authorize' => 'Controller',

Seu mtodo initialize agora deve parecer com:


public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize'=> 'Controller',//added this line
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
'unauthorizedRedirect' => $this->referer()
]);

// Permite a ao display, assim nosso pages controller


// continua a funcionar.
$this->Auth->allow(['display']);
}

Vamos usar como padro, negao do acesso, e de forma incremental conceder acesso onde faa sentido. Primeiro,
vamos adicionar a lgica de autorizao para os bookmarks. Em seu BookmarksController adicione o seguinte:
public function isAuthorized($user)
{

Tutorial - Criando um Bookmarker - Parte 2 59


CakePHP Cookbook Documentation, Release 3.next

$action = $this->request->params['action'];

// As aes add e index so permitidas sempre.


if (in_array($action, ['index', 'add', 'tags'])) {
return true;
}
// Todas as outras aes requerem um id.
if (!$this->request->getParam('pass.0')) {
return false;
}

// Checa se o bookmark pertence ao user atual.


$id = $this->request->getParam('pass.0');
$bookmark = $this->Bookmarks->get($id);
if ($bookmark->user_id == $user['id']) {
return true;
}
return parent::isAuthorized($user);
}

Agora, se voc tentar visualizar, editar ou excluir um bookmark que no pertena a voc, voc deve ser redirecionado
para a pgina de onde veio. No entanto, no h nenhuma mensagem de erro sendo exibida, ento vamos corrigir isso
a seguir:

// In src/Template/Layout/default.ctp
// Under the existing flash message.
<?= $this->Flash->render('auth') ?>

Agora voc deve ver as mensagens de erro de autorizao.

Corrigindo a view de listagem e formulrios

Enquanto view e delete esto trabalhando, edit, add e index tem alguns problemas:
1. Ao adicionar um bookmark, voc pode escolher o user.
2. Ao editar um bookmark, voc pode escolher o user.
3. A pgina de listagem mostra os bookmarks de outros users.
Vamos enfrentar o formulrio de adio em primeiro lugar. Para comear remova o input('user_id') a partir
de src/Template/Bookmarks/add.ctp. Com isso removido, ns tambm vamos atualizar o mtodo add:

public function add()


{
$bookmark = $this->Bookmarks->newEntity();
if ($this->request->is('post')) {
$bookmark = $this->Bookmarks->patchEntity($bookmark, $this->request->
getData());

$bookmark->user_id = $this->Auth->user('id');
if ($this->Bookmarks->save($bookmark)) {
$this->Flash->success('The bookmark has been saved.');
return $this->redirect(['action' => 'index']);
}
$this->Flash->error('The bookmark could not be saved. Please, try again.');
}
$tags = $this->Bookmarks->Tags->find('list');

60 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

$this->set(compact('bookmark', 'tags'));
}

Ao definir a propriedade da entidade com os dados da sesso, ns removemos qualquer possibilidade do user modificar
de que outro user um bookmark seja. Ns vamos fazer o mesmo para o formulrio edit e action edit. Sua ao edit
deve ficar assim:

public function edit($id = null)


{
$bookmark = $this->Bookmarks->get($id, [
'contain' => ['Tags']
]);
if ($this->request->is(['patch', 'post', 'put'])) {
$bookmark = $this->Bookmarks->patchEntity($bookmark, $this->request->
getData());

$bookmark->user_id = $this->Auth->user('id');
if ($this->Bookmarks->save($bookmark)) {
$this->Flash->success('The bookmark has been saved.');
return $this->redirect(['action' => 'index']);
}
$this->Flash->error('The bookmark could not be saved. Please, try again.');
}
$tags = $this->Bookmarks->Tags->find('list');
$this->set(compact('bookmark', 'tags'));
}

View de listagem

Agora, ns precisamos apenas exibir bookmarks para o user logado. Ns podemos fazer isso ao atualizar a chamada
para paginate(). Altere sua ao index:

public function index()


{
$this->paginate = [
'conditions' => [
'Bookmarks.user_id' => $this->Auth->user('id'),
]
];
$this->set('bookmarks', $this->paginate($this->Bookmarks));
}

Ns tambm devemos atualizar a action tags() e o mtodo localizador relacionado, mas vamos deixar isso como
um exerccio para que voc conclua por s.

Melhorando a experincia com as tags

Agora, adicionar novas tags um processo difcil, pois o TagsController probe todos os acessos. Em vez de
permitir o acesso, podemos melhorar a interface do usurio para selecionar tags usando um campo de texto separado
por vrgulas. Isso permitir dar uma melhor experincia para os nossos usurios, e usar mais alguns grandes recursos
no ORM.

Tutorial - Criando um Bookmarker - Parte 2 61


CakePHP Cookbook Documentation, Release 3.next

Adicionando um campo computado

Porque ns queremos uma maneira simples de acessar as tags formatados para uma entidade, podemos adicionar um
campo virtual/computado para a entidade. Em src/Model/Entity/Bookmark.php adicione o seguinte:

use Cake\Collection\Collection;

protected function _getTagString()


{
if (isset($this->_properties['tag_string'])) {
return $this->_properties['tag_string'];
}
if (empty($this->tags)) {
return '';
}
$tags = new Collection($this->tags);
$str = $tags->reduce(function ($string, $tag) {
return $string . $tag->title . ', ';
}, '');
return trim($str, ', ');
}

Isso vai nos deixar acessar a propriedade computada $bookmark->tag_string. Vamos usar essa propriedade
em inputs mais tarde. Lembre-se de adicionar a propriedade tag_string a lista _accessible em sua entidade.
Em src/Model/Entity/Bookmark.php adicione o tag_string ao _accessible desta forma:

protected $_accessible = [
'user_id' => true,
'title' => true,
'description' => true,
'url' => true,
'user' => true,
'tags' => true,
'tag_string' => true,
];

Atualizando as views

Com a entidade atualizado, podemos adicionar uma nova entrada para as nossas tags. Nas views add e edit, substitua
tags._ids pelo seguinte:

<?= $this->Form->input('tag_string', ['type' => 'text']) ?>

Persistindo a string tag

Agora que podemos ver as tags como uma string existente, vamos querer salvar os dados tambm. Por marcar o
tag_string como acessvel, o ORM ir copiar os dados do pedido em nossa entidade. Podemos usar um mtodo
beforeSave para analisar a cadeia tag e encontrar/construir as entidades relacionadas. Adicione o seguinte em
src/Model/Table/BookmarksTable.php:

public function beforeSave($event, $entity, $options)


{
if ($entity->tag_string) {
$entity->tags = $this->_buildTags($entity->tag_string);

62 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

}
}

protected function _buildTags($tagString)


{
$new = array_unique(array_map('trim', explode(',', $tagString)));
$out = [];
$query = $this->Tags->find()
->where(['Tags.title IN' => $new]);

// Remove tags existentes da lista de novas tags.


foreach ($query->extract('title') as $existing) {
$index = array_search($existing, $new);
if ($index !== false) {
unset($new[$index]);
}
}
// Adiciona tags existentes.
foreach ($query as $tag) {
$out[] = $tag;
}
// Adiciona novas tags.
foreach ($new as $tag) {
$out[] = $this->Tags->newEntity(['title' => $tag]);
}
return $out;
}

Embora esse cdigo seja um pouco mais complicado do que o que temos feito at agora, ele ajuda a mostrar o quo
poderosa a ORM do CakePHP . Voc pode facilmente manipular resultados da consulta usando os mtodos de
Collections (Colees), e lidar com situaes em que voc est criando entidades sob demanda com facilidade.

Terminando

Ns expandimos nossa aplicao bookmarker para lidar com situaes de autenticao e controle de autorizao/acesso
bsico. Ns tambm adicionamos algumas melhorias agradveis UX, aproveitando os recursos FormHelper e ORM.
Obrigado por dispor do seu tempo para explorar o CakePHP. Em seguida, voc pode saber mais sobre o Models
(Modelos), ou voc pode ler os /topics.

Tutorial - Criando um Blog - Parte 1

Este tutorial ir orient-lo atravs da criao de um simples blog. Faremos a instalao do CakePHP, criaremos um
banco de dados e implementaremos a lgica capaz de listar, adicionar, editar e apagar postagens do blog.
Aqui est o que voc vai precisar:
1. Um servidor web em funcionamento. Ns iremos assumir que voc esteja usando o Apache, embora as ins-
trues para outros servidores sejam bem similares. Talvez seja preciso alterar um pouco a configurao do
servidor, mas a maioria das pessoas pode ter o CakePHP instalado e funcionando sem qualquer trabalho extra.
Certifique-se de que voc tem o PHP 5.6.0 ou superior, e que as extenses mbstring e intl estejam habilitadas no
PHP. Caso no saiba a verso do PHP que est instalada, utilize a funo phpinfo() ou digite php -v no
seu terminal de comando.

Tutorial - Criando um Blog - Parte 1 63


CakePHP Cookbook Documentation, Release 3.next

2. Um servidor de banco de dados. Ns vamos usar o servidor MySQL neste tutorial. Voc precisa saber o mnimo
sobre SQL para ento criar um banco de dados, depois disso o CakePHP vai assumir as rdeas. J que usaremos
o MySQL, tambm certifique-se que a extenso pdo_mysql est habilitada no PHP.
3. Conhecimento bsico sobre PHP.
Vamos comear!

Instalao do CakePHP

A maneira mais fcil de instalar o CakePHP usando Composer, um gerenciador de dependncias para o PHP. Se trata
de uma forma simples de instalar o CakePHP a partir de seu terminal ou prompt de comando. Primeiro, voc precisa
baixar e instalar o Composer. Se possuir instalada a extenso cURL do PHP, execute o seguinte comando:

curl -s https://getcomposer.org/installer | php

Voc tambm pode baixar o arquivo composer.phar do site30 oficial do Composer.


Em seguida, basta digitar a seguinte linha de comando no seu terminal a partir do diretrio onde se localiza o arquivo
composer.phar para instalar o esqueleto da aplicao do CakePHP no diretrio [nome_do_app].

php composer.phar create-project --prefer-dist cakephp/app [nome_do_app]

A vantagem de usar o Composer que ele ir completar automaticamente um conjunto importante de tarefas, como
configurar corretamente as permisses de pastas e criar o config/app.php para voc.
H outras maneiras de instalar o CakePHP. Se voc no puder ou no quiser usar o Composer, confira a seo Instala-
o.
Independentemente de como voc baixou o CakePHP, uma vez que sua instalao for concluda, a estrutura dos
diretrios deve ficar parecida com o seguinte:

/nome_do_app
/bin
/config
/logs
/plugins
/src
/tests
/tmp
/vendor
/webroot
.editorconfig
.gitignore
.htaccess
.travis.yml
composer.json
index.php
phpunit.xml.dist
README.md

Agora pode ser um bom momento para aprender sobre como a estrutura de diretrios do CakePHP funciona: Confira
a seo Estrutura de pastas do CakePHP.
30 https://getcomposer.org/download/

64 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

Permisses dos diretrios tmp e logs

Os diretrios tmp e logs precisam ter permisses adequadas para que possam ser alterados pelo seu servidor web. Se
voc usou o Composer na instalao, ele deve ter feito isso por voc e confirmado com uma mensagem Permissions
set on <folder>. Se voc ao invs disso, recebeu uma mensagem de erro ou se quiser faz-lo manualmente, a melhor
forma seria descobrir por qual usurio o seu servidor web executado (<?= 'whoami'; ?>) e alterar o proprietrio
desses dois diretrios para este usurio. Os comandos finais a serem executados (em *nix) podem ser algo como:
chown -R www-data tmp
chown -R www-data logs

Se por alguma razo o CakePHP no puder escrever nesses diretrios, voc ser informado por uma advertncia
enquanto no estiver em modo de produo.
Embora no seja recomendado, se voc incapaz de redefinir as permisses do seu servidor web, voc pode simples-
mente alterar as permisses de gravao diretamente nos diretrios, executando os seguintes comandos:
chmod 777 -R tmp
chmod 777 -R logs

Criando o banco de dados do Blog

Em seguida, vamos configurar o banco de dados para o nosso blog. Se voc ainda no tiver feito isto, crie um banco
de dados vazio para usar neste tutorial, com um nome de sua escolha, por exemplo, cake_blog. Agora, vamos criar
uma tabela para armazenar nossos artigos:
/* Primeiro, criamos a tabela articles: */
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50),
body TEXT,
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);

Ns vamos tambm inserir alguns artigos para usarmos em nossos testes. Execute os seguintes comandos SQL em seu
banco de dados:
/* Ento inserimos articles para testes: */
INSERT INTO articles (title,body,created)
VALUES ('The title', 'This is the article body.', NOW());
INSERT INTO articles (title,body,created)
VALUES ('A title once again', 'And the article body follows.', NOW());
INSERT INTO articles (title,body,created)
VALUES ('Title strikes back', 'This is really exciting! Not.', NOW());

Os nomes de tabelas e colunas que usamos no foram arbitrrias. Usando convenes de nomenclatura do CakePHP,
podemos alavancar o desenvolvimento e acelerar a configurao do framework. O CakePHP flexvel o suficiente para
acomodar at mesmo esquemas de banco de dados legados inconsistentes, mas aderir s convenes vai lhe poupar
tempo.

Configurando o banco de dados do Blog

Em seguida, vamos dizer ao CakePHP onde nosso banco de dados est e como se conectar a ele. Para muitos, esta
ser a primeira e ltima vez que ser necessrio configurar algo.

Tutorial - Criando um Blog - Parte 1 65


CakePHP Cookbook Documentation, Release 3.next

A configurao bem simples e objetiva: basta alterar os valores no array Datasources.default localizado no
arquivo config/app.php, pelos valores que se aplicam sua configurao. Um exemplo completo de configuraes
deve se parecer como o seguinte:

return [
// Mais configuraes acima.
'Datasources' => [
'default' => [
'className' => 'Cake\Database\Connection',
'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
'username' => 'cakephp',
'password' => 'AngelF00dC4k3~',
'database' => 'cake_blog',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
],
],
// Mais configuraes abaixo.
];

Depois de salvar o arquivo config/app.php, voc deve notar a mensagem CakePHP is able to connect to the database
ao acessar o Blog pelo seu navegador.

Nota: Uma cpia do arquivo de configurao padro do CakePHP pode ser encontrada em config/app.default.php.

Configuraes opcionais

H alguns outros itens que podem ser configurados. Muitos desenvolvedores completam esta lista de itens, mas os
mesmos no so obrigatrios para este tutorial. Um deles definir uma sequncia personalizada (ou salt) para uso
em hashes de segurana.
A sequncia personalizada (ou salt) utilizada para gerar hashes de segurana. Se voc utilizou o Composer, ele
cuidou disso para voc durante a instalao. Apesar disso, voc precisa alterar a sequncia personalizada padro
editando o arquivo config/app.php. No importa qual ser o novo valor, somente dever ser algo difcil de descobrir:

'Security' => [
'salt' => 'algum valor longo contendo uma mistura aleatria de valores.',
],

Observao sobre o mod_rewrite

Ocasionalmente, novos usurios iro se atrapalhar com problemas de mod_rewrite. Por exemplo, se a pgina de boas
vindas do CakePHP parecer estranha (sem imagens ou estilos CSS). Isto provavelmente significa que o mod_rewrite
no est funcionando em seu servidor. Por favor, verifique a seo Reescrita de URL para obter ajuda e resolver
qualquer problema relacionado.
Agora continue o tutorial em Tutorial - Criando um Blog - Parte 2 e inicie a construo do seu Blog com o CakePHP.

66 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

Tutorial - Criando um Blog - Parte 2

Criando o model

Aps criar um model (modelo) no CakePHP, ns teremos a base necessria para interagirmos com o banco de dados e
executar operaes.
Os arquivos de classes, correspondentes aos models, no CakePHP esto divididos entre os objetos Table e Entity.
Objetos Table provm acesso coleo de entidades armazenada em uma tabela e so alocados em src/Model/Table.
O arquivo que criaremos dever ficar salvo em src/Model/Table/ArticlesTable.php:

// src/Model/Table/ArticlesTable.php

namespace App\Model\Table;

use Cake\ORM\Table;

class ArticlesTable extends Table


{
public function initialize(array $config)
{
$this->addBehavior('Timestamp');
}
}

Convenes de nomenclatura so muito importantes no CakePHP. Ao nomear nosso objeto como ArticlesTable,
o CakePHP automaticamente deduz que o mesmo utilize o ArticlesController e seja relacionado tabela
articles.

Nota: O CakePHP criar automaticamente um objeto model se no puder encontrar um arquivo correspondente
em src/Model/Table. Se voc nomear incorretamente seu arquivo (isto , artciclestable.php ou ArticleTable.php), o
CakePHP no reconhecer suas definies e usar o model gerado como alternativa.

Para mais informaes sobre models, como callbacks e validao, visite o captulo Models (Modelos) do manual.

Nota: Se voc completou a primeira parte do tutorial e criou a tabela articles, voc pode tomar proveito da
capacidade de gerao de cdigo do bake atravs do console do CakePHP para criar o model ArticlesTable:

bin/cake bake model Articles

Para mais informaes sobre o bake e suas caractersticas relacionadas a gerao de cdigo, visite o captulo Gerao
de cdigo com o Bake do manual.

Criando o controller

A seguir, criaremos um controller (controlador) para nossos artigos. O controller responsvel pela lgica de interao
da aplicao. o lugar onde voc utilizar as regras contidas nos models e executar tarefas relacionadas aos artigos.
Criaremos um arquivo chamado ArticlesController.php no diretrio src/Controller:

// src/Controller/ArticlesController.php

Tutorial - Criando um Blog - Parte 2 67


CakePHP Cookbook Documentation, Release 3.next

namespace App\Controller;

class ArticlesController extends AppController


{
}

Agora, vamos adicionar uma action (ao) ao nosso controller. Actions frequentemente, representam uma funo ou
interface em uma aplicao. Por exemplo, quando os usurios requisitarem www.example.com/articles/index (sendo
o mesmo que www.example.com/articles/), eles esperam ver uma lista de artigos:

// src/Controller/ArticlesController.php

namespace App\Controller;

class ArticlesController extends AppController


{

public function index()


{
$articles = $this->Articles->find('all');
$this->set(compact('articles'));
}
}

Ao definir a funo index() em nosso ArticlesController, os usurios podem acess-la requisitando


www.example.com/articles/index. Similarmente, se definssemos uma funo chamada foobar(), os usurios po-
deriam acess-la em www.example.com/articles/foobar.

Aviso: Vocs podem ser tentados a nomear seus controllers e actions para obter uma certa URL. Resista a essa
tentao. Siga as Convenes do CakePHP e crie nomes de action legveis e compreensveis. Voc pode mapear
URLs para o seu cdigo utilizando Roteamento.

A instruo na action usa set() para passar dados do controller para a view. A varivel definida como articles,
sendo igual ao valor retornado do mtodo find('all') do objeto ArticlesTable.

Nota: Se voc completou a primeira parte do tutorial e criou a tabela articles, voc pode tomar pro-
veito da capacidade de gerao de cdigo do bake atravs do console do CakePHP para criar o controller
ArticlesController:

bin/cake bake controller Articles

Para mais informaes sobre o bake e suas caractersticas sobre gerao de cdigo, visite o captulo Gerao de cdigo
com o Bake do manual.

Criando as views

Agora que ns temos os dados fluindo pelo nosso model, e nossa lgica da aplicao definida em nosso controller,
vamos criar uma view (visualizao) para a action index().
As views do CakePHP so camadas de apresentao que se encaixam nos layouts da aplicao. Para a maioria das
aplicaes, elas so uma mescla entre HTML e PHP, mas tambm podem ser distribudas como XML, CSV, ou ainda
dados binrios.

68 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

Um layout um conjunto de cdigos encontrado ao redor das views. Mltiplos layouts podem ser definidos, e voc
pode alterar entre eles, mas agora, vamos usar o default, localziado em src/Template/Layout/default.ctp.
Lembra que na ltima sesso atribumos a varivel articles view usando o mtodo set()? Isso levar a coleo
de objetos gerada pela query a ser invocada numa iterao foreach.
Arquivos de template do CakePHP so armazenados em src/Template dentro de uma pasta com o nome do controller
correspondente (ns teremos que criar a pasta Articles nesse caso). Para distribuir os dados de artigos em uma tabela,
precisamos criar uma view assim:

<!-- File: src/Template/Articles/index.ctp -->

<h1>Blog articles</h1>
<table>
<tr>
<th>Id</th>
<th>Title</th>
<th>Created</th>
</tr>

<!-- Aqui onde iremos iterar nosso objeto de solicitao $articles, exibindo
informaes de artigos -->

<?php foreach ($articles as $article): ?>


<tr>
<td><?= $article->id ?></td>
<td>
<?= $this->Html->link($article->title, ['action' => 'view', $article->
id]) ?>

</td>
<td>
<?= $article->created->format(DATE_RFC850) ?>
</td>
</tr>
<?php endforeach; ?>
</table>

Voc deve ter notado o uso de um objeto chamado $this->Html, uma instncia da classe
Cake\View\Helper\HtmlHelper do CakePHP. O CakePHP vem com um conjunto de view helpers que
simplificam tarefas como gerar links e formulrios. Voc pode aprender como us-los em Helpers (Facilitadores),
mas aqui importante notar que o mtodo link() ir gerar um link HTML com o referido ttulo (primeiro
parmetro) e URL (segundo parmetro).
Quando se especifca URLs no CakePHP, recomendado o uso do formato de array. Isto ser melhor explicado
posteriormente na seo Rotas. Usando o formato de array para URLs, voc toma vantagem das capacidades de
roteamento reverso do CakePHP. Voc tambm pode especificar URLs relativas a base da aplicao com o formato
/controller/action/param1/param2 ou usar named routes.
Neste ponto, voc pode visitar http://www.example.com/articles/index no seu navegador. Voc deve ver sua view
corretamente formatada listando os artigos.
Se voc clicar no link do ttulo de um artigo listado, provavelmente ser informado pelo CakePHP que a action ainda
no foi definida, ento vamos cri-la no ArticlesController agora:

// src/Controller/ArticlesController.php

namespace App\Controller;

class ArticlesController extends AppController

Tutorial - Criando um Blog - Parte 2 69


CakePHP Cookbook Documentation, Release 3.next

public function index()


{
$this->set('articles', $this->Articles->find('all'));
}

public function view($id = null)


{
$article = $this->Articles->get($id);
$this->set(compact('article'));
}
}

O uso do set() deve parecer familiar. Repare que voc est usando get() ao invs de find('all') porqu ns
queremos a informao de apenas um artigo.
Repare que nossa action recebe um parmetro: o ID do artigo que gostariamos de visualizar. Esse parmetro entregue
para a action atravs da URL solicitada. Se o usurio requisitar /articles/view/3, ento o valor 3 passado
como $id para a action.
Ao usar a funo get(), fazemos tambm algumas verificaes para garantir que o usurio realmente est acessando
um registro existente , se no ou se o $id for indefinido, a funo ir lanar uma NotFoundException.
Agora vamos criar a view para nossa action em src/Template/Articles/view.ctp

<!-- File: src/Template/Articles/view.ctp -->

<h1><?= h($article->title) ?></h1>


<p><?= h($article->body) ?></p>
<p><small>Criado: <?= $article->created->format(DATE_RFC850) ?></small></p>

Verifique se est tudo funcionando acessando os links em /articles/index ou manualmente solicite a visualiza-
o de um artigo acessando articles/view/{id}. Lembre-se de substituir {id} por um id de um artigo.

Adicionando artigos

Primeiro, comece criando a action add() no ArticlesController:

// src/Controller/ArticlesController.php

namespace App\Controller;

use App\Controller\AppController;

class ArticlesController extends AppController


{

public function initialize()


{
parent::initialize();

$this->loadComponent('Flash'); // Inclui o FlashComponent


}

public function index()


{

70 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

$this->set('articles', $this->Articles->find('all'));
}

public function view($id)


{
$article = $this->Articles->get($id);
$this->set(compact('article'));
}

public function add()


{
$article = $this->Articles->newEntity();
if ($this->request->is('post')) {
$article = $this->Articles->patchEntity($article, $this->request->
getData());

if ($this->Articles->save($article)) {
$this->Flash->success(__('Seu artigo foi salvo.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('No possvel adicionar o seu artigo.'));
}
$this->set('article', $article);
}
}

Nota: Voc precisa incluir o Flash component em qualquer controller que v us-lo. Se necessrio, inclua no
AppController e assim o FlashComponent estar disponvel para todos os controllers da aplicao.

A action add() checa se o mtodo HTTP da solicitao foi POST, e ento tenta salvar os dados utilizando o model
Articles. Se por alguma razo ele no salvar, apenas renderiza a view. Isto nos d a chance de exibir erros de validao
ou outros alertas.
Cada requisio do CakePHP instancia um objeto ServerRequest que acessvel usando $this->request.
O objeto contm informaes teis sobre a requisio que foi recebida e pode ser usado para controlar o fluxo de
sua aplicao. Nesse caso, ns usamos o mtodo Cake\Network\ServerRequest::is() para checar se a
requisio do tipo HTTP POST.
Quando se usa um formulrio para postar dados, essa informao fica disponvel em
$this->request->getData(). Voc pode usar as funes pr() ou debug() caso queira verificar
esses dados.
Usamos os mtodos success() e error() do FlashComponent para definir uma mensagem que ser
armazenada numa varivel de sesso. Esses mtodos so gerados usando os recursos de mtodos mgicos31
do PHP. Mensagens flash sero exibidas na pgina aps um redirecionamento. No layout ns temos <?=
$this->Flash->render() ?> que exibe a mensagem e limpa a varivel de sesso. A funo do con-
troller Cake\Controller\Controller::redirect redireciona para qualquer outra URL. O parmetro
['action' => 'index'] corresponde a URL /articles, isto , a action index() do ArticlesController.
Voc pode consultar a funo Cake\Routing\Router::url() na API32 e checar os formatos a partir dos quais
voc pode montar uma URL.
Chamar o mtodo save() vai checar erros de validao e abortar o processo caso os encontre. Ns vamos abordar
como esses erros so tratados nas sesses a seguir.
31 http://php.net/manual/en/language.oop5.overloading.php#object.call
32 https://api.cakephp.org

Tutorial - Criando um Blog - Parte 2 71


CakePHP Cookbook Documentation, Release 3.next

Validando artigos

O CakePHP torna mais prtica e menos montona a validao de dados de formulrio.


Para tirar proveito dos recursos de validao, voc vai precisar usar o Form helper em suas views. O
Cake\View\Helper\FormHelper est disponvel por padro em todas as views pelo uso do $this->Form.
Segue a view correspondente a action add:

<!-- File: src/Template/Articles/add.ctp -->

<h1>Add Article</h1>
<?php
echo $this->Form->create($article);
echo $this->Form->input('title');
echo $this->Form->input('body', ['rows' => '3']);
echo $this->Form->button(__('Salvar artigo'));
echo $this->Form->end();
?>

Ns usamos o FormHelper para gerar a tag de abertura HTML de um formulrio. Segue o HTML gerado por
$this->Form->create():

<form method="post" action="/articles/add">

Se create() chamado sem parmetros fornecidos, assume-se a construo de um formulrio que submete dados
via POST para a action add() (ou edit() no caso de um id estar includo nos dados do formulrio).
O mtodo $this->Form->input() usado para criar elementos do formulrio do mesmo nome. O primeiro
parmetro diz ao CakePHP qual o campo correspondente, e o segundo parmetro permite que voc especifique
um vasto array de opes, nesse, o nmero de linhas para o textarea. input() vai gerar diferentes elementos de
formulrios baseados no tipo de campo especificado no model.
O $this->Form->end() fecha o formulrio, entregando tambm elementos ocultos caso a preveno contra
CSRF/Form Tampering esteja habilitada.
Agora vamos voltar e atualizar nossa view src/Template/Articles/index.ctp para incluir um novo link. Antes do
<table>, adicione a seguinte linha:

<?= $this->Html->link('Adicionar artigo', ['action' => 'add']) ?>

Voc deve estar se perguntando: como eu digo ao CakePHP meus critrios de validao? Regras de validao so
definidas no model. Vamos fazer alguns ajustes no nosso model:

// src/Model/Table/ArticlesTable.php

namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;

class ArticlesTable extends Table


{
public function initialize(array $config)
{
$this->addBehavior('Timestamp');
}

public function validationDefault(Validator $validator)

72 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

{
$validator
->notEmpty('title')
->notEmpty('body');

return $validator;
}
}

O mtodo validationDefault() diz ao CakePHP como validar seus dados quando o mtodo save() for
solicitado. Aqui, estamos especificando que tanto o campo body quanto title no devem estar vazios. O CakePHP
possui muitos recursos de validao e um bom nmero de regras pr-determinadas (nmero de cartes, endereos
de email, etc), alm de flexibilidade para adicionar regras de validao customizadas. Para mais informaes sobre
configurao de validaes, visite a documentao em Validao.
Agora que suas regras de validao esto definidas, tente adicionar um artigo sem definir o
campo title e body para ver como a validao funciona. Desde que tenhamos usado o mtodo
Cake\View\Helper\FormHelper::input() do FormHelper para criar nossos elementos, nossas
mensagens de alerta da validao sero exibidas automaticamente.

Editando artigos

Edio, a vamos ns! Voc j um profissional do CakePHP agora, ento possivelmente detectou um padro... Cria-se
a action e ento a view. Aqui segue a action edit() que dever ser inserida no ArticlesController:
// src/Controller/ArticlesController.php

public function edit($id = null)


{
$article = $this->Articles->get($id);
if ($this->request->is(['post', 'put'])) {
$this->Articles->patchEntity($article, $this->request->getData());
if ($this->Articles->save($article)) {
$this->Flash->success(__('Seu artigo foi atualizado.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Seu artigo no pde ser atualizado.'));
}

$this->set('article', $article);
}

Essa action primeiramente certifica-se que o registro apontado existe. Se o parmetro $id no foi passado ou se o
registro inexistente, uma NotFoundException lanada pelo ErrorHandler do CakePHP.
Em seguida, a action verifica se a requisio POST ou PUT e caso seja, os dados so usados para atualizar a entidade
de artigo em questo ao usar o mtodo patchEntity(). Ento finalmente usamos o ArticlesTable para salvar
a entidade.
Segue a view correspondente a action edit:
<!-- File: src/Template/Articles/edit.ctp -->

<h1>Edit Article</h1>
<?php
echo $this->Form->create($article);
echo $this->Form->input('title');

Tutorial - Criando um Blog - Parte 2 73


CakePHP Cookbook Documentation, Release 3.next

echo $this->Form->input('body', ['rows' => '3']);


echo $this->Form->button(__('Salvar artigo'));
echo $this->Form->end();
?>

Essa view retorna o formulrio de edio com os dados populados, juntamente com qualquer mensagem de erro
proveniente de validaes.
O CakePHP ir determinar se o save() vai inserir ou atualizar um registro baseado nos dados da entidade.
Voc pode atualizar sua view index com os links para editar artigos:
<!-- File: src/Template/Articles/index.ctp (edit links added) -->

<h1>Blog articles</h1>
<p><?= $this->Html->link("Adicionar artigo", ['action' => 'add']) ?></p>
<table>
<tr>
<th>Id</th>
<th>Ttulo</th>
<th>Criado</th>
<th>Aes</th>
</tr>

<!-- Aqui onde iremos iterar nosso objeto de solicitao $articles, exibindo
informaes de artigos -->

<?php foreach ($articles as $article): ?>


<tr>
<td><?= $article->id ?></td>
<td>
<?= $this->Html->link($article->title, ['action' => 'view', $article->
id]) ?>

</td>
<td>
<?= $article->created->format(DATE_RFC850) ?>
</td>
<td>
<?= $this->Html->link('Editar', ['action' => 'edit', $article->id]) ?>
</td>
</tr>
<?php endforeach; ?>

</table>

Deletando artigos

A seguir, vamos criar uma forma de deletar artigos. Comece com uma action delete() no
ArticlesController:
// src/Controller/ArticlesController.php

public function delete($id)


{
$this->request->allowMethod(['post', 'delete']);

$article = $this->Articles->get($id);

74 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

if ($this->Articles->delete($article)) {
$this->Flash->success(__('O artigo com id: {0} foi deletado.', h($id)));
return $this->redirect(['action' => 'index']);
}
}

Essa lgica deleta o artigo especificado pelo $id e usa $this->Flash->success() para exibir uma mensagem
de confirmao aps o redirecionamento para /articles. Tentar excluir um registro usando uma requisio GET,
far com que o allowMethod() lance uma exceo. Excees so capturadas pelo gerenciador de excees do
CakePHP e uma pgina de erro exibida. Existem muitos Exceptions embutidos que podem indicar variados erros
HTTP que sua aplicao possa precisar.
Por estarmos executando apenas lgica e redirecionando, essa action no tem uma view. Vamos atualizar nossa view
index com links para excluir artigos:

<!-- File: src/Template/Articles/index.ctp (delete links added) -->

<h1>Blog articles</h1>
<p><?= $this->Html->link('Adicionar artigo', ['action' => 'add']) ?></p>
<table>
<tr>
<th>Id</th>
<th>Ttulo</th>
<th>Criado</th>
<th>Aes</th>
</tr>

<!-- Aqui onde iremos iterar nosso objeto de solicitao $articles, exibindo
informaes de artigos -->

<?php foreach ($articles as $article): ?>


<tr>
<td><?= $article->id ?></td>
<td>
<?= $this->Html->link($article->title, ['action' => 'view', $article->
id]) ?>

</td>
<td>
<?= $article->created->format(DATE_RFC850) ?>
</td>
<td>
<?= $this->Form->postLink(
'Deletar',
['action' => 'delete', $article->id],
['confirm' => 'Tem certeza?'])
?>
<?= $this->Html->link('Edit', ['action' => 'edit', $article->id]) ?>
</td>
</tr>
<?php endforeach; ?>

</table>

Usar View\Helper\FormHelper::postLink() vai criar um link que usa JavaScript para criar uma requisio
POST afim de deletar um artigo.

Tutorial - Criando um Blog - Parte 2 75


CakePHP Cookbook Documentation, Release 3.next

Aviso: Permitir que registros sejam deletados usando requisies GET perigoso, pois rastreadores na web podem
acidentalmente deletar todo o seu contedo.

Nota: Esse cdigo da view tambm usa o FormHelper para confirmar a action atravs de JavaScript.

Rotas

Para muitos o roteamento padro do CakePHP funciona bem o suficiente. Desenvolvedores que consideram facilidade
de uso e SEO iro apreciar a forma como o CakePHP mapeia determinadas URLs para actions especficas. Vamos
realizar uma pequena mudana nas rotas neste tutorial.
Para mais informaes sobre tcnicas avanadas de roteamento, visite Connecting Routes.
Por padro, o CakePHP responde a uma requisio pela raz do seu site usando o PagesController, ao
renderizar uma view chamada home.ctp. Alternativamente, ns vamos substituir esse comportamento pelo
ArticlesController ao criar uma regra de roteamento.
A configurao de rotas do CakePHP pode ser encontrada em config/routes.php. Voc deve comentar ou remover a
linha que define o roteamento padro:

$routes->connect('/', ['controller' => 'Pages', 'action' => 'display', 'home']);

Essa linha conecta a URL / com a pgina padro do CakePHP. Ns queremos que ela conecte-se ao nosso prprio
controller, ento a substitua por esta:

$routes->connect('/', ['controller' => 'Articles', 'action' => 'index']);

Isso ir conectar requisies por / a action index() do nosso ArticlesController

Nota: O CakePHP aproveita-se do uso de roteamento reverso. Se com a rota anterior definida voc gerar um link
com a seguinte estrutura de array: ['controller' => 'Articles','action' => 'index'], a URL
resultante ser /. Portanto, uma boa ideia sempre usar arrays para URLs, pois assim suas rotas definem o endereo
gerado e certificam-se que os links apontem sempre para o mesmo lugar.

Concluso

Simples, no ? Tenha em mente que esse foi um tutorial bsico. O CakePHP tem muito mais recursos a oferecer.
No abordamos outros tpicos aqui para manter a simplicidade. Use o restante do manual como um guia para criar
aplicaes mais ricas.
Agora que voc criou uma aplicao bsica no CakePHP, voc pode continuar no Tutorial - Criando um Blog - Parte
3, ou comear seu prprio projeto. Voc tambm pode folhear os /topics ou a API <https://api.cakephp.org/3.0> para
aprender mais sobre o CakePHP.
Se voc precisar de ajuda, h muitas formas de conseguir, por favor, visite a pgina Onde Conseguir Ajuda e bem-
vindo(a) ao CakePHP!

Leitura complementar

Existem tpicos comuns que as pessoas que esto estudando o CakePHP normalmente visitam a seguir:

76 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

1. Layouts: Customizando o layout da aplicao


2. Elements: Incluso e reutilizao de elementos na view
3. Gerao de cdigo com o Bake: Gerando cdigo CRUD
4. Tutorial - Criando um Blog - Autenticao e Autorizao: Tutorial de autorizao e autenticao

Tutorial - Criando um Blog - Parte 3

Criar uma arvore de Categoria

Vamos continuar o nosso aplicativo de blog e imaginar que queremos categorizar os nossos artigos. Queremos que
as categorias sejam ordenadas, e para isso, vamos usar o comportamento de rvore para nos ajudar a organizar as
categorias.
Mas primeiro, precisamos modificar nossas tabelas.

Migrao de Plugin

Ns vamos usar o plugin de migraes para criar uma tabela em nosso banco de dados. Se voc tem a tabela articles
no seu banco de dados, apague. Agora abra o arquivo composer.json do seu aplicativo. Normalmente, voc veria que
o plugin de migrao j est requisitando. Se no, addicione atrves da execuo:

composer require cakephp/migrations:~1.0

O plugin de migrao agora est na pasta de sua aplicao. Tambm, adicionar


Plugin::load('Migrations'); para o arquivo bootstrap.php do seu aplicativo.
Uma vez que o plugin est carregado, execute o seguinte comando para criar um arquivo de migrao:

bin/cake bake migration CreateArticles title:string body:text category_id:integer


created modified

Um arquivo de migrao ser gerado na pasta /config/Migrations com o seguinte:

<?php

use Migrations\AbstractMigration;

class CreateArticles extends AbstractMigration


{
public function change()
{
$table = $this->table('articles');
$table->addColumn('title', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
$table->addColumn('body', 'text', [
'default' => null,
'null' => false,
]);
$table->addColumn('category_id', 'integer', [
'default' => null,

Tutorial - Criando um Blog - Parte 3 77


CakePHP Cookbook Documentation, Release 3.next

'limit' => 11,


'null' => false,
]);
$table->addColumn('created', 'datetime', [
'default' => null,
'null' => false,
]);
$table->addColumn('modified', 'datetime', [
'default' => null,
'null' => false,
]);
$table->create();
}
}

Executar outro comando para criar uma tabela de categorias. Se voc precisar especificar um comprimento de campo,
voc pode faz-lo dentro de colchetes no tipo de campo, ou seja:
bin/cake bake migration CreateCategories parent_id:integer lft:integer[10] rght:
integer[10] name:string[100] description:string created modified

Isso ir gerar o seguinte arquivo no config/Migrations:


<?php

use Migrations\AbstractMigration;

class CreateCategories extends AbstractMigration


{
public function change()
{
$table = $this->table('categories');
$table->addColumn('parent_id', 'integer', [
'default' => null,
'limit' => 11,
'null' => false,
]);
$table->addColumn('lft', 'integer', [
'default' => null,
'limit' => 10,
'null' => false,
]);
$table->addColumn('rght', 'integer', [
'default' => null,
'limit' => 10,
'null' => false,
]);
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 100,
'null' => false,
]);
$table->addColumn('description', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
$table->addColumn('created', 'datetime', [

78 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

'default' => null,


'null' => false,
]);
$table->addColumn('modified', 'datetime', [
'default' => null,
'null' => false,
]);
$table->create();
}
}

Agora que os arquivos de migrao esto criadas, voc pode edit-los antes de criar suas tabelas. Precisamos mudar o
null => false para o campo parent_id com 'null' => true porque uma categoria de nvel superior tem null no
parent_id
Execute o seguinte comando para criar suas tabelas:

bin/cake migrations migrate

Modificando as Tabelas

Com nossas tabelas configuradas, agora podemos nos concentrar em categorizar os nossos artigos.
Supomos que voc j tem os arquivos (Tabelas, controladores e modelos dos artigos) da parte 2. Ento vamos adicionar
as referncias a categorias.
Precisamos associar os artigos e categorias juntos nas tabelas. Abra o arquivo src/Model/Table/ArticlesTable.php e
adicione o seguinte:

// src/Model/Table/ArticlesTable.php
namespace App\Model\Table;

use Cake\ORM\Table;

class ArticlesTable extends Table


{
public function initialize(array $config)
{
$this->addBehavior('Timestamp');
// Just add the belongsTo relation with CategoriesTable
$this->belongsTo('Categories', [
'foreignKey' => 'category_id',
]);
}
}

Gerar cdigo esqueleto por categorias

Crie todos os arquivos pelo comando bake:

bin/cake bake model Categories


bin/cake bake controller Categories
bin/cake bake template Categories

Tutorial - Criando um Blog - Parte 3 79


CakePHP Cookbook Documentation, Release 3.next

A ferramenta bake criou todos os seus arquivos em um piscar de olhos. Voc pode fazer uma leitura rpida se quiser
familiarizar como o CakePHP funciona.

Nota: Se voc estiver no Windows lembre-se de usar \ em vez de /.

Voc vai precisar editar o seguinte em src/Template/Categories/add.ctp e src/Template/Categories/edit.ctp:

echo $this->Form->input('parent_id', [
'options' => $parentCategories,
'empty' => 'No parent category'
]);

Anexar rvore de compartamento para CategoriesTable

O TreeBehavior ajuda voc a gerenciar as estruturas de rvore hierrquica na tabela do banco de dados. Usa a lgica
MPTT para gerenciar os dados. Estruturas de rvore MPTT so otimizados para l, o que muitas vezes torna uma boa
opo para aplicaes pesadas, como ler blogs.
Se voc abrir o arquivo src/Model/Table/CategoriesTable.php, voc ver que o TreeBehavior foi anexado a sua Cate-
goriesTable no mtodo initialize(). Bake acrescenta esse comportamento para todas as tabelas que contm lft e colunas
rght:

$this->addBehavior('Tree');

Com o TreeBehavior anexado voc vai ser capaz de acessar alguns recursos como a reordenao das categorias. Vamos
ver isso em um momento.
Mas, por agora, voc tem que remover as seguintes entradas em seus Categorias de adicionar e editar arquivos de
modelo:

echo $this->Form->input('lft');
echo $this->Form->input('rght');

Alm disso, voc deve desabilitar ou remover o requirePresence do validador, tanto para a lft e rght nas colunas
em seu modelo CategoriesTable:

public function validationDefault(Validator $validator)


{
$validator
->add('id', 'valid', ['rule' => 'numeric'])
->allowEmpty('id', 'create');

$validator
->add('lft', 'valid', ['rule' => 'numeric'])
// ->requirePresence('lft', 'create')
->notEmpty('lft');

$validator
->add('rght', 'valid', ['rule' => 'numeric'])
// ->requirePresence('rght', 'create')
->notEmpty('rght');
}

Esses campos so automaticamente gerenciados pelo TreeBehavior quando uma categoria salvo.

80 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

Usando seu navegador, adicione algumas novas categorias usando os /yoursite/categories/add ao do


controlador.

Reordenar categorias com TreeBahavior

Em seu arquivo de modelo de ndices de categorias, voc pode listar as categorias e reorden-los.
Vamos modificar o mtodo de ndice em sua CategoriesController.php e adicionar moveUp() e moveDown() para ser
capaz de reordenar as categorias na rvore:
class CategoriesController extends AppController
{
public function index()
{
$categories = $this->Categories->find()
->order(['lft' => 'ASC']);
$this->set(compact('categories'));
$this->set('_serialize', ['categories']);
}

public function moveUp($id = null)


{
$this->request->allowMethod(['post', 'put']);
$category = $this->Categories->get($id);
if ($this->Categories->moveUp($category)) {
$this->Flash->success('The category has been moved Up.');
} else {
$this->Flash->error('The category could not be moved up. Please, try
again.');

}
return $this->redirect($this->referer(['action' => 'index']));
}

public function moveDown($id = null)


{
$this->request->allowMethod(['post', 'put']);
$category = $this->Categories->get($id);
if ($this->Categories->moveDown($category)) {
$this->Flash->success('The category has been moved down.');
} else {
$this->Flash->error('The category could not be moved down. Please, try
again.');

}
return $this->redirect($this->referer(['action' => 'index']));
}
}

Em src/Template/Categories/index.ctp substituir o contedo existente com:


<div class="actions large-2 medium-3 columns">
<h3><?= __('Actions') ?></h3>
<ul class="side-nav">
<li><?= $this->Html->link(__('New Category'), ['action' => 'add']) ?></li>
</ul>
</div>
<div class="categories index large-10 medium-9 columns">
<table cellpadding="0" cellspacing="0">
<thead>

Tutorial - Criando um Blog - Parte 3 81


CakePHP Cookbook Documentation, Release 3.next

<tr>
<th>Id</th>
<th>Parent Id</th>
<th>Lft</th>
<th>Rght</th>
<th>Name</th>
<th>Description</th>
<th>Created</th>
<th class="actions"><?= __('Actions') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($categories as $category): ?>
<tr>
<td><?= $category->id ?></td>
<td><?= $category->parent_id ?></td>
<td><?= $category->lft ?></td>
<td><?= $category->rght ?></td>
<td><?= h($category->name) ?></td>
<td><?= h($category->description) ?></td>
<td><?= h($category->created) ?></td>
<td class="actions">
<?= $this->Html->link(__('View'), ['action' => 'view', $category->
id]) ?>

<?= $this->Html->link(__('Edit'), ['action' => 'edit', $category->


id]) ?>

<?= $this->Form->postLink(__('Delete'), ['action' => 'delete',


$category->id], ['confirm' => __('Are you sure you want to delete # {0}?',

$category->id)]) ?>

<?= $this->Form->postLink(__('Move down'), ['action' => 'moveDown',


$category->id], ['confirm' => __('Are you sure you want to move down # {0}?',

$category->id)]) ?>

<?= $this->Form->postLink(__('Move up'), ['action' => 'moveUp',


$category->id], ['confirm' => __('Are you sure you want to move up # {0}?',

$category->id)]) ?>

</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>

Modificando o ArticlesController

Em nossa ArticlesController, vamos obter a lista de todas as categorias. Isto ir permitir-nos para escolher uma
categoria para um artigo ao criar ou editar ele:

// src/Controller/ArticlesController.php
namespace App\Controller;

use Cake\Network\Exception\NotFoundException;

class ArticlesController extends AppController


{
// ...

82 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

public function add()


{
$article = $this->Articles->newEntity();
if ($this->request->is('post')) {
$article = $this->Articles->patchEntity($article, $this->request->
getData());

if ($this->Articles->save($article)) {
$this->Flash->success(__('Your article has been saved.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('Unable to add your article.'));
}
$this->set('article', $article);

// Just added the categories list to be able to choose


// one category for an article
$categories = $this->Articles->Categories->find('treeList');
$this->set(compact('categories'));
}
}

Modificando os artigos Templates

O artigo adicionado deveria se parecer como isto:

<!-- File: src/Template/Articles/add.ctp -->

<h1>Add Article</h1>
<?php
echo $this->Form->create($article);
// just added the categories input
echo $this->Form->input('category_id');
echo $this->Form->input('title');
echo $this->Form->input('body', ['rows' => '3']);
echo $this->Form->button(__('Save Article'));
echo $this->Form->end();

Quando voc vai para o endereo /yoursite/articles/add voc deve ver uma lista de categorias para escolher.

Tutorial - Criando um Blog - Autenticao e Autorizao

Continuando com o exemplo de Tutorial - Criando um Blog - Parte 1, imagine que queramos garantir o acesso a
certas URLs, com base no usurio logado. Temos tambm uma outra exigncia: permitir que o nosso blog para tenha
vrios autores que podem criar, editar e excluir seus prprios artigos, e bloquear para que outros autores no faam
alteraes nos artigos que no lhes pertencem.

Criando todo o cdigo relacionado ao Usurio

Primeiro, vamos criar uma nova tabela no banco de dados do blog para armazenar dados de nossos usurios:

CREATE TABLE users (


id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,

Tutorial - Criando um Blog - Autenticao e Autorizao 83


CakePHP Cookbook Documentation, Release 3.next

username VARCHAR(50),
password VARCHAR(255),
role VARCHAR(20),
created DATETIME DEFAULT NULL,
modified DATETIME DEFAULT NULL
);

Respeitado as convenes do CakePHP para nomear tabelas, mas tambm aproveitando de outras conveno: Usando
as colunas username e password da tabela de usurios, CakePHP ser capaz de configurar automaticamente a
maioria das coisas para ns, na implementao do login do usurio.
O prximo passo criar a nossa classe UsersTable, responsvel por encontrar, salvar e validar os dados do usurio:

// src/Model/Table/UsersTable.php
namespace App\Model\Table;

use Cake\ORM\Table;
use Cake\Validation\Validator;

class UsersTable extends Table


{

public function validationDefault(Validator $validator)


{
return $validator
->notEmpty('username', 'Usurio necessrio')
->notEmpty('password', 'Senha necessria')
->notEmpty('role', 'Funo necessria')
->add('role', 'inList', [
'rule' => ['inList', ['admin', 'author']],
'message' => 'Por favor informe uma funo vlida'
]);
}

Vamos tambm criar o nosso UsersController. O contedo a seguir corresponde a partes de uma classe UsersController
bsica gerado atrves do utilitrio de gerao de cdigo bake fornecido com CakePHP:

// src/Controller/UsersController.php

namespace App\Controller;

use App\Controller\AppController;
use Cake\Event\Event;

class UsersController extends AppController


{

public function beforeFilter(Event $event)


{
parent::beforeFilter($event);
$this->Auth->allow('add');
}

public function index()


{
$this->set('users', $this->Users->find('all'));

84 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

public function view($id)


{
$user = $this->Users->get($id);
$this->set(compact('user'));
}

public function add()


{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->getData());
if ($this->Users->save($user)) {
$this->Flash->success(__('O usurio foi salvo.'));
return $this->redirect(['action' => 'add']);
}
$this->Flash->error(__('No possvel adicionar o usurio.'));
}
$this->set('user', $user);
}

Da mesma maneira que criamos as views para os nossos artigos usando a ferramenta de gerao de cdigo, podemos
implementar as views do usurio. Para o propsito deste tutorial, vamos mostrar apenas o add.ctp:

<!-- src/Template/Users/add.ctp -->

<div class="users form">


<?= $this->Form->create($user) ?>
<fieldset>
<legend><?= __('Add User') ?></legend>
<?= $this->Form->input('username') ?>
<?= $this->Form->input('password') ?>
<?= $this->Form->input('role', [
'options' => ['admin' => 'Admin', 'author' => 'Author']
]) ?>
</fieldset>
<?= $this->Form->button(__('Submit')); ?>
<?= $this->Form->end() ?>
</div>

Autenticao (Login e Logout)

Agora estamos prontos para adicionar a nossa camada de autenticao. Em CakePHP isso tratado pelo
Cake\Controller\Component\AuthComponent, uma classe responsvel por exigir o login para determi-
nadas aes, a manipulao de login e logout de usurio, e tambm permite as aes para que esto autorizados.
Para adicionar este componente em sua aplicao abra o arquivos src/Controller/AppController.php e adicione as
seguintes linha:

// src/Controller/AppController.php

namespace App\Controller;

Tutorial - Criando um Blog - Autenticao e Autorizao 85


CakePHP Cookbook Documentation, Release 3.next

use Cake\Controller\Controller;
use Cake\Event\Event;

class AppController extends Controller


{
//...

public function initialize()


{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'loginRedirect' => [
'controller' => 'Articles',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
}

public function beforeFilter(Event $event)


{
$this->Auth->allow(['index', 'view', 'display']);
}
//...
}

No h muito para ser configurado, como usamos as convenes para a tabela de usurios. Ns apenas configuramos as
URLs que sero carregados aps o login e logout, ests aes so realizadas no nosso caso para os /articles/
e / respectivamente.
O que fizemos na funo beforeFilter() foi dizer ao AuthComponent para no exigir login em todos
index() e view(), em cada controlador. Queremos que os nossos visitantes sejam capaz de ler e listar as entradas
sem registrar-se no site.
Agora, precisamos ser capaz de registrar novos usurios, salvar seu username e password, e mais importante,
o hash da senha para que ele no seja armazenado como texto simples no nosso banco de dados. Vamos dizer
ao AuthComponet para permitir que usurios deslogados acessem a funo add e execute as aes de login e
logout:

// src/Controller/UsersController.php

public function beforeFilter(Event $event)


{
parent::beforeFilter($event);
// Permitir aos usurios se registrarem e efetuar logout.
// Voc no deve adicionar a ao de "login" a lista de permisses.
// Isto pode causar problemas com o funcionamento normal do AuthComponent.
$this->Auth->allow(['add', 'logout']);
}

public function login()


{
if ($this->request->is('post')) {
$user = $this->Auth->identify();

86 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Usurio ou senha nvalido, tente novamente'));
}
}

public function logout()


{
return $this->redirect($this->Auth->logout());
}

O hashing da senha ainda no est feito, precisamos de uma classe a fim de manipular sua gerao. Crie o arquivo
src/Model/Entity/User.php e adicione a seguinte trecho:
// src/Model/Entity/User.php
namespace App\Model\Entity;

use Cake\Auth\DefaultPasswordHasher;
use Cake\ORM\Entity;

class User extends Entity


{

// Gera conjunto de todos os campos exceto o com a chave primria.


protected $_accessible = [
'*' => true,
'id' => false
];

// ...

protected function _setPassword($password)


{
if (strlen($password) > 0) {
return (new DefaultPasswordHasher)->hash($password);
}
}

// ...
}

Agora, a senha criptografada usando a classe DefaultPasswordHasher. Est faltando apenas o arquivo para
exibio da tela de login. Abra o arquivo src/Template/Users/login.ctp e adicione as seguintes linhas:
<!-- File: src/Template/Users/login.ctp -->

<div class="users form">


<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Por favor informe seu usurio e senha') ?></legend>
<?= $this->Form->input('username') ?>
<?= $this->Form->input('password') ?>
</fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>

Tutorial - Criando um Blog - Autenticao e Autorizao 87


CakePHP Cookbook Documentation, Release 3.next

</div>

Agora voc pode registrar um novo usurio, acessando a URL /users/add e faa login com o usurio recm-criado,
indo para a URL /users/login. Alm disso, tente acessar qualquer outro URL que no tenha sido explicitamente
permitido, como /articles/add, voc vai ver que o aplicativo redireciona automaticamente para a pgina de
login.
E isso! Parece simples demais para ser verdade. Vamos voltar um pouco para explicar o que aconteceu. A funo
beforeFilter() est falando para o AuthComponent no solicitar um login para a ao add() em adio as
aes index() e view() que foram prontamente autorizadas na funo beforeFilter() do AppController.
A ao login() chama a funo $this->Auth->identify() da AuthComponent, que funciona sem qualquer
outra configurao porque estamos seguindo convenes, como mencionado anteriormente. Ou seja, ter uma tabela
de usurios com um username e uma coluna de password, e usamos um form para postar os dados do usurio
para o controller. Esta funo retorna se o login foi bem sucedido ou no, e caso ela retorne sucesso, ento ns
redirecionamos o usurio para a URL que configuramos quando adicionamos o AuthComponent em nossa aplicao.
O logout funciona quando acessamos a URL /users/logout que ir redirecionar o usurio para a url configurada
em logoutUrl. Essa url acionada quando a funo AuthComponent::logout().

Autorizao (quem tem permisso para acessar o que)

Como afirmado anteriormente, ns estamos convertendo esse blog em uma ferramenta multi usurio de autoria, e para
fazer isso, precisamos modificar a tabela de artigos um pouco para adicionar a referncia tabela de Usurios:

ALTER TABLE articles ADD COLUMN user_id INT(11);

Alm disso, uma pequena mudana no ArticlesController necessrio para armazenar o usurio conectado no mo-
mento como uma referncia para o artigo criado:

// src/Controller/ArticlesController.php

public function add()


{
$article = $this->Articles->newEntity();
if ($this->request->is('post')) {
$article = $this->Articles->patchEntity($article, $this->request->getData());
// Adicione esta linha
$article->user_id = $this->Auth->user('id');
// Voc tambm pode fazer o seguinte
//$newData = ['user_id' => $this->Auth->user('id')];
//$article = $this->Articles->patchEntity($article, $newData);
if ($this->Articles->save($article)) {
$this->Flash->success(__('Seu artigo foi salvo.'));
return $this->redirect(['action' => 'index']);
}
$this->Flash->error(__('No foi possvel adicionar seu artigo.'));
}
$this->set('article', $article);
}

A funo user() fornecida pelo componente retorna qualquer coluna do usurio logado no momento. Ns usamos
esse metdo para adicionar a informao dentro de request data para que ela seja salva.
Vamos garantir que nossa app evite que alguns autores editem ou apaguem posts de outros. Uma regra bsica para
nossa aplicao que usurios admin possam acessar qualquer url, enquanto usurios normais (o papel author) podem

88 Captulo 4. Tutoriais & Exemplos


CakePHP Cookbook Documentation, Release 3.next

somente acessar as actions permitidas. Abra novamente a classe AppController e adicione um pouco mais de opes
para as configuraes do Auth:

// src/Controller/AppController.php

public function initialize()


{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize' => ['Controller'], // Adicione est linha
'loginRedirect' => [
'controller' => 'Articles',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
}

public function isAuthorized($user)


{
// Admin pode acessar todas as actions
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}

// Bloqueia acesso por padro


return false;
}

Acabamos de criar um mecanismo de autorizao muito simples. Nesse caso os usurios com papel admin pode-
ro acessar qualquer url no site quando estiverem logados, mas o restante dos usurios (author) no podem acessar
qualquer coisa diferente dos usurios no logados.
Isso no exatamente o que ns queremos, por isso precisamos corrigir nosso metdo isAuthorized() para
fornecer mais regras. Mas ao invs de fazer isso no AppController, vamos delegar a cada controller para suprir essas
regras extras. As regras que adicionaremos para o add de ArticlesController deve permitir ao autores criarem os posts
mas evitar a edio de posts que no sejam deles. Abra o arquivo src/Controller/ArticlesController.php e adicione
o seguinte contedo:

// src/Controller/ArticlesController.php

public function isAuthorized($user)


{
// Todos os usurios registrados podem adicionar artigos
if ($this->request->getParam('action') === 'add') {
return true;
}

// Apenas o proprietrio do artigo pode editar e exclu


if (in_array($this->request->getParam('action'), ['edit', 'delete'])) {
$articleId = (int)$this->request->getParam('pass.0');
if ($this->Articles->isOwnedBy($articleId, $user['id'])) {
return true;
}

Tutorial - Criando um Blog - Autenticao e Autorizao 89


CakePHP Cookbook Documentation, Release 3.next

return parent::isAuthorized($user);
}

Estamos sobrescrevendo a chamada isAuthorized()``do AppController e internamente


verificando na classe pai se o usurio est autorizado. Caso no esteja,ento
apenas permitem acessar a action ``add, e condicionalmente action edit e delete. Uma ltima
coisa no foi implementada. Para dizer ou no se o usurio est autorizado a editar o artigo, ns estamos chamando
uma funo isOwnedBy() na tabela artigos. Vamos, ento, implementar essa funo:

// src/Model/Table/ArticlesTable.php

public function isOwnedBy($articleId, $userId)


{
return $this->exists(['id' => $articleId, 'user_id' => $userId]);
}

Isso conclui ento nossa autorizao simples e nosso tutorial de autorizao. Para garantir o UsersController voc
pode seguir as mesmas tcnicas que usamos para ArticlesController, voc tambm pode ser mais criativo e codificar
algumas coisas mais gerais no AppController para suas prprias regras baseadas em papis.
Se precisar de mais controle, ns sugerimos que leia o guia completo do Auth Authentication seo onde voc encon-
trar mais sobre a configurao do componente, criao de classes de Autorizao customizadas, e muito mais.

Sugerimos as seguintes leituras

1. Gerao de cdigo com o Bake Generating basic CRUD code


2. Authentication: User registration and login

90 Captulo 4. Tutoriais & Exemplos


CAPTULO 5

Contribuindo

Existem vrias maneiras de contribuir com o CakePHP. As sees abaixo iro abordar essas formas de contribuio:

Documentao

Contribuir com a documentao simples. Os arquivos esto hospedados em https://github.com/cakephp/docs. Sinta-


se a vontade para copiar o repositrio, adicionar suas alteraes/melhorias/tradues e enviar um pull request. Voc
tambm pode editar a documentao online pelo Github, mesmo sem ter que fazer download dos arquivos O boto
IMPROVE THIS DOC presente na lateral direita em qualquer pgina vai direcion-lo para o editor online do Github.
A documentao do CakePHP continuamente integrada33 , sendo assim, voc pode checar o status de vrias builds34
no servidor Jenkins a qualquer momento.

Tradues

Envie um email para o time de documentao (docs at cakephp dot org) ou aparea no IRC (#cakephp na freenode)
para discutir sobre qualquer rea de traduo que voc queira participar.

Nova traduo lingustica

Ns queremos oferecer tradues completas tanto quanto possvel, porm, podem haver momentos que um arquivo de
traduo no est atualizado. Voc deve sempre considerar a verso em ingls como a prevalecente.
Se o seu idioma no est dentre os listados, por favor nos contate pelo Github e ns vamos considerar inclu-lo. As
sees a seguir so as primeiras que voc deve considerar traduzir, pois seus arquivos no mudam frequentemente:
index.rst
intro.rst
quickstart.rst
installation.rst
/intro (todo o diretrio)
33 http://en.wikipedia.org/wiki/Continuous_integration
34 https://ci.cakephp.org

91
CakePHP Cookbook Documentation, Release 3.next

/tutorials-and-examples (todo o diretrio)

Lembrete para administradores de documentao

A estrutura de todos os diretrios de idioma devem espelhar a estrutura da matriz em ingls. Se a estrutura da docu-
mentao inglesa sofrer mudanas, as mesmas devem ser aplicadas em outros idiomas.
Por exemplo, se um novo arquivo criado em en/file.rst, ns devemos:
Adicionar o arquivo a outros idiomas: pt/file.rst, fr/file.rst, etc
Deletar o contedo, mas manter as informaes title, meta` e eventuais elementos
``toc-tree. A nota a seguir ser adicionada at que algum traduza o arquivo:

File Title
##########

.. note::
Atualmente, a documentao desta pgina no suportada em portugus.

Por favor, sinta-se a vontade para nos enviar um *pull request* para o
`Github <https://github.com/cakephp/docs>`_ ou use o boto
**IMPROVE THIS DOC** para propor suas mudanas diretamente.

Voc pode consultar a verso em ingls deste tpico atravs do seletor de


idiomas localizado ao lado direito do campo de buscas da documentao.

// Se os elementos toc-tree existirem na verso inglesa


.. toctree::
:maxdepth: 1

toc-file-x
toc-file-y
toc-file-z

.. meta::
:title lang=pt: Ttulo do arquivo
:keywords lang=pt: ttulo, descrio,...

Dicas para tradutores

Navegue pelo idioma para o qual deseja traduzir a fim de certificar-se do que j foi traduzido.
Sinta-se a vontade para mergulhar na traduo caso o seu idioma j exista no manual.
Use Linguagem Informal35 .
Traduza o contedo e o ttulo ao mesmo tempo.
Antes de submeter uma correo, compare verso original. (se voc corrigir algo, mas no indicar uma
referncia, sua submisso no ser aceita).
Se voc precisar escrever um termo em ingls, envolva-o na tag <em>. E.g. asdf asdf Controller asdf ou
asdf asdf Kontroller (Controller) asfd, como for apropriado.
No submeta tradues incompletas.
No edite uma seo com alteraes pendentes.
35 https://pt.wikipedia.org/wiki/Linguagem_coloquial

92 Captulo 5. Contribuindo
CakePHP Cookbook Documentation, Release 3.next

No use Entidades HTML36 para caracteres acentuados, o manual usa UTF-8.


No faa alteraes significativas na marcao (HTML) ou adicione novo contedo.
Se estiver faltando alguma informao no contedo original, submeta uma correo paral tal antes de inclu-la
em seu idioma.

Guia de formatao para documentao

A nova documentao do CakePHP escrita com ReST37 . ReST (Re Structured Text) uma sintaxe de marcao de
texto simples, semelhante a markdown ou textfile. Para manter a consistncia, recomenda-se que ao adicionar contedo
documentao do CakePHP, voc siga as diretrizes aqui exemplificadas.

Comprimento da linha

Linhas de texto devem ser limitadas a 80 colunas. As nicas excees devem ser URLs longas e trechos de cdigo.

Ttulos e Sees

Cabealhos de seo so criados ao sublinhar o ttulo com caracteres de pontuao seguindo o comprimento do texto.
# usado para ttulos de pginas.
= usado para sees de pgina.
- usado para sub-sees de pgina.
~ usado para sub-sub-sees de pgina.
^ usado para sub-sub-sub-sees de pgina.
Os ttulos no devem ser aninhados por mais de 5 nveis de profundidade. Os ttulos devem ser precedidos e seguidos
por uma linha em branco.

Pargrafos

Os pargrafos so simplesmente blocos de texto, com todas as linhas no mesmo nvel de recuo. Os pargrafos devem
ser separados por mais do que uma linha vazia.

Marcao em linha

Um asterisco: texto para dar nfase (itlico) Vamos us-lo para realce/nfase.
*texto*.
Dois asterscos: texto para nfase forte (negrito) Vamos us-lo para diretrios, ttulos de listas, nomes de tabelas
(excluindo a palavra tabela).
**/config/Migrations**, **articles**, etc.
Dois backquotes: texto para exemplos de cdigo Vamos us-lo para opes, nomes de colunas de tabelas,
nomes de objetos (excluindo a palavra objeto) e nomes de mtodos/funes incluir ().
36 http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references
37 http://en.wikipedia.org/wiki/ReStructuredText

Documentao 93
CakePHP Cookbook Documentation, Release 3.next

``cascadeCallbacks``, ``true``, ``id``, ``PagesController``, ``config()``,


etc.
Se asterscos ou backquotes aparecerem em texto corrido e ficarem confusos com delimitadores de marao em linha,
eles devem ser escapados com um backslash.
Marcao em linha tem algumas restries:
No deve estar aninhado.
O contedo no deve comear ou terminar com espao: * texto* est errado.
O contedo deve estar separado de texto adjacente por caracteres non-word. Use um espao escapado com uma
contrabarra ao seu redor: umalonga\ *negrito*\ palavra.

Listas

A marcao de listas muito parecida com o markdown. Listas desordenadas comeam com um astersco e um espao.
Listas enumeradas podem ser criadas tanto com nmeros, ou # para auto numerao:

* Esse um item
* Esse tambm, mas esse tem
duas linhas.

1. Primeira linha
2. Segunda linha

#. Numerao automtica
#. Vai lhe economizar algum tempo...

Listas com recuos tambm podem ser criadas ao recuar sees e separ-las com uma linha em branco:

* Primeira linha
* Segunda linha

* Mais fundo
* WOW!

* De volta ao primeiro nvel...

Listas de definio podem ser criadas assim:

Termo
Definio
CakePHP
Um framework MVC para PHP

Termos no podem ultrapassar uma linha, porm definies podem e devem estar recuadas consistentemente.

Links

Existem diveros tipos de links, cada um com usos particulares.

Links externos

Links para documentos externos podem ser feitos desta forma:

94 Captulo 5. Contribuindo
CakePHP Cookbook Documentation, Release 3.next

`Link externo para php.net <http://php.net>`_

O link resultante ficaria assim: Link externo para php.net38

Links para outras pginas

:doc:
Outras pginas na documentao podem ser referenciadas ao usar a funo :doc:. Voc pode referen-
ciar pginas usando caminho absoluto ou relativo. Voc deve omitir a extenso .rst. Por exemplo,
se a referncia :doc:`form` estivesse no documento core-helpers/html, ento o link referencia-
ria core-helpers/form. Caso a referncia fosse :doc:`/core-helpers`, iria sempre referenciar
/core-helpers independente de onde a funo fosse usada.

Links de referncias cruzados

:ref:
Voc pode referenciar qualquer ttulo de um documento usando a funo :ref:. O ttulo por sua vez, no pode
ser repetido por toda a documentao. Ao criar ttulos para mtodos de classes, melhor usar class-method
como formato.
A posio mais comum a cima de um ttulo. Exemplo:

.. _label-name:

Ttulo da seo
---------------

Mais contedo aqui

Em qualquer lugar voc pode referenciar a seo a cima usando :ref:`label-name`. O texto do link
dever ser o ttulo que o link precedeu. Voc pode indicar qualquer formato usando :ref:`Seu texto
<label-name>`.

Prevenindo alertas do Sphinx

O Sphinx vai disparar alertas se um arquivo no for referenciado em um toc-tree. uma forma de garantir que todos
os arquivos possuem um link referenciado a eles, mas as vezes, voc no precisa inserir um link para um arquivo,
e.g. para seus arquivos epub-contents and pdf-contents. Nesses casos, voc pode adicionar :orphan: no topo do
arquivo, para suprimir alertas.

Descrevendo classes e seus contedos

A documentao do CakePHP usa o phpdomain39 para fornecer directivas customizadas a fim de descrever objetos e
construtores no PHP. Usar essas directivas e funes um requisito para gerar a indexao adequada e recursos de
referncia cruzada.
38 http://php.net
39 http://pypi.python.org/pypi/sphinxcontrib-phpdomain

Documentao 95
CakePHP Cookbook Documentation, Release 3.next

Descrevendo classes e construtores

Cada directiva popula o ndice, e/ou o ndice do namespace.


.. php:global:: name
Esta directiva declara uma nova varivel global PHP.
.. php:function:: name(signature)
Esta directiva define uma nova funo global fora de uma classe.
.. php:const:: name
Esta directiva declara uma nova constante PHP, voc tambm pode us-lo aninhada dentro de uma directiva de
classe para criar constantes de classe.
.. php:exception:: name
Esta directiva declara uma nova exceo no namespace atual. A assinatura pode incluir argumentos do constru-
tor.
.. php:class:: name
Esta directiva descreve uma classe. Mtodos, atributos, e as constantes pertencentes classe devem estar dentro
do corpo desta directiva:

.. php:class:: MyClass

Descrio da classe

.. php:method:: method($argument)

Descrio do mtodo

Atributos, mtodos e constantes no precisam estar aninhados. Eles podem


apenas seguir a declarao da classe::

.. php:class:: MyClass

Texto sobre a classe

.. php:method:: methodName()

Texto sobre o mtodo

Ver tambm:
php:method, php:attr, php:const
.. php:method:: name(signature)
Descreve um mtodo de classe, seus argumentos, valor de retorno e excees:

.. php:method:: instanceMethod($one, $two)

:param string $one: O primeiro parmetro.


:param string $two: O segundo parmetro.
:returns: Um vetor de coisas.
:throws: InvalidArgumentException

Este um mtodo de instncia

.. php:staticmethod:: ClassName::methodName(signature)
Descreve um mtodo esttico, seus argumentos, valor de retorno e excees. Ver php:method para opes.

96 Captulo 5. Contribuindo
CakePHP Cookbook Documentation, Release 3.next

.. php:attr:: name
Descreve uma propriedade/atributo numa classe.

Prevenindo alertas do Sphinx

O Sphinx vai disparar alertas se uma funo estiver referenciada em mltiplos arquivos. um meio de garantir que
voc no adicionou uma funo duas vezes, porm, algumas vezes voc quer escrever a funo em dois ou mais
arquivos, e.g. debug object est referenciado em /development/debugging e em /core-libraries/global-constants-and-
functions. Nesse caso, voc pode adicionar :noindex: abaixo do debug da funo para suprimir alertas. Mantenha
apenas uma referncia sem :no-index: para preservar a funo referenciada:

.. php:function:: debug(mixed $var, boolean $showHtml = null, $showFrom = true)


:noindex:

Referenciamento cruzado

As funes a seguir se referem a objetos PHP e os links so gerados se uma directiva correspondente for encontrada:
:php:func:
Referencia uma funo PHP.
:php:global:
Referencia uma varivel global cujo nome possui o prefixo $.
:php:const:
Referencia tanto uma constante global como uma constante de classe. Constantes de classe devem ser precedidas
pela classe me:

DateTime possui uma constante :php:const:`DateTime::ATOM`.

:php:class:
Referencia uma classe por nome:

:php:class:`ClassName`

:php:meth:
Referencia um mtodo de uma classe. Essa funo suporta ambos os mtodos:

:php:meth:`DateTime::setDate`
:php:meth:`Classname::staticMethod`

:php:attr:
Referencia a propriedade de um objeto:

:php:attr:`ClassName::$propertyName`

:php:exc:
Referencia uma exceo.

Cdigo-fonte

Blocos de cdigo literais so criados ao finalizar um pargrafo com ::. O bloco de cdigo literal deve estar recuado,
e como todos os pargrafos, estar separado por linhas vazias:

Documentao 97
CakePHP Cookbook Documentation, Release 3.next

Isto um pargrafo::

while ($i--) {
doStuff()
}

Isto texto novamente.

Texto literal no modificado ou formatado, com exceo do primeiro nvel de recuo que removido.

Notas e alertas

Muitas vezes h momentos em que voc deseja informar o leitor sobre uma dica importante, nota especial ou um
perigo potencial. Admoestaes no Sphinx so utilizados apenas para isto. Existem cinco tipos de advertncias.
.. tip:: Dicas so usadas para documentar ou re-iterar informaes importantes ou interessantes. O con-
tedo da directiva deve ser escrito em sentenas completas e incluir a pontuao adequada.
.. note:: Notas so usadas para documentar uma pea importante de informao. O contedo da directiva
deve ser escrita em sentenas completas e incluir a pontuao adequada.
.. warning:: Alertas so usados para documentar obstculos em potencial, ou informao referente a
segurana. O contedo da directiva deve ser escrito em sentenas completas e incluir a pontuao adequada.
.. versionadded:: X.Y.Z Admoestaes de verso so usados como notas de recursos adicionados
em uma verso especfica, X.Y.Z sendo a verso na qual o dito recurso foi adicionado.
.. deprecated:: X.Y.Z O oposto das admoestaes de verso, admoestaes de obsolescncia so
usados para notificar sobre um recurso obsoleto, are used to notify of a deprecated feature, X.Y.Z sendo a
verso na qual o dito recurso foi abandonado.
Todas as admoestaes so feitas da mesma forma:

.. note::

Recuadas e precedido e seguido por uma linha em branco. Assim como um


pargrafo.

Esse texto no parte da nota.

Exemplos

Dica: Essa uma dica que voc no sabia.

Nota: Voc deve prestar ateno aqui.

Aviso: Pode ser perigoso.

Novo na verso 2.6.3: Esse recurso incrvel foi adicionado na verso 2.6.3
Obsoleto desde a verso 2.6.3: Esse recurso antigo foi descontinuado na verso 2.6.3

98 Captulo 5. Contribuindo
CakePHP Cookbook Documentation, Release 3.next

Tickets

Receber feedback e ajuda da comunidade em forma de tickets uma parte extremamente importante do processo de
desenvolvimento do CakePHP. Todos os tickets esto hospedados no GitHub40 .

Reportando bugs

Relatrios de bugs bem escritos so muito teis. Existem algumas medidas que ajudam a criar relatrios de erro
melhores:
Faa: Busque41 por tickets similares para garantir que ningum reportou algo similar, ou que o erro no tenha
sido corrigido.
Faa: Inclua informaes detalhadas de como reproduzir o erro. Pode ser na forma de um roteiro de testes ou
um trecho de cdigo que demonstre o problema. Sem que haja uma forma de reproduzir o problema pouco
provvel que seja corrigido.
Faa: D o mximo de detalhes sobre o seu ambiente: (SO, verso do PHP, verso do CakePHP).
No faa: No use o sistema de tickets para sanar dvidas. O canal de IRC #cakephp na Freenode42 possui
muitos desenvolvedores dispnveis para ajudar a responder suas dvidas. Tambm d uma olhada no Stack
Overflow43 .

Reportando problemas de segurana

Se voc encontrar um problema de segurana no CakePHP, use o procedimento a seguir ao invs do sistema de
relatrios de bugs padro. Envie um email para security [at] cakephp.org. Emails enviados para esse endereo so
encaminhados para os core developers do CakePHP numa lista privada.
Para cada relatrio, tentaremos inicialmente confirmar a vulnerabilidade. Uma vez confirmada, o time do CakePHP
tomar as aes seguintes:
Confirmar ao relatante que recebemos o relatrio e que estamos trabalhando em um fix. Solicitamos ao relatante
que o problema seja mantido confidencialmente at que o anunciemos.
Preparar uma correo/patch.
Preparar um post descrevendo o problema, e possveis vulnerabilidades.
Lanar novas verses para todas as verses afetadas.
Anunciar o problema no anncio de lanamento.

Cdigo

Patches e pull requests so formas de contribuir com cdigo para o CakePHP. Pull requests podem ser criados no
Github e tem preferncia sobre arquivos de patch nos comentrios dos tickets.
40 https://github.com/cakephp/cakephp/issues
41 https://github.com/cakephp/cakephp/search?q=it+is+broken&ref=cmdform&type=Issues
42 https://webchat.freenode.net
43 https://stackoverflow.com/questions/tagged/cakephp

Tickets 99
CakePHP Cookbook Documentation, Release 3.next

Configurao inicial

Antes de trabalhar em patches para o CakePHP, uma boa ideia configurar seu ambiente. Voc vai precisar do seguinte
software:
Git
PHP 5.6.0 ou maior
PHPUnit 3.7.0 ou maior
Defina suas informaes de usurio com seu nome e endereo de email:

git config --global user.name 'Bob Barker'


git config --global user.email 'bob.barker@example.com'

Nota: Se voc novo no Git, recomendamos que leia o gratuito e excelente manual ProGit44 .

Clone o cdigo-fonte do CakePHP do Github:


Se voc no tem uma conta no GitHub45 , crie uma.
D Fork no repositrio do CakePHP46 clicando no boto Fork&.
Depois que seu fork for feito, clone seu fork para sua mquina:

git clone git@github.com:SEUNOME/cakephp.git

Adicione o repositrio original do CakePHP como seu repositrio remoto. Voc ir us-lo posteriormente para solicitar
atualizaes das alteraes no repositrio do CakePHP. Assim sua verso local estar sempre atualizada:

cd cakephp
git remote add upstream git://github.com/cakephp/cakephp.git

Agora que voc tem o CakePHP configurado voc pode definir uma conexo com o banco de dados $test, e executar
todos os testes.

Trabalhando em um patch

Toda vez que for trabalhar em um bug, feature ou melhoria, crie um branch especfico.
O branch criado deve ser baseado na verso que deseja atualizar. Por exemplo, se voc estiver corrigindo um bug na
verso 3.x, voc deve usar o branch master como base. Se sua alterao for uma correo de bug para a verso
2.x, voc deve usar o branch 2.x. Isso faz o merging das suas alteraes uma tarefa muito mais simples futuramente:

# corrigindo um bug na verso 3.x


git fetch upstream
git checkout -b ticket-1234 upstream/master

# corrigindo um bug na verso 2.x


git fetch upstream
git checkout -b ticket-1234 upstream/2.x

44 http://git-scm.com/book/
45 http://github.com
46 http://github.com/cakephp/cakephp

100 Captulo 5. Contribuindo


CakePHP Cookbook Documentation, Release 3.next

Dica: Use um nome descritivo para o seu branch, referenciar o nome do ticket ou da feature uma boa conveno,
e.g. ticket-1234, feature-awesome

A cima criamos um branch local baseado no branch do upstream (CakePHP) 2.x. Trabalhe na sua correo/atualizao
e faa quantos commits precisar, mas tenha em mente o seguinte:
Siga as Padres de codificao.
Adicione um caso de teste para mostrar que o bug est corrigido, ou que a nova feature funciona.
Mantenha alguma lgica em seus commits e escreva mensagens limpas e coerentes.

Enviando um pull request

Uma vez que suas alteraes estiverem concludas e prontas para serem integradas ao CakePHP, voc deve atualizar
seu branch:
# Correo por rebase a partir do topo do branch master
git checkout master
git fetch upstream
git merge upstream/master
git checkout <branch_name>
git rebase master

Isso ir requisitar e mesclar quaisquer alteraes que aconteceram no CakePHP desde que voc comeou suas alte-
raes, e ento executar rebase ou replicar suas alteraes no topo da lista atual. Voc pode encontrar um conflito
durante o rebase. Se o rebase abortar prcocemente, voc pode verificar que arquivos so conflitantes usando o
comando git status. Resolva cada conflito e ento continue o rebase:
git add <nome-do-arquivo> # faa isso para cada arquivo conflitante.
git rebase --continue

Verifique se todos os seus testes continuam a passar e ento faa push do seu branch para o seu fork:
git push origin <nome-do-branch>

Se voc usou rebase aps enviar as atualizaes do seu branch por push, voc precisar forar o push:
git push --force origin <nome-do-branch>

Uma vez que o seu branch estiver no Github, voc pode enviar um pull request .

Escolhendo onde suas alteraes sero incorporadas

Ao fazer pull requests voc deve ter certeza que selecionou o branch correto , pois voc no pode fazer qualquer edio
aps o pull request ter sido criado .
Se sua alterao for um bugfix, no introduzir uma nova funcionalidade e apenas corrigir um comportamento
existente que est presente no release atual, escolhe o branch master como seu alvo.
Se sua alterao for uma feature, ento voc deve escolher o branch referente ao prximo nmero de verso.
Por exemplo, se o branch atual estvel for 3.2.10, o branch a receber novas funcionalidades ser o 3.next.
Se sua alterao quebra funcionalidades existentes, ou APIs, ento voc dever escolher o prximo major
release. Por exemplo, se o branch estvel atual for 3.2.2, ento a verso na qual o comportamento pode ser
quebrado ser na verso 4.x.

Cdigo 101
CakePHP Cookbook Documentation, Release 3.next

Nota: Lembre-se que todo cdigo que voc contribui com o CakePHP ser licensiado sob a licena MIT, e a Cake
Software Foundation47 ser a proprietria de qualquer cdigo proveniente de contribuio. Os contribuidores devem
seguir as regras comunitrias do CakePHP48 .

Todas as correes de bugs incorporadas a um branch de manuteno sero posteriormente mescladas nos lanamentos
futuros realizados pelo time do CakePHP.

Padres de codificao

Desenvolvedores do CakePHP devero usar o guia de codificao PSR-249 em adio s regras apresentadas a seguir
e definidas como padro.
recomendado que outros desenvolvedores que optem pelo CakePHP sigam os mesmos padres.
Voc pode usar o CakePHP Code Sniffer50 para verificar se o seu cdigo segue os padres estabelecidos.

Adicionando novos recursos

Nenhum novo recurso deve ser adicionado sem que tenha seus prprios testes definidos, que por sua vez, devem estar
passando antes que o novo recurso seja enviado para o repositrio.

Indentao

Quatro espaos sero usados para indentao.


Ento, teremos uma estrutura similar a:

// nvel base
// nvel 1
// nvel 2
// nvel 1
// nvel base

Ou:

$booleanVariable = true;
$stringVariable = 'jacar';
if ($booleanVariable) {
echo 'Valor booleano true';
if ($stringVariable === 'jacar') {
echo 'Ns encontramos um jacar';
}
}

Em situaes onde voc estiver usando uma funo em mais de uma linha, siga as seguintes orientaes:
O parntese de abertura de uma funo multi-linha deve ser o ltimo contedo da linha.
Apenas um argumento permitido por linha em uma funo multi-linha.
47 http://cakefoundation.org/pages/about
48 http://community.cakephp.org/guidelines
49 http://www.php-fig.org/psr/psr-2/
50 https://github.com/cakephp/cakephp-codesniffer

102 Captulo 5. Contribuindo


CakePHP Cookbook Documentation, Release 3.next

O parntese de fechamento de uma funo multi-linha deve ter uma linha reservada para s.
Um exemplo, ao invs de usar a seguinte formatao:

$matches = array_intersect_key($this->_listeners,
array_flip(preg_grep($matchPattern,
array_keys($this->_listeners), 0)));

Use esta:

$matches = array_intersect_key(
$this->_listeners,
array_flip(
preg_grep($matchPattern, array_keys($this->_listeners), 0)
)
);

Comprimento da linha

recomendado manter as linhas prximas de 100 caracteres no comprimento para melhor leitura do cdigo. As linhas
no devem ser mais longas que 120 caracteres.
Resumindo:
100 caracteres o limite recomendado.
120 caracteres o limite mximo.

Estruturas de controle

Estruturas de controle so por exemplo, if, for, foreach, while, switch, etc. A baixo, um exemplo
com if:

if ((expr_1) || (expr_2)) {
// ao_1;
} elseif (!(expr_3) && (expr_4)) {
// ao_2;
} else {
// ao_padro;
}

Nas estruturas de controle deve existir 1 (um) espao antes do primeiro parntese e 1 (um) espao entre o ltimo
parntese e a chave de abertura.
Sempre use chaves nas estruturas de controle, mesmo que no sejam necessrias. Elas melhorar a leitura do
cdigo e tendem a causar menos erros lgicos.
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 nvel de indentao que a estrutura de controle. O contedo
de dentro das chaves deve comear em uma nova linha e receber um novo nvel de indentao.
Atribuies em linha no devem ser usadas dentro de estruturas de controle.

// errado = sem chaves, declarao mal posicionada


if (expr) declarao;

// errado = sem chaves

Padres de codificao 103


CakePHP Cookbook Documentation, Release 3.next

if (expr)
declarao;

// certo
if (expr) {
declarao;
}

// errado = atribuio em linha


if ($variable = Class::function()) {
declarao;
}

// certo
$variable = Class::function();
if ($variable) {
declarao;
}

Operadores ternrios

Operadores ternrios so admissveis quando toda a operao ternria se encaixa em uma nica linha. J operaes
mais longas devem ser divididas em declaraes if else. Operadores ternrios nunca devem ser aninhados. Opci-
onalmente parnteses podem ser usados ao redor da verificao de condio ternria para esclarecer a operao:

// Bom, simples e legvel


$variable = isset($options['variable']) ? $options['variable'] : true;

// Aninhamento ruim
$variable = isset($options['variable']) ? isset($options['othervar']) ? true : false :
false;

Arquivos de template

Em arquivos de template (arquivos .ctp) 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 cdigo PHP, ou ainda em tags PHP separadas:

<?php
if ($isAdmin):
echo '<p>Voc o usurio administrador.</p>';
endif;
?>
<p>A seguinte estrutura tambm aceitvel:</p>
<?php if ($isAdmin): ?>
<p>Voc o usurio administrador.</p>
<?php endif; ?>

Comparao

Sempre tente ser o mais rigoroso possvel. Se uma comparao deliberadamente no estrita, pode ser inteligente
comentar sobre isso para evitar confuses geradas por falta de informao.

104 Captulo 5. Contribuindo


CakePHP Cookbook Documentation, Release 3.next

Para testar se uma varivel nula, recomendado usar uma verificao estrita:

if ($value === null) {


// ...
}

O valor a ser verificado deve ser posto do lado direito:

// no recomendado
if (null === $this->foo()) {
// ...
}

// recomendado
if ($this->foo() === null) {
// ...
}

Chamadas de funo

Funes devem ser chamadas sem espao entre o nome da funo e o parntese de abertura. Deve haver um espao
entre cada parmetro de uma chamada de funo:

$var = foo($bar, $bar2, $bar3);

Como voc pode ver a cima, deve haver um espao em ambos os lados do sinal de igual (=).

Definio de mtodo

Exemplo de uma definio de mtodo:

public function someFunction($arg1, $arg2 = '')


{
if (expr) {
declarao;
}
return $var;
}

Parmetros com um valor padro, devem ser posicionados por ltimo na definio de uma funo. Tente fazer suas
funes retornarem algo, pelo menos true ou false, assim pode-se determinar se a chamada de funo foi bem-
sucedida:

public function connection($dns, $persistent = false)


{
if (is_array($dns)) {
$dnsInfo = $dns;
} else {
$dnsInfo = BD::parseDNS($dns);
}

if (!($dnsInfo) || !($dnsInfo['phpType'])) {
return $this->addError();
}

Padres de codificao 105


CakePHP Cookbook Documentation, Release 3.next

return true;
}

Existem espaos em ambos os lados dos sinais de igual.

Declarao de tipo

Argumentos que esperam objetos, arrays ou callbacks (vlidos) podem ser declarados por tipo. Ns apenas declaramos
mtodos pblicos, porm, o uso da declarao por tipo no livre de custos:

/**
* Descrio do mtodo.
*
* @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.
*/
public function foo(Table $table, array $array, callable $callback, $boolean)
{
}

Aqui $table deve ser uma instncia de \Cake\ORM\Table, $array deve ser um array e $callback deve
ser do tipo callable (um callback vlido).
Perceba que se voc quiser permitir $array ser tambm uma instncia de \ArrayObject voc no deve declar-lo,
pois array aceita apenas o tipo primitivo:

/**
* Descrio do mtodo.
*
* @param array|\ArrayObject $array Algum valor em formato array.
*/
public function foo($array)
{
}

Funes annimas (Closures)

Para se definir funes annimas, segue-se o estilo de codificao PSR-251 , onde elas so declaradas com um espao
depois da palavra-chave function, e um espao antes e depois da palavra-chave use:

$closure = function ($arg1, $arg2) use ($var1, $var2) {


// cdigo
};

Encadeamento de mtodos

Encadeamento de mtodos deve ter mltiplos mtodos distribuidos em linhas separadas e indentados com quatro
espaos:
51 http://www.php-fig.org/psr/psr-2/

106 Captulo 5. Contribuindo


CakePHP Cookbook Documentation, Release 3.next

$email->from('foo@exemplo.com')
->to('bar@exemplo.com')
->subject('Uma mensagem legal')
->send();

Comentando cdigo

Todos os comentrios devem ser escritos em ingls, e devem de forma clara descrever o bloco de cdigo comentado.
Comentrios podem incluir as seguintes tags do phpDocumentor52 :
@author53
@copyright54
@deprecated55 Usando o formato @version <vector> <description>, onde version e
description so obrigatrios.
@example56
@ignore57
@internal58
@link59
@see60
@since61
@version62
Tags PhpDoc so muito semelhantes a tags JavaDoc no Java. Tags so apenas processadas se forem a primeira coisa
numa linha de DocBlock, por exemplo:

/**
* Exemplo de tag.
*
* @author essa tag analisada, mas essa verso ignorada
* @version 1.0 essa tag tambm analisada
*/

/**
* Exemplo de tags phpDoc em linha.
*
* Essa funo cria planos com foo() para conquistar o mundo.
*
* @return void
*/

52 http://phpdoc.org
53 http://phpdoc.org/docs/latest/references/phpdoc/tags/author.html
54 http://phpdoc.org/docs/latest/references/phpdoc/tags/copyright.html
55 http://phpdoc.org/docs/latest/references/phpdoc/tags/deprecated.html
56 http://phpdoc.org/docs/latest/references/phpdoc/tags/example.html
57 http://phpdoc.org/docs/latest/references/phpdoc/tags/ignore.html
58 http://phpdoc.org/docs/latest/references/phpdoc/tags/internal.html
59 http://phpdoc.org/docs/latest/references/phpdoc/tags/link.html
60 http://phpdoc.org/docs/latest/references/phpdoc/tags/see.html
61 http://phpdoc.org/docs/latest/references/phpdoc/tags/since.html
62 http://phpdoc.org/docs/latest/references/phpdoc/tags/version.html

Padres de codificao 107


CakePHP Cookbook Documentation, Release 3.next

function bar()
{
}

/**
* Funo foo.
*
* @return void
*/
function foo()
{
}

Blocos de comentrios, com a exceo do primeiro bloco em um arquivo, devem sempre ser precedidos por uma nova
linha.

Tipos de variveis

Tipos de variveis para serem usadas em DocBlocks:


Tipo Descrio
mixed Uma varivel com mltiplos tipos ou tipo indefinido.
int Varivel de tipo int (nmero inteiro).
float Varivel de tipo float (nmero decimal).
bool Varivel de tipo bool (lgico, verdadeiro ou falso).
string Varivel de tipo string (qualquer valor dentro de ou ).
null Varivel de tipo null. Normalmente usada em conjunto com outro tipo.
array Varivel de tipo array.
object Varivel de tipo object. Um nome especfico de classe deve ser usado, se possvel.
resource Varivel de tipo resource (retornado de mysql_connect() por exemplo). Lembre-se que quando voc espe-
cificar o tipo como mixed, voc deve indicar se o mesmo desconhecido, ou quais os tipos possveis.
callable Varivel de tipo funo.
Voc tambm pode combinar tipos usando o caractere de barra vertical:

int|bool

Para mais de dois tipos melhor usar mixed.


Ao retornar o prprio objeto, e.g. para encadeamento, use $this ao invs:

/**
* Funo Foo.
*
* @return $this
*/
public function foo()
{
return $this;
}

108 Captulo 5. Contribuindo


CakePHP Cookbook Documentation, Release 3.next

Incluindo arquivos

include, require, include_once e require_once no tem parnteses:

// errado = com parnteses


require_once('ClassFileName.php');
require_once ($class);

// certo = sem parnteses


require_once 'ClassFileName.php';
require_once $class;

Ao incluir arquivos com classes ou bibliotecas, use sempre e apenas a funo require_once63 .

Tags do PHP

Use sempre tags longas (<?php ?>) ao invs de tags curtas (<? ?>). O short echo deve ser usado em arquivos de
template (.ctp) quando apropriado.

Short Echo

O short echo deve ser usado em arquivos de template no lugar de <?php echo. Deve tambm, ser imediatamente
seguido por um espao em branco, a varivel ou funo a ser chamada pelo echo, um espao em branco e a tag de
fechamento do PHP:

// errado = ponto-e-virgula, sem espaos


<td><?=$name;?></td>

// certo = sem ponto-e-virgula, com espaos


<td><?= $name ?></td>

A partir do PHP 5.4 a tag short echo (<?=) no mais considerada um atalho, estando sempre disponvel indepen-
dentemente da configurao da chave short_open_tag.

Conveno de nomenclatura

Funes

Escreva todas as funes no padro camelBack, isto , com a letra da primeira palavra minscula e a primeira letra
das demais palavras maisculas:

function longFunctionName()
{
}

Classes

Escreva todas as funes no padro CamelCase, isto , com a primeira letra de cada palavra que compem o nome
da classe maiscula:
63 http://php.net/require_once

Padres de codificao 109


CakePHP Cookbook Documentation, Release 3.next

class ExampleClass
{
}

Variveis

Nomes de variveis devem ser tanto curtas como descritivas, o quanto possvel. Todas as variveis devem comear
com letra minscula e seguir o padro camelBack no caso de muitas palavras. Variveis referenciando objetos
devem estar de alguma forma associadas classe indicada. Exemplo:

$user = 'John';
$users = ['John', 'Hans', 'Arne'];

$dispatcher = new Dispatcher();

Visibilidade

Use as palavras reservadas do PHP5, private e protected para indicar mtodos e variveis. Adicionalmente, nomes de
mtodos e variveis no-pblicos comear com um underscore singular (_). Exemplo:

class A
{
protected $_iAmAProtectedVariable;

protected function _iAmAProtectedMethod()


{
/* ... */
}

private $_iAmAPrivateVariable;

private function _iAmAPrivateMethod()


{
/* ... */
}
}

Endereos para exemplos

Para qualquer URL e endereos de email, use example.com, example.org e example.net, por exemplo:
Email: someone@example.com
WWW: http://www.example.com
FTP: ftp://ftp.example.com
O nome de domnio example.com foi reservado para isso (see RFC 260664 ), sendo recomendado o seu uso em
documentaes como exemplos.
64 https://tools.ietf.org/html/rfc2606.html

110 Captulo 5. Contribuindo


CakePHP Cookbook Documentation, Release 3.next

Arquivos

Nomes de arquivos que no contm classes devem ser em caixa baixa e sublinhados, por exemplo:

long_file_name.php

Moldagem de tipos

Para moldagem usamos:


Tipo Descrio
(bool) Converte para boolean.
(int) Converte para integer.
(float) Converte para float.
(string) Converte para string.
(array) Converte para array.
(object) Converte para object.
Por favor use (int)$var ao invs de intval($var) e (float)$var ao invs de floatval($var) quando
aplicvel.

Constante

Constantes devem ser definidas em caixa alta:

define('CONSTANT', 1);

Se o nome de uma constante consiste de mltiplas palavras, eles devem ser separados por um underscore, por exemplo:

define('LONG_NAMED_CONSTANT', 2);

Cuidados usando empty()/isset()

Apesar de empty() ser uma funo simples de ser usada, pode mascarar erros e causar efeitos no intencionais
quando '0' e 0 so retornados. Quando variveis ou propriedades j esto definidas, o uso de empty() no
recomendado. Ao trabalhar com variveis, melhor confiar em coero de tipo com booleanos ao invs de empty():

function manipulate($var)
{
// No recomendado, $var j est definida no escopo
if (empty($var)) {
// ...
}

// Recomendado, use coero de tipo booleano


if (!$var) {
// ...
}
if ($var) {
// ...

Padres de codificao 111


CakePHP Cookbook Documentation, Release 3.next

}
}

Ao lidar com propriedades definidas, voc deve favorecer verificaes por null sobre verificaes por
empty()/isset():

class Thing
{
private $property; // Definida

public function readProperty()


{
// No recomendado j que a propriedade est definida na classe
if (!isset($this->property)) {
// ...
}
// Recomendado
if ($this->property === null) {

}
}
}

Ao trabalhar com arrays, melhor mesclar valores padronizados ao usar verificaes por empty(). Assim, voc se
assegura que as chaves necessrias esto definidas:

function doWork(array $array)


{
// Mescla valores para remover a necessidade de verificaes via empty.
$array += [
'key' => null,
];

// No recomendado, a chave j est definida


if (isset($array['key'])) {
// ...
}

// Recomendado
if ($array['key'] !== null) {
// ...
}
}

Guia de retrocompatibilidade

Garantir que voc possa atualizar suas aplicaes facilmente importante para ns. Por esse motivo, apenas quebramos
compatibilidade nos major releases. Voc deve estar familiarizado com versionamento semntico65 , orientao 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 no
podem quebrar retrocompatibilidades. Releases de correo de bugs (tais como 2.1.2, 3.0.1) no incluem novos
recursos, so destinados apenas correo de erros e melhora de desempenho.
65 http://semver.org/

112 Captulo 5. Contribuindo


CakePHP Cookbook Documentation, Release 3.next

Nota: O CakePHP comeou a seguir o versionamento semntico na verso 2.0.0. Essas regras no se aplicam s
verses 1.x.

Para esclarecer que mudanas voc pode esperar em cada ciclo de release, ns temos mais informaes detalhadas
para desenvolvedores usando o CakePHP, e para desenvolvedores trabalhando No CakePHP que ajudam a definir es-
pectativas do que pode ser feito em minor releases. Major releases podem ter tantas quebras quanto forem necessrias.

Guia de migrao

Para cada major ou minor releases, a equipe do CakePHP vai disponibilizar um guia de migrao. Esses guias
explicam os novos recursos e qualquer quebra de compatibilidade. Eles podem ser encontrados na seo Apndices do
manual.

Usando o CakePHP

Se voc est construindo sua aplicao com o CakePHP, as orientaes a seguir vo demonstrar a estabilidade que
voc pode esperar.

Interfaces

Com exceo dos major releases, interfaces oferecidas pelo CakePHP no iro ter alteraes em qualquer mtodo.
Novos mtodos podem ser includos, mas nenhum mtodo existente ser alterado.

Classes

Classes oferecidas pelo CakePHP podem ser construidas e ter seus mtodos pblicos e propriedades usados No
cdigo da aplicao e com exceo de major releases a retrocompatibilidade garantida.

Nota: Algumas classes No CakePHP so marcadas com a tag da documentao da API @internal. Essas classes
no so estveis e no tem garantias de retrocompatibilidade.

Em minor releases, novos mtodos podem ser adicionados a classes, e mtodos existentes podem passar a receber
novos argumentos. Qualquer novo argumento vai ter valores padres, mas se voc sobrescrever mtodos com uma
assinatura diferente, possvel que voc receba erros fatais. Mtodos que recebem novos argumentos sero documen-
tados No guia de migrao correspondente ao release.
A tabela a seguir descreve quais casos de uso e que tipo de compatibilidade voc pode esperar do CakePHP.

Guia de retrocompatibilidade 113


CakePHP Cookbook Documentation, Release 3.next

Se voc... Retrocompatibilidade?
Typehint referente classe Sim
Criar uma nova instncia Sim
Estender a classe Sim
Acessar uma propriedade pblica Sim
Chamar um mtodo pblico Sim
Estender uma classe e...
Sobrescrever uma propriedade pblica Sim
Acessar uma propriedade protegida No 1
Sobrescrever uma propriedade protegida No 1
Sobrescrever um mtodo No 1
Chamar um mtodo protegido No 1
Adicionar uma propriedade pblica No
Adicionar um mtodo pblico No
Adicionar um argumento a um mtodo sobrescrito No 1
Adicinar um valor padro a um argumento de mtodo existente Sim

Trabalhando no CakePHP

Se voc est ajudando a fazer o CakePHP ainda melhor, por favor, siga as orientaes a seguir quando estiver adicio-
nando/alterando funcionalidades:
Em um minor release voc pode:
Em um minor release voc pode...
Classes
Remover uma classe No
Remover uma interface No
Remover um trait No
Tornar final No
Tornar abstract No
Trocar o nome Sim 2
Properties
Adicionar uma propriedade pblica Sim
Remove a public property No
Adicionar uma propriedade protegida Sim
Remover uma propriedade protegida Sim 3
Mtodos
Adicionar um mtodo pblico Sim
Remover um mtodo pblico No
Adicionar um mtodo pblico Sim
Mover para uma classe parente Sim
Remover um mtodo protegido Sim 3
Reduzir visibilidade No
Mudar nome do mtodo Sim 2
Adicionar um novo argumento com valor padro Sim
Adicionar um novo argumento a um mtodo existente. No
Remover um valor padro de um argumento existente No

1 Seu cdigo pode ser quebrado por minor releases. Verifique o guia de migrao para mais detalhes.
2 Voc pode mudar o nome de uma classe/mtodo desde que o nome antigo permanea disponvel. Isso normalmente evitado, a no ser que a
renomeao traga algum benefcio significante.
3 Evite sempre que possvel. Qualquer remoo precisa ser documentada no guia de migrao.

114 Captulo 5. Contribuindo


CAPTULO 6

Instalao

O CakePHP rpido e fcil de instalar. Os requisitos mnimos so um servidor web e uma cpia do CakePHP, s
isso! Apesar deste manual focar principalmente na configurao do Apache (porqu ele o mais simples de instalar
e configurar), o CakePHP vai ser executado em uma srie de servidores web como nginx, LightHTTPD, ou Microsoft
IIS.

Requisitos

HTTP Server. Por exemplo: Apache. De preferncia com mod_rewrite ativo, mas no obrigatrio.
PHP 5.6.0 ou superior.
extenso mbstring
extenso intl

Nota: Tanto no XAMPP quanto no WAMP, as extenses mcrypt e mbstring so setadas por padro.
Se voc estiver usando o XAMPP, j tem a extenso intl inclusa, mas preciso descomentar a linha
extension=php_intl.dll no arquivo php.ini e ento, reiniciar o servidor atravs do painel de controle
do XAMPP.
Caso voc esteja usando o WAMP, a extenso intl est ativa por padro, mas no est funcional. Para
faz-la funcionar, voc deve ir pasta do php (que por padro ) C:\wamp\bin\php\php{version},
copiar todos os arquivos que se paream com icu***.dll e col-los no diretrio bin do apache
C:\wamp\bin\apache\apache{version}\bin. Reiniciando todos os servios a extenso j deve ficar ok.

Apesar de um mecanismo de banco de dados no ser exigido, ns imaginamos que a maioria das aplicaes ir utilizar
um. O CakePHP suporta uma variedade de mecanismos de armazenamento de banco de dados:
MySQL (5.1.10 ou superior)
PostgreSQL
Microsoft SQL Server (2008 ou superior)
SQLite 3

115
CakePHP Cookbook Documentation, Release 3.next

Nota: Todos os drivers inclusos internamente requerem PDO. Voc deve assegurar-se que possui a extenso PDO
correta instalada.

Instalando o CakePHP

O CakePHP utiliza Composer66 , uma ferramenta de gerenciamento de dependncias para PHP 5.3+, como o mtodo
suportado oficial para instalao.
Primeiramente, voc precisar baixar e instalar o Composer se no o fez anteriormente. Se voc tem cURL instalada,
to fcil quanto executar o seguinte:

curl -s https://getcomposer.org/installer | php

Ou, voc pode baixar composer.phar do Site oficial do Composer67 .


Para sistemas Windows, voc pode baixar o instalador aqui68 . Mais instrues para o instalador Windows do Composer
podem ser encontradas dentro do LEIA-ME aqui69 .
Agora que voc baixou e instalou o Composer, voc pode receber uma nova aplicao CakePHP executando:

php composer.phar create-project --prefer-dist cakephp/app [app_name]

Ou se o Composer estiver instalado globalmente:

composer create-project --prefer-dist cakephp/app [app_name]

Uma vez que o Composer terminar de baixar o esqueleto da aplicao e o ncleo da biblioteca CakePHP, voc deve ter
uma aplicao funcional instalada via Composer. Esteja certo de manter os arquivos composer.json e composer.lock
com o restante do seu cdigo fonte.
You can now visit the path to where you installed your CakePHP application and see the setup traffic lights.

Mantendo sincronizao com as ltimas alteraes no CakePHP

Se voc quer se manter atualizado com as ltimas mudanas no CakePHP, voc pode adicionar o seguinte ao
composer.json de sua aplicao:

"require": {
"cakephp/cakephp": "dev-master"
}

Onde <branch> o nome do branch que voc segue. Toda vez que voc executar php composer.phar
update voc receber as ltimas atualizaes do branch escolhido.
66 http://getcomposer.org
67 https://getcomposer.org/download/
68 https://github.com/composer/windows-setup/releases/
69 https://github.com/composer/windows-setup

116 Captulo 6. Instalao


CakePHP Cookbook Documentation, Release 3.next

Permisses

O CakePHP utiliza o diretrio tmp para diversas operaes. Descrio de models, views armazenadas em cache e
informaes de sesso so apenas alguns exemplos. O diretrio logs utilizado para escrever arquivos de log pelo
mecanismo padro FileLog.
Como tal, certifique-se que os diretrios logs, tmp e todos os seus sub-diretrios em sua instalao CakePHP so
gravveis pelo usurio relacionado ao servidor web. O processo de instalao do Composer faz tmp e seus sub-
diretrios globalmente gravveis para obter as coisas funcionando rapidamente, mas voc pode atualizar as permisses
para melhor segurana e mant-los gravveis apenas para o usurio relacionado ao servidor web.
Um problema comum que os diretrios e sub-diretrios de logs e tmp devem ser gravveis tanto pelo servidor
quanto pelo usurio da linha de comando. Em um sistema UNIX, se seu usurio relacionado ao servidor web
diferente do seu usurio da linha de comando, voc pode executar somente uma vez os seguintes comandos a partir do
diretrio da sua aplicao para assegurar que as permisses sero configuradas corretamente:

HTTPDUSER=`ps aux | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v


root | head -1 | cut -d\ -f1`
setfacl -R -m u:${HTTPDUSER}:rwx tmp
setfacl -R -d -m u:${HTTPDUSER}:rwx tmp
setfacl -R -m u:${HTTPDUSER}:rwx logs
setfacl -R -d -m u:${HTTPDUSER}:rwx logs

Servidor de Desenvolvimento

Uma instalao de desenvolvimento o mtodo mais rpido de configurar o CakePHP. Neste exemplo, ns vamos
utilizar o console CakePHP para executar o servidor integrado do PHP que vai tornar sua aplicao disponvel em
http://host:port. A partir do diretrio da aplicao, execute:

bin/cake server

Por padro, sem nenhum argumento fornecido, isso vai disponibilizar a sua aplicao em
http://localhost:8765/.
Se voc tem algo conflitante com localhost ou porta 8765, voc pode dizer ao console CakePHP para executar o
servidor web em um host e/ou porta especfica utilizando os seguintes argumentos:

bin/cake server -H 192.168.13.37 -p 5673

Isto ir disponibilizar sua aplicao em http://192.168.13.37:5673/.


isso a! Sua aplicao CakePHP est instalada e funcionando sem ter que configurar um servidor web.

Aviso: O servidor de desenvolvimento nunca deve ser usado em um ambiente de produo. Destina-se apenas
como um servidor de desenvolvimento bsico.

Se voc preferir usar um servidor web real, voc deve ser capaz de mover a instalao do CakePHP (incluindo os
arquivos ocultos) para dentro do diretrio raiz do seu servidor web. Voc deve, ento, ser capaz de apontar seu
navegador para o diretrio que voc moveu os arquivos para dentro e ver a aplicao em ao.

Permisses 117
CakePHP Cookbook Documentation, Release 3.next

Produo

Uma instalao de produo uma forma mais flexvel de configurar o CakePHP. Usar este mtodo permite total
domnio para agir como uma aplicao CakePHP singular. Este exemplo o ajudar a instalar o CakePHP em qualquer
lugar em seu sistema de arquivos e torn-lo disponvel em http://www.example.com. Note que esta instalao pode
exigir os direitos de alterar o DocumentRoot em servidores web Apache.
Depois de instalar a aplicao usando um dos mtodos acima no diretrio de sua escolha - vamos supor que voc
escolheu /cake_install - sua configurao de produo ser parecida com esta no sistema de arquivos:

/cake_install/
bin/
config/
logs/
plugins/
src/
tests/
tmp/
vendor/
webroot/ (esse diretrio definido como DocumentRoot)
.gitignore
.htaccess
.travis.yml
composer.json
index.php
phpunit.xml.dist
README.md

Desenvolvedores utilizando Apache devem definir a diretiva DocumentRoot pelo domnio para:

DocumentRoot /cake_install/webroot

Se o seu servidor web est configurado corretamente, agora voc deve encontrar sua aplicao CakePHP acessvel em
http://www.example.com.

Aquecendo

Tudo bem, vamos ver o CakePHP em ao. Dependendo de qual configurao voc usou, voc deve apontar seu
navegador para http://example.com/ ou http://localhost:8765/. Nesse ponto, voc ser apresentado pgina home
padro do CakePHP e uma mensagem que diz a voc o estado da sua conexo atual com o banco de dados.
Parabns! Voc est pronto para create your first CakePHP application.

Reescrita de URL

Apache

Apesar do CakePHP ser construdo para trabalhar com mod_rewrite fora da caixa, e normalmente o faz, nos atentamos
que alguns usurios lutam para conseguir fazer tudo funcionar bem em seus sistemas.
Aqui esto algumas coisas que voc poderia tentar para conseguir tudo rodando corretamente. Primeiramente ob-
serve seu httpd.conf. (Tenha certeza que voc est editando o httpd.conf do sistema ao invs de um usurio, ou site
especfico.)

118 Captulo 6. Instalao


CakePHP Cookbook Documentation, Release 3.next

Esses arquivos podem variar entre diferentes distribuies e verses do Apache. Voc tambm pode pesquisar em
http://wiki.apache.org/httpd/DistrosDefaultLayout para maiores informaes.
1. Tenha certeza que a sobreescrita do .htaccess est permitida e que AllowOverride est definido para All no
correto DocumentRoot. Voc deve ver algo similar a:

# Cada diretrio ao qual o Apache tenha acesso pode ser configurado com respeito
# a quais servios e recursos esto permitidos e/ou desabilitados neste
# diretrio (e seus sub-diretrios).
#
# Primeiro, ns configuramos o "default" para ser um conjunto bem restrito de
# recursos.
<Directory />
Options FollowSymLinks
AllowOverride All
# Order deny,allow
# Deny from all
</Directory>

2. Certifique-se que o mod_rewrite est sendo carregado corretamente. Voc deve ver algo como:

LoadModule rewrite_module libexec/apache2/mod_rewrite.so

Em muitos sistemas estar comentado por padro, ento voc pode apenas remover os smbolos #.
Depois de fazer as mudanas, reinicie o Apache para certificar-se que as configuraes esto ativas.
Verifique se os seus arquivos .htaccess esto realmente nos diretrios corretos. Alguns sistemas operacionais
tratam arquivos iniciados com . como ocultos e portanto, no os copia.
3. Certifique-se de sua cpia do CakePHP vir da seo de downloads do site ou do nosso repositrio Git, e que foi
descompactado corretamente, verificando os arquivos .htaccess.
O diretrio app do CakePHP (ser copiado para o diretrio mais alto de sua aplicao atravs do bake):

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>

O diretrio webroot do CakePHP (ser copiado para a raz de sua aplicao atravs do bake):

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

Se o seu site CakePHP ainda possuir problemas com mod_rewrite, voc pode tentar modificar as confi-
guraes para Virtual Hosts. No Ubuntu, edita o arquivo /etc/apache2/sites-available/default (a localizao
depende da distribuio). Nesse arquivo, certifique-se que AllowOverride None seja modificado para
AllowOverride All, ento voc ter:

<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www>

Reescrita de URL 119


CakePHP Cookbook Documentation, Release 3.next

Options Indexes FollowSymLinks MultiViews


AllowOverride All
Order Allow,Deny
Allow from all
</Directory>

No macOS, outra soluo usar a ferramenta virtualhostx70 para fazer um Virtual Host apontar para o seu
diretrio.
Para muitos servios de hospedagem (GoDaddy, land1), seu servidor web na verdade oferecido a partir de
um diretrio de usurio que j utiliza mod_rewrite. Se voc est instalando o CakePHP em um diretrio de
usurio (http://example.com/~username/cakephp/), ou qualquer outra estrutura URL que j utilize mod_rewrite,
voc precisar adicionar declaraes RewriteBase para os arquivos .htaccess que o CakePHP utiliza. (.htaccess,
webroot/.htaccess).
Isso pode ser adicionado na mesma seo com a diretiva RewriteEngine, por exemplo, seu arquivo we-
broot/.htaccess ficaria como:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/app
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

Os detalhes dessas mudanas vo depender da sua configurao, e podem incluir coisas adicionais que no esto
relacionadas ao CakePHP. Por favor, busque pela documentao online do Apache para mais informaes.
4. (Opcional) Para melhorar a configurao de produo, voc deve prevenir contedos invidos de serem analisa-
dos pelo CakePHP. Modifique seu webroot/.htaccess para algo como:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /path/to/app/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/(webroot/)?(img|css|js)/(.*)$
RewriteRule ^ index.php [L]
</IfModule>

Isto ir simplesmente prevenir contedo incorreto de ser enviado para o index.php e ento exibir sua pgina de
erro 404 do servidor web.
Adicionalmente voc pode criar uma pgina HTML de erro 404 correspondente, ou utilizar a padro do Ca-
kePHP ao adicionar uma diretiva ErrorDocument:

ErrorDocument 404 /404-not-found

nginx

nginx no utiliza arquivos .htaccess como o Apache, ento necessrio criar as reescritas de URL na configurao de
sites disponveis. Dependendo da sua configurao, voc precisar modificar isso, mas pelo menos, voc vai precisar
do PHP rodando como uma instncia FastCGI:

70 http://clickontyler.com/virtualhostx/

120 Captulo 6. Instalao


CakePHP Cookbook Documentation, Release 3.next

server {
listen 80;
server_name www.example.com;
rewrite ^(.*) http://example.com$1 permanent;
}

server {
listen 80;
server_name example.com;

# root directive should be global


root /var/www/example.com/public/webroot/;
index index.php;

access_log /var/www/example.com/log/access.log;
error_log /var/www/example.com/log/error.log;

location / {
try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}

IIS7 (Windows hosts)

IIS7 no suporta nativamente arquivos .htaccess. Mesmo existindo add-ons que adicionam esse suporte, voc tambm
pode importar as regras .htaccess no IIS para utilizar as reescritas nativas do CakePHP. Para isso, siga os seguintes
passos:
1. Utilize o Microsofts Web Platform Installer71 para instalar o Rewrite Module 2.072 ou baixe-o diretamente
(32-bit73 / 64-bit74 ).
2. Crie um novo arquivo chamado web.config em seu diretrio raiz do CakePHP.
3. Utilize o Notepad ou qualquer editor seguro XML para copiar o seguinte cdigo em seu novo arquivo
web.config:

<?xml version="1.0" encoding="UTF-8"?>


<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="Exclude direct access to webroot/*"
stopProcessing="true">
<match url="^webroot/(.*)$" ignoreCase="false" />
<action type="None" />

71 http://www.microsoft.com/web/downloads/platform.aspx
72 http://www.iis.net/downloads/microsoft/url-rewrite
73 http://www.microsoft.com/en-us/download/details.aspx?id=5747
74 http://www.microsoft.com/en-us/download/details.aspx?id=7435

Reescrita de URL 121


CakePHP Cookbook Documentation, Release 3.next

</rule>
<rule name="Rewrite routed access to assets(img, css, files, js,
favicon)"

stopProcessing="true">
<match url="^(img|css|files|js|favicon.ico)(.*)$" />
<action type="Rewrite" url="webroot/{R:1}{R:2}"
appendQueryString="false" />
</rule>
<rule name="Rewrite requested file/folder to index.php"
stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<action type="Rewrite" url="index.php"
appendQueryString="true" />
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>

Uma vez que o arquivo web.config criado com as regras amigveis de reescrita do IIS, os links, CSS, JavaScript, e
roteamento do CakePHP agora devem funcionar corretamente.

No posso utilizar Reescrita de URL

Se voc no quer ou no pode ter mod_rewrite (ou algum outro mdulo compatvel) funcionando no seu servidor,
voc precisar utilizar as URLs amigveis natvas do CakePHP. No config/app.php, descomente a linha que se parece
como:

'App' => [
// ...
// 'baseUrl' => env('SCRIPT_NAME'),
]

Tambm remova esses arquivos .htaccess:

/.htaccess
webroot/.htaccess

Isso far suas URLs parecem como www.example.com/index.php/controllername/actionname/param ao invs de


www.example.com/controllername/actionname/param.

122 Captulo 6. Instalao


CAPTULO 7

Configurao

Embora as convenes eliminem a necessidade de configurar todo o CakePHP, Voc ainda precisar configurar algu-
mas coisas, como suas credenciais de banco de dados por exemplo.
Alm disso, h opes de configurao opcionais que permitem trocar valores padro e implementaes com as per-
sonalizadas para seu aplicativo.

Configurando sua Aplicao

A configurao geralmente armazenada em arquivos PHP ou INI, e carregada durante a execuo do cdigo de inici-
alizao. O CakePHP vem com um arquivo de configurao por padro. Mas se necessrio, voc pode adicionar arqui-
vos de configurao adicionais e carreg-los no cdigo de inicializao do aplicativo. Cake\Core\Configure
usado para configurao global, e classes como Cache providenciam config() mtodos para tornar a configurao
simples e transparente.

Carregando Arquivos de Configuraes Adicionais

Se sua aplicao tiver muitas opes de configurao, pode ser til dividir a configurao em vrios arquivos. Depois
de criar cada um dos arquivos no seu config/ diretrio, voc pode carreg-los em bootstrap.php:

use Cake\Core\Configure;
use Cake\Core\Configure\Engine\PhpConfig;

Configure::config('default', new PhpConfig());


Configure::load('app', 'default', false);
Configure::load('other_config', 'default');

Voc tambm pode usar arquivos de configurao adicionais para fornecer sobreposies especficas do ambiente.
Cada arquivo carregado aps app.php pode redefinir valores previamente declarados permitindo que voc personalize
a configurao para ambientes de desenvolvimento ou de homologao.

Configurao Geral

Abaixo est uma descrio das variveis e como elas afetam seu aplicativo CakePHP.

123
CakePHP Cookbook Documentation, Release 3.next

debug Altera a sada de depurao do CakePHP. false = Modo Produo. No exibido nenhuma mensagem de
erro e/ou aviso. true = Modo de Desenvolvimento. exibido todas as mensagens de erros e/ou avisos.
App.namespace O namespace em que as classes do aplicativo esto.

Nota: Ao alterar o namespace em sua configurao, voc tambm precisar atualizar o arquivo ** compo-
ser.json ** para usar esse namespace tambm. Alm disso, crie um novo carregador automtico executando
php composer.phar dumpautoload.

App.baseUrl No comentar esta definio se voc no planeja usar o mod_rewrite do Apache com o CakePHP. No
se esquea de remover seus arquivos .htaccess tambm.
App.base O diretrio base no qual o aplicativo reside. Se false isso ser detectado automaticamente. Se no
false, certifique-se de que sua seqncia de caracteres comea com um / e NO termina com um /. Por exem-
plo, /basedir deve ser uma App.base vlida. Caso contrrio, o AuthComponent no funcionar corretamente.
App.encoding Defina a codificao que seu aplicativo usa. Essa codificao usada para gerar o charset no layout e
codificar entidades. Ele deve corresponder aos valores de codificao especificados para o seu banco de dados.
App.webroot O diretrio raiz da aplicao web.
App.wwwRoot O diretrio raiz dos arquivos da aplicao web.
App.fullBaseUrl O nome de domnio totalmente qualificado (incluindo o protocolo) para a raiz do aplicativo. Isso
usado ao gerar URLs absolutos. Por padro, esse valor gerado usando a varivel $_SERVER. Entretanto,
Voc deve defini-lo manualmente para otimizar o desempenho ou se voc est preocupado com as pessoas
manipulando o cabealho do Host. Em um contexto CLI (do Shell) a fullBaseUrl no pode ser lido a partir de
$_SERVER, como no h servidor envolvido. Voc precisar especific-lo se precisar gerar URLs de um shell
(por exemplo, ao enviar e-mails).
App.imageBaseUrl O caminho da web para as imagens pblicas na webroot da aplicao. Se voc estiver usando
um CDN, voc deve definir este valor para a localizao do CDN.
App.cssBaseUrl O caminho da web para os arquivos de estilos em cascata(.css) pblicos na webroot da aplicao.
Se voc estiver usando um CDN, voc deve definir este valor para a localizao do CDN.
App.jsBaseUrl O caminho da web para os scripts (em JavaScript) pblicos na webroot da aplicao. Se voc estiver
usando um CDN, voc deve definir este valor para a localizao do CDN.
App.paths Configurar caminhos para recursos no baseados em classe. Suporta as subchaves plugins,
templates, locales, que permitem a definio de caminhos para plugins, templates e arquivos de locale
respectivamente.
Security.salt Uma seqncia aleatria usada em hash. Uma seqncia aleatria usada em hash. Este valor tambm
usado como o sal HMAC ao fazer criptografia simtrica.
Asset.timestamp Acrescenta um carimbo de data/hora que a ltima hora modificada do arquivo especfico no final
dos URLs de arquivos de recurso (CSS, JavaScript, Image) ao usar assistentes adequados. Valores vlidos:
(bool) false - No fazer nada (padro)
(bool) true - Acrescenta o carimbo de data/hora quando depurao true
(string) force - Sempre anexa o carimbo de data/hora.

Configurao do banco de dados

Consulte Database Configuration para obter informaes sobre como configurar suas conexes de banco de dados.

124 Captulo 7. Configurao


CakePHP Cookbook Documentation, Release 3.next

Configurao do Cache

Consulte Caching Configuration para obter informaes sobre como configurar o cache no CakePHP.

Configurao de manipulao de erro e exceo

Consulte Error and Exception Configuration para obter informaes sobre como configurar manipuladores de erro e
exceo.

Configurao de log

Consulte Logging Configuration para obter informaes sobre como configurar o log no CakePHP.

Configurao de e-mail

Consulte Email Configuration para obter informaes sobre como configurar predefinies de e-mail no CakePHP.

Configurao de sesso

Consulte Session Configuration para obter informaes sobre como configurar o tratamento de sesso no CakePHP.

Configurao de roteamento

Consulte Routes Configuration para obter mais informaes sobre como configurar o roteamento e criar rotas para seu
aplicativo.

Caminhos adicionais de classe

Caminhos de classe adicionais so configurados atravs dos carregadores automticos usados pelo aplicativo. Ao usar
o Composer para gerar o seu arquivo de autoload, voc pode fazer o seguinte, para fornecer caminhos alternativos
para controladores em seu aplicativo:

"autoload": {
"psr-4": {
"App\\Controller\\": "/path/to/directory/with/controller/folders",
"App\": "src"
}
}

O cdigo acima seria configurar caminhos para o namespace App e App\Controller. A primeira chave ser
pesquisada e, se esse caminho no contiver a classe/arquivo, a segunda chave ser pesquisada. Voc tambm pode
mapear um namespace nico para vrios diretrios com o seguinte cdigo:

"autoload": {
"psr-4": {
"App\": ["src", "/path/to/directory"]
}
}

Caminhos adicionais de classe 125


CakePHP Cookbook Documentation, Release 3.next

Plugin, Modelos de Visualizao e Caminhos Locais

Como os plug-ins, os modelos de visualizao (Templates) e os caminhos locais (locales) no so classes, eles no
podem ter um autoloader configurado. O CakePHP fornece trs variveis de configurao para configurar caminhos
adicionais para esses recursos. No config/app.php voc pode definir estas variveis

return [
// More configuration
'App' => [
'paths' => [
'plugins' => [
ROOT . DS . 'plugins' . DS,
'/path/to/other/plugins/'
],
'templates' => [
APP . 'Template' . DS,
APP . 'Template2' . DS
],
'locales' => [
APP . 'Locale' . DS
]
]
]
];

Caminhos devem terminar com um separador de diretrio, ou eles no funcionaro corretamente.

Configurao de Inflexo

Consulte Configurao da inflexo para obter mais informaes sobre como fazer a configurao de inflexo.

Configurar classe

class Cake\Core\Configure
A classe de Configurao do CakePHP pode ser usada para armazenar e recuperar valores especficos do aplicativo
ou do tempo de execuo. Tenha cuidado, pois essa classe permite que voc armazene qualquer coisa nela, para que
em seguida, us-la em qualquer outra parte do seu cdigo: Dando ma certa tentao de quebrar o padro MVC do
CakePHP. O objetivo principal da classe Configurar manter variveis centralizadas que podem ser compartilhadas
entre muitos objetos. Lembre-se de tentar viver por conveno sobre a configurao e voc no vai acabar quebrando
a estrutura MVC previamente definida.
Voc pode acessar o Configure de qualquer lugar de seu aplicativo:

Configure::read('debug');

Escrevendo dados de configurao

static Cake\Core\Configure::write($key, $value)


Use write() para armazenar dados na configurao do aplicativo:

126 Captulo 7. Configurao


CakePHP Cookbook Documentation, Release 3.next

Configure::write('Company.name', 'Pizza, Inc.');


Configure::write('Company.slogan','Pizza for your body and soul');

Nota: O dot notation usado no parmetro $key pode ser usado para organizar suas configuraes em grupos lgicos.

O exemplo acima tambm pode ser escrito em uma nica chamada:

Configure::write('Company', [
'name' => 'Pizza, Inc.',
'slogan' => 'Pizza for your body and soul'
]);

Voc pode usar Configure::write('debug',$bool) para alternar entre os modos de depurao e produo
na mosca. Isso especialmente til para interaes JSON onde informaes de depurao podem causar problemas
de anlise.

Leitura de dados de configurao

static Cake\Core\Configure::read($key = null)


Usado para ler dados de configurao da aplicao. Por padro o valor de depurao do CakePHP importante. Se
for fornecida uma chave, os dados so retornados. Usando nossos exemplos de write() acima, podemos ler os dados
de volta:

Configure::read('Company.name'); // Yields: 'Pizza, Inc.'


Configure::read('Company.slogan'); // Yields: 'Pizza for your body
// and soul'

Configure::read('Company');

//Rendimentos:
['name' => 'Pizza, Inc.', 'slogan' => 'Pizza for your body and soul'];

Se $key for deixada nula, todos os valores em Configure sero retornados.


static Cake\Core\Configure::readOrFail($key)
L dados de configurao como Cake\Core\Configure::read, mas espera encontrar um par chave/valor. Caso
o par solicitado no exista, a RuntimeException ser lanada:

Configure::readOrFail('Company.name'); // Rendimentos: 'Pizza, Inc.'


Configure::readOrFail('Company.geolocation'); // Vai lanar uma exceo

Configure::readOrFail('Company');

// Rendimentos:
['name' => 'Pizza, Inc.', 'slogan' => 'Pizza for your body and soul'];

Novo na verso 3.1.7: Configure::readOrFail() Foi adicionado na verso 3.1.7

Verificar se os dados de configurao esto definidos

static Cake\Core\Configure::check($key)

Configurar classe 127


CakePHP Cookbook Documentation, Release 3.next

Usado para verificar se uma chave/caminho existe e tem valor no nulo:

$exists = Configure::check('Company.name');

Excluindo Dados de Configurao

static Cake\Core\Configure::delete($key)
Usado para excluir informaes da configurao da aplicao:

Configure::delete('Company.name');

Leitura e excluso de dados de configurao

static Cake\Core\Configure::consume($key)
Ler e excluir uma chave do Configure. Isso til quando voc deseja combinar leitura e excluso de valores em uma
nica operao.

Lendo e escreveendo arquivos de configurao

static Cake\Core\Configure::config($name, $engine)


O CakePHP vem com dois mecanismos de arquivos de configurao embutidos.
Cake\Core\Configure\Engine\PhpConfig capaz de ler arquivos de configurao do PHP, no mesmo
formato que o Configure tem lido historicamente. Cake\Core\Configure\Engine\IniConfig capaz de
ler os arquivos de configurao no formato ini(.ini). Consulte a documentao do PHP75 para obter mais informaes
sobre os detalhes dos arquivos ini. Para usar um mecanismo de configurao do ncleo, voc precisar conect-lo ao
Configure usando Configure::config():

use Cake\Core\Configure\Engine\PhpConfig;

// Ler os arquivos de configurao da configurao


Configure::config('default', new PhpConfig());

// Ler arquivos de configurao de outro diretrio.


Configure::config('default', new PhpConfig('/path/to/your/config/files/'));

Voc pode ter vrios mecanismos anexados para Configure, cada um lendo diferentes tipos ou fontes de arquivos de
configurao. Voc pode interagir com os motores conectados usando alguns outros mtodos em Configure. Para
verificar quais aliases de motor esto conectados voc pode usar Configure::configured():

// Obter a matriz de aliases para os motores conectados.


Configure::configured();

// Verificar se um motor especfico est ligado.


Configure::configured('default');

static Cake\Core\Configure::drop($name)
Voc tambm pode remover os motores conectados. Configure::drop('default') removeria o alias de me-
canismo padro. Quaisquer tentativas futuras de carregar arquivos de configurao com esse mecanismo falhariam:
75 http://php.net/parse_ini_file

128 Captulo 7. Configurao


CakePHP Cookbook Documentation, Release 3.next

Configure::drop('default');

Carregando arquivos de configuraes

static Cake\Core\Configure::load($key, $config = default, $merge = true)


Depois de ter anexado um motor de configurao para o Configure, ficar disponvel para poder carregar ficheiros de
configurao:

// Load my_file.php using the 'default' engine object.


Configure::load('my_file', 'default');

Os arquivos de configurao que foram carregados mesclam seus dados com a configurao de tempo de execuo
existente no Configure. Isso permite que voc sobrescreva e adicione novos valores configurao de tempo de
execuo existente. Ao definir $merge para true, os valores nunca substituiro a configurao existente.

Criando ou modificando arquivos de configurao

static Cake\Core\Configure::dump($key, $config = default, $keys = [])


Despeja todos ou alguns dos dados que esto no Configure em um sistema de arquivos ou armazenamento suportado
por um motor de configurao. O formato de serializao decidido pelo mecanismo de configurao anexado como
$config. Por exemplo, se o mecanismo padro Cake\Core\Configure\Engine\PhpConfig, o arquivo
gerado ser um arquivo de configurao PHP carregvel pelo Cake\Core\Configure\Engine\PhpConfig
Dado que o motor default uma instncia do PhpConfig. Salve todos os dados em Configure no arquivo
my_config.php:

Configure::dump('my_config', 'default');

Salvar somente a configurao de manipulao de erro:

Configure::dump('error', 'default', ['Error', 'Exception']);

Configure::dump() pode ser usado para modificar ou substituir arquivos de configurao que so legveis com
Configure::load()

Armazenando Configurao do Tempo de Execuo

static Cake\Core\Configure::store($name, $cacheConfig = default, $data = null)


Voc tambm pode armazenar valores de configurao de tempo de execuo para uso em uma solicitao futura.
Como o configure s lembra valores para a solicitao atual, voc precisar armazenar qualquer informao de confi-
gurao modificada se voc quiser us-la em solicitaes futuras:

// Armazena a configurao atual na chave 'user_1234' no cache 'default'.


Configure::store('user_1234', 'default');

Os dados de configurao armazenados so mantidos na configurao de cache nomeada. Consulte a documentao


Caching para obter mais informaes sobre o cache.

Lendo e escreveendo arquivos de configurao 129


CakePHP Cookbook Documentation, Release 3.next

Restaurando a Configurao do Tempo de Execuo

static Cake\Core\Configure::restore($name, $cacheConfig = default)


Depois de ter armazenado a configurao de tempo de execuo, voc provavelmente precisar restaur-la para que
voc possa acess-la novamente. Configure::restore() faz exatamente isso:
// Restaura a configurao do tempo de execuo do cache.
Configure::restore('user_1234', 'default');

Ao restaurar informaes de configurao, importante restaur-lo com a mesma chave e configurao de cache
usada para armazen-lo. As informaes restauradas so mescladas em cima da configurao de tempo de execuo
existente.

Criando seus prprios mecanismos de configurao

Como os mecanismos de configurao so uma parte extensvel do CakePHP, voc pode criar meca-
nismos de configurao em seu aplicativo e plugins. Os motores de configurao precisam de uma
Cake\Core\Configure\ConfigEngineInterface. Esta interface define um mtodo de leitura, como o
nico mtodo necessrio. Se voc gosta de arquivos XML, voc pode criar um motor de XML de configurao sim-
ples para sua aplicao:
// Em src/Configure/Engine/XmlConfig.php
namespace App\Configure\Engine;

use Cake\Core\Configure\ConfigEngineInterface;
use Cake\Utility\Xml;

class XmlConfig implements ConfigEngineInterface


{

public function __construct($path = null)


{
if (!$path) {
$path = CONFIG;
}
$this->_path = $path;
}

public function read($key)


{
$xml = Xml::build($this->_path . $key . '.xml');
return Xml::toArray($xml);
}

public function dump($key, array $data)


{
// Code to dump data to file
}
}

No seu config/bootstrap.php voc poderia anexar este mecanismo e us-lo:


use App\Configure\Engine\XmlConfig;

Configure::config('xml', new XmlConfig());

130 Captulo 7. Configurao


CakePHP Cookbook Documentation, Release 3.next

...

Configure::load('my_xml', 'xml');

O mtodo read() de um mecanismo de configurao, deve retornar uma matriz das informaes de configurao
que o recurso chamado $key contm.
interface Cake\Core\Configure\ConfigEngineInterface
Define a interface usada pelas classes que lem dados de configurao e armazenam-no em Configure
Cake\Core\Configure\ConfigEngineInterface::read($key)
Parmetros
$key (string) O nome da chave ou identificador a carregar.
Esse mtodo deve carregar/analisar os dados de configurao identificados pelo $key e retornar uma matriz de
dados no arquivo.
Cake\Core\Configure\ConfigEngineInterface::dump($key)
Parmetros
$key (string) O identificador para escrever.
$data (array) Os dados para despejo.
Esse mtodo deve despejar/armazenar os dados de configurao fornecidos para uma chave identificada pelo
$key.

Motores de Configurao Integrados

Arquivos de configurao do PHP

class Cake\Core\Configure\Engine\PhpConfig
Permite ler arquivos de configurao que so armazenados como arquivos simples do PHP. Voc pode ler arquivos
da configurao do aplicativo ou do plugin configs diretrios usando sintaxe plugin. Arquivos devem retornar uma
matriz. Um exemplo de arquivo de configurao seria semelhante a:

return [
'debug' => 0,
'Security' => [
'salt' => 'its-secret'
],
'App' => [
'namespace' => 'App'
]
];

Carregue seu arquivo de configurao personalizado inserindo o seguinte em config/bootstrap.php:

Configure::load('customConfig');

Arquivos de configurao Ini

class Cake\Core\Configure\Engine\IniConfig

Motores de Configurao Integrados 131


CakePHP Cookbook Documentation, Release 3.next

Permite ler arquivos de configurao armazenados como arquivos .ini simples. Os arquivos ini devem ser compatveis
com a funo parse_ini_file() do php e beneficiar das seguintes melhorias.
Os valores separados por ponto so expandidos em arrays.
Valores booleanos como on e off so convertidos em booleanos.
Um exemplo de arquivo ini seria semelhante a:

debug = 0

[Security]
salt = its-secret

[App]
namespace = App

O arquivo ini acima, resultaria nos mesmos dados de configurao final do exemplo PHP acima. As estruturas de
matriz podem ser criadas atravs de valores separados por pontos ou por sees. As sees podem conter chaves
separadas por pontos para um assentamento mais profundo.

Arquivos de configurao do Json

class Cake\Core\Configure\Engine\JsonConfig
Permite ler/descarregar arquivos de configurao armazenados como cadeias codificadas JSON em arquivos .json.
Um exemplo de arquivo JSON seria semelhante a:

{
"debug": false,
"App": {
"namespace": "MyApp"
},
"Security": {
"salt": "its-secret"
}
}

Bootstrapping CakePHP

Se voc tiver alguma necessidade de configurao adicional, adicione-a ao arquivo config/bootstrap.php do seu apli-
cativo. Este arquivo includo antes de cada solicitao, e o comando CLI.
Este arquivo ideal para vrias tarefas de bootstrapping comuns:
Definir funes de convenincia.
Declarao de constantes.
Definio da configurao do cache.
Definio da configurao de log.
Carregando inflexes personalizadas.
Carregando arquivos de configurao.

132 Captulo 7. Configurao


CakePHP Cookbook Documentation, Release 3.next

Pode ser tentador para colocar as funes de formatao l, a fim de us-los em seus controladores. Como voc ver
nas sees Controllers (Controladores) e Views (Visualizao) h melhores maneiras de adicionar lgica personalizada
sua aplicao.

Application::bootstrap()

Alm do arquivo config/bootstrap.php que deve ser usado para configurar preocupaes de baixo nvel do seu aplica-
tivo, voc tambm pode usar o mtodo Application::bootstrap() para carregar/inicializar plugins, E anexar
ouvintes de eventos globais:

// Em src/Application.php
namespace App;

use Cake\Core\Plugin;
use Cake\Http\BaseApplication;

class Application extends BaseApplication


{
public function bootstrap()
{
// Chamar o pai para `require_once` config/bootstrap.php
parent::bootstrap();

Plugin::load('MyPlugin', ['bootstrap' => true, 'routes' => true]);


}
}

Carregar plugins/eventos em Application::bootstrap() torna Controller Integration Testing mais fcil


medida que os eventos e rotas sero re-processados em cada mtodo de teste.

Variveis de Ambiente

Alguns dos provedores modernos de nuvem, como o Heroku, permitem definir variveis de ambiente. Ao definir
variveis de ambiente, voc pode configurar seu aplicativo CakePHP como um aplicativo 12factor. Seguir as instrues
do aplicativo 12factor app instructions76 uma boa maneira de criar um app sem estado e facilitar a implantao do
seu plicativo. Isso significa, por exemplo, que, se voc precisar alterar seu banco de dados, voc precisar modificar
uma arivel DATABASE_URL na sua configurao de host sem a necessidade de alter-la em seu cdigo-fonte.
Como voc pode ver no seu app.php, as seguintes variveis esto em uso:
DEBUG (0 ou1)
APP_ENCODING (ie UTF-8)
APP_DEFAULT_LOCALE (ie en_US)
SECURITY_SALT
CACHE_DEFAULT_URL (ie File:///?prefix=myapp_&serialize=true&timeout=3600&path=../tmp/cach
CACHE_CAKECORE_URL (ie File:///?prefix=myapp_cake_core_&serialize=true&timeout=3600&path=
CACHE_CAKEMODEL_URL (ie File:///?prefix=myapp_cake_model_&serialize=true&timeout=3600&pat
EMAIL_TRANSPORT_DEFAULT_URL (ie smtp://user:password@hostname:port?tls=null&client=null&t
76 http://12factor.net/

Variveis de Ambiente 133


CakePHP Cookbook Documentation, Release 3.next

DATABASE_URL (ie mysql://user:pass@db/my_app)


DATABASE_TEST_URL (ie mysql://user:pass@db/test_my_app)
LOG_DEBUG_URL (ie file:///?levels[]=notice&levels[]=info&levels[]=debug&file=debug&path=.
LOG_ERROR_URL (ie file:///?levels[]=warning&levels[]=error&levels[]=critical&levels[]=ale
Como voc pode ver nos exemplos, definimos algumas opes de configurao como DSN. Este o caso de bancos
de dados, logs, transporte de e-mail e configuraes de cache.
Se as variveis de ambiente no estiverem definidas no seu ambiente, o CakePHP usar os valores definidos no
app.php. Voc pode usar a biblioteca php-dotenv library77 para usar variveis de ambiente em um desenvolvimento
local. Consulte as instrues Leiame da biblioteca para obter mais informaes.

Desabilitando tabelas genricas

Embora a utilizao de classes de tabela genricas - tambm chamadas auto-tables - quando a criao rpida de novos
aplicativos e modelos de cozimento til, a classe de tabela genrica pode tornar a depurao mais difcil em alguns
cenrios.
Voc pode verificar se qualquer consulta foi emitida de uma classe de tabela genrica via DebugKit atravs do painel
SQL no DebugKit. Se voc ainda tiver problemas para diagnosticar um problema que pode ser causado por tabelas
automticas, voc pode lanar uma exceo quando o CakePHP implcitamente usa um Cake\ORM\Table genrico
em vez de sua classe concreta assim:

// No seu bootstrap.php
use Cake\Event\EventManager;
use Cake\Network\Exception\InternalErrorException;

$isCakeBakeShellRunning = (PHP_SAPI === 'cli' && isset($argv[1]) && $argv[1] === 'bake
');

if (!$isCakeBakeShellRunning) {
EventManager::instance()->on('Model.initialize', function($event) {
$subject = $event->getSubject();
if (get_class($subject === 'Cake\ORM\Table') {
$msg = sprintf(
'Missing table class or incorrect alias when registering table class
for database table %s.',

$subject->getTable());
throw new InternalErrorException($msg);
}
});
}

77 https://github.com/josegonzalez/php-dotenv

134 Captulo 7. Configurao


CAPTULO 8

Roteamento

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github78 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Connecting Routes

Using Named Routes

Filtros do Dispatcher

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github79 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

78 https://github.com/cakephp/docs
79 https://github.com/cakephp/docs

135
CakePHP Cookbook Documentation, Release 3.next

136 Captulo 8. Roteamento


CAPTULO 9

Objetos de requisio e resposta

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github80 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Requisio

Enviando Arquivos

80 https://github.com/cakephp/docs

137
CakePHP Cookbook Documentation, Release 3.next

138 Captulo 9. Objetos de requisio e resposta


CAPTULO 10

Controllers (Controladores)

class Cake\Controller\Controller
Os controllers (controladores) correspondem ao C no padro MVC. Aps o roteamento ter sido aplicado e o controller
correto encontrado, a ao do controller chamada. Seu controller deve lidar com a interpretao dos dados de
uma requisio, certificando-se que os models corretos so chamados e a resposta ou view esperada seja exibida.
Os controllers podem ser vistos como intermedirios entre a camada Model e View. Voc vai querer manter seus
controllers magros e seus Models gordos. Isso lhe ajudar a reutilizar seu cdigo e test-los mais facilmente.
Mais comumente, controllers so usados para gerenciar a lgica 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 so nome-
ados de acordo com o model que manipulam. tambm absolutamente possvel ter controllers que usam mais de um
model.
Os controllers da sua aplicao so classes que estendem a classe AppController, a qual por sua vez estende a
classe do core Controller. A classe AppController pode ser definida em src/Controller/AppController.php
e deve conter mtodos que so compartilhados entre todos os controllers de sua aplicao.
Os controllers fornecem uma srie de mtodos que lidam com requisies. Estas so chamados de actions. Por padro,
todos os mtodos pblicos em um controller so uma action e acessveis por uma URL. Uma action responsvel por
interpretar a requisio e criar a resposta. Normalmente as respostas so na forma de uma view renderizada, mas
tambm existem outras formas de criar respostas.

O App Controller

Como mencionado anteriormente, a classe AppController a me de todos os outros controllers da sua aplica-
o. A prpria AppController estendida da classe Cake\Controller\Controller includa no CakePHP.
Assim sendo, AppController definida em src/Controller/AppController.php como a seguir:

namespace App\Controller;

use Cake\Controller\Controller;

class AppController extends Controller


{
}

139
CakePHP Cookbook Documentation, Release 3.next

Os atributos e mtodos criados em seu AppController vo estar disponveis para todos os controllers que a ex-
tendam. Components (sobre os quais voc ir aprender mais tarde) so a melhor alternativa para cdigos usados por
muitos (mas no necessariamente em todos) controllers.
Voc pode usar seu AppController para carregar components que sero usados em cada controller de sua aplica-
o. O CakePHP oferece um mtodo initialize() que invocado ao final do construtor do controller para esse
tipo de uso:

namespace App\Controller;

use Cake\Controller\Controller;

class AppController extends Controller


{

public function initialize()


{
// Sempre habilite o CSRF component.
$this->loadComponent('Csrf');
}

Em adio ao mtodo initialize(), a antiga propriedade $components tambm vai permitir voc declarar
quais components devem ser carregados. Enquanto heranas objeto-orientadas normais so enquadradas, os com-
ponents e helpers usados por um controller so especialmente tratados. Nestes casos, os valores de propriedade do
AppController so mesclados com arrays de classes controller filhas. Os valores na classe filha iro sempre
sobre-escrever aqueles na AppController.

Fluxo de requisies

Quando uma requisio feita para uma aplicao CakePHP, a classe Cake\Routing\Router e a classe
Cake\Routing\Dispatcher usam Connecting Routes para encontrar e criar a instncia correta do controller.
Os dados da requisio so encapsulados em um objeto de requisio. O CakePHP coloca todas as informaes im-
portantes de uma requisio na propriedade $this->request. Veja a seo Requisio para mais informaes
sobre o objeto de requisio do CakePHP.

Mtodos (actions) de controllers

Actions de controllers so responsveis por converter os parmetros de requisio em uma resposta para o navega-
dor/usurio que fez a requisio. O CakePHP usa convenes para automatizar este processo e remove alguns cdigos
clichs que voc teria que escrever de qualquer forma.
Por conveno, o CakePHP renderiza uma view com uma verso 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:

// src/Controller/RecipesController.php

class RecipesController extends AppController


{
function view($id)
{

140 Captulo 10. Controllers (Controladores)


CakePHP Cookbook Documentation, Release 3.next

// A lgica da action vai aqui.


}

function share($customerId, $recipeId)


{
// A lgica da action vai aqui.
}

function search($query)
{
// A lgica da action vai aqui.
}
}

Os arquivos de template para estas actions seriam src/Template/Recipes/view.ctp, src/Template/Recipes/share.ctp


e src/Template/Recipes/search.ctp. A nomenclatura convencional para arquivos view a verso lowercased (mins-
cula) e underscored (sem sublinhado) do nome da action.
Actions dos controllers geralmente usam Controller::set() para criar um contexto que a View usa para ren-
derizar a camada view. Devido s convenes que o CakePHP usa, voc no precisa criar e renderizar as views
manualmente. Ao invs, uma vez que uma action de controller completada, o CakePHP ir manipular a renderizao
e devolver a view.
Se por alguma razo voc quiser pular o comportamento padro, voc pode retornar um objeto
Cake\Network\Response a partir da action com a resposta definida.
Para que voc possa utilizar um controller de forma eficiente em sua prpria aplicao, ns iremos cobrir alguns dos
atributos e mtodos oferecidos pelo controller do core do CakePHP.

Interagindo com views

Os controllers interagem com as views de diversas maneiras. Primeiro eles so capazes de passar dados para as views
usando Controller::set(). Voc tambm pode decidir no seu controller qual arquivo view deve ser renderizado
atravs do controller.

Definindo variveis para a view

Cake\Controller\Controller::set(string $var, mixed $value)


O mtodo Controller::set() a principal maneira de enviar dados do seu controller para a sua view. Aps ter
usado o mtodo Controller::set(), a varivel pode ser acessada em sua view:

// Primeiro voc passa os dados do controller:

$this->set('color', 'pink');

// Ento, na view, voc pode utilizar os dados:


?>

Voc selecionou a cobertura <?php echo $color; ?> para o bolo.

O mtodo Controller::set() tambm aceita um array associativo como primeiro parmetro. Isto pode oferecer
uma forma rpida para atribuir uma srie de informaes para a view:

Mtodos (actions) de controllers 141


CakePHP Cookbook Documentation, Release 3.next

$data = [
'color' => 'pink',
'type' => 'sugar',
'base_price' => 23.95
];

// Faa $color, $type, e $base_price


// disponveis na view:

$this->set($data);

Renderizando uma view

Cake\Controller\Controller::render(string $view, string $layout)


O mtodo Controller::render() chamado automaticamente no fim de cada ao requisitada de um
controller. Este mtodo executa toda a lgica da view (usando os dados que voc passou usando o mtodo
Controller::set()), coloca a view em View::$layout, e serve de volta para o usurio final.
O arquivo view usado pelo mtodo Controller::render() determinado por conveno. Se a
action search() do controller RecipesController requisitada, o arquivo view encontrado em
src/Template/Recipes/search.ctp ser renderizado:

namespace App\Controller;

class RecipesController extends AppController


{
// ...
public function search()
{
// Render the view in src/Template/Recipes/search.ctp
$this->render();
}
// ...
}

Embora o CakePHP ir chamar o mtodo Controller::render() automaticamente (ao menos que voc altere o
atributo $this->autoRender para false) aps cada action, voc pode us-lo para especificar um arquivo view
alternativo especificando o nome do arquivo view como primeiro parmetro do mtodo Controller::render().
Se o parmetro $view comear com /, assumido ser um arquivo view ou elemento relativo ao diretrio
/src/Template. Isto permite a renderizao direta de elementos, muito til em chamadas AJAX:

// Renderiza o elemento em src/Template/Element/ajaxreturn.ctp


$this->render('/Element/ajaxreturn');

O segundo parmetro $layout do Controller::render() permite que voc especifique o layout pelo qual a
view renderizada.

Renderizando uma view especfica

Em seu controller voc pode querer renderizar uma view diferente do que a convencional. Voc pode
fazer isso chamando o mtodo Controller::render() diretamente. Uma vez chamado o mtodo
Controller::render(), o CakePHP no tentar renderizar novamente a view:

142 Captulo 10. Controllers (Controladores)


CakePHP Cookbook Documentation, Release 3.next

namespace App\Controller;

class PostsController extends AppController


{
public function my_action()
{
$this->render('custom_file');
}
}

Isto renderizaria o arquivo src/Template/Posts/custom_file.ctp ao invs de src/Template/Posts/my_action.ctp


Voc tambm pode renderizar views de plugins utilizando a seguinte sintaxe:
$this->render('PluginName.PluginController/custom_file'). Por exemplo:

namespace App\Controller;

class PostsController extends AppController


{
public function my_action()
{
$this->render('Users.UserDetails/custom_file');
}
}

Isto renderizaria plugins/Users/src/Template/UserDetails/custom_file.ctp

Redirecionando para outras pginas

Cake\Controller\Controller::redirect(string|array $url, integer $status)


O mtodo de controle de fluxo que voc vai usar na majoritariamente Controller::redirect(). Este mtodo
recebe seu primeiro parmetro na forma de uma URL relativa do CakePHP. Quando um usurio executar um pedido
com xito, voc pode querer redirecion-lo para uma tela de recepo.

public function place_order()


{
// Logic for finalizing order goes here
if ($success) {
return $this->redirect(
['controller' => 'Orders', 'action' => 'thanks']
);
}
return $this->redirect(
['controller' => 'Orders', 'action' => 'confirm']
);
}

Este mtodo ir retornar a instncia da resposta com cabealhos apropriados definidos. Voc deve retornar a instncia
da resposta da sua action para prevenir renderizao de view e deixar o dispatcher controlar o redirecionamento
corrente.
Voc tambm pode usar uma URL relativa ou absoluta como o parmetro $url:

return $this->redirect('/orders/thanks');
return $this->redirect('http://www.example.com');

Redirecionando para outras pginas 143


CakePHP Cookbook Documentation, Release 3.next

Voc tambm pode passar dados para a action:

return $this->redirect(['action' => 'edit', $id]);

O segundo parmetro passado no Controller::redirect() permite a voc definir um cdigo de status HTTP
para acompanhar o redirecionamento. Voc pode querer usar o cdigo 301 (movido permanentemente) ou 303 (veja
outro), dependendo da natureza do redirecionamento.
Se voc precisa redirecionar o usurio de volta para a pgina que fez a requisio, voc pode usar:

$this->redirect($this->referer());

Um exemplo usando seqncias de consulta e hash pareceria com:

return $this->redirect([
'controller' => 'Orders',
'action' => 'confirm',
'?' => [
'product' => 'pizza',
'quantity' => 5
],
'#' => 'top'
]);

A URL gerada seria:

http://www.example.com/orders/confirm?product=pizza&quantity=5#top

Redirecionando para outra action no mesmo Controller

Cake\Controller\Controller::setAction($action, $args...)
Se voc precisar redirecionar a atual action para uma diferente no mesmo controller, voc pode usar
Controller::setAction() para atualizar o objeto da requisio, modificar o template da view que ser rende-
rizado e redirecionar a execuo para a action especificada:

// De uma action delete, voc pode renderizar uma pgina


// de ndice atualizada.
$this->setAction('index');

Carregando models adicionais

Cake\Controller\Controller::loadModel(string $modelClass, string $type)


O mtodo loadModel vem a calhar quando voc precisa usar um model que no padro do controller ou o seu
model no est associado com este.:

// Em um mtodo do controller.
$this->loadModel('Articles');
$recentArticles = $this->Articles->find('all', [
'limit' => 5,
'order' => 'Articles.created DESC'
]);

144 Captulo 10. Controllers (Controladores)


CakePHP Cookbook Documentation, Release 3.next

Se voc est usando um provedor de tabelas que no os da ORM nativa voc pode ligar este sistema de tabelas aos
controllers do CakePHP conectando seus mtodos de factory:

// Em um mtodo do controller.
$this->modelFactory(
'ElasticIndex',
['ElasticIndexes', 'factory']
);

Depois de registrar uma tabela factory, voc pode usar o loadModel para carregar instncias:

// Em um mtodo do controller
$this->loadModel('Locations', 'ElasticIndex');

Nota: O TableRegistry da ORM nativa conectado por padro como o provedor de Tabelas.

Paginando um model

Cake\Controller\Controller::paginate()
Este mtodo usado para fazer a paginao dos resultados retornados por seus models. Voc pode especificar o
tamanho da pgina (quantos resultados sero retornados), as condies de busca e outros parmetros. Veja a seo
pagination para mais detalhes sobre como usar o mtodo paginate()
O atributo paginate lhe oferece uma forma fcil de customizar como paginate() se comporta:

class ArticlesController extends AppController


{
public $paginate = [
'Articles' => [
'conditions' => ['published' => 1]
]
];
}

Configurando components para carregar

Cake\Controller\Controller::loadComponent($name, $config = [])


Em seu mtodo initialize() do controller voc pode definir qualquer component que quiser carregado, e qual-
quer configurao de dados para eles:

public function intialize()


{
parent::initialize();
$this->loadComponent('Csrf');
$this->loadComponent('Comments', Configure::read('Comments'));
}

property Cake\Controller\Controller::$components
A propriedade $components em seus controllers permitem a voc configurar components. Components configu-
rados e suas dependncias sero criados pelo CakePHP para voc. Leia a seo Configuring Components para mais

Paginando um model 145


CakePHP Cookbook Documentation, Release 3.next

informaes. Como mencionado anteriormente, a propriedade $components ser mesclada com a propriedade
definida em cada classe parente do seu controller.

Configurando helpers para carregar

property Cake\Controller\Controller::$helpers
Vamos observar como dizer ao controller do CakePHP que voc planeja usar classes MVC adicionais:

class RecipesController extends AppController


{
public $helpers = ['Form'];
}

Cada uma dessas variveis so mescladas com seus valores herdados, portanto no necessrio (por exemplo) rede-
clarar o FormHelper, ou qualquer coisa declarada em seu AppController.

Ciclo de vida de callbacks em uma requisio

Os controllers do CakePHP vm equipados com callbacks que voc pode usar para inserir lgicas em torno do ciclo
de vida de uma requisio:
Cake\Controller\Controller::beforeFilter(Event $event)
Este mtodo executado antes de cada ao dos controllers. um timo lugar para verificar se h uma sesso
ativa ou inspecionar as permisses de um usurio.

Nota: O mtodo beforeFilter() ser chamado para aes perdidas.

Cake\Controller\Controller::beforeRender(Event $event)
Chamada aps a lgica da action de um controller, mas antes da view ser renderizada. Esse
callback no usado frequentemente, mas pode ser necessrio se voc estiver chamando
Controller\Controller::render() manualmente antes do final de uma determinada action.
Cake\Controller\Controller::afterFilter()
Chamada aps cada ao dos controllers, e aps a completa renderizao da view. Este o ltimo mtodo
executado do controller.
Em adio ao ciclo de vida dos callbacks do controller, Components (Componentes) tambm oferece um conjunto de
callbacks similares.
Lembre de chamar os callbacks do AppController em conjunto com os callbacks dos controllers para melhores
resultados:

public function beforeFilter(Event $event)


{
parent::beforeFilter($event);
}

146 Captulo 10. Controllers (Controladores)


CakePHP Cookbook Documentation, Release 3.next

Mais sobre controllers

O Pages Controller

CakePHP distribudo com o controller PagesController.php. Esse controller simples, seu uso opcional e
normalmente direcionado a prover pginas estticas. A homepage que voc v logo depois de instalar o Ca-
kePHP utiliza esse controller e o arquivo da view fica em src/Template/Pages/home.ctp. Se voc criar o arquivo
src/Template/Pages/about.ctp, 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.
Quando voc cria sua aplicao pelo Composer, o PagesController vai ser criado na pasta src/Controller/.

Components (Componentes)

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github81 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Configuring Components

Authentication

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github82 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

CookieComponent

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github83 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

81 https://github.com/cakephp/docs
82 https://github.com/cakephp/docs
83 https://github.com/cakephp/docs

Mais sobre controllers 147


CakePHP Cookbook Documentation, Release 3.next

Cross Site Request Forgery

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github84 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Flash

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github85 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Security

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github86 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Pagination

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github87 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

84 https://github.com/cakephp/docs
85 https://github.com/cakephp/docs
86 https://github.com/cakephp/docs
87 https://github.com/cakephp/docs

148 Captulo 10. Controllers (Controladores)


CakePHP Cookbook Documentation, Release 3.next

Request Handling

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github88 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

88 https://github.com/cakephp/docs

Mais sobre controllers 149


CakePHP Cookbook Documentation, Release 3.next

150 Captulo 10. Controllers (Controladores)


CAPTULO 11

Views (Visualizao)

class Cake\View\View
Views so o V no MVC. Views so responsveis por gerar a sada especfica requerida para a requisio. Muitas vezes
isso um formulrio Html, XML, ou JSON, mas streaming de arquivos e criar PDFs que os usurios podem baixar
tambm so responsabilidades da camanda View.
O CakePHP vem com a algumas Classes View construdas para manipular os cenrios de renderizao mais comuns:
Para criar webservices XML ou JSON voc pode usar a Views JSON & XML.
Para servir arquivos protegidos, ou arquivos gerados dinamicamente, voc pode usar Enviando Arquivos.
Para criar multiplas views com temas, voc pode usar Temas.

A App View

AppView sua Classe View default da aplicao. AppView extende a propria Cake\View\View, classe includa
no CakePHP e definida em src/View/AppView.php como segue:

<?php
namespace App\View;

use Cake\View\View;

class AppView extends View


{
}

Voc pode usar sua AppView para carregar helpers que sero usados por todas as views renderizadas na sua aplicao.
CakePHP prov um mtodo initialize() que invocado no final do construtor da View para este tipo de uso:

<?php
namespace App\View;

use Cake\View\View;

class AppView extends View


{

151
CakePHP Cookbook Documentation, Release 3.next

public function initialize()


{
// Sempre habilita o *helper* MyUtils
$this->loadHelper('MyUtils');
}

View Templates

A camada View do CakePHP como voc pode falar com seus usurios. A maior parte do tempo suas views iro
renderizar documentos HTML/XHTML para os browsers, mas voc tambm pode precisar responder uma aplicao
remota via JSON, ou ter uma sada de um arquivo csv para o usurio.
Os arquivos de template CakePHP tem a extenso padro .ctp (CakePHP Template) e utiliza a Sintaxe PHP alterna-
tiva89 para controlar estruturas e sadas. Esses arquivos contem a lgica necessria para preparar os dados recebidos
do controller para o formato de apresentao que estar pronto para o seu pblico.

Echos Alternativos

Echo, ou imprime a varivel no seu template:


<?php echo $variable; ?>

Usando o suporte a Tag curta:


<?= $variable ?>

Estruturas de controle alternativas

Estruturas de controle, como if, for, foreach, switch, e while podem ser escritas em um formato simplificado.
Observe que no h chaves. Ao invs disso, a chave de fim doforeach substituida por endforeach. Cada
uma das estruturas de controle listadas anteriormente tem uma sintaxe de fechamento similar: endif, endfor,
endforeach, e endwhile. Observe tambm que ao invs do uso de ponto e virgula depois da estrutura do
foreach (Exceto o ltimo), existem dois pontos.
O bloco a seguir um exempo do uso de foreach:
<ul>
<?php foreach ($todo as $item): ?>
<li><?= $item ?></li>
<?php endforeach; ?>
</ul>

Outro exemplo, usando if/elseif/else. Note os dois pontos:


<?php if ($username === 'sally'): ?>
<h3>Ol Sally</h3>
<?php elseif ($username === 'joe'): ?>
<h3>Ol Joe</h3>

89 http://php.net/manual/en/control-structures.alternative-syntax.php

152 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

<?php else: ?>


<h3>Ol usurio desconhecido</h3>
<?php endif; ?>

Se voc preferir usar uma linguagem de template como Twig90 , uma subclasse da View ir ligar sua linguagem de
template e o CakePHP.
Arquivos de template so armazenados em src/Template/, em uma pasta nomeada com o nome do controller, e com
o nome da ao a que corresponde. Por exemplo, o arquivo da View da ao view() do controller Products, seria
normalmente encontrada em src/Template/Products/view.ctp.
A camada view do CakePHP pode ser constituida por um nmero diferente de partes. Cada parte tem diferentes usos,
e sero abordadas nesse captulo:
views: Templates so a parte da pgina que nica para a ao sendo executada. Eles formam o cerne da
resposta da aplicao.
elements: pequenos bits resaveis do cdigo da view. Elements so usualmente renderizados dentro das views.
layouts: Arquivos de modelo que contem cdigo de apresentao que envolve interfaces da sua aplicao. A
maioria das Views so renderizadas em um layout.
helpers: Essas classes encapsulam lgica de View que necessria em vrios lugares na camada view. Entre
outras coisas, helpers em CakePHP podem ajudar voc a construir formulrios, construir funcionalidades AJAX,
paginar dados do Model, ou servir feed RSS.
cells: Essas classes proveem uma miniatura de funcionalidades de um controller para criar conponentes de
interface de usurio independentes. Veja a documentao View Cells (Clulas de Visualizao) para mais infor-
maes.

Variveis da View

Quaisquer variveis que voc definir no seu controller com set() ficaro disponveis tanto na view quanto no layout
que sua view renderiza. Alm do mais, quaisquer variveis definidas tambm ficaro disponveis em qualquer element.
Se voc precisa passar variveis adicionais da view para o layout voc pode chamar o set() no template da view, ou
use os Usando View Blocks.
Voc deve lembrar de sempre escapar dados do usurio antes de fazer a sada, pois, o CakePHP no escapa automati-
camente a sada. Voc pode escapar o contedo do usurio com a funo h():

<?= h($user->bio); ?>

Definindo Variveis da View

Cake\View\View::set(string $var, mixed $value)


Views tem um mtodo set() que anlogo com o set() encontrado nos objetos Controller. Usando set() no
arquivo da sua view ir adicionar as variveis para o layout e elements que iro ser renderizadas mais tarde. Veja
Definindo variveis para a view para mais informaes para usar o mtodo set().
Em seu arquivo da view voc pode fazer:

$this->set('activeMenuButton', 'posts');

Ento, em seu layout, a varivel $activeMenuButton ficar disponvel e conter o valor posts.
90 http://twig.sensiolabs.org

View Templates 153


CakePHP Cookbook Documentation, Release 3.next

Estendendo Views

Estender Views permite a voc utilizar uma view em outra. Combinando isso com os view blocks d a voc uma forma
poderosa para deixar suas views DRY. Por Exemplo, sua aplicao tem uma sidebar que precisa mudar dependendo
da view especifica que est sendo renderizada. Ao estender um arquivo de exibio comum, Voc pode evitar repetir a
marcao comum para sua barra lateral e apenas definir as partes que mudam:

<!-- src/Template/Common/view.ctp -->


<h1><?= $this->fetch('title') ?></h1>
<?= $this->fetch('content') ?>

<div class="actions">
<h3>Related actions</h3>
<ul>
<?= $this->fetch('sidebar') ?>
</ul>
</div>

O arquivo view acima poderia ser usado como uma view pai. Espera-se que a view estendida ir definir os blocks
sidebar e title. O block content um block especial que o CakePHP cria. Ir conter todo o contedo no
capturado da view extendida. Assumindo que nosso arquivo da view tem a varivel $post com os dados sobre nosso
post, a view poderia se parecer com isso:

<!-- src/Template/Posts/view.ctp -->


<?php
$this->extend('/Common/view');

$this->assign('title', $post);

$this->start('sidebar');
?>
<li>
<?php
echo $this->Html->link('edit', [
'action' => 'edit',
$post->id
]); ?>
</li>
<?php $this->end(); ?>

// O contedo restante estar disponvel como o bloco 'content'


// na view pai.
<?= h($post->body) ?>

A view do post acima mostra como voc pode estender uma view, e preencher um conjunto de blocks. Qualquer ele-
mento que ainda no esteja em um block definido ser capturado e colocado em um block especial chamado content.
Quando uma view contm uma chamada extend(), a execuo continua at o final do arquivo da view atual. Uma
vez completado, a view estendida ser renderizada. Chamando extend() mais de uma vez em um arquivo da view
ir substituir a view pai processada em seguida:

$this->extend('/Common/view');
$this->extend('/Common/index');

A view acima ir resultar em /Common/index.ctp sendo renderizada como a view para a view atual.
Voc pode aninhar as view estendidas quantas vezes achar necessrio. Cada view pode extender outra view se neces-
srio. Cada view pai ir pegar o contedo da view anterior com o block content.

154 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

Nota: Voc deve evitar usar content como um nome de bloco em seu aplicativo. O CakePHP usa isso para
contedo no capturado em exibies estendidas.

Voc pode resgatar a lista de todos os blocos populados usand o mtodo blocks():
$list = $this->blocks();

Usando View Blocks

View blocks prov uma API flexvel que lhe permite definir slots ou blocos em suas views/layouts que sero definidas
em outro lugar. Por exemplo, blocks so ideais para implementar coisas como sidebars, ou regies para carregar assets
ao final/inicio do seu layout. Blocks podem ser definidos de duas formas: Capturando um bloco, ou por atribuio
direta. Os mtodos start(), append(), prepend(), assign(), fetch(), e end() permitem que voc
trabalhe capturando blocos:
// Cria o bloco *sidebar*.
$this->start('sidebar');
echo $this->element('sidebar/recent_topics');
echo $this->element('sidebar/recent_comments');
$this->end();

// Anexa ao *sidebar* posteriormente.


$this->start('sidebar');
echo $this->fetch('sidebar');
echo $this->element('sidebar/popular_topics');
$this->end();

Voc tambm pode anexar em um block usando append():


$this->append('sidebar');
echo $this->element('sidebar/popular_topics');
$this->end();

// O mesmo que acima.


$this->append('sidebar', $this->element('sidebar/popular_topics'));

Se voc precisa limpar ou sobrescrever um block h algumas alternativas. O mtodo reset() ir limpar ou sobres-
crever um bloco em qualquer momento. O mtodo assign() com uma string vazia tambm pode ser usado para
limpar um block expecifico.:
// Limpa o contedo anterior do *block* sidebar.
$this->reset('sidebar');

// Atribuir uma string vazia tambm limpar o bloco *sidebar*.


$this->assign('sidebar', '');

Novo na verso 3.2: View::reset() foi adicionado na verso 3.2


Atribuir um contedo de um block muitas vezes usado quando voc quer converter uma varvel da view em um bloco.
Por exemplo, voc pode querer usar um block para a pgina Ttulo e s vezes atribuir o ttulo como uma varivel da
view no controller:
// No arquivo da *view* ou *layout* acima $this->fetch('title')
$this->assign('title', $title);

Usando View Blocks 155


CakePHP Cookbook Documentation, Release 3.next

O mtodo prepend() permite que voc prefixe contedo para um block existente:

// Prefixa para *sidebar*


$this->prepend('sidebar', 'this content goes on top of sidebar');

Nota: Voc deve evitar usar content como um nome de block. Isto utilizado pelo CakePHP Internamente para
exibies estendidas e exibir contedo no layout.

Exibindo Blocks

Voc pode exibir blocks usando o mtodo fetch(). fetch() ir dar sada ao block, retornando se um block no
existir:

<?= $this->fetch('sidebar') ?>

Voc tambm pode usar fetch para condicionalmente mostrar o contedo que dever caso o block existir. Isso til
em layouts, ou estender view onde voc quer condicionalmente mostrar titulos ou outras marcaes:

// In src/Template/Layout/default.ctp
<?php if ($this->fetch('menu')): ?>
<div class="menu">
<h3>Menu options</h3>
<?= $this->fetch('menu') ?>
</div>
<?php endif; ?>

Voc tambm pode fornecer um valor padro para o bloco se ele no existir. Isso lhe permiti adicionar um contedo
placeholder quando o block no existe. Voc pode definir um valor default usando o segundo argumento:

<div class="shopping-cart">
<h3>Your Cart</h3>
<?= $this->fetch('cart', 'Seu carrinho est vazio') ?>
</div>

Usando Blocks para arquivos de script e css

O HtmlHelper se baseia em view blocks, e os mtodos script(), css(), e meta() cada um atualizam um
bloco com o mesmo nome quando usados com a opo block = true:

<?php
// No seu arquivo da *view*
$this->Html->script('carousel', ['block' => true]);
$this->Html->css('carousel', ['block' => true]);
?>

// No seu arquivo do *layout*.


<!DOCTYPE html>
<html lang="en">
<head>
<title><?= $this->fetch('title') ?></title>
<?= $this->fetch('script') ?>
<?= $this->fetch('css') ?>

156 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

</head>
// Restante do seu layout abaixo

O Cake\View\Helper\HtmlHelper tambm lhe permite controlar qual block o css ou script ir:

// Na sua *view*
$this->Html->script('carousel', ['block' => 'scriptBottom']);

// No seu *layout*
<?= $this->fetch('scriptBottom') ?>

Layouts

Um layout contm cdigos de apresentao que envolvem uma view. Qualquer coisa que voc quer ver em todas as
suas views deve ser colocada em um layout.
O layout default do CakePHP est localizado em src/Template/Layout/default.ctp. Se voc quer alterar a aparn-
cia geral da sua aplicao, ento este o lugar certo para comear, porque o cdigo de exibio processado pelo
controlador colocado dentro do layout padro quando a pgina processada.
Outros arquivos de layout devem estar localizados em src/Template/Layout. Quando voc cria um layout, voc
precisa dizer para o cakePHP onde colocar o resultado de suas views. Para fazer isso, tenha certeza que seu layout
inclui um lugar para $this->fetch('content'). Aqui um exemplo do que um layout padro pode parecer:

<!DOCTYPE html>
<html lang="en">
<head>
<title><?= h($this->fetch('title')) ?></title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<!-- Inclui arquivos externos e scripts aqui. (Veja HTML helper para mais informaes.
) -->

<?php
echo $this->fetch('meta');
echo $this->fetch('css');
echo $this->fetch('script');
?>
</head>
<body>

<!-- Se voc quiser algum tipo de menu para mostrar no topo


de todas as suas *views*, inclua isso aqui -->
<div id="header">
<div id="menu">...</div>
</div>

<!-- Aqui onde eu quero que minhas views sejam exibidas -->
<?= $this->fetch('content') ?>

<!-- Adicione um rodap para cada pgina exibida -->


<div id="footer">...</div>

</body>
</html>

Os blocos script, css e meta contm qualquer contedo definido nas views usando o HTML helper do CakePHP.
til para incluir arquivos JavaScript e CSS das suas views.

Layouts 157
CakePHP Cookbook Documentation, Release 3.next

Nota: Quando usado HtmlHelper::css() ou HtmlHelper::script() em arquivos de template, especi-


fique 'block' => true para colocar o cdigo HTML em um bloco com o mesmo nome. (Veja API para mais
detalhes de como utilizar).

O bloco content contm os contedos da view renderizada.


Voc pode definir o contedo do bloco title de dentro do seu arquivo da view:

$this->assign('title', 'Visualizar Usurios Ativos');

Voc pode criar quantos layouts voc quiser: somente os coloque no diretrio src/Template/Layout, a troca entre eles
dentro das suas aes do controller ocorre usando a propriedade do controller ou view $layout:

// Em um controller
public function admin_view()
{
// Define o layout.
$this->viewBuilder()->setLayout('admin');

// Antes da verso 3.4


$this->viewBuilder()->layout('admin');

// Antes da verso 3.1


$this->layout = 'admin';
}

// Em um arquivo de *view*
$this->layout = 'loggedin';

Por exemplo, se uma seo de meu site inclui um pequeno espao para um banner de propaganda, Eu devo criar um
novo layout com o pequeno espao de propaganda e especific-lo para todas as aes dos controllers usando algo
parecido com:

namespace App\Controller;

class UsersController extends AppController


{
public function viewActive()
{
$this->set('title', 'Visualizar Usurios Ativos');
$this->viewBuilder()->setLayout('default_small_ad');

// Antes da verso 3.4


$this->viewBuilder()->layout('default_small_ad');

// Antes da verso 3.1


$this->layout = 'default_small_ad';
}

public function viewImage()


{
$this->viewBuilder()->setLayout('image');

// Exibe a imagem do usurio


}
}

158 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

Alm do layout padro, A aplicao esqueleto CakePHP tambm tem um layout ajax. O layout Ajax til para criar
resposta AJAX - um layout vazio. (A maioria das chamadas AJAX somente necessitam retornar uma poro de
marcao, ao invs de uma interface totalmente renderizada.)
A aplicao esqueleto tambm tem um layout padro para ajudar a gerar RSS.

Usando Layouts de Plugins

Se voc quer usar um layout existente em um plugin, voc pode usar sintaxe plugin. Por exemplo, para usar o layout
contact do plugin Contacts:

namespace App\Controller;

class UsersController extends AppController


{
public function view_active()
{
$this->viewBuilder()->layout('Contacts.contact');
// ou o seguinte para a verso anterior a 3.1
$this->layout = 'Contacts.contact';
}
}

Elements

Cake\View\View::element(string $elementPath, array $data, array $options = [])


Muitas aplicaes tem pequenos blocos de cdigo de apresentao que precisam ser repetidos pgina a pgina, algumas
vezes em diferentes lugares do layout. O CakePHP pode ajudar voc repetir partes do seu website que precisam ser
reusadas. Essas partes reusveis so chamadas de Elements. Publicidade, Caixas de ajuda, controles de navegao,
menus extras, formulrios de login, e callouts so muitas vezes implementados em CakePHP como elements. Um
elemento basicamente uma mini-view que pode ser includa em outras views, em layouts, e mesmo em outros
elements. Elements podem ser usados para fazer uma view mais legvel, colocando a renderizao de elementos
repetitivos em seu prprio arquivo. Eles tambm podem ajud-lo a reusar contedos fragmentados em sua aplicao.
Elements esto na pasta src/Template/Element/, e tem a extenso .ctp. Eles so exibidos usando o mtodo element
da view:

echo $this->element('helpbox');

Passando variveis para um Element

Voc pode passar dados para um element atravs do segundo parmetro do mtodo element:

echo $this->element('helpbox', [
"helptext" => "Ah, Este texto muito til."
]);

Dentro do arquivo do element, todas as variveis estaro disponveis como membros de um array de parmetros (da
mesma forma que Controller::set() no controller funciona com arquivos de template). No exemplo a seguir,
no arquivo src/Template/Element/helpbox.ctp pode usar a varivel $helptext:

Elements 159
CakePHP Cookbook Documentation, Release 3.next

// Dentro do arquivo src/Template/Element/helpbox.ctp


echo $helptext; // Resulta em "Ah, Esse texto muito til."

O mtodo View::element() tambm suporta opes para o elemento. As opes suportadas so cache e call-
backs. Um exemplo:

echo $this->element('helpbox', [
"helptext" => "Isso passado para o *element* como $helptext",
"foobar" => "Isso passado para o *element* como $foobar",
],
[
// Usa a configurao de cache "long_view"
"cache" => "long_view",
// Define como true para ter before / afterRender chamado para o elemento
"callbacks" => true
]
);

Cache de Elementos facilidatado atravs da Classe Cache. Voc pode configurar elements para serem armazenados
em qualquer configurao de cache que voc possua. Isso d a voc uma grande flexibilidade para decidir onde e
por quanto tempo elements sero armazenados. Para fazer cache de diferentes verses do mesmo element em uma
aplicao, fornea um valor para a chave nica de cache usando o seguinte formato:

$this->element('helpbox', [], [
"cache" => ['config' => 'short', 'key' => 'unique value']
]
);

Se voc precisa de mais lgica em seu element, como dados dinamicos de uma fonte de dados, considere usar uma
View Cell ao invs de um element. Encontre mais sobre View Cells.

Fazendo Cache de Elements

Voc pode tirar vantagem do cache de view do CakePHP se voc fornecer um parametro de cache. Se definido como
true, isso ir fazer cache do element na Configurao de cache default. De qualquer forma, voc pode escolher
a configurao de cache que ser usada. Veja Caching para mais informaes ao configurar Cache. Um simples
exemplo de caching de element poderia ser:

echo $this->element('helpbox', [], ['cache' => true]);

Se voc renderizar o mesmo element mais de uma vez em uma view e tiver o cache habilitado, tenha certeza de definir o
parmetro key com um nome diferente a cada vez. Isso impedir que cada chamada sucessiva sobrescreva o resultado
do cache do element anterior. Por exemplo:

echo $this->element(
'helpbox',
['var' => $var],
['cache' => ['key' => 'first_use', 'config' => 'view_long']]
);

echo $this->element(
'helpbox',
['var' => $differenVar],
['cache' => ['key' => 'second_use', 'config' => 'view_long']]
);

160 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

O bloco acima assegurar que o resultado dos elements tero o cache armazenados separadamente. Se
voc quer todos os elements usando a mesma configurao de cache, voc pode evitar a repetio definindo
View::$elementCache para a configurao que deseja utilizar. O CakePHP ir usar essa configurao quando
nenhuma for fornecida.

Requisitando Elements de um plugin

Se voc est usando um plugin e deseja usar elements de dentro do plugin, simplesmente use a familiar sintaxe plugin.
Se a view est sendo renderizada de um controller/action de um plugin, o nome do plugin ser automaticamente
prefixado em todos os elements a no ser que outro nome de plugin esteja presente. Se o element no existe no plugin,
ir buscar na pasta principal da aplicao:

echo $this->element('Contacts.helpbox');

Se sua view uma parte de um plugin, voc pode omitir o nome do plugin. Por exemplo, se voc est em
ContactsController do plugin Contacts, ter o seguinte:

echo $this->element('helpbox');
// and
echo $this->element('Contacts.helpbox');

So equivalentes e ir resultar no mesmo elementos sendo renderizado.


Para elements dentro de uma subpasta de um plugin (e.g., plugins/Contacts/Template/Element/sidebar/helpbox.ctp),
use o seguinte:

echo $this->element('Contacts.sidebar/helpbox');

Requisitando Elements do App

Se voc est dentro de um arquivos de template de um plugin e quer renderizar um element residido em sua aplicao
principal ou outro plugin, use o seguinte:

echo $this->element('some_global_element', [], ['plugin' => false]);


// or...
echo $this->element('some_global_element', ['localVar' => $someData], ['plugin' =>
false]);

Routing prefix e Elements

Novo na verso 3.0.1.


Se voc tiver um Routing prefix configurado, o caminho do Element pode ser trocado para a localizao do prefixo,
como layouts e actions da View fazem. Assumindo que voc tem um prefixo Admin configurado e voce chama:

echo $this->element('my_element');

O primeiro element procurado ser em src/Template/Admin/Element/. Se o arquivo no existir, ser procurado na


localizao padro.

Elements 161
CakePHP Cookbook Documentation, Release 3.next

Fazendo Cache de Sees da sua View

Cake\View\View::cache(callable $block, array $options = [])


As vezes gerar uma seo do resultado da sua view pode ser custoso porque foram renderizados View Cells (Clulas
de Visualizao) ou operaes de helpers custosas. Para ajudar sua aplicao a rodar mais rapidamente o CakePHP
fornece uma forma de fazer cache de sees de view:

// Assumindo algumas variveis locais


echo $this->cache(function () use ($user, $article) {
echo $this->cell('UserProfile', [$user]);
echo $this->cell('ArticleFull', [$article]);
}, ['key' => 'my_view_key']);

Por padro um contedo da view em cache ir ir para a configurao de cache View::$elementCache, mas voc
pode usar a opo config para alterar isso.

Eventos da View

Como no Controller, view dispara vrios eventos/callbacks que voc pode usar para inserir lgica em torno do ciclo
de vida da renderizao:

Lista de Eventos

View.beforeRender
View.beforeRenderFile
View.afterRenderFile
View.afterRender
View.beforeLayout
View.afterLayout
Voc pode anexar aplicao event listeners para esses eventos ou usar Helper Callbacks.

Criando suas prprias Classes View

Talvez voc precise criar classes view personalizadas para habilitar novos tipos de visualizaes de dados ou adicione
uma lgica de exibio de visualizao personalizada adicional sua aplicao. Como a maioria dos Componentes do
CakePHP, as classes view tm algumas convenes:
Arquivos das Classes View devem ser colocados em src/View. Por exemplo: src/View/PdfView.php
Classes View devem ter o sufixo View. Por Exemplo: PdfView.
Quando referenciar nome de Classes view voc deve omitir o sufixo View. Por Exemplo:
$this->viewBuilder()->className('Pdf');.
Voc tambm vai querer estender a Classe View para garantir que as coisas funcionem corretamente:

162 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

// Em src/View/PdfView.php
namespace App\View;

use Cake\View\View;

class PdfView extends View


{
public function render($view = null, $layout = null)
{
// Custom logic here.
}
}

Substituir o mtodo de renderizao permite que voc tome controle total sobre como seu contedo Processado.

Mais sobre Views

View Cells (Clulas de Visualizao)

View cells so pequenos mini-controllers que podem invocar lgica de visualizao e renderizar templates. A ideia de
cells emprestada das cells do Ruby91 , onde desempenham papel e finalidade semelhantes.

Quando usar Cells

Cells so ideais para construir componentes de pginas reutilizveis que requerem interao com modelos, lgica
de visualizao, e lgica de renderizao. Um exemplo simples seria o carinho em uma loja online, ou um menu de
navegao data-driven em um CMS.
Para criar uma cell, defina uma classe em src/View/Cell e um template em src/Template/Cell/. Nesse exemplo, ns
estaremos fazendo uma cell para exibir o nmero de mensagens em uma caixa de notificaes do usurio. Primeiro,
crie o arquivo da classe. O seu contedo deve se parecer com:

namespace App\View\Cell;

use Cake\View\Cell;

class InboxCell extends Cell


{

public function display()


{
}

Salve esse arquivo dentro de src/View/Cell/InboxCell.php. Como voc pode ver, como em outras classes no Ca-
kePHP, Cells tem algumas convenes:
As Cells ficam no namespace App\View\Cell. Se voc est fazendo uma cell em um plugin, o namespace
seria NomeDoPlugin\View\Cell.
Os nomes das classes devem terminar com Cell.
91 https://github.com/apotonick/cells

Mais sobre Views 163


CakePHP Cookbook Documentation, Release 3.next

Classes devem herdar de Cake\View\Cell.


Ns adicionamos um mtodo display() vazio para nossa cell; esse o mtodo padro convencional quando a
cell renderizada. Ns vamos abordar o uso de outros mtodos mais tarde na documentao. Agora, crie o arquivo
src/Template/Cell/Inbox/display.ctp. Esse ser nosso template para a nossa nova cell.
Voce pode gerar este esboo de cdigo rapidamente usando o bake:

bin/cake bake cell Inbox

Gera o cdigo que digitamos acima.

Implementando a Cell

Assumindo que ns estamos trabalhando em uma aplicao que permite que usurios enviem mensagens um para o
outro. Ns temos o modelo Messages, e ns queremos mostrar a quantidade de mensagens no lidas sem ter que
poluir o AppController. Este um perfeito caso de uso para uma cell. Na classe que acabamos de fazer, adicione o
seguinte:

namespace App\View\Cell;

use Cake\View\Cell;

class InboxCell extends Cell


{

public function display()


{
$this->loadModel('Messages');
$unread = $this->Messages->find('unread');
$this->set('unread_count', $unread->count());
}

Porque as Cells usam o ModelAwareTrait e o ViewVarsTrait, Elas tem um comportamento muito parecido
com um controller. Ns podemos usar os mtodos loadModel() e set() como faramos em um controller. Em
nosso arquivo de template, adicione o seguinte:

<!-- src/Template/Cell/Inbox/display.ctp -->


<div class="notification-icon">
Voc tem <?= $unread_count ?> mensagen no lidas.
</div>

Nota: Cell templates tm um escopo isolado que no compartilha a mesma instncia da view utilizada para processar
o template e o layout para o controller ou outras cells. Assim, eles no sabem de nenhuma chamada de helper feita ou
blocos definidos no template / layout da action e vice-versa.

Carregando Cells

Cells podem ser carregadas nas views usando o mtodo cell() e funciona da mesma forma em ambos os contextos:

164 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

// Carrega uma *cell* da aplicao


$cell = $this->cell('Inbox');

// Carrega uma *cell* de um plugin


$cell = $this->cell('Messaging.Inbox');

O cdigo acima ir carregar a clula nomeada e executar o mtodo display(). Voc pode executar outros mtodo
usando o seguinte:

// Executa o mtodo *Run* na *cell* *Inbox*


$cell = $this->cell('Inbox::expanded');

Se voc precisa de lgica no controller para decidir quais cells sero carregadas em uma requisio, voc pode usar o
CellTrait no seu controller para habilitar o mtodo cell() l:

namespace App\Controller;

use App\Controller\AppController;
use Cake\View\CellTrait;

class DashboardsController extends AppController


{
use CellTrait;

// More code.
}

Passando argumento para a Cell

Voc muitas vezes vai querer parametrizar mtodos da cell para fazer cells mais flexveis. Usando o segundo e terceiro
argumento do mtodo cell(), voc pode passar parametros de ao e opes adicionais para suas classes de cell,
como um array indexado:

$cell = $this->cell('Inbox::recent', ['-3 days']);

O cdigo acima corresponderia a seguinte assinatura de funo:

public function recent($since)


{
}

Renderizando uma Cell

Uma vez a clula carregada e executada, voc provavelmente vai querer renderiz-la. A maneira mais fcil para
renderizar uma cell dando um echo:

<?= $cell ?>

Isso ir renderizar o template correspondente a verso minuscula e separada com underscore do nome da nossa action,
e.g. display.ctp.
Porque as cells usam View para renderizar templates, voc pode carregar cells adicionais dentro do template da cell
se necessrio.

Mais sobre Views 165


CakePHP Cookbook Documentation, Release 3.next

Nota: O echo da cell usa o mtodo PHP mgico __toString() para prevenir o PHP de mostrar o nome do
arquivo e o nmero da linha caso algum erro fatal seja disparado. Para obter uma mensagem de erro significativa,
remomendado usar o mtodo Cell::render(), por exemplo <?= $cell->render() ?>.

Renderizando template alternativos

Por conveno cells renderizam templates que correspondem a action que est sendo executada. Se voc precisar ren-
derizar um template de visualizao diferente, voc pode especificar o template para usar quando estiver renderizando
a cell:

// Chamando render() explicitamente


echo $this->cell('Inbox::recent', ['-3 days'])->render('messages');

// Especificando o template antes de executar *echo* da *cell*


$cell = $this->cell('Inbox');
$cell->template = 'messages';
echo $cell;

Caching Cell Output

Ao renderizar uma clula, voc pode querer armazenar em cache a sada renderizada se o contedo no mudar fre-
quentemente ou para ajudar a melhorar o desempenho do sua aplicao. Voc pode definir a opo cache ao criar
uma clula para ativar e configurar o cache:

// Faz cache usando a configurao padro e uma chave gerada


$cell = $this->cell('Inbox', [], ['cache' => true]);

// Faz cache usando uma configurao especifica a uma chave gerada


$cell = $this->cell('Inbox', [], ['cache' => ['config' => 'cell_cache']]);

// Especificando a chave e a configurao utilizada


$cell = $this->cell('Inbox', [], [
'cache' => ['config' => 'cell_cache', 'key' => 'inbox_' . $user->id]
]);

Se uma chave gerada a verso sublinhada da classe da cell e o nome do template sero usados

Nota: Uma nova instncia da View usada para cada cell e esses novos objetos no compartilham o contexto com
o template principal/layout. Cada cell self-contained e somente tem acesso as variaveis passadas como argumento
pelo chamada do mtodo View::cell().

Temas

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github92 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
92 https://github.com/cakephp/docs

166 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Views JSON & XML

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github93 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Helpers (Facilitadores)

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github94 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Breadcrumbs

class Cake\View\Helper\BreadcrumbsHelper(View $view, array $config = [])


Novo na verso 3.3.6.

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github95 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Flash

class Cake\View\Helper\FlashHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


93 https://github.com/cakephp/docs
94 https://github.com/cakephp/docs
95 https://github.com/cakephp/docs

Mais sobre Views 167


CakePHP Cookbook Documentation, Release 3.next

Por favor, sinta-se a vontade para nos enviar um pull request para o Github96 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Form

class Cake\View\Helper\FormHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github97 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Criando Inputs para Dados Associados

Html

class Cake\View\Helper\HtmlHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github98 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Number

class Cake\View\Helper\NumberHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github99 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

96 https://github.com/cakephp/docs
97 https://github.com/cakephp/docs
98 https://github.com/cakephp/docs
99 https://github.com/cakephp/docs

168 Captulo 11. Views (Visualizao)


CakePHP Cookbook Documentation, Release 3.next

Paginator

class Cake\View\Helper\PaginatorHelper(View $view, array $config = [])

PaginatorHelper Templates

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github100 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

RSS

class Cake\View\Helper\RssHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github101 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Session

class Cake\View\Helper\SessionHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github102 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Text

class Cake\View\Helper\TextHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


100 https://github.com/cakephp/docs
101 https://github.com/cakephp/docs
102 https://github.com/cakephp/docs

Mais sobre Views 169


CakePHP Cookbook Documentation, Release 3.next

Por favor, sinta-se a vontade para nos enviar um pull request para o Github103 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Time

class Cake\View\Helper\TimeHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github104 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Url

class Cake\View\Helper\UrlHelper(View $view, array $config = [])

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github105 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Classe Helper

103 https://github.com/cakephp/docs
104 https://github.com/cakephp/docs
105 https://github.com/cakephp/docs

170 Captulo 11. Views (Visualizao)


CAPTULO 12

Models (Modelos)

Models (Modelos) so as classes que servem como camada de negcio na sua aplicao. Isso significa que eles devem
ser responsveis pela gesto de quase tudo o que acontece em relao a seus dados, sua validade, interaes e evoluo
do fluxo de trabalho de informao no domnio do trabalho.
No CakePHP seu modelo de domnio da aplicao dividido em 2 tipos de objetos principais. Os primeiros so
repositories (repositrios) ou table objects (objetos de tabela). Estes objetos fornecem acesso a colees de dados.
Eles permitem a voc salvar novos registros, modificar/deletar os que j existem, definir relacionamentos, e executar
operaes em massa. O segundo tipo de objetos so as entities (entidades). Entities representam registros individuais
e permitem a voc definir comportamento em nvel de linha/registro e funcionalidades.
O ORM (MOR - Mapeamento Objeto-Relacional) nativo do CakePHP especializa-se em banco de dados relacionais,
mas pode ser extendido para suportar fontes de dados alternativas.
O ORM do Cakephp toma emprestadas ideias e conceitos dos padres ActiveRecord e Datamapper. Isso permite criar
uma implementao hbrida que combina aspectos de ambos padres para criar uma ORM rpida e simples de utilizar.
Antes de ns comearmos explorando o ORM, tenha certeza que voc configure your database connections.

Nota: Se voc familiarizado com verses anteriores do CakePHP, voc deveria ler o Guia de atualizao para o
novo ORM para esclarecer diferenas importantes entre o CakePHP 3.0 e suas verses antigas.

Exemplo rpido

Para comear voc no precisa escrever cdigo. Se voc seguiu as convenes do CakePHP para suas tabelas de banco
de dados, voc pode simplesmente comear a usar o ORM. Por exemplo, se quisssemos carregar alguns dados da
nossa tabela articles poderamos fazer:

use Cake\ORM\TableRegistry;
$articles = TableRegistry::get('Articles');
$query = $articles->find();
foreach ($query as $row) {
echo $row->title;
}

Nota-se que ns no temos que criar qualquer cdigo ou definir qualquer configurao. As convenes do CakePHP
nos permitem pular alguns cdigos clich, e permitir que o framework insera classes bsicas enquanto sua aplicao

171
CakePHP Cookbook Documentation, Release 3.next

no criou uma classe concreta. Se quisssemos customizar nossa classe ArticlesTable adicionando algumas associa-
es ou definir alguns mtodos adicionais, deveriamos acrescentar o seguinte a src/Model/Table/ArticlesTable.php
aps a tag de abertura <?php:

namespace App\Model\Table;

use Cake\ORM\Table;

class ArticlesTable extends Table


{

Classes de tabela usam a verso CamelCased do nome da tabela com o sufixo Table como o nome da classe. Uma
vez que sua classe fora criada, voc recebe uma referncia para esta utilizando o ORM\TableRegistry como antes:

use Cake\ORM\TableRegistry;
// Agora $articles uma instncia de nossa classe ArticlesTable.
$articles = TableRegistry::get('Articles');

Agora que temos uma classe de tabela concreta, ns provavelmente vamos querer usar uma classe de entidade concreta.
As classes de entidade permitem definir mtodos de acesso, mtodos mutantes, definir lgica personalizada para os
registros individuais e muito mais. Vamos comear adicionando o seguinte para src/Model/Entity/Article.php aps
a tag de abertura <?php:

namespace App\Model\Entity;

use Cake\ORM\Entity;

class Article extends Entity


{

Entidades usam a verso singular CamelCase do nome da tabela como seu nome de classe por padro. Agora que
ns criamos nossa classe de entidade, quando carregarmos entidades do nosso banco de dados, ns iremos receber
instncias da nossa nova classe Article:

use Cake\ORM\TableRegistry;

// Agora uma instncia de ArticlesTable.


$articles = TableRegistry::get('Articles');
$query = $articles->find();

foreach ($query as $row) {


// Cada linha agora uma instncia de nossa classe Article.
echo $row->title;
}

CakePHP utiliza convenes de nomenclatura para ligar as classes de tabela e entidade juntas. Se voc precisar
customizar qual entidade uma tabela utiliza, voc pode usar o mtodo entityClass() para definir nomes de classe
especficos.
Veja os captulos em Objetos de tabela e Entidades para mais informaes sobre como usar objetos de tabela e
entidades em sua aplicao.

172 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Mais informao

O bsico sobre banco de dados

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github106 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Adicionando Tipos Personalizados

Construtor de queries

Returning the Total Count of Records

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github107 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Atualizando Dados

Objetos de tabela

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github108 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Entidades

class Cake\ORM\Entity
106 https://github.com/cakephp/docs
107 https://github.com/cakephp/docs
108 https://github.com/cakephp/docs

Mais informao 173


CakePHP Cookbook Documentation, Release 3.next

Enquanto Objetos de tabela representam e fornecem acesso a uma coleo de objetos, entidades representam linhas
individuais ou objetos de domnio na sua aplicao. Entidades contm propriedades persistentes e mtodos para
manipular e acessar os dados que elas contm.
Entidades so criadas para voc pelo CakePHP cada vez que utilizar o find() em um objeto de Table.

Criando Classes de Entidade

Voc no precisa criar classes de entidade para iniciar com o ORM no CakePHP. No entanto, se voc deseja ter
lgica personalizada nas suas entidades, voc precisar criar classes. Por convenso, classes de entidades ficam em
src/Model/Entity/. Se a nossa aplicao tem um tabela articles, poderiamos criar a seguinte entidade:

// src/Model/Entity/Article.php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class Article extends Entity


{
}

Neste momento, essa entidade no faz muita coisa. No entanto, quando carregarmos dados da nossa tabela articles,
obteremos instncias dessa classe.

Nota: Se voc no definir uma classe de entitdade o CakePHP usar a classe Entity bsica.

Criando Entidade

Entidades podem ser instanciadas diretamente:

use App\Model\Entity\Article;

$article = new Article();

Ao instanciar uma entidade, voc pode passar as propriedades com os dados que deseja armazenar nelas:

use App\Model\Entity\Article;

$article = new Article([


'id' => 1,
'title' => 'New Article',
'created' => new DateTime('now')
]);

Outro maneira de obter novas entidades usando o mtodo newEntity() dos objetos Table:

use Cake\ORM\TableRegistry;

$article = TableRegistry::get('Articles')->newEntity();
$article = TableRegistry::get('Articles')->newEntity([
'id' => 1,
'title' => 'New Article',
'created' => new DateTime('now')
]);

174 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Acessando Dados de Entidade

Entidades fornecem algumas maneiras de acessar os dados que contm. Normalmente, voc acessar os dados de uma
entidade usando notao de objeto (object notation):

use App\Model\Entity\Article;

$article = new Article;


$article->title = 'This is my first post';
echo $article->title;

Voc tambm pode usar os mtodos get() e set():

$article->set('title', 'This is my first post');


echo $article->get('title');

Ao usar set(), voc pode atualizar vrias propriedades ao mesmo tempo usando um array:

$article->set([
'title' => 'My first post',
'body' => 'It is the best ever!'
]);

Aviso: Ao atualizar entidades com dados de requisio, voc deve especificar com whitelist quais campos podem
ser definidos com atribuio de massa.

Accessors & Mutators

Alm da simples interface get/set, as entidades permitem que voc fornea mtodos acessadores e mutadores. Esses
mtodos deixam voc personalizar como as propriedades so lidas ou definidas.
Acessadores usam a conveno de _get seguido da verso CamelCased do nome do campo.
Cake\ORM\Entity::get($field)
Eles recebem o valor bsico armazenado no array _properties como seu nico argumento. Acessadores sero
usadas ao salvar entidades, ento seja cuidadoso ao definir mtodos que formatam dados, j que os dados formatados
sero persistido. Por exemplo:

namespace App\Model\Entity;

use Cake\ORM\Entity;

class Article extends Entity


{
protected function _getTitle($title)
{
return ucwords($title);
}
}

O acessador seria executado ao obter a propriedade atravs de qualquer uma dessas duas formas:

echo $user->title;
echo $user->get('title');

Mais informao 175


CakePHP Cookbook Documentation, Release 3.next

Voc pode personalizar como as propriedades so atribuidas definindo um mutador:


Cake\ORM\Entity::set($field = null, $value = null)
Os mtodos mutadores sempre devem retornar o valor que deve ser armazenado na propriedade. Como voc pode ver
acima, voc tambm pode usar mutadores para atribuir outras propriedades calculadas. Ao fazer isso, seja cuidadoso
para no introduzir nenhum loos, j que o CakePHP no impedir os mtodos mutadores de looping infinitos.
Os mutadores permitem voc converter as propriedades conforme so atribuidas, ou criar dados calculados. Os mu-
tadores e acessores so aplicados quando as propriedades so lidas usando notao de objeto (object notation), ou
usando os mtodos get() e set(). Por exemplo:

namespace App\Model\Entity;

use Cake\ORM\Entity;
use Cake\Utility\Text;

class Article extends Entity


{

protected function _setTitle($title)


{
return Text::slug($title);
}

O mutador seria executado ao atribuir a propriedade atravs de qualquer uma dessas duas formas:

$user->title = 'foo'; // slug is set as well


$user->set('title', 'foo'); // slug is set as well

Criando Propriedades Virtuais

Ao definir acessadores, voc pode fornecer acesso aos campos/propriedades que no existem. Por exemplo, se sua
tabela users tem first_name e last_name, voc poderia criar um mtodo para o full_name:

namespace App\Model\Entity;

use Cake\ORM\Entity;

class User extends Entity


{

protected function _getFullName()


{
return $this->_properties['first_name'] . ' ' .
$this->_properties['last_name'];
}

Voc pode acessar propriedades virtuais como se elas existissem na entidade. O nome da propriedade ser a verso
lower case e underscored do mtodo:

echo $user->full_name;

176 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Tenha em mente que as propriedades virtuais no podem ser usadas nos finds. Se voc deseja que as propriedades
virtuais faam parte de representaes JSON ou array de suas entidades, consulte Expondo Propriedades Virtuais.

Verificando se uma Entidade Foi Modificada

Cake\ORM\Entity::dirty($field = null, $dirty = null)


Voc pode querer fazer cdigo condicional com base em se as propriedades foram modificadas ou no em uma enti-
dade. Por exemplo, voc pode s querer validar campos quando eles mudarem:
// See if the title has been modified.
$article->dirty('title');

Voc tambm pode marcar campos como sendo modificados. Isso til quando adiciona item em propriedades do tipo
array:
// Adiciona um comentrio e marca o campo como modificado
$article->comments[] = $newComment;
$article->dirty('comments', true);

Alm disso, voc tambm pode basear o seu cdigo condicional nos valores de proprieades originais usando o mtodo
getOriginal(). Esse mtodo retornar o valor original da propriedade se tiver sido modificado ou seu valor real.
Voc tambm pode verificar se h mudanas em qualquer propriedade na entidade:
// Verifica se a entidade foi modificada
$article->dirty();

Para remover a marca de modificao (dirty flag) em um entidade, voc pode usar o mtodo clean():
$article->clean();

Ao criar uma nova entidade, voc pode evitar que os campos sejam marcados como modificados (dirty) passando uma
opo extra:
$article = new Article(['title' => 'New Article'], ['markClean' => true]);

Para obter uma lista de todos as propriedades modificada (dirty) de uma Entity, voc pode chamar:
$dirtyFields = $entity->getDirty();

Novo na verso 3.4.3: getDirty() foi adicionado.

Erros de Validao

Cake\ORM\Entity::errors($field = null, $errors = null)


Depois que voc salva uma entidade, quaisquer erros de validao sero armazenados na prpria entidade. Voc pode
acessar os erros de validao usando os mtodos getErrors() ou getError():
// Obtem todos os errors
$errors = $user->getErrors();
// Antes da verso 3.4.0
$errors = $user->errors();

// Obtem os errors para um nico campo.


$errors = $user->getError('password');

Mais informao 177


CakePHP Cookbook Documentation, Release 3.next

// Antes da verso 3.4.0


$errors = $user->errors('password');

Os mtodos setErrors() ou setError() podem tambm ser usados para definir erros em uma entidade, tor-
nando mais fcil testar cdigo que trabalha com mensagens de erro:

$user->setError('password', ['Password is required']);


$user->setErrors(['password' => ['Password is required'], 'username' => ['Username is
required']]);

// Antes da verso 3.4.0


$user->errors('password', ['Password is required.']);

Atribuio em Massa

Embora a definio de propriedades para entidades em massa seja simples e conveniente, isso pode criar problemas
de segurana significativos. Atribuindo em massa dados de usurio apartir da requisio a uma entidade permite ao
usurio modificar todas e quaisquer colunas. Ao usar classes de entidade annimas ou criar a classe de entidade com
Bake Console, o CakePHP no protege contra a atribuio em massa.
A propriedade _accessible permite que voc fornea um mapa de propriedades e se elas podem ou no ser
atribudas em massa. Os valores true e false indicam se um campo pode ou no ser atribudo em massa:

namespace App\Model\Entity;

use Cake\ORM\Entity;

class Article extends Entity


{
protected $_accessible = [
'title' => true,
'body' => true
];
}

Alm dos campos concretos, existe um campo especial * que define o comportamento de falbback se um campo no
for especificamente nomeado:

namespace App\Model\Entity;

use Cake\ORM\Entity;

class Article extends Entity


{
protected $_accessible = [
'title' => true,
'body' => true,
'*' => false,
];
}

Nota: Se a propriedade * no for definida, seu padro ser false.

178 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Evitando Proteo de Atribuio em Massa

Ao criar uma nova entidade usando a palavra-chave new, voc pode dizer para no se proteger de atribuio em massa:

use App\Model\Entity\Article;

$article = new Article(['id' => 1, 'title' => 'Foo'], ['guard' => false]);

Modificando os Campos Vigiados em Tempo de Execuo

Voc pode modificar a lista de campos vigiados em tempo de execuo usando o mtodo accessible:

// Faz user_id ser acessvel.


$article->accessible('user_id', true);

// Faz title ser vigiado.


$article->accessible('title', false);

Nota: A modificao de campos afetam apenas a instncia em que o mtodo chamado.

Ao usar os mtodos newEntity() e patchEntity() nos objetos Table, voc pode personalizar a proteo de
atribuio em massa com opes, Por favor consulte a seo Alterando Campos Acessveis para obter mais informa-
es.

Ignorando Proteo de Campo

Existem algumas situaes em que voc deseja permitir atribuio em massa para campos vigiados (guarded):

$article->set($properties, ['guard' => false]);

Definindo a opo guard como false, voc pode ignorar a lista de campos acessveis para uma nica chamado ao
mtodo set().

Verificando se uma Entidade foi Persistida

Frequentemente necessrio saber se uma entnidade representa uma linha que j est no banco de dados. Nessas
situaes, use o mtodo isNew():

if (!$article->isNew()) {
echo 'This article was saved already!';
}

Se voc est certo que uma entidade j foi persistida, voc pode usar isNew() como um setter:

$article->isNew(false);

$article->isNew(true);

Mais informao 179


CakePHP Cookbook Documentation, Release 3.next

Lazy Loading Associations

Embora que eager loading de associaes geralmente o modo mais eficiente de acessar suas associaes, pode
exister momentos em que voc precisa carregar seus dados sobre demanda (lazy load). Antes de entrar em como
carregar associaes sobre demanda, devemos discutir as diferenas entre eager loading e lazy loading de associaes:
Eager loading Eager loading utiliza joins (onde possvel) para buscar os dados do banco de dados em poucas con-
sultas possvel. Quando uma consulta separada necessria, como no caso de uma associao HasMany, uma
nica consulta emitida para buscar todos os dados associados para o conjunto atual de objetos.
Lazy loading Lazy loading difere o carregamento de associao at que seja absolutamente necessrio. Embora isso
posso economizar tempo de CPU, porque possivelmente dados no utilizados no so hidratados (hydrated) em
objetos, isso pode resultar em muitas outras consultas sendo emitidas para o banco de dados. Por exemplo,
fazer um loop sobre um conjunto de artigos e seus comentrios frequentemente emitiro N consultas onde N
o nmero de artigos sendo iterados.
Embora lazy loading no esteja includo no ORM do CakePHP, voc pode usar um dos plugins da comunidade para
fazer isso. Ns recomendamos o LazyLoad Plugin109
Depois de adicionar o plugin em sua entidade, voc ser capaz de fazer o seguinte:

$article = $this->Articles->findById($id);

// A propriedade comments foi carregado sobre demanda (lazy loaded)


foreach ($article->comments as $comment) {
echo $comment->body;
}

Criando Cdigo Re-utilizvel com Traits

Voc pode encontrar-se precisando da mesma lgica em vrias classes de entidades. As Traits do PHP so perfeitas
para isso. Voc pode colocar as traits da sua aplicao em src/Model/Entity. Por convenso traits no CakePHP so
sufixadas com Trait para que elas possam ser discernveis de classes ou interfaces. Traits so geralmente um bom
complemento para os behaviors, permitindo que voc fornea funcionalidade para objetos de tabela e entidade.
Por exemplo, se tivssemos plugin SoftDeletable, isso poderia fornecer uma trait. Essa trait poderia fornecer mtodos
para marcar entidades como deleted, o mtodo softDelete poderia ser fornecido por uma trait:

// SoftDelete/Model/Entity/SoftDeleteTrait.php

namespace SoftDelete\Model\Entity;

trait SoftDeleteTrait
{

public function softDelete()


{
$this->set('deleted', true);
}

Voc poderia ento usar essa trait na sua classe de entidade importando-a e inclundo-a:

109 https://github.com/jeremyharris/cakephp-lazyload

180 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

namespace App\Model\Entity;

use Cake\ORM\Entity;
use SoftDelete\Model\Entity\SoftDeleteTrait;

class Article extends Entity


{
use SoftDeleteTrait;
}

Convertendo para Arrays/JSON

Ao construir APIs, voc geralmente pode precisar converter entidades em arrays ou dados JSON. CakePHP torna isso
simples:
// Obtem um array.
// Associaes sero convertida com toArray() tambm.
$array = $user->toArray();

// Converte para JSON


// Associaes sero convertida com jsonSerialize hook tambm.
$json = json_encode($user);

Ao converter uma entidade para um JSON, as listas de campos virtuais e ocultos so aplicadas. Entidades so recur-
sivamente convertidas para JSON tambm. Isso signinifica que, se voc eager loaded entidades e suas associaes, o
CakePHP manipular corretamente a converso dos dados associados no formato correto.

Expondo Propriedades Virtuais

Por padro, campos virtuais no so exportados ao converter entidades para arrays ou JSON. Para expor propriedades
virtuais, voc precisa torna-las visveis. Ao definir sua classe de entidade, voc pode fornecer uma lista de propriedades
virtuais que devem ser expostas:
namespace App\Model\Entity;

use Cake\ORM\Entity;

class User extends Entity


{

protected $_virtual = ['full_name'];

Esta lista pode ser modificada em tempo de execuo usando o mtodo virtualProperties:
$user->virtualProperties(['full_name', 'is_admin']);

Ocultando Propriedades

Muitas vezes, h campos que voc no deseja ser exportado em formatos de array ou JSON. Por exemplo geralmente
no sensato expor hash de senha ou perguntas de recuperao de conta. Ao definir uma classe de entidade, defina
quais propriedades devem ser ocultadas:

Mais informao 181


CakePHP Cookbook Documentation, Release 3.next

namespace App\Model\Entity;

use Cake\ORM\Entity;

class User extends Entity


{

protected $_hidden = ['password'];

Esta lista pode ser modificada em tempo de execuo usando o mtodo hiddenProperties:

$user->hiddenProperties(['password', 'recovery_question']);

Armazenando Tipos Complexos

Mtodos Acessores & Mutadores em entidades no so destinados para conter a lgica de serializar e deserializar dados
complexos vindo do banco de dados. Consulte a seo Salvando Tipos Complexos (Complex Types) para entender
como sua aplicao pode armazenar tipos de dado complexos, como arrays e objetos.

Retornando dados e conjuntos de resultados

class Cake\ORM\Table
Quando executar uma query, voc obter um objeto Entidade. Nesta sesso discutiremos diferentes caminhos para
se obter: entidades, carregar informaes relacionais, abstratas, ou complexo relacional. Voc poder ler mais sobre
Entidades ( Entity em ingls ).

Depurando Queries e Resultados

Quando o ORM foi implementado, era muito difcil depurar os resultados obtidos nas verses anteriores do CakePHP.
Agora existem muitas formas fceis de inspecionar os dados retornados pelo ORM.
debug($query) Mostra o SQL e os parmetros includos, no mostra resultados.
debug($query->all()) Mostra a propriedade ResultSet retornado pelo ORM.
debug($query->toArray()) Um caminho mais fcil para mostrar todos os resultados.
debug(json_encode($query,JSON_PRETTY_PRINT)) Exemplo em JSON.
debug($query->first()) Primeiro resultado obtido na query.
debug((string)$query->first()) Mostra as propriedades de uma nica entidade em JSON.
Tente isto na camada Controller: debug( $this->{EntidadeNome}->find()->all() );

Pegando uma entidade com a chave primria

Cake\ORM\Table::get($id, $options = [])


Sempre que necessrio editar ou visualizar uma entidade ou dados relacionais voc pode usar get():

182 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

// No controller ou table tente isto.

// Retorna um nico artigo pelo id primrio.


$article = $articles->get($id);

// Retorna um artigo com seus comentrios


$article = $articles->get($id, [
'contain' => ['Comments']
]);

Quando no conseguir obter um resultado Cake\Datasource\Exception\RecordNotFoundException


ser disparado. Voc poder tratar esta exceo, ou converter num erro 404.
O metdo find() usa uma cache integrado. Voc pode uma a opo cache quando chamar get() para uma
performance na leitura - caching:

// No controller ou table tente isto.

// Use uma configurao de cache ou uma instncia do CacheEngine do Cake com uma ID
gerada.

$article = $articles->get($id, [
'cache' => 'custom',
]);

// mykey reserva uma id especifica para determinado cache de resultados.


$article = $articles->get($id, [
'cache' => 'custom', 'key' => 'mykey'
]);

// Desabilitando cache explicitamente


$article = $articles->get($id, [
'cache' => false
]);

Por padro o CakePHP possui um sistema interno de cache que viabiliza busca e
aumenta a performance -no recomendado desabilatar.
Opcionalmente voc pode usar get() nas entidades com busca customizavl Personalizando Metdos de Consulta.
Por exemplo, voc pode querer pegar todas as tradues de uma entidade. Poder usar a opo finder:

$article = $articles->get($id, [
'finder' => 'translations',
]);

Usando find() para carregar dados

Cake\ORM\Table::find($type, $options = [])


Agora que voc sabe e pode trabalhar com entidades, Precisar carrega las e gostar muito como fazer isso. O caminho
mais simples para carregar uma Entidade ou objetos relacionais metdo find(). find prov um extensivl e facl
caminho para procurar e retornar dados, talves voc se interesse por in:

// No controller ou table.

// Procure todos os artigos


$query = $articles->find('all');

Mais informao 183


CakePHP Cookbook Documentation, Release 3.next

O valor retornado por qualquer metdo find() ser sempre um Cake\ORM\Query objeto. A class Query assim
permitindo que possa posteriormente refinar a consulta depois de cria l. Objeto Query no ser executado at que
inicie um busca por linhas, seja convertido num array, ou chamado outro metdo, exemplo: all():

// No controller ou table.

// Retorne todos os artigos


// At este ponto, nada acontece.
$query = $articles->find('all');

// Uma iterao executa a consulta


foreach ($query as $row) {
}

// Chamando all() executa a consulta.


// e retorna os conjuntos de resultados.
$results = $query->all();

// Linhas so retornadas em forma de array


$data = $results->toArray();

// Armazenando a consulta num array


$results = $query->toArray();

Nota: Voc j sabe executar uma consulta, gostar de Construtor de queries para implementar e construir consul-
tas otimizadas ou complexas, adicionando condies especfica, limites, inclundo associao ou uma interface mais
flunte, ou busca de resultados por id de usurio lgado.

// No controller ou table.
$query = $articles->find('all')
->where(['Articles.created >' => new DateTime('-10 days')])
->contain(['Comments', 'Authors'])
->limit(10);

No se limite, poder ir muito alm com find(). Isto o ajuda com metdos simulados:

// No controller ou table.
$query = $articles->find('all', [
'conditions' => ['Articles.created >' => new DateTime('-10 days')],
'contain' => ['Authors', 'Comments'],
'limit' => 10
]);
//Ao buscar todos os artigos, retorne somente artigos com data de hoje - 10 dias atrs
//Depois junto com esses artigos me retorne tambm seus autores e comentrios
inclusos.

Opes suportadas por find() so:


conditions prov acesso direto na clusula Where.
limit Limite o nmero de resultados.
offset Uma pgina que voc quer. Use page para clculo simplificado.
contain defina uma associao para carregar.
fields Quais campos voc deseja carregar somente? Quando carregar somente alguns campos o lembre-se
dos plugins, callbacks.

184 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

group adicione um GROUP BY. muito usado para funoes agregadas.


having adicionar HVAING.
join Defina um Join especfico.
order Ordenar resultados por.
Outras opes fora dessa lista, sero passadas para o beforeFind ou outras funes de tratamento, onde podem ser
usados para tratar a consulta a sua maneira. Pode usar o metdo getOptions() no objeto para retornar as opes
utilizadas. Quando uma consulta for passada para o controller, recomendamos uma leitura sobre consultas personali-
zadas em Personalizando Metdos de Consulta. Usando metdos de consultas personalizados, voc ter um melhor
reuso de seu cdigo, e ficar fcil para testar a sua maneira.
Por padro consultas retornam Entidades objeto. Voc pode retorna array basico usando hydration:
$query->hydrate(false);

// $data is ResultSet that contains array data.


$data = $query->all();

Primeiro Resultado

O metdo first() permite pegar apenas o primeiro resultado da consulta. Caso no seja bem executado a clusula
LIMIT 1 ser aplicada:
// No controller ou table.
$query = $articles->find('all', [
'order' => ['Articles.created' => 'DESC']
]);
$row = $query->first();
//Ex: Retorne todos os artigos, mais quero somente o primeiro.

Uma abordagem diferente find('first') da verso anterior do CakePHP. Voc tambm pode usar o metdo
get() caso queira carregar uma entidade pelo chave primria.

Nota: O metdo first() retorna null caso nenhum resultado seja encontrado.

Contando os resultados

Criando uma consulta voc gosta do metdo count() para retornar a quantidade de resultados encontrado:
// No controller ou table.
$query = $articles->find('all', [
'conditions' => ['Articles.title LIKE' => '%Ovens%']
]);
$number = $query->count();
//Retorne todos os artigos, me mostre quantos so.

Veja Returning the Total Count of Records para modos de uso diferentes com o metdo count().

Encontrando Chaves/Pares de Valores

Frequentemente precisamos gerar um dados associados em array de nossas aplicaes. Muito usado para criar o
elemento <select>. O Cake prov um metdo simples e fcil lists:

Mais informao 185


CakePHP Cookbook Documentation, Release 3.next

// No controller ou table.
$query = $articles->find('list');
$data = $query->toArray();

// Os dados organizados :D
$data = [
1 => 'First post',
2 => 'Second article I wrote',
];

Com as opes adicionais as chaves de $data podem representar uma coluna de sua tabela, Por exemplo, use
'displayField()' no objeto tabela na funo initialize(), isto configura um valor a ser mostrado na chave:
class ArticlesTable extends Table
{

public function initialize(array $config)


{
$this->displayField('title');
}
}

Quando se chama list voc pode configurar quais campos deseja usar para a chave e valor passando as opes
keyField e valueField respectivamente:
// No controller ou table.
$query = $articles->find('list', [
'keyField' => 'slug',
'valueField' => 'title'
]);
$data = $query->toArray();

// Dados organizados :D
$data = [
'first-post' => 'First post',
'second-article-i-wrote' => 'Second article I wrote',
];
//slug passa a ser a chave
// title o valor do option no select

Resultados podem ser agrupados se necessitar. Muito usado quando desejar diferencias Chave/Valores por grupo no
elemento <optgroup> com FormHelper:
// No controller ou table
$query = $articles->find('list', [
'keyField' => 'slug',
'valueField' => 'title',
'groupField' => 'author_id'
]);
$data = $query->toArray();

// Dados organizados :D
$data = [
1 => [
'first-post' => 'First post',
'second-article-i-wrote' => 'Second article I wrote',
],
2 => [

186 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

// More data.
]
];
// Temos ento os artigos com sua Chave/Valores diferenciados por autores.

No complicado, use dados associados e poder gostar do resultado:


$query = $articles->find('list', [
'keyField' => 'id',
'valueField' => 'author.name'
])->contain(['Authors']);
//Retorne uma lista de todos os artigos, o id representar a idenficao do artigo,
porm seu valor ser o nome do seu Author.

//Importante, sempre que pesquisar ou informar campos adicionais use o '.' como
mostrado em 'valueField'.

Por ultimo, muito bom quando podemos usar metdos criados em nossas entidades, isto tambm possvel no
metdo list. . Neste exemplo mostra o uso metdo mutador _getFullName() criado na entidade Author.
$query = $articles->find('list', [
'keyField' => 'id',
'valueField' => function ($e) {
return $e->author->get('full_name');
}
]);
//O valor da chave, representar o nome completo
//Que usa de uma funo para acessar o metdo mutador criado na entidade
//Onde ao juntar o 1 nome com o 2 formar o nome completo.

Encontrando dados enfileirados

O metdo find('threaded') retorna que estaro relacionados por chaves. Por padro o Cake usa o campo
chave parent_id. Nesse modelo, possvel encontrar valores no banco de dados adjacentes. Todas as entidades
correspondentes recebem um parent_id e so alocadas no atributo children:
// No controller ou table.
$query = $comments->find('threaded');

// Expandindo os comentrios de outros comentrios


$query = $comments->find('threaded', [
'keyField' => $comments->primaryKey(),
'parentField' => 'parent_id'
]);
$results = $query->toArray();
// transformando todos os resultados em array.

echo count($results[0]->children);
//Para o primeiro resultado, mostra quantos filhos possue ou registros relacionados e
co-relacionados.

echo $results[0]->children[0]->comment;
//Mostre o comentrio relacionado ao primeiro comentrio

Um pouco mal explicado pela equipe do Cake, quando buscamos por dados enfileirados podemos ir bem alm, at per-
ceber que pode se encaixar perfeitamente em uma carrinho de shopping com seus itens e quantidades co-relacionados.
O parentField e keyField chaves que sero usadas para encontrar ocorrncias.
Ser mais interessante quando aprender sobre rvore de dados ao considerar Tree posteriormente.

Mais informao 187


CakePHP Cookbook Documentation, Release 3.next

Personalizando Metdos de Consulta

Mostramos os exemplos de uso do all e list. Ficar interessado em saber as inmeras possibilidades, e que
tambm recomendamos seriamente, que voc as implemente. Um metdo personalizado de busca pode ser ideal
para simplificar processos, consultar dados complexos, otimizar buscas, ou criar uma busca padro em um metdo
simplificado feito por voc. Eles podem ser definidos na criao do objeto tabela e devem obedecer a conveo
padro do Cake. Ao criar um metdo dever iniciar seu nome com find e logo aps adicionar o nome desejado
para sua busca personalizada, exemplo: find e adicionar Users = findUsers. de grande ajuda, por exemplo,
quando queremos que em uma busca, nossa consulta sempre tenha a condio de que seus resultados sejam de um
determinado usurio, ou que em um carrinho tenha sua prpria listra agregada, sem precisar encher o controller de
cdigos e facilitando muito a manuteno no reuso de cdigo. Neste exemplo mostramos como encontrarmos um
artigo quando este estiver publicado somente.:

use Cake\ORM\Query;
use Cake\ORM\Table;

//Lembre se, dever cria-lo no objeto Artigos


//Ou melhor /src/Model/Table/ArticlesTable.php

class ArticlesTable extends Table


{
//Nosso metdo personalizado
public function findOwnedBy(Query $query, array $options)
{
$user = $options['user'];
return $query->where(['author_id' => $user->id]);
}

// No controller ou table.
$articles = TableRegistry::get('Articles');
$query = $articles->find('ownedBy', ['user' => $userEntity]);
//Retorne todos os artigos, quero que seja de meu usurio, porm somente os j
publicados.

O metdo traz muita funcionalidade, em alguns casos precisamos definir uma pilha de lgica, isto ser possvel usando
o atributo $options para personalizao de consulta com lgica irelevante. Sem esforo voc pode expressar algu-
mas consultas complexas. Assumindo que voc tem ambas as buscas published e recent, poderia fazer assim:

// No controller ou table.
$articles = TableRegistry::get('Articles');
$query = $articles->find('published')->find('recent');
//Busque todos os artigos, dentre eles encontre os publicados, e retorne somente os
recentes.

Nossos exemplos, foram definidos na classe da prpria tabela, porm, voc pode ver como um behavior o ajudar a
automatizar muitos processos e como a reutilizao de cdigo feito no CakePHP leia mais em Behaviors (Compor-
tamentos).
Em uma necessidade de mudar os resultados aps uma busca, deve usar a funo Modifying Results with Map/Reduce
para isto. Isto substitu o antigo afterFind na verso anterior do Cake. que por sinal trouxe clareza, mais agilidade
no processo e menos consumo de memria.

188 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Buscadores dinmicos

CakePHPs ORM prov uma dinmica na construo de metdos de busca, onde na chamada do metdo poder apenas
adicionar o nome do campo que desejar buscar. Por exemplo, se voc quer buscar usurios por seu nome gostar de:

// No controller
// Duas chamadas iguais.
$query = $this->Users->findByUsername('joebob');
$query = $this->Users->findAllByUsername('joebob');

// Na tabela
$users = TableRegistry::get('Users');
// Duas chamadas tambm iguais.
$query = $users->findByUsername('joebob');
$query = $users->findAllByUsername('joebob');

Pode usar tambm multiplos campos na pesquisa:

$query = $users->findAllByUsernameAndApproved('joebob', 1);


//Retorne usurios com Joebob e eles devem estar aprovados ou = 1

Use a condio OR expressa:

$query = $users->findAllByUsernameOrEmail('joebob', 'joe@example.com');


//Retorne usurio com nome joebob ou que possua o email joe@example.com

Neste caso, ao usar OR ou AND voce no pode combinar os dois em nico metdo. Tambm no ser possvel
associar dados com o atributo contain, pois no compatvel com buscas dinmicas. Lembra-se dos nossos queridos
Personalizando Metdos de Consulta eles podem fazer esse trabalho para voc com consultas complexas. Por ultimos
combine suas buscas personalizadas com as dinmicas:

$query = $users->findTrollsByUsername('bro');
// Procure pelos trolls, esses trolls devem username = bro

Abaixo um jeito mais organizado:

$users->find('trolls', [
'conditions' => ['username' => 'bro']
]);

Caso tenha objeto Query retornado da busca dinmica voc necessitar de chamar first() Se quer o primeiro
resultado.

Nota: Esses metdos de busca podem ser simples, porm eles trazem uma sobrecargar adicional, pelo fato de ser
necessrio enteder as expresses.

Retornando Dados Associados

Quando desejar alguns dados associados ou um filtro baseado nesses dados associados, ter dois caminhos para atingir
seu objetivo:
use CakePHP ORM query functions like contain() and matching()
use join functions like innerJoin(), leftJoin(), and rightJoin()

Mais informao 189


CakePHP Cookbook Documentation, Release 3.next

Use contain() quando desejar carregar uma entidade e seus dados associados. contain() aplicar uma condio
adicional aos dados relacinados, porm voc no poder aplicar condies nesses dados baseado nos dados relacionais.
Mais detalhes veja contain() em Eager Loading Associations.
matching() se voc deseja aplicar condies na sua entidade baseado nos dados relacionais, deve usar isto. Por
exemplo, voc quer carregar todos os artigos que tem uma tag especfica neles. Mais detalhes veja matching(), em
Filtering by Associated Data.
Caso prefira usar a funo join, veja mais informaes em adding-joins.

Eager Loading Associations

By default CakePHP does not load any associated data when using find(). You need to contain or eager-load each
association you want loaded in your results.
Eager loading helps avoid many of the potential performance problems surrounding lazy-loading in an ORM. The
queries generated by eager loading can better leverage joins, allowing more efficient queries to be made. In CakePHP
you define eager loaded associations using the contain method:

// In a controller or table method.

// As an option to find()
$query = $articles->find('all', ['contain' => ['Authors', 'Comments']]);

// As a method on the query object


$query = $articles->find('all');
$query->contain(['Authors', 'Comments']);

The above will load the related author and comments for each article in the result set. You can load nested associations
using nested arrays to define the associations to be loaded:

$query = $articles->find()->contain([
'Authors' => ['Addresses'], 'Comments' => ['Authors']
]);

Alternatively, you can express nested associations using the dot notation:

$query = $articles->find()->contain([
'Authors.Addresses',
'Comments.Authors'
]);

You can eager load associations as deep as you like:

$query = $products->find()->contain([
'Shops.Cities.Countries',
'Shops.Managers'
]);

If you need to reset the containments on a query you can set the second argument to true:

$query = $articles->find();
$query->contain(['Authors', 'Comments'], true);

190 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Passing Conditions to Contain

When using contain() you are able to restrict the data returned by the associations and filter them by conditions:

// In a controller or table method.

$query = $articles->find()->contain([
'Comments' => function ($q) {
return $q
->select(['body', 'author_id'])
->where(['Comments.approved' => true]);
}
]);

This also works for pagination at the Controller level:

$this->paginate['contain'] = [
'Comments' => function (\Cake\ORM\Query $query) {
return $query->select(['body', 'author_id'])
->where(['Comments.approved' => true]);
}
];

Nota: When you limit the fields that are fetched from an association, you must ensure that the foreign key columns
are selected. Failing to select foreign key fields will cause associated data to not be present in the final result.

It is also possible to restrict deeply-nested associations using the dot notation:

$query = $articles->find()->contain([
'Comments',
'Authors.Profiles' => function ($q) {
return $q->where(['Profiles.is_published' => true]);
}
]);

If you have defined some custom finder methods in your associated table, you can use them inside contain():

// Bring all articles, but only bring the comments that are approved and
// popular.
$query = $articles->find()->contain([
'Comments' => function ($q) {
return $q->find('approved')->find('popular');
}
]);

Nota: For BelongsTo and HasOne associations only the where and select clauses are used when loading the
associated records. For the rest of the association types you can use every clause that the query object provides.

If you need full control over the query that is generated, you can tell contain() to not append the foreignKey
constraints to the generated query. In that case you should use an array passing foreignKey and queryBuilder:

$query = $articles->find()->contain([
'Authors' => [
'foreignKey' => false,

Mais informao 191


CakePHP Cookbook Documentation, Release 3.next

'queryBuilder' => function ($q) {


return $q->where(...); // Full conditions for filtering
}
]
]);

If you have limited the fields you are loading with select() but also want to load fields off of contained associations,
you can pass the association object to select():

// Select id & title from articles, but all fields off of Users.
$query = $articles->find()
->select(['id', 'title'])
->select($articlesTable->Users)
->contain(['Users']);

Alternatively, if you have multiple associations, you can use autoFields():

// Select id & title from articles, but all fields off of Users, Comments
// and Tags.
$query->select(['id', 'title'])
->contain(['Comments', 'Tags'])
->autoFields(true)
->contain(['Users' => function($q) {
return $q->autoFields(true);
}]);

Novo na verso 3.1: Selecting columns via an association object was added in 3.1

Sorting Contained Associations

When loading HasMany and BelongsToMany associations, you can use the sort option to sort the data in those
associations:

$query->contain([
'Comments' => [
'sort' => ['Comment.created' => 'DESC']
]
]);

Filtering by Associated Data

A fairly common query case with associations is finding records matching specific associated data. For example if
you have Articles belongsToMany Tags you will probably want to find Articles that have the CakePHP tag. This is
extremely simple to do with the ORM in CakePHP:

// In a controller or table method.

$query = $articles->find();
$query->matching('Tags', function ($q) {
return $q->where(['Tags.name' => 'CakePHP']);
});

You can apply this strategy to HasMany associations as well. For example if Authors HasMany Articles, you could
find all the authors with recently published articles using the following:

192 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

$query = $authors->find();
$query->matching('Articles', function ($q) {
return $q->where(['Articles.created >=' => new DateTime('-10 days')]);
});

Filtering by deep associations is surprisingly easy, and the syntax should be already familiar to you:

// In a controller or table method.


$query = $products->find()->matching(
'Shops.Cities.Countries', function ($q) {
return $q->where(['Countries.name' => 'Japan']);
}
);

// Bring unique articles that were commented by 'markstory' using passed variable
// Dotted matching paths should be used over nested matching() calls
$username = 'markstory';
$query = $articles->find()->matching('Comments.Users', function ($q) use ($username) {
return $q->where(['username' => $username]);
});

Nota: As this function will create an INNER JOIN, you might want to consider calling distinct on the find
query as you might get duplicate rows if your conditions dont exclude them already. This might be the case, for
example, when the same users comments more than once on a single article.

The data from the association that is matched will be available on the _matchingData property of entities. If
you both match and contain the same association, you can expect to get both the _matchingData and standard
association properties in your results.

Using innerJoinWith

Using the matching() function, as we saw already, will create an INNER JOIN with the specified association and
will also load the fields into the result set.
There may be cases where you want to use matching() but are not interested in loading the fields into the result
set. For this purpose, you can use innerJoinWith():

$query = $articles->find();
$query->innerJoinWith('Tags', function ($q) {
return $q->where(['Tags.name' => 'CakePHP']);
});

The innerJoinWith() method works the same as matching(), that means that you can use dot notation to join
deeply nested associations:

$query = $products->find()->innerJoinWith(
'Shops.Cities.Countries', function ($q) {
return $q->where(['Countries.name' => 'Japan']);
}
);

Again, the only difference is that no additional columns will be added to the result set, and no _matchingData
property will be set.
Novo na verso 3.1: Query::innerJoinWith() was added in 3.1

Mais informao 193


CakePHP Cookbook Documentation, Release 3.next

Using notMatching

The opposite of matching() is notMatching(). This function will change the query so that it filters results that
have no relation to the specified association:
// In a controller or table method.

$query = $articlesTable
->find()
->notMatching('Tags', function ($q) {
return $q->where(['Tags.name' => 'boring']);
});

The above example will find all articles that were not tagged with the word boring. You can apply this method to
HasMany associations as well. You could, for example, find all the authors with no published articles in the last 10
days:
$query = $authorsTable
->find()
->notMatching('Articles', function ($q) {
return $q->where(['Articles.created >=' => new \DateTime('-10 days')]);
});

It is also possible to use this method for filtering out records not matching deep associations. For example, you could
find articles that have not been commented on by a certain user:
$query = $articlesTable
->find()
->notMatching('Comments.Users', function ($q) {
return $q->where(['username' => 'jose']);
});

Since articles with no comments at all also satisfy the condition above, you may want to combine matching() and
notMatching() in the same query. The following example will find articles having at least one comment, but not
commented by a certain user:
$query = $articlesTable
->find()
->notMatching('Comments.Users', function ($q) {
return $q->where(['username' => 'jose']);
})
->matching('Comments');

Nota: As notMatching() will create a LEFT JOIN, you might want to consider calling distinct on the find
query as you can get duplicate rows otherwise.

Keep in mind that contrary to the matching() function, notMatching() will not add any data to the
_matchingData property in the results.
Novo na verso 3.1: Query::notMatching() was added in 3.1

Using leftJoinWith

On certain occasions you may want to calculate a result based on an association, without having to load all the records
for it. For example, if you wanted to load the total number of comments an article has along with all the article data,

194 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

you can use the leftJoinWith() function:

$query = $articlesTable->find();
$query->select(['total_comments' => $query->func()->count('Comments.id')])
->leftJoinWith('Comments')
->group(['Articles.id'])
->autoFields(true);

The results for the above query will contain the article data and the total_comments property for each of them.
leftJoinWith() can also be used with deeply nested associations. This is useful, for example, for bringing the
count of articles tagged with a certain word, per author:

$query = $authorsTable
->find()
->select(['total_articles' => $query->func()->count('Articles.id')])
->leftJoinWith('Articles.Tags', function ($q) {
return $q->where(['Tags.name' => 'awesome']);
})
->group(['Authors.id'])
->autoFields(true);

This function will not load any columns from the specified associations into the result set.
Novo na verso 3.1: Query::leftJoinWith() was added in 3.1

Changing Fetching Strategies

As you may know already, belongsTo and hasOne associations are loaded using a JOIN in the main finder query.
While this improves query and fetching speed and allows for creating more expressive conditions when retrieving
data, this may be a problem when you want to apply certain clauses to the finder query for the association, such as
order() or limit().
For example, if you wanted to get the first comment of an article as an association:

$articles->hasOne('FirstComment', [
'className' => 'Comments',
'foreignKey' => 'article_id'
]);

In order to correctly fetch the data from this association, we will need to tell the query to use the select strategy,
since we want order by a particular column:

$query = $articles->find()->contain([
'FirstComment' => [
'strategy' => 'select',
'queryBuilder' => function ($q) {
return $q->order(['FirstComment.created' =>'ASC'])->limit(1);
}
]
]);

Dynamically changing the strategy in this way will only apply to a specific query. If you want to make the strategy
change permanent you can do:

$articles->FirstComment->strategy('select');

Mais informao 195


CakePHP Cookbook Documentation, Release 3.next

Using the select strategy is also a great way of making associations with tables in another database, since it would
not be possible to fetch records using joins.

Fetching With The Subquery Strategy

As your tables grow in size, fetching associations from them can become slower, especially if you are querying big
batches at once. A good way of optimizing association loading for hasMany and belongsToMany associations is
by using the subquery strategy:

$query = $articles->find()->contain([
'Comments' => [
'strategy' => 'subquery',
'queryBuilder' => function ($q) {
return $q->where(['Comments.approved' => true]);
}
]
]);

The result will remain the same as with using the default strategy, but this can greatly improve the query and fetching
time in some databases, in particular it will allow to fetch big chunks of data at the same time in databases that limit
the amount of bound parameters per query, such as Microsoft SQL Server.
You can also make the strategy permanent for the association by doing:

$articles->Comments->strategy('subquery');

Lazy Loading Associations

While CakePHP makes it easy to eager load your associations, there may be cases where you need to lazy-load
associations. You should refer to the lazy-load-associations and loading-additional-associations sections for more
information.

Working with Result Sets

Once a query is executed with all(), you will get an instance of Cake\ORM\ResultSet. This object offers
powerful ways to manipulate the resulting data from your queries. Like Query objects, ResultSets are a Collection and
you can use any collection method on ResultSet objects.
Result set objects will lazily load rows from the underlying prepared statement. By default results will be buffered in
memory allowing you to iterate a result set multiple times, or cache and iterate the results. If you need work with a
data set that does not fit into memory you can disable buffering on the query to stream results:

$query->bufferResults(false);

Turning buffering off has a few caveats:


1. You will not be able to iterate a result set more than once.
2. You will also not be able to iterate & cache the results.
3. Buffering cannot be disabled for queries that eager load hasMany or belongsToMany associations, as these
association types require eagerly loading all results so that dependent queries can be generated. This limitation
is not present when using the subquery strategy for those associations.

196 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Aviso: Streaming results will still allocate memory for the entire results when using PostgreSQL and SQL Server.
This is due to limitations in PDO.

Result sets allow you to cache/serialize or JSON encode results for API results:

// In a controller or table method.


$results = $query->all();

// Serialized
$serialized = serialize($results);

// Json
$json = json_encode($results);

Both serializing and JSON encoding result sets work as you would expect. The serialized data can be unserialized into
a working result set. Converting to JSON respects hidden & virtual field settings on all entity objects within a result
set.
In addition to making serialization easy, result sets are a Collection object and support the same methods that collec-
tion objects do. For example, you can extract a list of unique tags on a collection of articles by running:

// In a controller or table method.


$articles = TableRegistry::get('Articles');
$query = $articles->find()->contain(['Tags']);

$reducer = function ($output, $value) {


if (!in_array($value, $output)) {
$output[] = $value;
}
return $output;
};

$uniqueTags = $query->all()
->extract('tags.name')
->reduce($reducer, []);

Some other examples of the collection methods being used with result sets are:

// Filter the rows by a calculated property


$filtered = $results->filter(function ($row) {
return $row->is_recent;
});

// Create an associative array from result properties


$articles = TableRegistry::get('Articles');
$results = $articles->find()->contain(['Authors'])->all();

$authorList = $results->combine('id', 'author.name');

The Collections (Colees) chapter has more detail on what can be done with result sets using the collections features.
The format-results section show how you can add calculated fields, or replace the result set.

Getting the First & Last Record From a ResultSet

You can use the first() and last() methods to get the respective records from a result set:

Mais informao 197


CakePHP Cookbook Documentation, Release 3.next

$result = $articles->find('all')->all();

// Get the first and/or last result.


$row = $result->first();
$row = $result->last();

Getting an Arbitrary Index From a ResultSet

You can use skip() and first() to get an arbitrary record from a ResultSet:

$result = $articles->find('all')->all();

// Get the 5th record


$row = $result->skip(4)->first();

Checking if a Query or ResultSet is Empty

You can use the isEmpty() method on a Query or ResultSet object to see if it has any rows in it. Calling
isEmpty() on a Query object will evaluate the query:

// Check a query.
$query->isEmpty();

// Check results
$results = $query->all();
$results->isEmpty();

Loading Additional Associations

Once youve created a result set, you may need to load additional associations. This is the perfect time to lazily eager
load data. You can load additional associations using loadInto():

$articles = $this->Articles->find()->all();
$withMore = $this->Articles->loadInto($articles, ['Comments', 'Users']);

You can eager load additional data into a single entity, or a collection of entities.

Modifying Results with Map/Reduce

More often than not, find operations require post-processing the data that is found in the database. While entities
getter methods can take care of most of the virtual property generation or special data formatting, sometimes you need
to change the data structure in a more fundamental way.
For those cases, the Query object offers the mapReduce() method, which is a way of processing results once they
are fetched from the database.
A common example of changing the data structure is grouping results together based on certain conditions. For this
task we can use the mapReduce() function. We need two callable functions the $mapper and the $reducer. The
$mapper callable receives the current result from the database as first argument, the iteration key as second argument
and finally it receives an instance of the MapReduce routine it is running:

198 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

$mapper = function ($article, $key, $mapReduce) {


$status = 'published';
if ($article->isDraft() || $article->isInReview()) {
$status = 'unpublished';
}
$mapReduce->emitIntermediate($article, $status);
};

In the above example $mapper is calculating the status of an article, either published or unpublished, then it calls
emitIntermediate() on the MapReduce instance. This method stores the article in the list of articles labelled
as either published or unpublished.
The next step in the map-reduce process is to consolidate the final results. For each status created in the mapper, the
$reducer function will be called so you can do any extra processing. This function will receive the list of articles in
a particular bucket as the first parameter, the name of the bucket it needs to process as the second parameter, and
again, as in the mapper() function, the instance of the MapReduce routine as the third parameter. In our example,
we did not have to do any extra processing, so we just emit() the final results:
$reducer = function ($articles, $status, $mapReduce) {
$mapReduce->emit($articles, $status);
};

Finally, we can put these two functions together to do the grouping:


$articlesByStatus = $articles->find()
->where(['author_id' => 1])
->mapReduce($mapper, $reducer);

foreach ($articlesByStatus as $status => $articles) {


echo sprintf("The are %d %s articles", count($articles), $status);
}

The above will ouput the following lines:


There are 4 published articles
There are 5 unpublished articles

Of course, this is a simplistic example that could actually be solved in another way without the help of a map-reduce
process. Now, lets take a look at another example in which the reducer function will be needed to do something more
than just emitting the results.
Calculating the most commonly mentioned words, where the articles contain information about CakePHP, as usual we
need a mapper function:
$mapper = function ($article, $key, $mapReduce) {
if (stripos('cakephp', $article['body']) === false) {
return;
}

$words = array_map('strtolower', explode(' ', $article['body']));


foreach ($words as $word) {
$mapReduce->emitIntermediate($article['id'], $word);
}
};

It first checks for whether the cakephp word is in the articles body, and then breaks the body into individual words.
Each word will create its own bucket where each article id will be stored. Now lets reduce our results to only extract
the count:

Mais informao 199


CakePHP Cookbook Documentation, Release 3.next

$reducer = function ($occurrences, $word, $mapReduce) {


$mapReduce->emit(count($occurrences), $word);
}

Finally, we put everything together:

$articlesByStatus = $articles->find()
->where(['published' => true])
->andWhere(['published_date >=' => new DateTime('2014-01-01')])
->hydrate(false)
->mapReduce($mapper, $reducer);

This could return a very large array if we dont clean stop words, but it could look something like this:

[
'cakephp' => 100,
'awesome' => 39,
'impressive' => 57,
'outstanding' => 10,
'mind-blowing' => 83
]

One last example and you will be a map-reduce expert. Imagine you have a friends table and you want to find
fake friends in our database, or better said, people who do not follow each other. Lets start with our mapper()
function:

$mapper = function ($rel, $key, $mr) {


$mr->emitIntermediate($rel['source_user_id'], $rel['target_user_id']);
$mr->emitIntermediate($rel['target_user_id'], $rel['source_target_id']);
};

We just duplicated our data to have a list of users each other user follows. Now its time to reduce it. For each call to
the reducer, it will receive a list of followers per user:

// $friends list will look like


// repeated numbers mean that the relationship existed in both directions
[2, 5, 100, 2, 4]

$reducer = function ($friendsList, $user, $mr) {


$friends = array_count_values($friendsList);
foreach ($friends as $friend => $count) {
if ($count < 2) {
$mr->emit($friend, $user);
}
}
}

And we supply our functions to a query:

$fakeFriends = $friends->find()
->hydrate(false)
->mapReduce($mapper, $reducer)
->toArray();

This would return an array similar to this:

200 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

[
1 => [2, 4],
3 => [6]
...
]

The resulting array means, for example, that user with id 1 follows users 2 and 4, but those do not follow 1 back.

Stacking Multiple Operations

Using mapReduce in a query will not execute it immediately. The operation will be registered to be run as soon as
the first result is attempted to be fetched. This allows you to keep chaining additional methods and filters to the query
even after adding a map-reduce routine:

$query = $articles->find()
->where(['published' => true])
->mapReduce($mapper, $reducer);

// At a later point in your app:


$query->where(['created >=' => new DateTime('1 day ago')]);

This is particularly useful for building custom finder methods as described in the Personalizando Metdos de Consulta
section:

public function findPublished(Query $query, array $options)


{
return $query->where(['published' => true]);
}

public function findRecent(Query $query, array $options)


{
return $query->where(['created >=' => new DateTime('1 day ago')]);
}

public function findCommonWords(Query $query, array $options)


{
// Same as in the common words example in the previous section
$mapper = ...;
$reducer = ...;
return $query->mapReduce($mapper, $reducer);
}

$commonWords = $articles
->find('commonWords')
->find('published')
->find('recent');

Moreover, it is also possible to stack more than one mapReduce operation for a single query. For example, if we
wanted to have the most commonly used words for articles, but then filter it to only return words that were mentioned
more than 20 times across all articles:

$mapper = function ($count, $word, $mr) {


if ($count > 20) {
$mr->emit($count, $word);
}
};

Mais informao 201


CakePHP Cookbook Documentation, Release 3.next

$articles->find('commonWords')->mapReduce($mapper);

Removing All Stacked Map-reduce Operations

Under some circumstances you may want to modify a Query object so that no mapReduce operations are executed
at all. This can be done by calling the method with both parameters as null and the third parameter (overwrite) as
true:

$query->mapReduce(null, null, true);

Validando dados

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github110 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Validando dados antes de construir entidades

Aplicando regras da aplicao

Usando um Conjunto de Validao Diferente

Usando um Conjunto de Validao Diferente para Associaes

Salvando Dados

class Cake\ORM\Table
Depois que voc carregou seus dados provavelmente vai querer atualizar e salvar as alteraes.

Viso Geral Sobre Salvando Dados

Aplicaes geralmente ter algumas maneiras de como os dados so salvos. A primeira , obviamente, atravz de
formulrios web e a outra por gerao direta ou alterando dados no cdigo para enviar ao banco de dados.

Inserindo Dados

A maneira mais fcil de inserir dados no banco de dados criando uma nova entidade e passando ela pro mtodo
save() na classe Table:

110 https://github.com/cakephp/docs

202 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

use Cake\ORM\TableRegistry;

$articlesTable = TableRegistry::get('Articles');
$article = $articlesTable->newEntity();

$article->title = 'A New Article';


$article->body = 'This is the body of the article';

if ($articlesTable->save($article)) {
// The $article entity contains the id now
$id = $article->id;
}

Atualizando Dados

Atualizar seus dados igualmente fcil, e o mtodo save() tambm usado para esse propsito:
use Cake\ORM\TableRegistry;

$articlesTable = TableRegistry::get('Articles');
$article = $articlesTable->get(12); // Return article with id 12

$article->title = 'CakePHP is THE best PHP framework!';


$articlesTable->save($article);

CakePHP saber quando deve realizar uma insero ou atualizao com base no valor de retorno do mtodo isNew().
Entidades que foram obtidas com get() ou find() sempre retornar false quando isNew() chamado nelas.

Salvando com Associaes

Por padro o mtodo save() tambm salvar associaes de um nvel:


$articlesTable = TableRegistry::get('Articles');
$author = $articlesTable->Authors->findByUserName('mark')->first();

$article = $articlesTable->newEntity();
$article->title = 'An article by mark';
$article->author = $author;

if ($articlesTable->save($article)) {
// A chave estrangeira foi atribuda automaticamente
echo $article->author_id;
}

O mtodo save() tambm capaz de criar novos registros para associaes:


$firstComment = $articlesTable->Comments->newEntity();
$firstComment->body = 'The CakePHP features are outstanding';

$secondComment = $articlesTable->Comments->newEntity();
$secondComment->body = 'CakePHP performance is terrific!';

$tag1 = $articlesTable->Tags->findByName('cakephp')->first();
$tag2 = $articlesTable->Tags->newEntity();
$tag2->name = 'awesome';

Mais informao 203


CakePHP Cookbook Documentation, Release 3.next

$article = $articlesTable->get(12);
$article->comments = [$firstComment, $secondComment];
$article->tags = [$tag1, $tag2];

$articlesTable->save($article);

Associe Muitos para Muitos (N para N) registros

O exemplo anterior demonstra como associar algumas tags a um artigo. Outra maneira de realizar a mesma coisa
usando o mtodo link() na associao:

$tag1 = $articlesTable->Tags->findByName('cakephp')->first();
$tag2 = $articlesTable->Tags->newEntity();
$tag2->name = 'awesome';

$articlesTable->Tags->link($article, [$tag1, $tag2]);

Salvando Dados da Tabela de Ligao

Salvar dados na tabela de ligao realizado usando a propriedade especial _joinData. Esta propriedade deve ser
um instncia de Entity da classe Table de ligao:

// Link records for the first time.


$tag1 = $articlesTable->Tags->findByName('cakephp')->first();
$tag1->_joinData = $articlesTable->ArticlesTags->newEntity();
$tag1->_joinData->tagComment = 'The CakePHP ORM is so powerful!';

$articlesTable->Tags->link($article, [$tag1]);

// Update an existing association.


$article = $articlesTable->get(1, ['contain' => ['Tags']]);
$article->tags[0]->_joinData->tagComment = 'Fresh comment.'

// Necessary because we are changing a property directly


$article->dirty('tags', true);

$articlesTable->save($article, ['associated' => ['Tags']]);

Voc tambm pode criar / atualizar informaes na tabela de ligao utilizando newEntity() ou
patchEntity(). Os seus dados de POST devem parecer:

$data = [
'title' => 'My great blog post',
'body' => 'Some content that goes on for a bit.',
'tags' => [
[
'id' => 10,
'_joinData' => [
'tagComment' => 'Great article!',
]
],
]

204 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

];
$articlesTable->newEntity($data, ['associated' => ['Tags']]);

Remover Associao Muitos para Muitos (N para N) Registros

A remoo de associao Muitos para Muitos registros realizada atravs do mtodo unlink():

$tags = $articlesTable
->Tags
->find()
->where(['name IN' => ['cakephp', 'awesome']])
->toArray();

$articlesTable->Tags->unlink($article, $tags);

Quando modificando registros, configurando ou alterando diretamente as propriedades, nenhuma validao realizada,
que um problema quando est aceitando dados de formulrio. As sees seguintes demostraro como converter
eficientemente dados de formulrio em entidades que podem ser validadas e salva.

Convertendo Dados de Requisio em Entidades

Antes de editar e salvar os dados de volta no seu banco de dados, voc precisar converter os dados da requisio, de
array mantido na requisio em entidades que o ORM utiliza. A classe Table fornece uma maneira fcil e eficiente de
converter uma ou vrias entidades dos dados de requisio. Voc pode converter uma entidade usando:

//No controller
$articles = TableRegistry::get('Articles');

// Valida e converte em um objeto do tipo Entity


$entity = $articles->newEntity($this->request->getData());

Nota: Se voc estiver usando newEntity() e as entidades resultantes esto faltando algum ou todos os dados passados,
verifique se as colunas que deseja definir esto listadas na propriedade $_accessible da sua entidade. Consulte
Atribuio em Massa.

Os dados da requisio devem seguir a estrutura de suas entidades. Por exemplo, se voc tem um artigo, que pertence
a um usurio, e tem muitos comentrios, os seus dados de requisio devem ser semelhante:

$data = [
'title' => 'CakePHP For the Win',
'body' => 'Baking with CakePHP makes web development fun!',
'user_id' => 1,
'user' => [
'username' => 'mark'
],
'comments' => [
['body' => 'The CakePHP features are outstanding'],
['body' => 'CakePHP performance is terrific!'],
]
];

Mais informao 205


CakePHP Cookbook Documentation, Release 3.next

Por padro, o mtodo newEntity() valida os dados que so passados para ele, conforme explicado na seo Vali-
dando dados antes de construir entidades. Se voc deseja pular a validao de dados, informe a opo 'validate'
=> false:
$entity = $articles->newEntity($data, ['validate' => false]);

Ao criar formulrios que salvam associaes aninhadas, voc precisa definir quais associaes devem ser convertidas:
// No controller
$articles = TableRegistry::get('Articles');

// Nova entidade com associaes aninhadas


$entity = $articles->newEntity($this->request->getData(), [
'associated' => [
'Tags', 'Comments' => ['associated' => ['Users']]
]
]);

O exemplo acima indica que Tags, Comments e Users para os artigos devem ser convertidos. Alternativamente,
voc pode usar a notao de ponto (dot notation) por brevidade:
// No controller
$articles = TableRegistry::get('Articles');

// Nova entidade com associaes aninhada usando notao de ponto


$entity = $articles->newEntity($this->request->getData(), [
'associated' => ['Tags', 'Comments.Users']
]);

Voc tambm pode desativar a converso de possveis associaes aninhadas como:


$entity = $articles->newEntity($data, ['associated' => []]);
// ou...
$entity = $articles->patchEntity($entity, $data, ['associated' => []]);

Os dados associados tambm so validados por padro, a menos que seja informado o contrrio. Voc tambm pode
alterar o conjunto de validao a ser usada por associao:
// No controller
$articles = TableRegistry::get('Articles');

// Pular validao na associao de Tags e


// Definino 'signup' como mtodo de validao para Comments.Users
$entity = $articles->newEntity($this->request->getData(), [
'associated' => [
'Tags' => ['validate' => false],
'Comments.Users' => ['validate' => 'signup']
]
]);

O capitulo Usando um Conjunto de Validao Diferente para Associaes possui mais informaes sobre como usar
diferentes validadores para associaes ao transformar em entidades.
O diagrama a seguir fornece uma viso geral do que acontece dentro dos mtodos newEntity() ou
patchEntity():

Voc
sem-

206 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

pre
pode
con-
tar
de
ob-
ter
uma
en-
ti-
dade
de
volta
com
newEntity().
Se a
vali-
dao
falhar,
sua
enti-
dade
con-
ter
er-
ros, e
quais-
quer
cam-
pos
inv-
lidos
no
sero
preen-
chidos
na en-
tidade
criada.

Convertendo
Dados de Associao BelongsToMany

Se voc est salvando associaes belongsToMany, voc pode tanto usar uma lista de entidades ou uma lista de ids.
Ao usar uma lista de dados de entidade, seus dados de requisio devem parecer com:
$data = [
'title' => 'My title',
'body' => 'The text',
'user_id' => 1,
'tags' => [
['tag' => 'CakePHP'],
['tag' => 'Internet'],
]

Mais informao 207


CakePHP Cookbook Documentation, Release 3.next

];

O exemplo acima criar 2 novas tags. Se voc deseja associar um artigo com tags existentes, voc pode usar uma lista
de ids. Seus dados de requisio devem parecer com:
$data = [
'title' => 'My title',
'body' => 'The text',
'user_id' => 1,
'tags' => [
'_ids' => [1, 2, 3, 4]
]
];

Se voc precisa associar a alguns belongsToMany registros existentes, e criar novos ao mesmo tempo, voc pode usar
um formato expandido:
$data = [
'title' => 'My title',
'body' => 'The text',
'user_id' => 1,
'tags' => [
['name' => 'A new tag'],
['name' => 'Another new tag'],
['id' => 5],
['id' => 21]
]
];

Quando os dados acima so convertidos em entidades, voc ter 4 tags. As duas primeiras sero objetos novos, e as
outras duas sero referncias a registros existentes.
Ao converter dados belongsToMany, voc pode desativar a criao de nova entidade, usando a opo onlyIds.
Quando habilitado, esta opo restringe transformao de belongsToMany para apenas usar a chave _ids e ignorar
todos os outros dados.
Novo na verso 3.1.0: A opo onlyIds foi adicionada na verso 3.1.0

Convertendo Dados de Associao HasMany

Se voc deseja atualizar as associaes hasMany existentes e atualizar suas propriedades, primeiro voc deve garantir
que sua entidade seja carregada com a associao hasMany. Voc pode ento usar dados de requisio semelhantes a:
$data = [
'title' => 'My Title',
'body' => 'The text',
'comments' => [
['id' => 1, 'comment' => 'Update the first comment'],
['id' => 2, 'comment' => 'Update the second comment'],
['comment' => 'Create a new comment'],
]
];

Se voc est salvando associaoes hasMany e deseja vincular a registros existentes, voc pode usar o formato _ids:
$data = [
'title' => 'My new article',

208 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

'body' => 'The text',


'user_id' => 1,
'comments' => [
'_ids' => [1, 2, 3, 4]
]
];

Ao converter dados hasMany, voc pode desativar a criao de nova entidade, usando a opo onlyIds`.
Quando ativada,esta opo restringe transformao de hasMany para apenas usar
a chave ``_ids e ignorar todos os outros dados.
Novo na verso 3.1.0: A opo onlyIds foi adicionada na verso 3.1.0

Conventendo Vrios Registros

Ao criar formulrios que cria/atualiza vrios registros ao mesmo tempo, voc pode usar o mtodo newEntities():

// No controller.
$articles = TableRegistry::get('Articles');
$entities = $articles->newEntities($this->request->getData());

Nessa situao, os dados de requisio para vrios artigos devem parecer com:

$data = [
[
'title' => 'First post',
'published' => 1
],
[
'title' => 'Second post',
'published' => 1
],
];

Uma vez que voc converteu os dados de requisio em entidades, voc pode salvar com save() e remover com
delete():

// No controller.
foreach ($entities as $entity) {
// Salva a entidade
$articles->save($entity);

// Remover a entidade
$articles->delete($entity);
}

O exemplo acima executar uma transao separada para cada entidade salva. Se voc deseja processar todas as
entidades como uma nica transao, voc pode usar transactional():

// No controller.
$articles->getConnection()->transactional(function () use ($articles, $entities) {
foreach ($entities as $entity) {
$articles->save($entity, ['atomic' => false]);
}
});

Mais informao 209


CakePHP Cookbook Documentation, Release 3.next

Alterando Campos Acessveis

Tambm possvel permitir newEntity() escrever em campos no acessiveis. Por exemplo, id geralmente est
ausente da propriedade _accessible. Nesse caso , voc pode usar a opo accessibleFields. Isso pode ser
til para manter ids de entidades associadas:

// No controller
$articles = TableRegistry::get('Articles');
$entity = $articles->newEntity($this->request->getData(), [
'associated' => [
'Tags', 'Comments' => [
'associated' => [
'Users' => [
'accessibleFields' => ['id' => true]
]
]
]
]
]);

O exemplo acima manter a associao inalterada entre Comments e Users para a entidade envolvida.

Nota: Se voc estiver usando newEntity() e as entidades resultantes esto faltando algum ou todos os dados passados,
verifique se as colunas que deseja definir esto listadas na propriedade $_accessible da sua entidade. Consulte
Atribuio em Massa.

Mesclando Dados de Requisio em Entidades

Para atualizar as entidades, voc pode escolher de aplicar dados de requisio diretamente em uma entidade existente.
Isto tem a vantagem que apenas os campos que realmente mudaram sero salvos, em oposio ao envio de todos
os campos para o banco de dados pra ser persistido. Voc pode mesclar um array de dados bruto em uma entidade
existente usando o mtodo patchEntity():

// No controller.
$articles = TableRegistry::get('Articles');
$article = $articles->get(1);
$articles->patchEntity($article, $this->request->getData());
$articles->save($article);

Validao e patchEntity

Semelhante ao newEntity(), o mtodo patchEntity validar os dados antes de ser copiado para entidade. O
mecanismo explicado na seo Validando dados antes de construir entidades. Se voc deseja desativar a validao,
informe a o opo validate assim:

// No controller.
$articles = TableRegistry::get('Articles');
$article = $articles->get(1);
$articles->patchEntity($article, $data, ['validate' => false]);

Voc tambm pode alterar a regra de validao utilizada pela entidade ou qualquer uma das associaes:

210 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

$articles->patchEntity($article, $this->request->getData(), [
'validate' => 'custom',
'associated' => ['Tags', 'Comments.Users' => ['validate' => 'signup']]
]);

Patching HasMany and BelongsToMany

Como explicado na seo anterior, os dados de requisio deve seguir a estrutura de sua entidade. O mtodo patchEn-
tity() igualmente capaz de mesclar associaes, por padro, apenas o primeiro nvel de associaes so mesclados,
mas se voc deseja controlar a lista de associaes a serem mescladas ou mesclar em nveis mais profundos, voc pode
usar o terceiro parmetro do mtodo:
// No controller.
$associated = ['Tags', 'Comments.Users'];
$article = $articles->get(1, ['contain' => $associated]);
$articles->patchEntity($article, $this->request->getData(), [
'associated' => $associated
]);
$articles->save($article);

As associaes so mescladas ao combinar o campo da chave primria nas entidades de origem com os campos
correspondentes no array de dados. As associaes iro construir novas entidades se nenhuma entidade anterior for
encontrada para a propriedade alvo da associao.
Por exemplo, fornea alguns dados de requisio como este:
$data = [
'title' => 'My title',
'user' => [
'username' => 'mark'
]
];

Tentando popular uma entidade sem uma entidade na propriedade user criar uma nova entidade do tipo user:
// In a controller.
$entity = $articles->patchEntity(new Article, $data);
echo $entity->user->username; // Echoes 'mark'

O mesmo pode ser dito sobre associaes hasMany e belongsToMany, com uma advertncia importante:

Nota: Para as associaes belongsToMany, garanta que a entidade relevante tenha uma propriedade acessvel para a
entidade associada.

Se um Produto pertence a vrias (belongsToMany) Tag:


// Na classe da entidade Product
protected $_accessible = [
// .. outras propriedades
'tags' => true,
];

Nota: Para as associaes hasMany e belongsToMany, se houvesse algumas entidades que que no pudessem ser
correspondidas por chave primaria a um registro no array de dados, ento esses registros sero descartados da entidade

Mais informao 211


CakePHP Cookbook Documentation, Release 3.next

resultante.
Lembre-se que usando patchEntity() ou patchEntities() no persiste os dados, isso apenas edita (ou cria)
as entidades informadas. Para salvar a entidade voc ter que chamar o mtodo save() da model Table.

Por exemplo, considere o seguinte caso:

$data = [
'title' => 'My title',
'body' => 'The text',
'comments' => [
['body' => 'First comment', 'id' => 1],
['body' => 'Second comment', 'id' => 2],
]
];
$entity = $articles->newEntity($data);
$articles->save($entity);

$newData = [
'comments' => [
['body' => 'Changed comment', 'id' => 1],
['body' => 'A new comment'],
]
];
$articles->patchEntity($entity, $newData);
$articles->save($entity);

No final, se a entidade for convertida de volta para um array, voc obter o seguinte resultado:

[
'title' => 'My title',
'body' => 'The text',
'comments' => [
['body' => 'Changed comment', 'id' => 1],
['body' => 'A new comment'],
]
];

Como voc pode ver, o comentrio com id 2 no est mais l, j que ele no pode ser correspondido a nada no array
$newData. Isso acontece porque CakePHP est refletindo o novo estado descrito nos dados de requisio.
Algumas vantagens adicionais desta abordagem que isto reduz o nmero de operaes a serem executadas ao persistir
a entidade novamente.
Por favor, observe que isso no significa que o comentrio com id 2 foi removido do bando de dados, se voc deseja
remover os comentrios para este artigo que no esto presentes na entidade, voc pode coletar as chaves primrias e
executar uma excluso de lote para esses que no esto na lista:

// Num controller.
$comments = TableRegistry::get('Comments');
$present = (new Collection($entity->comments))->extract('id')->filter()->toArray();
$comments->deleteAll([
'article_id' => $article->id,
'id NOT IN' => $present
]);

Como voc pode ver, isso tambm ajuda ao criar solues onde uma associao precisa de ser implementada como
um nico conjunto.

212 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Voc tambm pode popular vrias entidades ao mesmo tempo. As consideraes feitas para popular (patch) associ-
aes hasMany e belongsToMany se aplicam para popular vrias entidades: As comparao so feitas pelo valor do
campo da chave primria e as correspondncias que faltam no array das entidades originais sero removidas e no
estaro presentes no resultado:

// Num controller.
$articles = TableRegistry::get('Articles');
$list = $articles->find('popular')->toArray();
$patched = $articles->patchEntities($list, $this->request->getData());
foreach ($patched as $entity) {
$articles->save($entity);
}

Semelhante de usar patchEntity(), voc pode usar o terceiro argumento para controlar as associaes que sero
mescladas em cada uma das entidades no array:

// Num controller.
$patched = $articles->patchEntities(
$list,
$this->request->getData(),
['associated' => ['Tags', 'Comments.Users']]
);

Modificando Dados de Requisio Antes de Contruir Entidades

Se voc precisa modificar dados de requisio antes de converter em entidades, voc pode usar o evento
Model.beforeMarshal. Esse evento deixa voc manipular o dados de requisio antes das entidades serem
criadas:

// Inclua as instrues na rea superior do seu arquivo.


use Cake\Event\Event;
use ArrayObject;

// Na classe da sua table ou behavior


public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
{
if (isset($data['username'])) {
$data['username'] = mb_strtolower($data['username']);
}
}

O parmetro $data uma instncia de ArrayObject, ento voc no precisa retornar ele para alterar os dados
usado para criar entidades.
O propsito principal do beforeMarshal auxiliar os usurios a passar o processo de validao quando erros
simples podem ser automaticamente resolvidos, ou quando os dados precisam ser reestruturados para que ele possa
ser colocado nos campos corretos.
O evento Model.beforeMarshal disparado apenas no incio do processo de validao, uma das razes que
o beforeMarshal permitido de alterar as regras de validao e opes de salvamento, como o campo whitelist.
Validao disparada logo aps este evento ser finalizado. Um exemplo comum de alterao de dados antes de ser
validado, retirar espao no nicio e final (trimming) de todos os campos antes de salvar:

// Inclua as instrues na rea superior do seu arquivo.


use Cake\Event\Event;
use ArrayObject;

Mais informao 213


CakePHP Cookbook Documentation, Release 3.next

// Na classe da sua table ou behavior


public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options)
{
foreach ($data as $key => $value) {
if (is_string($value)) {
$data[$key] = trim($value);
}
}
}

Por causa de como o processo de marshalling trabalha, se um campo no passar na validao ele ser automaticamente
removido do array de dados e no ser copiado na entidade. Isso previne que dados inconsistentes entrem no objeto
de entidade.
Alm disso, os dados em beforeMarshal so uma cpia dos dados passados. Isto assim porque importante
preservar a entrada original do usurio, pois ele pode ser usado em outro lugar.

Validando Dados Antes de Construir Entidades

O captulo Validando dados contm mais informaes de como usar os recursos de validao do CakePHP para garantir
que os seus dados permaneam corretos e consitentes.

Evitando Ataques de Atribuio em Massa de Propriedade

Ao criar ou mesclar entidades a partir de dados de requisio, voc precisa ser cuidadoso com o que voc permite seus
usurios de alterar ou incluir nas entidades. Por exemplo, ao enviar um array na requisio contendo o user_id um
invasor pode alterar o proprietrio de um artigo, causando efeitos indesejveis:

// Contm ['user_id' => 100, 'title' => 'Hacked!'];


$data = $this->request->getData();
$entity = $this->patchEntity($entity, $data);
$this->save($entity);

H dois modos de proteger voc contra este problema. O primeiro configurando as colunas padro que podem ser
definidas com segurana a partir de um requisio usando o recurso Atribuio em Massa nas entidades.
O segundo modo usando a opo fieldList ao criar ou mesclar dados em uma entidade:

// Contem ['user_id' => 100, 'title' => 'Hacked!'];


$data = $this->request->getData();

// Apenas permite alterar o campo title


$entity = $this->patchEntity($entity, $data, [
'fieldList' => ['title']
]);
$this->save($entity);

Voc tambm pode controlar quais propriedades poder ser atribuidas para associaes:

// Apenas permite alterar o title e tags


// e nome da tag a nica columa que pode ser definido
$entity = $this->patchEntity($entity, $data, [
'fieldList' => ['title', 'tags'],
'associated' => ['Tags' => ['fieldList' => ['name']]]

214 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

]);
$this->save($entity);

Usar este recurso til quando voc tem vrias funces diferentes que seus usurios podem acessar, e voc deseja que
eles editem difentes dados baseados em seus privilgios.
A opo fieldList tambm aceita nos mtodos newEntity(), newEntities() e patchEntities().

Salvando Entidades

Cake\ORM\Table::save(Entity $entity, array $options = [])


Ao salvar dados de requisio no seu banco de dados, voc primeiro precisa hidratar (hydrate) uma nova entidade
usando newEntity() para passar no save(). Por exemplo:

// Num controller
$articles = TableRegistry::get('Articles');
$article = $articles->newEntity($this->request->getData());
if ($articles->save($article)) {
// ...
}

O ORM usa o mtodo isNew() em uma entidade para determinar quando um insert ou update deve ser realizado ou
no. Se o mtodo isNew() retorna true e a entidade tiver um valor de chave primria, ento ser emitida uma query
exists. A query exists pode ser suprimida informando a opo 'checkExisting' => false no argumento
$options:

$articles->save($article, ['checkExisting' => false]);

Uma vez, que voc carregou algumas entidades, voc provavelmente desejar modificar elas e atualizar em seu banco
de dados. Este um exerccio bem simples no CakePHP:

$articles = TableRegistry::get('Articles');
$article = $articles->find('all')->where(['id' => 2])->first();

$article->title = 'My new title';


$articles->save($article);

Ao salvar, CakePHP ir aplicar suas regras, e envolver a operao de salvar em uma trasao de banco de dados.
Tambm atualizar as propriedades que mudaram. A chamada save() do exemplo acima geraria SQL como:

UPDATE articles SET title = 'My new title' WHERE id = 2;

Se voc tem uma nova entidade, o seguinte SQL seria gerado:

INSERT INTO articles (title) VALUES ('My new title');

Quando uma entidade salva algumas coisas acontecem:


1. A verificao de regras ser iniciada se no estiver desativada.
2. A verificao de regras ir disparar o evento Model.beforeRules. Se esse evento for parado, a operao
de salvamento falhar e retornar false.
3. As regras sero verificadas. Se a entidade est sendo criada, as regras create sero usadas. Se a entidade
estiver sendo atualizada, as regras update sero usadas.
4. O evento Model.afterRules ser disparado.

Mais informao 215


CakePHP Cookbook Documentation, Release 3.next

5. O evento Model.beforeSave ser disparado. Se ele for parado, o processo de salvamento ser abortado, e
save() retornar false.
6. As associaes de pais so salvas. Por exemplo, qualquer associao belongsTo listada sero salvas.
7. Os campos modificados na entidade sero salvos.
8. As associaes filhas so salvas. Por exemplo, qualquer associao hasMany, hasOne, ou belongsToMany
listada sero salvas.
9. O evento Model.afterSave ser disparado.
10. O evento Model.afterSaveCommit ser disparado.
O seguinte diagrama ilustra o processo acima:

Consule a
seo Apli-
cando regras
da aplicao
para mais
informao
sobre como
criar e usar
regras.

Aviso:
Se ne-
nhuma
alterao
feita na
entidade
quando
ela
salva, os
callbacks
no sero
disparado
porque o
salvar no
execu-
tado.

O mtodo
save()
retornar
a entidade
modificada
quando
sucesso,
e false
quando fa-
lhar. Voc
pode desa-
tivar regras

216 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

e/ou transa-
es usando
o argumento
$options
para salvar:

Salvando
Associa-
es

Quando voc
est salvando
uma enti-
dade, voc
tambm pode
escolher de
salvar alguma
ou todas as
entidades as-
sociadas. Por
padro, todos
as entidades
de primeiro
nvel sero
salvas. Por
exemplo
salvando um
Artigo, voc
tambm atu-
alizar todas
as entidades
modifica-
das (dirty)
que so di-

Mais informao 217


CakePHP Cookbook Documentation, Release 3.next

retamente
realicionadas
a tabela de
artigos.
Voc pode
ajustar as
associa-
es que
so sal-
vas usando
a opo
associated:

// Num controller.

// Apenas salva a associao de comentrios


$articles->save($entity, ['associated' => ['Comments']]);

Voc pode definir para salvar associaes distantes ou profundamente aninhadas usando a notao de pontos (dot
notation):

// Salva a company (empresa), employees (funcionrios) e os addresses (endereos)


relacionado

para cada um deles


$companies->save($entity, ['associated' => ['Employees.Addresses']]);

Alm disso, voc pode combinar a notao de pontos (dot notation) para associaes com o array de opes:

$companies->save($entity, [
'associated' => [
'Employees',
'Employees.Addresses'
]
]);

As suas entidades devem ser estruturadas na mesma maneira como elas so quando carregadas do banco de dados.
Consulte a documentao do form helper para saber como criar inputs para associaes.
Se voc est construindo ou modificando dados de associao aps a construo de suas entidades, voc ter que
marcar a propriedade da associao como modificado com o mtodo dirty():

$company->author->name = 'Master Chef';


$company->dirty('author', true);

Salvando Associaes BelongsTo

Ao salvar associaes belongsTo, o ORM espera uma nica entidade aninhada nomeada com a singular, underscored
verso do nome da associao. Por exemplo:

// Num controller.
$data = [
'title' => 'First Post',
'user' => [
'id' => 1,
'username' => 'mark'

218 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

]
];
$articles = TableRegistry::get('Articles');
$article = $articles->newEntity($data, [
'associated' => ['Users']
]);

$articles->save($article);

Salvando Associaes HasOne

Ao salvar associaes hasOne, o ORM espera uma nica entidade aninhada nomeada com a singular, underscored
verso do nome da associao. Por exemplo:

// Num controller.
$data = [
'id' => 1,
'username' => 'cakephp',
'profile' => [
'twitter' => '@cakephp'
]
];
$users = TableRegistry::get('Users');
$user = $users->newEntity($data, [
'associated' => ['Profiles']
]);
$users->save($user);

Salvando Associaes HasMany

Ao salvar associaes hasMany, o ORM espera um array de entidades nomeada com a plural, underscored verso do
nome da associao. Por exemplo:

// Num controller.
$data = [
'title' => 'First Post',
'comments' => [
['body' => 'Best post ever'],
['body' => 'I really like this.']
]
];
$articles = TableRegistry::get('Articles');
$article = $articles->newEntity($data, [
'associated' => ['Comments']
]);
$articles->save($article);

Ao salvar associaes hasMany, registros associados sero atualizados ou inseridos. Para os caso em que o registro j
tem registros associados no banco de dados, voc tem que escolher entre duas estrategias de salvamento:
append Os registros associados so atualizados no banco de dados ou, se no econtrado nenhum registro existente
ele inserido.
replace Todos os registros existentes que no esto presentes nos registros fornecidos sero removidos do banco
dados. Apenas os registros fornecidos permanecero (ou sero inseridos).

Mais informao 219


CakePHP Cookbook Documentation, Release 3.next

Por padro utilizado a estratgia de salvamento append. Consosule Associaes HasMany para mais detalhes sobre
como definir saveStrategy.
Sempre que voc adiciona novos registros a uma associao existente, voc sempre deve marcar a propriedade de
associao como dirty. Isso permite que o ORM saiba que a propriedade de associao tem que ser persistida:

$article->comments[] = $comment;
$article->dirty('comments', true);

Sem a chamada ao mtodo dirty() os comentrios atualizados no sero salvos.

Salvando Associaes BelongsToMany

Ao salvar associaes belongsToMany, o ORM espera um array de entidades nomeada com a plural, underscored
verso do nome da associao. Por exemplo:

// Num controller.
$data = [
'title' => 'First Post',
'tags' => [
['tag' => 'CakePHP'],
['tag' => 'Framework']
]
];
$articles = TableRegistry::get('Articles');
$article = $articles->newEntity($data, [
'associated' => ['Tags']
]);
$articles->save($article);

Ao converter dados de requisio em entidades, os mtodos newEntity() e newEntities() processaro ambos,


arrays de propriedades, bem como uma lista de ids na chave _ids. Utilizando a chave _ids facilita a criao de uma
caixa de seleo ou checkox para associaes pertence a muitos (belongs to many). Consulte a seo Convertendo
Dados de Requisio em Entidades para mais informaes.
Ao salvar associaes belongsToMany, voc tem que escolher entre duas estrategias de salvamento:
append Apenas novos links sero criados entre cada lado dessa associao. Essa estratgia no destruir links exis-
tentes, mesmo se no estiver presente no array de entidades a serem salvas.
replace Ao salvar, os links existentes sero removidos e novos links sero criados na tabela de ligao. Se houver
link existente no banco de dados para algumas das entidades a serem salvas, esses links sero atualizados, e no
excludos para ento serem salvos novamente.
Consulte Associaes BelongsToMany para detalhes de como definir saveStrategy.
Por padro utilizado a estratgia replace. Sempre que voc adiciona novos registros a uma associao existente,
voc sempre deve marcar a propriedade de associao como dirty. Isso permite que o ORM saiba que a propriedade
de associao tem que ser persistida:

$article->tags[] = $tag;
$article->dirty('tags', true);

Sem a chamada ao mtodo dirty() as tags atualizadas no sero salvas.


Frequentemente voc se encontrar querendo fazer uma associao entre duas entidades existentes, por exemplo. Um
usurio que autor de um artigo. Isso feito usando o mtodo link(), como isso:

220 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

$article = $this->Articles->get($articleId);
$user = $this->Users->get($userId);

$this->Articles->Users->link($article, [$user]);

Ao salvar associaes belongsToMany, pode ser relevente de salvar algumas informaes adicionais na tabela de
ligao. No exemplo anterior de tags, poderia ser o vote_type da pessoa que votou nesse artigo. O vote_type
pode ser upvote ou downvote e ele representado por uma string. A relao entre Users e Articles.
Salvando essa associaao, e o vote_type feito primeiramente adicionando alguns dados em _joinData e ento
salvando a associao com link(), exemplo:

$article = $this->Articles->get($articleId);
$user = $this->Users->get($userId);

$user->_joinData = new Entity(['vote_type' => $voteType], ['markNew' => true]);


$this->Articles->Users->link($article, [$user]);

Salvando Dados Adicionais na Tabela de Ligao

Em algumas situaes a tabela ligando sua associao BelongsToMany, ter colunas adicionais nela. CakePHP torna
simples salvar propriendade nessas colunas. Cada entidade em uma associao belongsToMany tem uma propriedade
_joinData que contm as colunas adicionais na tabela de ligao. Esses dados podem ser um array ou uma instncia
de Entity. Por exemplo se Students BelongsToMany Courses, ns poderamos ter uma tabela de ligao que parece
com:

id | student_id | course_id | days_attended | grade

Ao salvar dados, voc pode popular as colunas adicionais na tabela de ligao definindo dados na propriedade
_joinData:

$student->courses[0]->_joinData->grade = 80.12;
$student->courses[0]->_joinData->days_attended = 30;

$studentsTable->save($student);

A propriedade _joinData pode ser uma entity, ou um array de dados, se voc estiver salvando entidades construdas
a partir de dados de requisio. Ao salvar os dados de tabela de ligao apartir de dados de requisio, seus dados
POST devem parecer com:

$data = [
'first_name' => 'Sally',
'last_name' => 'Parker',
'courses' => [
[
'id' => 10,
'_joinData' => [
'grade' => 80.12,
'days_attended' => 30
]
],
// Other courses.
]
];
$student = $this->Students->newEntity($data, [

Mais informao 221


CakePHP Cookbook Documentation, Release 3.next

'associated' => ['Courses._joinData']


]);

Consulte a documentao Criando Inputs para Dados Associados para saber como criar inputs com FormHelper
corretamente.

Salvando Tipos Complexos (Complex Types)

As tabelas so capazes de armazenar dados representados em tipos bsicos, como strings, inteiros, flutuante, booleanos,
etc. Mas tambm pode ser estendido para aceitar tipos mais complexos, como arrays ou objects e serializar esses dados
em tipos mais simples que podem ser salvos em banco de dados.
Essa funcionalidade alcanada usando o sistema de tipos personalizados (custom types system). Consulte a seo
Adicionando Tipos Personalizados para descobrir como criar tipo de coluna personalizada (custom column Types):

// No config/bootstrap.php
use Cake\Database\Type;
Type::map('json', 'Cake\Database\Type\JsonType');

// No src/Model/Table/UsersTable.php
use Cake\Database\Schema\TableSchema;

class UsersTable extends Table


{

protected function _initializeSchema(TableSchema $schema)


{
$schema->columnType('preferences', 'json');
return $schema;
}

O cdigo acima mapeia a coluna preferences para o tipo personalizado (custom type) json. Isso significa que, ao
obter dados dessa coluna, ele ser desserializado de uma string JSON no banco de dados e colocado em uma entidade
como um array.
Da mesma forma, quando salvo, o array ser transformado novamente em sua representao de JSON:

$user = new User([


'preferences' => [
'sports' => ['football', 'baseball'],
'books' => ['Mastering PHP', 'Hamlet']
]
]);
$usersTable->save($user);

Ao usar tipos complexos, importante validar que os dados que voc est recebendo do usurio final so do tipo
correto. A falha ao gerir corretamente dados complexos, pode resultar em usurio mal-intencionados serem capazes
de armazenar dados que eles normalmente no seriam capaz.

Strict Saving

Cake\ORM\Table::saveOrFail($entity, $options = [])


Usar este mtodo lanar uma Cake\ORM\Exception\PersistenceFailedException se:

222 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

as verificaes das regras de validao falharam


a entidade contm erros
o save foi abortado por um callback.
Usar isso pode ser til quando voc estiver realizando operaes complexas no banco de dado sem monitoramento
humano, por exemplo, dentro de uma tarefa de Shell.

Nota: Se voc usar esse mtodo em um controller, certifique-se de tratar a PersistenceFailedException


que pode ser lanada.

Se voc quiser rastrear a entidade que falhou ao salvar, voc pode usar o mtodo
Cake\ORMException\PersistenceFailedException::getEntity():

try {
$table->saveOrFail($entity);
} catch (\Cake\ORM\Exception\PersistenceFailedException $e) {
echo $e->getEntity();
}

Como isso executa internamente uma chamada ao Cake\ORM\Table::save(), todos eventos de save correspon-
dentes sero disparados.
Novo na verso 3.4.1.

Salvando Vrias Entidades

Cake\ORM\Table::saveMany($entities, $options = [])


Usando esse mtodo voc pode salvar vrias entidades atomicamente. $entities podem ser um array de entida-
des criadas usando newEntities() / patchEntities(). $options pode ter as mesmas opes aceitas por
save():

$data = [
[
'title' => 'First post',
'published' => 1
],
[
'title' => 'Second post',
'published' => 1
],
];
$articles = TableRegistry::get('Articles');
$entities = $articles->newEntities($data);
$result = $articles->saveMany($entities);

O resultado ser as entidades atualizadas em caso de sucesso ou false em caso de falha.


Novo na verso 3.2.8.

Atualizao em Massa

Cake\ORM\Table::updateAll($fields, $conditions)

Mais informao 223


CakePHP Cookbook Documentation, Release 3.next

Pode haver momentos em que atualizar linhas individualmente no eficiente ou necessria. Nesses casos, mais
eficiente usar uma atualizao em massa para modificar vrias linhas de uma vez s:

// Publique todos artigos no publicados


function publishAllUnpublished()
{
$this->updateAll(
['published' => true], // fields
['published' => false]); // conditions
}

Se voc precisa de atualizao em massa e usar expresses SQL, voc precisar usar um objeto de expresso como
updateAll() usa prepared statements por baixo dos panos:

use Cake\Database\Expression\QueryExpression;

...

function incrementCounters()
{
$expression = new QueryExpression('view_count = view_count + 1');
$this->updateAll([$expression], ['published' => true]);
}

Uma atualizao em massa ser considera bem-sucedida se uma ou mais linhas forem atualizadas.

Aviso: updateAll no ir disparar os eventos beforeSave/afterSave. Se voc precisa deles, primeiro carregue uma
coleo de registros e ento atualize eles.

updateAll() apenas por convenincia. Voc tambm pode usar essa interface mais flexvel:

// Publique todos artigos no publicados.


function publishAllUnpublished()
{
$this->query()
->update()
->set(['published' => true])
->where(['published' => false])
->execute();
}

Consulte tambm: Atualizando Dados.

Excluindo Dados

class Cake\ORM\Table
Cake\ORM\Table::delete(Entity $entity, $options = [])
Depois que voc carregou uma entidade, voc pode excluir ela chamando o o mtodo delete da tabela de origem:

// Num a controller.
$entity = $this->Articles->get(2);
$result = $this->Articles->delete($entity);

Ao excluir entidades algumas coisas acontecem:

224 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

1. As delete rules sero aplicadas. Se as regras falharem, a excluso ser impedida.


2. O evento Model.beforeDelete disparado. Se esse evento for interrompido, a excluso ser cancelada e
o resultado do evento ser retornado.
3. A entidade ser excluda.
4. Todas as associaes dependentes sero excludas. Se as associaes esto sendo excludas como entidades,
eventos adicionais sero disparados.
5. Qualquer registro da tabela de ligao para associao BelongsToMany sero removidos.
6. O evento Model.afterDelete ser disparado.
Por padro, todas as excluses acontecem dentro de uma transao. Voc pode desativar a transao com a opo
atomic:

$result = $this->Articles->delete($entity, ['atomic' => false]);

Excluso em Cascata

Ao excluir entidades, os dados associados tambm podem ser excludos. Se suas associaes HasOne e HasMany
esto configurados como dependent, as operaes de excluso sero cascate para essas entidades tambm.
Por padro entidades em tabelas associadas so removidas usando Cake\ORM\Table::deleteAll(). Voc
pode optar que o ORM carregue as entidades relacionadas, para ento excluir individualmente, definindo a opo
cascadeCallbacks como true:

// No mtodo initialize de alguma modelo Table


$this->hasMany('Comments', [
'dependent' => true,
'cascadeCallbacks' => true,
]);

Nota: Configurando cascadeCallbacks para true, resulta em excluses consideravelmente mais lentos quando
comparado com excluso em masa. A opo cascadeCallbacks apenas deve ser ativada quando sua aplicao tem
trabalho importante manipulado por event listeners.

Excluso em Massa

Cake\ORM\Table::deleteAll($conditions)
Pode ter momentos em que excluir linhas individualmente no eficiente ou til. Nesses casos, mais eficiente usar
uma excluso em massa para remover vrias linhas de uma vez s:

// Exclui todos oss spam


function destroySpam()
{
return $this->deleteAll(['is_spam' => true]);
}

Uma excluso em massa ser considerada bem-sucedida se uma ou mais linhas forem excludas.

Aviso: deleteAll no dispara os eventos beforeDelete/afterDelete. Se voc precisa deles, voc precisa, primeiro
carregar uma coleo de registros e ento exclu-las.

Mais informao 225


CakePHP Cookbook Documentation, Release 3.next

Excluses Estrita

Cake\ORM\Table::deleteOrFail($entity, $options = [])


Usar esse mtodo lanar uma Cake\ORM\Exception\PersistenceFailedException se:
a entidade nova
a entidade no tem valor de chave primria
as verificaes das regras da aplicao falharam
a excluso foi interrompida por um callback.
Se voc deseja rastrear a entidade que falhou ao salvar, voc pode usar o mtodo
Cake\ORMException\PersistenceFailedException::getEntity():

try {
$table->deleteOrFail($entity);
} catch (\Cake\ORM\Exception\PersistenceFailedException $e) {
echo $e->getEntity();
}

Como isso executa internamente uma chamada ao Cake\ORM\Table::delete(), todos eventos de excluso
correspondentes sero disparados.
Novo na verso 3.4.1.

Associaes - Conectando tabelas

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github111 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Associaes HasOne

Associaes HasMany

Associaes BelongsToMany

Behaviors (Comportamentos)

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github112 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
111 https://github.com/cakephp/docs
112 https://github.com/cakephp/docs

226 Captulo 12. Models (Modelos)


CakePHP Cookbook Documentation, Release 3.next

Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

CounterCache

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github113 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Timestamp

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github114 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Translate

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github115 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Tree

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github116 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

113 https://github.com/cakephp/docs
114 https://github.com/cakephp/docs
115 https://github.com/cakephp/docs
116 https://github.com/cakephp/docs

Mais informao 227


CakePHP Cookbook Documentation, Release 3.next

Schema

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github117 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

ORM Cache Shell

O OrmCacheShell fornece uma ferramenta CLI simples para gerenciar caches de metadados da sua aplicao. Em
situaes de implantao, 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 conexo default. Se voc s precisa reconstruir
uma nica tabela, voc pode fazer isso fornecendo seu nome:

bin/cake orm_cache build --connection default <<Nome>>

Alm de criar dados em cache, voc pode usar o OrmCacheShell para remover metadados em cache tambm:

# Limpar todos os metadados


bin/cake orm_cache clear

# Limpar uma nica tabela de metadados


bin/cake orm_cache clear <<Nome>>

117 https://github.com/cakephp/docs

228 Captulo 12. Models (Modelos)


CAPTULO 13

Bake Console

O bake console do CakePHP outro empenho para voc ter o CakePHP configurado e funcionando rpido. O bake
console pode criar qualquer ingrediente bsico do CakePHP: models, behaviors, views, helpers, components, test
cases, fixtures e plugins. E ns no estamos apenas falando de classes esqueleto: O Bake pode criar uma aplicao
totalmente funcional em questo de minutos. De fato, o Bake um passo natural a se dar uma vez que a aplicao tem
seu alicerce construdo.

Instalao

Antes de tentar usar ou extender o bake, tenha certeza que ele est instalado em sua aplicao. O bake distribudo
como um plugin que voc pode instalar com o Composer:

composer require --dev cakephp/bake:~1.0

Isto ir instalar o bake como uma dependncia de desenvolvimento, sendo assim, no instalado quando em um ambi-
ente de produo. As sees a seguir cobrem o uso do bake com mais detalhes:

Gerao de cdigo com o Bake

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github118 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Extendendo o Bake

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


118 https://github.com/cakephp/docs

229
CakePHP Cookbook Documentation, Release 3.next

Por favor, sinta-se a vontade para nos enviar um pull request para o Github119 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

119 https://github.com/cakephp/docs

230 Captulo 13. Bake Console


CAPTULO 14

Caching

Configuring Cache Class

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github120 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

120 https://github.com/cakephp/docs

231
CakePHP Cookbook Documentation, Release 3.next

232 Captulo 14. Caching


CAPTULO 15

Console e Shells

O CakePHP no oferece um framework apenas para desenvolvimento web, mas tambm um framework para criao de
aplicaes de console. Estas aplicaes so ideais para manipular variadas tarefas em segundo plano como manuteno
e complementao de trabalho fora do ciclo requisio-resposta. As aplicaes de console do CakePHP permitem a
voc reutilizar suas classes de aplicao a partir da linha de comando.
O CakePHP traz consigo algumas aplicaes de console nativas. Algumas dessas aplicaes so utilizadas em conjunto
com outros recursos do CakePHP (como i18n), e outros de uso geral para acelerao de trabalho.

O Console do CakePHP

Esta seo prov uma introduo linha de comando do CakePHP. Ferramentas de console so ideais para uso em
cron jobs, ou utilitrios baseados em linha de comando que no precisam ser acessveis por um navegador web.
O PHP prov um cliente CLI que faz interface com o seu sistema de arquivos e aplicaes de forma muito mais
suave. O console do CakePHP prov um framework para criar scripts shell. O console utiliza uma configurao tipo
dispatcher para carregar uma shell ou tarefa, e prover seus parmetros.

Nota: Uma linha de comando (CLI) constutuda a partir do PHP deve estar disponvel 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 seo sero em bash, mas o Console do CakePHP
compatvel com o Windows tambm. Este exemplo assume que o usurio est conectado em um prompt do bash e
est atualmente na raiz de uma aplicao CakePHP.
Aplicaes CakePHP possuem um diretrio Console que contm todas as shells e tarefas para uma aplicao. Ele
tambm vem com um executvel:

$ cd /path/to/app
$ bin/cake

Executar o Console sem argumentos produz esta mensagem de ajuda:

Welcome to CakePHP v3.0.0 Console


---------------------------------------------------------------

233
CakePHP Cookbook Documentation, Release 3.next

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 informao 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 diretrio src/Shell de sua aplicao crie HelloShell.php. Coloque o seguinte cdigo dentro do arquivo
recem criado:

namespace App\Shell;

use Cake\Console\Shell;

class HelloShell extends Shell


{
public function main()
{
$this->out('Hello world.');
}
}

As convenes para as classes de shell so de que o nome da classe deve corresponder ao nome do arquivo, com o
sufixo de Shell. No nosso shell criamos um mtodo main(). Este mtodo 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 diretrio da aplicao, execute:

234 Captulo 15. Console e Shells


CakePHP Cookbook Documentation, Release 3.next

bin/cake hello

Voc deve ver a seguinte sada:

Welcome to CakePHP Console


---------------------------------------------------------------
App : app
Path: /Users/markstory/Sites/cake_dev/src/
---------------------------------------------------------------
Hello world.

Como mencionado antes, o mtodo main() em shells um mtodo especial chamado sempre que no h outros co-
mandos ou argumentos dados para uma shell. Por nosso mtodo principal no 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 mtodo pblico no prefixado por um _ permitido para ser chamado a partir da linha de comando. Como
voc pode ver, os mtodos invocados a partir da linha de comando so transformados do argumento prefixado para a
forma correta do nome camel-cased (camelizada) na classe.
No nosso mtodo heyThere() podemos ver que os argumentos posicionais so providos para nossa funo
heyThere(). Argumentos posicionais tambm esto disponvels na propriedade args. Voc pode acessar switches
ou opes em aplicaes shell, estando disponveis em $this->params, mas ns iremos cobrir isso daqui a pouco.
Quando utilizando um mtodo main() voc no estar liberado para utilizar argumentos posicionais. Isso se deve
ao primeiro argumento posicional ou opo ser interpretado(a) como o nome do comando. Se voc quer utilizar
argumentos, voc deve usar mtodos diferentes de main().

Usando Models em suas shells

Voc frequentemente precisar acessar a camada lgica de negcios em seus utilitrios shell; O CakePHP faz essa
tarefa super fcil. Voc pode carregar models em shells assim como faz em um controller utilizando loadModel().
Os models carregados so definidos como propriedades anexas sua shell:

namespace App\Shell;

Criando uma Shell 235


CakePHP Cookbook Documentation, Release 3.next

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 usurio.');
}
$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 informao armazenada no banco de dados.

Tasks de Shell

Havero momentos construindo aplicaes mais avanadas de console que voc vai querer compor funcionalidades
em classes reutilizveis que podem ser compartilhadas atravs 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 padro sintaxe plugin. Tasks so armazenadas sob Shell/Task/
em arquivos nomeados depois de suas classes. Ento se ns estivssemos criando uma nova task FileGenerator, voc
deveria criar src/Shell/Task/FileGeneratorTask.php.
Cada task deve ao menos implementar um mtodo main(). O ShellDispatcher, vai chamar esse mtodo 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 tambm pode prover acesso a suas tasks como propriedades, que fazem tasks serem timas para criar
punhados de funcionalidade reutilizveis similares a Components (Componentes):

236 Captulo 15. Console e Shells


CakePHP Cookbook Documentation, Release 3.next

// 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 tambm pode acessar tasks diretamente da linha de comando:

$ cake sea sound

Nota: Para acessar tasks diretamente atravs da linha de comando, a task deve ser includa na propriedade da classe
shell $tasks. Portanto, esteja ciente que um mtodo 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 no foram
declaradas no $tasks dessa forma:

$project = $this->Tasks->load('Project');

Carregar e retornar uma instncia ProjectTask. Voc pode carregar tasks de plugins usando:

$progressBar = $this->Tasks->load('ProgressBar.ProgressBar');

Invocando outras Shells a partir da sua Shell

Cake\Console\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 argu-
mentos e opes tanto como variveis ou como strings:

// Como uma string


$this->dispatchShell('schema create Blog --plugin Blog');

// Como um array
$this->dispatchShell('schema', 'create', 'Blog', '--plugin', 'Blog');

O contedo acima mostra como voc pode chamar a shell schema para criar o schema de um plugin de dentro da shell
do prprio.

Invocando outras Shells a partir da sua Shell 237


CakePHP Cookbook Documentation, Release 3.next

Recenendo Input de usurios

Cake\Console\in($question, $choices = null, $defaut = null)


Quando construir aplicaes interativas pelo console voc ir precisar receber inputs dos usurios. CakePHP oferece
uma forma fcil de fazer isso:

// Receber qualquer texto dos usurios.


$color = $this->in('What color do you like?');

// Receber uma escolha dos usurios.


$selection = $this->in('Red or Green?', ['R', 'G'], 'R');

A validao de seleo insensitiva a maisculas / minsculas.

Criando Arquivos

Cake\Console\createFile($path, $contents)
Muitas aplicaes Shell auxiliam tarefas de desenvolvimento e implementao. Criar arquivos frequentemente im-
portante nestes casos de uso. O CakePHP oferece uma forma fcil de criar um arquivo em um determinado diretrio:

$this->createFile('bower.json', $stuff);

Se a Shell for interativa, um alerta vai ser gerado, e o usurio questionado se ele quer sobreescrever o arquivo caso j
exista. Se a propriedade de interao da shell for false, nenhuma questo ser disparada e o arquivo ser simples-
mente sobreescrito.

Sada de dados do Console

A classe Shell oferece alguns mtodos para direcionar contedo:

// 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 tambm inclui mtodos para limpar a sada de dados, criando linhas em branco, ou desenhando uma linha de
traos:

// Exibe 2 linhas novas


$this->out($this->nl(2));

// Limpa a tela do usurio


$this->clear();

// Desenha uma linha horizontal


$this->hr();

238 Captulo 15. Console e Shells


CakePHP Cookbook Documentation, Release 3.next

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 no pode sobreescrever texto uma vez que uma nova linha tenha sido exibida.

Console Output Levels

Shells frequentemente precisam de diferentes nveis de verbosidade. Quando executadas como cron jobs, muitas sadas
so desnecessrias. E h ocasies que voc no estar interessado em tudo que uma shell tenha a dizer. Voc pode usar
os nveis de sada para sinalizar sadas apropriadamente. O usurio da shell, pode ento decidir qual nvel de detalhe
ele est interessado ao sinalizar o chamado da shell. Cake\Console\Shell::out() suporta 3 tipos de sada por
padro.
QUIET - Apenas informao absolutamente importante deve ser sinalizada.
NORMAL - O nvel padro, e uso normal.
VERBOSE - Sinalize mensagens que podem ser irritantes em demasia para uso dirio, mas informativas para
depurao como VERBOSE.
Voc pode sinalizar a sade da seguinte forma:

// Deve aparecer em todos os nveis.


$this->out('Quiet message', 1, Shell::QUIET);
$this->quiet('Quiet message');

// No deve aparecer quando a sada 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 sade verbose estiver habilitada.


$this->out('extra message', 1, Shell::VERBOSE);
$this->verbose('Verbose output');

Voc pode controlar o nvel de sada das shells, ao usar as opes --quiet e --verbose. Estas opes so adici-
onadas por padro, e permitem a voc controlar consistentemente nveis de sada dentro das suas shells do CakePHP.

Estilizando a sada de dados

Estilizar a sada de dados feito ao incluir tags - como no HTML - em sua sada. O ConsoleOutput ir substituir estas
tags com a seqncia correta de cdigo ansi. Ho diversos estilos nativos, e voc pode criar mais. Os nativos so:
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 questo, adicionado automaticamente pela shell.

Sada de dados do Console 239


CakePHP Cookbook Documentation, Release 3.next

Voc pode criar estilos adicionais usando $this->stdout->styles(). Para declarar um novo estilo de sade
voc pode fazer:

$this->_io->styles('flashy', ['text' => 'magenta', 'blink' => true]);

Isso deve ento permit-lo usar uma <flashy> tag na sada de sua shell, e se as cores ansi estiverem habilitadas,
o seguinte pode ser renderizado como texto magenta piscante $this->out('<flashy>Whoooa</flashy>
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 tambm pode usar as seguintes opes atravs de valores boleanos, defini-los com valor positivo os habilita.
bold
underline
blink
reverse
Adicionar um estilo o torna disponvel para todas as instncias do ConsoleOutput, ento voc no tem que redeclarar
estilos para os objetos stdout e stderr respectivamente.

Desabilitando a colorizao

Mesmo que a colorizao seja incrvel, havero ocasies que voc querer desabilit-la, ou for-la:

$this->_io->outputAs(ConsoleOutput::RAW);

O citado ir colocar o objeto de sada em modo raw. Em modo raw, nenhum estilo aplicado. Existem trs modos que
voc pode usar.
ConsoleOutput::RAW - Sada raw, nenhum estilo ou formatao sero aplicados. Este um modo indicado
se voc estiver exibindo XML ou, quiser depurar porqu seu estilo no est funcionando.
ConsoleOutput::PLAIN - Sada de texto simples, tags conhecidas de estilo sero removidas da sada.
ConsoleOutput::COLOR - Sada onde a cor removida.
Por padro em sistemas *nix objetos ConsoleOutput padronizam-se a a sada de cores. Em sistemas Windows, a sada
simples padro a no ser que a varivel de ambiente ANSICON esteja presente.

Opes de configurao e Gerao de ajuda

class Cake\Console\ConsoleOptionParser

240 Captulo 15. Console e Shells


CakePHP Cookbook Documentation, Release 3.next

ConsoleOptionParser oferece uma opo de CLI e analisador de argumentos.


OptionParsers permitem a voc completar dois objetivos ao mesmo tempo. Primeiro, eles permitem definir opes
e argumentos para os seus comandos. Isso permite separar validao bsica de dados e seus comandos do console.
Segundo, permite prover documentao, que usada para gerar arquivos de ajuda bem formatados.
O console framework no CakePHP recebe as opes do seu interpetador shell ao chamar
$this->getOptionParser(). Sobreescrever esse mtodo permite configurar o OptionParser para definir
as entradas aguardadas da sua shell. Voc tambm pode configurar interpetadores de subcomandos, que permitem
ter diferentes interpretadores para subcomandos e tarefas. O ConsoleOptionParser implementa uma interface fluida e
inclui mtodos para facilmente definir mltiplas opes/argumentos de uma vez:

public function getOptionParser()


{
$parser = parent::getOptionParser();
// Configure parser
return $parser;
}

Configurando um interpretador de opo com a interface fluida

Todos os mtodos que configuram um interpretador de opes podem ser encadeados, permitindo definir um interpre-
tador de opes completo em uma srie de chamadas de mtodos:

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 mtodos que permitem encadeamento so:


description()
epilog()
command()
addArgument()
addArguments()
addOption()
addOptions()
addSubcommand()
addSubcommands()
Cake\Console\ConsoleOptionParser::description($text = null)

Opes de configurao e Gerao de ajuda 241


CakePHP Cookbook Documentation, Release 3.next

Recebe ou define a descrio para o interpretador de opes. A descrio exibida acima da informao do argumento
e da opo. Ao instanciar tanto em array como em string, voc pode definir o valor da descrio. Instanciar sem
argumentos vai retornar o valor atual:

// Define mltiplas linhas de uma vez


$parser->description(['line one', 'line two']);

// L o valor atual
$parser->description();

Cake\Console\ConsoleOptionParser::epilog($text = null)
Recebe ou define o eplogo para o interpretador de opes. O eplogo exibido depois da informao do argumento
e da opo. Ao instanciar tanto em array como em string, voc pode definir o valor do eplogo. Instanciar sem
argumentos vai retornar o valor atual:

// Define mltiplas linhas de uma vez


$parser->epilog(['line one', 'line two']);

// L o valor atual
$parser->epilog();

Adicionando argumentos

Cake\Console\ConsoleOptionParser::addArgument($name, $params = [])


Argumentos posicionais so frequentemente usados em ferramentas de linha de comando, e
ConsoleOptionParser permite definir argumentos bem como torn-los requirveis. Voc pode adi-
cionar argumentos um por vez com $parser->addArgument(); ou mltiplos de uma vez com
$parser->addArguments();:

$parser->addArgument('model', ['help' => 'The model to bake']);

Voc pode usar as seguintes opes ao criar um argumento:


help O texto de ajuda a ser exibido para este argumento.
required Se esse parmetro 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 opo ser sobreescrita.
choices Um array de opes vlidas para esse argumento. Se deixado vazio, todos os valores so vlidos.
Uma exceo ser lanada quando parse() encontrar um valor invlido.
Argumentos que forem definidos como requisito lanaro uma exceo quando interpretarem o comando se eles forem
omitidos. Ento voc no tem que lidar com isso em sua shell.
Cake\Console\ConsoleOptionParser::addArguments(array $args)
Se voc tem um array com mltiplos 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]
]);

242 Captulo 15. Console e Shells


CakePHP Cookbook Documentation, Release 3.next

Assim como todos os mtodos de construo no ConsoleOptionParser, addArguments pode ser usado como parte de
um fluido mtodo encadeado.

Validando argumentos

Ao criar argumentos posicionais, voc pode usar a marcao required para indicar que um argumento deve estar
presente quando uma shell chamada. Adicionalmente voc pode usar o choices para forar um argumento a ser
de uma lista de escolhas vlidas:

$parser->addArgument('type', [
'help' => 'The type of node to interact with.',
'required' => true,
'choices' => ['aro', 'aco']
]);

O cdigo acima ir criar um argumento que requisitado e tem validao no input. Se o argumento est tanto indefi-
nodo, ou possui um valor incorreto, uma exceo ser lanada e a shell parar.

Adicionando opes

Cake\Console\ConsoleOptionParser::addOption($name, $options = [])


Opes so frequentemente usadas em ferramentas CLI. ConsoleOptionParser suporta a criao de opes
com verbose e aliases curtas, suprindo padres e criando ativadores boleanos. Opes so criadas tanto com
$parser->addOption() ou $parser->addOptions().:

$parser->addOption('connection', [
'short' => 'c',
'help' => 'connection',
'default' => 'default',
]);

O cdigo citado permite a voc usar tanto cake myshell --connection=other, cake myshell
--connection other, ou cake myshell -c other quando invocando a shell. Voc tambm criar ati-
vadores boleanos. Estes ativadores no consumem valores, e suas presenas apenas os habilitam nos parmetros
interpretados.:

$parser->addOption('no-commit', ['boolean' => true]);

Com essa opo, ao chamar uma shell como cake myshell --no-commit something o parmetro no-
commit deve ter um valor de true, e something deve ser tratado como um argumento posicional. As opes nativas
--help, --verbose, e --quiet usam essa funcionalidade.
Ao criar opes voc pode usar os seguintes argumentos para definir o seu comportamento:
short - A variao de letra nica para essa opo, deixe indefinido para none.
help - Texto de ajuda para essa opo. Usado ao gerar ajuda para a opo.
default - O valor padro para essa opo. Se no estiver definido o valor padro ser true.
boolean - A opo no usa valor, apenas um ativador boleano. Por padro false.
choices - Um array de escolhas vlidas para essa opo. Se deixado vazio, todos os valores so considerados
vlidos. Uma exceo ser lanada quando parse() encontrar um valor invlido.
Cake\Console\ConsoleOptionParser::addOptions(array $options)

Opes de configurao e Gerao de ajuda 243


CakePHP Cookbook Documentation, Release 3.next

Se voc tem um array com mltiplas opes, 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 mtodos construtores, no ConsoleOptionParser, addOptions pode ser usado como parte de
um mtodo fluente encadeado.

Validando opes

Opes podem ser fornecidas com um conjunto de escolhas bem como argumentos posicionais podem ser. Quando
uma opo define escolhas, essas so as nicas opes vlidas para uma opo. Todos os outros valores iro gerar um
InvalidArgumentException:

$parser->addOption('accept', [
'help' => 'What version to accept.',
'choices' => ['working', 'theirs', 'mine']
]);

Usando opes boleanas

As opes podem ser definidas como opes boleanas, que so teis quando voc precisa criar algumas opes de
marcao. Como opes com padres, opes boleanas sempre iro incluir -se nos parmetros analisados. Quando as
marcaes esto presentes elas so definidas para true, quando elas esto ausentes, so definidas como false:

$parser->addOption('verbose', [
'help' => 'Enable verbose output.',
'boolean' => true
]);

A opo seguinte resultaria em $this->params['verbose'] sempre estando disponvel. Isso permite a voc
omitir verificaes empty() ou isset() em marcaes boleanas:

if ($this->params['verbose']) {
// Do something.
}

Desde que as opes boleanas estejam sempre definidas como true ou false, voc pode omitir mtodos de verifi-
cao adicionais.

Adicionando subcomandos

Cake\Console\ConsoleOptionParser::addSubcommand($name, $options = [])


Aplicativos de console so muitas vezes feitas de subcomandos, e esses subcomandos podem exigir a anlise de
opes especiais e terem a sua prpria ajuda. Um perfeito exemplo disso bake. Bake feita de muitas tarefas
separadas e todas tm a sua prpria ajuda e opes. ConsoleOptionParser permite definir subcomandos e
fornecer comandos analisadores de opo especfica, de modo que a shell sabe como analisar os comandos para as
suas funes:

244 Captulo 15. Console e Shells


CakePHP Cookbook Documentation, Release 3.next

$parser->addSubcommand('model', [
'help' => 'Bake a model',
'parser' => $this->Model->getOptionParser()
]);

A descrio acima um exemplo de como voc poderia fornecer ajuda e um especializado interpretador de opo
para a tarefa de uma shell. Ao chamar a tarefa de getOptionParser() no temos de duplicar a gerao do
interpretador de opo, ou misturar preocupaes 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
tambm d fcil acesso ao subcomando help. Com o subcomando acima criado voc poderia chamar cake myshell
--help e ver a lista de subcomandos, e tambm executar o cake myshell model --help para exibir a ajuda
apenas o modelo de tarefa.

Nota: Uma vez que seu Shell define subcomandos, todos os subcomandos deve ser explicitamente definidos.

Ao definir um subcomando, voc pode usar as seguintes opes:


help - Texto de ajuda para o subcomando.
parser - Um ConsoleOptionParser para o subcomando. Isso permite que voc crie mtodos analisado-
res de opo especfios. Quando a ajuda gerada por um subcomando, se um analisador est presente
ele vai ser usado. Voc tambm pode fornecer o analisador como uma matriz que seja compatvel com
Cake\Console\ConsoleOptionParser::buildFromArray()
Adicionar subcomandos pode ser feito como parte de uma cadeia de mtodos fluente.

Construir uma ConsoleOptionParser de uma matriz

Cake\Console\ConsoleOptionParser::buildFromArray($spec)
Como mencionado anteriormente, ao criar interpretadores de opo de subcomando, voc pode definir a especificao
interpretadora como uma matriz para esse mtodo. 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 especificao do interpretador, voc pode definir as chaves para arguments, options, description
e epilog. Voc no pode definir subcommands dentro de um construtor estilo array. Os valores para os argumen-
tos e opes, devem seguir o formato que Cake\Console\ConsoleOptionParser::addArguments() e
Cake\Console\ConsoleOptionParser::addOptions() usam. Voc tambm pode usar buildFromArray
por conta prpria, para construir um interpretador de opo:

Opes de configurao e Gerao de ajuda 245


CakePHP Cookbook Documentation, Release 3.next

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 adio de ConsoleOptionParser receber ajuda de shells feito de uma forma consistente e uniforme. Ao usar a
opo --help ou -h voc pode visualizar a ajuda para qualquer ncleo 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 especfica para a tarefa bake dos models.

Recebendo ajuda como XML

Quando a construo de ferramentas automatizadas ou ferramentas de desenvolvimento que necessitam interagir com
shells do CakePHP, bom ter ajuda disponvel em uma mquina 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, opes, argumentos e subcomando para o
shell selecionado. Um documento XML de amostra seria algo como:

<?xml version="1.0"?>
<shell>
<command>bake fixture</command>
<description>Generate fixtures for use with the test suite. You can use
`bake fixture all` to bake all fixtures.</description>
<epilog>
Omitting all arguments and options will enter into an interactive
mode.
</epilog>

246 Captulo 15. Console e Shells


CakePHP Cookbook Documentation, Release 3.next

<subcommands/>
<options>
<option name="--help" short="-h" boolean="1">
<default/>
<choices/>
</option>
<option name="--verbose" short="-v" boolean="1">
<default/>
<choices/>
</option>
<option name="--quiet" short="-q" boolean="1">
<default/>
<choices/>
</option>
<option name="--count" short="-n" boolean="">
<default>10</default>
<choices/>
</option>
<option name="--connection" short="-c" boolean="">
<default>default</default>
<choices/>
</option>
<option name="--plugin" short="-p" boolean="">
<default/>
<choices/>
</option>
<option name="--records" short="-r" boolean="1">
<default/>
<choices/>
</option>
</options>
<arguments>
<argument name="name" help="Name of the fixture to bake.
Can use Plugin.name to bake plugin fixtures." required="">
<choices/>
</argument>
</arguments>
</shell>

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 especfica, no esto definidas.
Se voc gerar relatrios ou enviar e-mails que fazem uso de Router::url(), estes contero a mquina padro
http://localhost/ e resultando assim em URLs invlidas. Neste caso, voc precisa especificar o domnio
manualmente. Voc pode fazer isso usando o valor de configurao App.fullBaseUrl no seu bootstrap ou na sua
configurao, 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 so vlidos e adequados para o domnio a partir do qual os e-mails so
enviados.

Roteamento em Shells / CLI 247


CakePHP Cookbook Documentation, Release 3.next

Mtodos enganchados

Cake\Console\ConsoleOptionParser::initialize()
Inicializa a Shell para atua como construtor de subclasses e permite configurao de tarefas antes de desenvolver
a execuo.
Cake\Console\ConsoleOptionParser::startup()
Inicia-se a Shell e exibe a mensagem de boas-vindas. Permite a verificao e configurao antes de comandar
ou da execuo principal.
Substitua este mtodo se voc quiser remover as informaes de boas-vindas, ou outra forma modificar o fluxo
de pr-comando.

Mais tpicos

Shell Helpers

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github121 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Console Interativo (REPL)

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github122 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

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 so de domingo a sbado, ou
use os nomes)

# | | | \---------- ms (1 - 12)

121 https://github.com/cakephp/docs
122 https://github.com/cakephp/docs

248 Captulo 15. Console e Shells


CakePHP Cookbook Documentation, Release 3.next

# | | \--------------- dia do ms (1 - 31)


# | \-------------------- hora (0 - 23)
# \------------------------- minuto (0 - 59)

Voc pode ver mais informaes aqui: https://pt.wikipedia.org/wiki/Crontab

Dica: Use -q (ou quiet) para silenciar qualquer sada para cronjobs.

I18N Shell

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github123 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Completion Shell

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github124 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Plugin Shell

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github125 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Routes Shell

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


123 https://github.com/cakephp/docs
124 https://github.com/cakephp/docs
125 https://github.com/cakephp/docs

Mais tpicos 249


CakePHP Cookbook Documentation, Release 3.next

Por favor, sinta-se a vontade para nos enviar um pull request para o Github126 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Upgrade Shell

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github127 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Server Shell

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github128 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Cache Shell

Para ajud-lo a gerenciar melhor os dados armazenados em cache a partir de um ambiente CLI, um comando shell est
disponvel para limpar os dados em cache que seu aplicativo possui:

// Limpar uma configurao de cache


bin/cake cache clear <configname>

// Limpar todas as configuraes de cache


bin/cake cache clear_all

Novo na verso 3.3.0: Os comandos shell do cache foram adicionados na verso 3.3.0

126 https://github.com/cakephp/docs
127 https://github.com/cakephp/docs
128 https://github.com/cakephp/docs

250 Captulo 15. Console e Shells


CAPTULO 16

Depurao

Depurao uma etapa inevitvel e importante de qualquer ciclo de desenvolvimento. Ainda que o CakePHP no
fornea nenhuma ferramenta que se conecte com qualquer IDE ou editor de texto, este oferece vrias ferramentas que
auxiliam na depurao e exibio de tudo que est sendo executado por baixo dos panos na sua aplicao.

Depurao Bsica

debug(mixed $var, boolean $showHtml = null, $showFrom = true)


A funo debug() uma funo de escopo global que funciona de maneira similar a funo PHP print_r(). A
funo debug() exibe os contedos de uma varivel de diversas maneiras. Primeiramente, se voc deseja exibir os
dados no formato HTML, defina o segundo parmetro como true. A funo tambm exibe a linha e o arquivo de
onde a mesma foi chamada.
A sada da funo somente exibida caso a varivel $debug do core esteja definida com o valor true.
stackTrace()
A funo stackTrace() uma funo de escopo global, funo esta que permite que seja exibida a pilha de
execuo onde quer que a mesma tenha sido chamada.
breakpoint()
Novo na verso 3.1.
Se voc tem o Psysh129 instalado poder usar esta funo em ambientes de interface de linha de comando (CLI) para
abrir um console interativo com o escopo local atual:

// Some code
eval(breakpoint());

Abrir um console interativo que poder ser utilizado para avaliar variveis locais e executar outros trechos de cdigo.
Voc pode sair do depurador interativo executando os comandos quit ou q na sesso.
129 http://psysh.org/

251
CakePHP Cookbook Documentation, Release 3.next

Usando a Classe Debugger

class Cake\Error\Debugger
Para usar o depurador, assegure que Configure::read('debug') esteja definida como true.

Valores de sada

static Cake\Error\Debugger::dump($var, $depth = 3)


O mtodo dump exibe o contedo da varivel, incluindo todas as propriedades e mtodos (caso existam) da varivel
fornecida no primeiro parmetro:
$foo = [1,2,3];

Debugger::dump($foo);

// Sadas
array(
1,
2,
3
)

// Objeto
$car = new Car();

Debugger::dump($car);

// Sadas
object(Car) {
color => 'red'
make => 'Toyota'
model => 'Camry'
mileage => (int)15000
}

Criando Logs com Pilha de Execuo

static Cake\Error\Debugger::log($var, $level = 7, $depth = 3)


Cria um log detalhado da pilha de execuo no momento em que a mesma foi invocada. O mtodo log() exibe dados
similares aoDebugger::dump(), mas no arquivo debug.log ao invs do buffer de sada principal. valido ressaltar
que o diretrio tmp e seu contedo devem ter permisso de escrita para o servidor web a fim de que a funo log()
consiga executar corretamente.

Gerando Pilhas de Execuo

static Cake\Error\Debugger::trace($options)
Retorna a pilha de execuo atual. Cada linha inclui o mtodo que chamou, qual arquivo e linha do qual a chamada
foi originada:

252 Captulo 16. Depurao


CakePHP Cookbook Documentation, Release 3.next

// Em PostsController::index()
pr(Debugger::trace());

// Sadas
PostsController::index() - APP/Controller/DownloadsController.php, line 48
Dispatcher::_invoke() - CORE/src/Routing/Dispatcher.php, line 265
Dispatcher::dispatch() - CORE/src/Routing/Dispatcher.php, line 237
[main] - APP/webroot/index.php, line 84

Abaixo encontra-se a pilha de execuo gerada ao chamar Debugger::trace() em uma ao de um controller. A


leitura do fim para o incio da pilha exibe a ordem de execuo das funes.

Pegando Trechos de Arquivos

static Cake\Error\Debugger::excerpt($file, $line, $context)


Colete um trecho de um arquivo localizado em $path (caminho absoluto), na linha $line com nmero de linhas em
torno deste trecho $context:
pr(Debugger::excerpt(ROOT . DS . LIBS . 'debugger.php', 321, 2));

// Gera como sada o seguinte:


Array
(
[0] => <code><span style="color: #000000"> * @access public</span></code>
[1] => <code><span style="color: #000000"> */</span></code>
[2] => <code><span style="color: #000000"> function excerpt($file, $line,
$context = 2) {</span></code>

[3] => <span class="code-highlight"><code><span style="color: #000000">


$data = $lines = array();</span></code></span>
[4] => <code><span style="color: #000000"> $data = @explode("\n", file_get_
contents($file));</span></code>

Ainda que este mtodo seja usado internamente, o mesmo pode ser conveniente caso voc esteja criando suas prprias
mensagens de erros e registros de logs.
static Cake\Error\Debugger::getType($var)
Obtm o tipo da varivel. Caso seja um objeto, o retorno do mtodo ser o nome de sua classe

Usando Logging para Depurao

Registrar as mensagens uma outra boa maneira de se depurar aplicaes. Para isto, pode ser usada a classe
Cake\Log\Log para fazer o logging na sua aplicao. Todos os objetos que fazem uso de LogTrait tm um
mtodo de instanciao log() que pode ser usado para registrar mensagens:
$this->log('Cheguei aqui', 'debug');

O cdigo acima escrever Cheguei aqui no arquivo de registros de depurao (debug log). Voc pode usar seus
registros para auxiliar na depurao de mtodos que contm redirecionamentos e laos complicados. Voc poder usar
tambm Cake\Log\Log::write() para escrever mensagens nos registros. Esse mtodo pode ser chamado de
forma esttica em qualquer lugar da sua aplicao, pressupondo-se que Log j esteja carregado:

Pegando Trechos de Arquivos 253


CakePHP Cookbook Documentation, Release 3.next

// No incio do arquivo que deseja registrar.


use Cake\Log\Log;

// Em qualquer lugar que Log tenha sido importado.


Log::debug('Cheguei aqui');

Debug Kit

O DebugKit um plugin composto por timas ferramentas de depurao. Uma dessas ferramentas uma toolbar
renderizada em HTML, na qual possvel visualizar uma grande quantidade de informaes sobre sua aplicao e a
atual requisio realizada pela mesma. Veja no captulo Debug Kit como instalar e usar o DebugKit.

254 Captulo 16. Depurao


CAPTULO 17

Implantao

Uma vez que sua aplicao est completa, ou mesmo antes quando voc quiser coloc-la no ar. Existem algumas
poucas coisas que voc deve fazer quando colocar em produo uma aplicao CakePHP.

Atualizar config/app.php

Atualizar o arquivo core.php, especificamente o valor do debug de extrema importncia. Tornar o debug igual a
false desabilita muitos recursos do processo de desenvolvimento que nunca devem ser expostos ao mundo. Desabi-
litar o debug, altera as seguintes coisas:
Mensagens de depurao criadas com pr() e debug() sero desabilitadas.
O cache interno do CakePHP ser descartado aps 999 dias ao invs de ser a cada 10 segundos como em
desenvolvimento.
Views de erros sero menos informativas, retornando mensagens de erros genricas.
Erros do PHP no sero mostrados.
O rastreamento de stack traces (conjunto de excees) ser desabilitado.
Alm dos itens citados acima, muitos plugins e extenses usam o valor do debug para modificarem seus comporta-
mentos.
Por exemplo, voc pode setar uma varivel de ambiente em sua configurao do Apache:

SetEnv CAKEPHP_DEBUG 1

E ento voc pode definir o level de debug dinamicamente no config/app.php:

$debug = (bool)getenv('CAKEPHP_DEBUG');

return [
'debug' => $debug,
.....
];

255
CakePHP Cookbook Documentation, Release 3.next

Checar a segurana

Se voc est jogando sua aplicao na selva, uma boa idia certificar-se que ela no possui vulnerabilidades bvias:
Certifique-se de utilizar o Cross Site Request Forgery.
Voc pode querer habilitar o Security. Isso pode prevenir diversos tipos de adulterao de formulrios e reduzir
a possibilidade de overdose de requisies.
Certifique-se que seus models possuem as regras Validao de validao habilitadas.
Verifique se apenas o seu diretrio webroot visvel publicamente, e que seus segredos (como seu app salt, e
qualquer chave de segurana) so privados e nicos tambm.

Definir a raiz do documento

Definir a raiz do documento da sua aplicao corretamente um passo importante para manter seu cdigo protegido e
sua aplicao mais segura. As aplicaes desenvolvidas com o CakePHP devem ter a raiz apontando para o diretrio
webroot. Isto torna a aplicao e os arquivos de configuraes inacessveis via URL. Configurar a raiz do documento
depende de cada servidor web. Veja a Reescrita de URL para informaes sobre servidores web especficos.
De qualquer forma voc vai querer definir o host/domnio virtual para o webroot/. Isso remove a possibilidade de
arquivos fora do diretrio raiz serem executados.

Aprimorar a performance de sua aplicao

O carregamento de classes pode alocar facilmente o tempo de processamento de sua aplicao. A fim de evitar esse
problema, recomendado que voc execute este comando em seu servidor de produo uma vez que a aplicao esteja
implantada:

php composer.phar dumpautoload -o

Sabendo que manipulao de referncias estticas, como imagens, JavaScript e arquivos CSS, plugins, atravs do
Dispatcher incrivelmente ineficiente, fortemente recomendado referenci-los simbolicamente para produo.
Por exemplo:

ln -s Plugin/YourPlugin/webroot/css/yourplugin.css webroot/css/yourplugin.css

256 Captulo 17. Implantao


CAPTULO 18

Email

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github130 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Aviso: Antes da verso 3.1, as classes Email e Transport estavam com o namespace
Cake\Network\Email em vez do namespace Cake\Mailer.

class Cake\Mailer\Email(mixed $profile = null)


Email uma nova classe para enviar E-mail. Com essa classe voc pode enviar e-mail de qualquer lugar em sua
aplicao.

Uso Bsico

Primeiro de tudo, voc deve garantir que a classe est carregada:

use Cake\Mailer\Email;

Depois que voc carregou Email, you pode enviar um e-mail com o seguinte:

$email = new Email('default');


$email->from(['remetente@example.com' => 'Meu Site'])
->to('destinatario@exemplo.com')
->subject('Assunto')
->send('Minha mensagem');

Com os mtodos construtores da classe Email, voc capaz de definir suas propriedades com o encadeamento de
mtodo.
130 https://github.com/cakephp/docs

257
CakePHP Cookbook Documentation, Release 3.next

Email tem vrios mtodos para definir os destinatrios - to(), cc(), bcc(), addTo(), addCc() e addBcc().
A diferena que os trs primeiros iro substituir o que j foi definido antes e mais tarde ser apenas como adicionar
mais destinatrios ao seu respectivo campo:

$email = new Email();


$email->to('to@example.com', 'To Example');
$email->addTo('to2@example.com', 'To2 Example');
// Os destinatrios so: to@example.com and to2@example.com
$email->to('test@example.com', 'ToTest Example');
// O destinatrio : test@example.com

Escolhendo Rementente

Quando enviamos um e-mail em nome de outra pessoa, uma boa ideia definirmos quem o remetente original usando
o cabealho Sender. Voc pode fazer isso usando sender():

$email = new Email();


$email->sender('app@example.com', 'MyApp emailer');

Nota: tambm uma boa ideia para definir o envelope remetente quando enviar um correio em nome de outra pessoa.
Isso as impede de obter quaisquer mensagens sobre a capacidade de entrega.

Configurao

A configurao de Email padro criada usando config() e configTransport(). Voc deve colocar as
predefinies de e-mail no arquivo config/app.php. O arquivo config/app.default.php um exemplo deste arquivo.
No necessrio definir a configurao de e-mail em config/app.php. Email pode ser usado sem ele e usar os
respectivos mtodos para definir todas as configuraes separadamente ou carregar uma variedade de configuraes.
Ao definir perfis e transportes, voc pode manter o cdigo do aplicativo livre dos dados de configurao, e evitar a
duplicao que faz manuteno e implantao mais difcil.
Para carregar uma configurao pr-definida, voc pode usar o mtodo profile() ou pass-lo para o construtor de
Email:

$email = new Email();


$email->profile('default');

// Ou no Construtor
$email = new Email('default');

Em vez de passar uma string que corresponde a um nome de configurao predefinida, voc tambm pode apenas
carregar uma variedade de opes:

$email = new Email();


$email->profile(['from' => 'me@example.org', 'transport' => 'my_custom']);

// Ou no Construtor
$email = new Email(['from' => 'me@example.org', 'transport' => 'my_custom']);

Alterado na verso 3.1: O perfil default do e-mail automaticamente setado quando uma instncia Email criada.

258 Captulo 18. Email


CakePHP Cookbook Documentation, Release 3.next

Configurando Transportes

static Cake\Mailer\Email::configTransport($key, $config = null)


As mensagens de email so entregues por transportes. Diferentes transportes permitem o envio de mensagens via
funes PHP mail do PHP servidores SMTP (ou no em todos, que til para depurao. Configurar transportes
permite-lhe manter os dados de configurao fora de seu cdigo do aplicativo e torna a implantao mais simples, como
voc pode simplesmente mudar os dados de configurao. Um exemplo de configurao de transporte parecido com:

use Cake\Mailer\Email;

// Configurao Simples de Email


Email::configTransport('default', [
'className' => 'Mail'
]);

// Configurao smtp Simples


Email::configTransport('gmail', [
'host' => 'ssl://smtp.gmail.com',
'port' => 465,
'username' => 'my@gmail.com',
'password' => 'secret',
'className' => 'Smtp'
]);

Voc pode configurar servidores SSL SMTP, como o Gmail. Para fazer isso, colocar o prefixo ssl:// no hospedeiro
e configurar o valor de porta em conformidade. Voc tambm pode ativar TLS SMTP usando o tls opo:

use Cake\Mailer\Email;

Email::configTransport('gmail', [
'host' => 'smtp.gmail.com',
'port' => 587,
'username' => 'my@gmail.com',
'password' => 'secret',
'className' => 'Smtp',
'tls' => true
]);

A configurao acima possibilita uma comunicao TLS para mensagens de e-mail.

Aviso: Voc vai precisar ter ativado o acesso para aplicaes menos seguras em sua conta do Google para que isso
funcione: Permitindo aplicaes menos seguras para acessar sua conta131 .
131 https://support.google.com/accounts/answer/6010255

Nota: Para usar SSL + SMTP, voc precisar ter o SSL configurado no seu PHP.

As opes de configurao tambm pode ser fornecido como uma string DSN. Isso til quando se trabalha com
variveis de ambiente ou prestadores PaaS:

Email::configTransport('default', [
'url' => 'smtp://my@gmail.com:secret@smtp.gmail.com:465?tls=true',
]);

Configurao 259
CakePHP Cookbook Documentation, Release 3.next

Ao usar uma string DSN voc pode definir quaisquer parmetros/opes adicionais como argumentos de string de
consulta.
static Cake\Mailer\Email::dropTransport($key)
Uma vez configurado, os transportes no pode ser modificado. A fim de modificar um transporte, voc deve primeiro
solt-lo e, em seguida, configur-lo.

Perfis de Configurao

Definio de perfis de entrega permitem consolidar as configuraes de e-mail comuns em perfis reutilizveis. Seu
aplicativo pode ter tantos perfis como necessrio. As seguintes chaves de configurao so usados:
'from': E-mail ou array do remetente. Visto Email::from().
'sender': E-mail ou array do Remetente original. Visto Email::sender().
'to': E-mail ou array do Destinatrio. Visto Email::to().
'cc': E-mail ou array da Copia de Carbono. Visto Email::cc().
'bcc': E-mail ou array da cpia oculta. Visto Email::bcc().
'replyTo': Email ou array do E-mail de respostas. Visto Email::replyTo().
'readReceipt': Endereo de E-mail ou array de endereos para receber a recepo de leitura. Visto
Email::readReceipt().
'returnPath': Endereo de E-mail ou um array de endereos para retornar se teve alguns erros. Visto
Email::returnPath().
'messageId': ID da mensagem do e-mail. Visto Email::messageId().
'subject': Assunto da mensagem. Visto Email::subject().
'message': Contedo de mensagem. No defina este campo se voc estiver usando o contedo processado.
'headers': Cabealhos sejam includas. Visto Email::setHeaders().
'viewRender': Se voc estiver usando contedo renderizado, definir o nome da classe da view. Visto
Email::viewRender().
'template': Se voc estiver usando contedo renderizado, definir o nome do template. Visto
Email::template().
'theme': Tema usado quando o template renderizado. Visto Email::theme().
'layout': Se voc estiver usando contedo renderizado, definir o layout para renderizar. Se voc quer
renderizar um template sem layout, definir este campo como null. Visto Email::template().
'viewVars': Se voc estiver usando contedo renderizado, definir o array com as variveis para serem usadas
na view. Visto Email::viewVars().
'attachments': Lista de arquivos para anexar. Visto Email::attachments().
'emailFormat': Formato do e-mail (html, text ou both). Visto Email::emailFormat().
'transport': Nome da configurao de transporte. Visto Mailer\Email::configTransport().
'log': Nvel de log para registrar os cabealhos de e-mail e mensagem. true usar LOG_DEBUG. Visto
tabmm como CakeLog::write()
'helpers': Array de helpers usado no template do e-mail.

260 Captulo 18. Email


CakePHP Cookbook Documentation, Release 3.next

Todas essas configuraes so opcionais, exceto 'from'.

Nota: Os valores das chaves acima usando e-mail ou array, como from, to, cc, etc ser passado como primeiro
parmetro de mtodos correspondentes. O equivalente de: Email::from('my@example.com','My Site')
pode ser difinido como 'from' => ['my@example.com' => 'My Site'] na sua configurao.

Definindo Cabealho

Em Email voc est livre para definir os cabealhos que voc deseja. Quando migrar usando e-mail, no se esquea
de colocar o prefixo X- em seus cabealhos.
Visto como Email::setHeaders() e Email::addHeaders().

Enviando E-mail com Templates

E-mails so frequentemente muito mais do que apenas uma simples mensagem de texto. A fim de facilitar, o CakePHP
fornece uma maneira de enviar e-mails usando o CakePHP. Veja em view layer.
Os templates para e-mails residir em uma pasta especial em sua aplicao no diretrio Template chamado Email.
Visualizaes de e-mail tambm pode usar layouts e os elementos assim como vistas normais:

$email = new Email();


$email->template('welcome', 'fancy')
->emailFormat('html')
->to('bob@example.com')
->from('app@domain.com')
->send();

O acima usaria src/Template/Email/html/welcome.ctp para a vista e src/Template/Layout/E-mail/html/fancy.ctp


para o layout. Voc pode enviar mensagens de e-mail com templates de vrias partes, veja:

$email = new Email();


$email->template('welcome', 'fancy')
->emailFormat('both')
->to('bob@example.com')
->from('app@domain.com')
->send();

Este usaria os seguintes arquivos de template:


src/Template/Email/text/welcome.ctp
src/Template/Layout/Email/text/fancy.ctp
src/Template/Email/html/welcome.ctp
src/Template/Layout/Email/html/fancy.ctp
Ao enviar e-mails com templates, voc tem a opo de enviar qualquer text, html ou both.
Voc pode definir as vriaveis da view com Email::viewVars():

$email = new Email('templated');


$email->viewVars(['value' => 12345]);

Definindo Cabealho 261


CakePHP Cookbook Documentation, Release 3.next

Em seus templates de e-mail, voc pode usar isso com:

<p>Aqui est o seu valor: <b><?= $value ?></b></p>

Voc pode usar helpers em e-mails, bem como voc pode em arquivos de modelo normais. Por padro, somente o
HtmlHelper carregado. Voc pode carregar helpers adicionais usando os mtodos helpers():

$email->helpers(['Html', 'Custom', 'Text']);

Ao definir ajudantes se esquea de incluir Html ou ele ser removido do helpers carregado no seu template de e-mail.
Se voc quiser enviar e-mail usando templates em um plugin, voc pode usar o familiar Sintaxe Plugin para faze-l:

$email = new Email();


$email->template('Blog.new_comment', 'Blog.auto_message');

O acima usaria templates a partir do plug-in Blog como um exemplo.


Em alguns casos, pode ser necessrio substituir o template padro fornecido pelo plugins. Voc pode fazer isso usando
temas, dizendo par ao E-mail usar o tema apropriado usando o mtodo Email::theme():

$email = new Email();


$email->template('Blog.new_comment', 'Blog.auto_message');
$email->theme('TestTheme');

Isso permite que voc substituir o new_comment em seu tema, sem modificar o plug-in Blog. O arquivo de template
precisa ser criado no seguinte caminho: src/Template/Plugin/TestTheme/Blog/Email/text/new_comment.ctp.

Envio de Anexos

Cake\Mailer\Email::attachments($attachments = null)
Voc pode anexar arquivos a mensagens de email tambm. H alguns diferentes formatos, dependendo do tipo de
arquivos que voc tem, e como voc quer os nomes dos arquivos para aparecer no email do destinatrio:
1. String: $email->attachments('/full/file/path/file.png') ir anexar este arquivo com o
nome file.png.
2. Array: $email->attachments(['/full/file/path/file.png']) tem o mesmo comportamento
como o uso de uma String.
3. Array com chave: $email->attachments(['photo.png' => '/full/some_hash.png']) ir
anexar alguns hash.png com o nome photo.png. O destinatrio ver photo.png, no hash.png.
4. Arrays aninhados:

$email->attachments([
'photo.png' => [
'file' => '/full/some_hash.png',
'mimetype' => 'image/png',
'contentId' => 'my-unique-id'
]
]);

O acima ir anexar o arquivo com diferentes mimetypes e com identificao de contedo personalizado (quando
definir o ID de contedo do anexo transformado para linha). O mimetype e contentId so opcionais nessa
forma.

262 Captulo 18. Email


CakePHP Cookbook Documentation, Release 3.next

4.1. Quando voc estiver usando o contentId, voc pode usar o arquivo no corpo HTML como <img
src="cid:my-content-id">.
4.2. Voc pode usar a opo contentDisposition contedo para desativar cabealho
Content-Disposition para um anexo. Isso til quando feito o envio de convites para o iCal
para clientes usando o Outlook.
4.3 Em vez de a opo file voc pode fornecer o contedo do arquivo como uma string usando a opo data.
Que lhe permite anexar arquivos sem a necessidade de caminhos de arquivo para eles.

Usando Transportes

Transportes so classes atribudas a enviar o e-mail sobre algum protocolo ou mtodo. CakePHP suporta o o transporte
de Mail (padro), Debug e SMTP.
Para configurar o mtodo, voc deve usar o mtodo Cake\Mailer\Email::transport() ou ter o transporte
em sua configurao:

$email = new Email();

// Usar um transporte chamado j configurado usando Email::configTransport()


$email->transport('gmail');

// Usando um mtodo Construtor


$transport = new DebugTransport();
$email->transport($transport);

Usando Transportes 263


CakePHP Cookbook Documentation, Release 3.next

264 Captulo 18. Email


CAPTULO 19

Erros & Excees

Error & Exception Configuration

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github132 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

132 https://github.com/cakephp/docs

265
CakePHP Cookbook Documentation, Release 3.next

266 Captulo 19. Erros & Excees


CAPTULO 20

Sistema de eventos

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github133 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

133 https://github.com/cakephp/docs

267
CakePHP Cookbook Documentation, Release 3.next

268 Captulo 20. Sistema de eventos


CAPTULO 21

Internacionalizao e Localizao

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github134 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Uma das melhores maneiras para uma aplicao alcanar uma maior audincia atender a vrios idiomas. Isso muitas
vezes pode provar ser uma tarefa difcil, mas a internacionalizao e recursos de localizao do CakePHP tornam
muito mais fcil.
Primeiro, importante entender a terminologia. Internacionalizao refere-se capacidade de um aplicativo ser
localizado. O termo localizao refere-se adaptao de uma aplicao, para atender idioma especfico (ou cultura)
requisitos (Isto , uma localidade). Internacionalizao e Localizao so frequentemente abreviado como i18n
(internacionalization) e l10n (localization); 18 e 10 so o nmero de caracteres entre a primeira e ltima letra de cada
termo.

Configurando Tradues

Existem apenas alguns passos para ir de um aplicativo de um nico idioma a uma aplicao multi-lingual, o primeiro
deles fazer uso da funo :php:func: __() em seu cdigo. Abaixo est um exemplo de algum cdigo para uma
aplicao de um nico idioma:

<h2>Popular Articles</h2>

Para Internacionalizar seu cdigo, tudo que voc precisa fazer refatorar a string usando :php:func: __() por exemplo:

<h2><?= __('Popular Articles') ?></h2>

Fazendo nada mais, estes dois exemplos de cdigo so funcionalmente idnticos - ambos iro enviar o mesmo contedo
para o navegador. A funo :php:func: __() ir traduzir a string passada se a traduo estiver disponvel, ou devolv-la
inalterada.
134 https://github.com/cakephp/docs

269
CakePHP Cookbook Documentation, Release 3.next

Arquivos de Idiomas

Tradues podem ser disponibilizados usando arquivos de idiomas armazenados na aplicao. O formato padro para
arquivos de traduo do CakePHP o formato Gettext135 . Os arquivos precisam ser colocado dentro do Diretrio
src/Locale/ e dentro deste diretrio, deve haver uma subpasta para cada idioma, por exemplo:

/src
/Locale
/en_US
default.po
/en_GB
default.po
validation.po
/es
default.po

O domnio padro default, portanto, a pasta src/Locale/ deve pelo menos conter o arquivo default.po como mos-
trado acima. Um domnio refere-se a qualquer arbitrrio agrupamento de mensagens de traduo. Quando nenhum
grupo usado, o grupo padro selecionado.
As mensagens das Strings do core extrados da biblioteca CakePHP podem ser armazenado separadamente em um
arquivo chamado cake.po em src/Locale/. O CakePHP localized library136 possui tradues para as mensagens tra-
duzidas voltados para o cliente no ncleo (o domnio Cake). Para usar esses arquivos, baixar ou copi-los para o seu
local esperado: src/Locale/<locale>/cake.po. Se sua localidade est incompleta ou incorreta, por favor envie um PR
neste repositrio para corrigi-lo.
Plugins tambm podem conter arquivos de traduo, a conveno usar o under_score do nome do plugin como
o domnio para a traduo mensagens:

MyPlugin
/src
/Locale
/fr
my_plugin.po
/de
my_plugin.po

Pastas de traduo pode ser o cdigo ISO de duas letras do idioma ou nome do local completo, como fr_FR, es_AR,
da_DK que contm tanto o idioma e o pas onde ele falado.
Um exemplo de arquivo de traduo pode ser visto como:

msgid "My name is {0}"


msgstr "Je m'appelle {0}"

msgid "I'm {0,number} years old"


msgstr "J'ai {0,number} ans"

Extraindo arquivos .pot com I18n Shell

Para criar os arquivos .pot apartir de __() e outros tipos de mensagens internacionalizadas que podem ser encontrados
no cdigo do aplicativo, voc pode usar o shell i18n. Por favor, leia o Captulo Seguinte para saber mais.
135 http://en.wikipedia.org/wiki/Gettext
136 https://github.com/cakephp/localized

270 Captulo 21. Internacionalizao e Localizao


CakePHP Cookbook Documentation, Release 3.next

Definir a localidade padro

A localidade padro pode ser definida em no arquivo config/app.php, definindo App.default Locale:

'App' => [
...
'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'),
...
]

Isto vai controlar vrios aspectos da aplicao, incluindo o padro da linguagem de tradues, o formato da data,
formato de nmero e moeda sempre que qualquer daqueles exibida usando as bibliotecas de localizao que o
CakePHP fornece.

Alterando o local em tempo de execuo

Para alterar o idioma para as mensagens traduzidas voc pode chamar esse mtodo:

use Cake\I18n\I18n;

I18n::locale('de_DE');

Isso tambm ir alterar a forma como nmeros e datas so formatadas quando usamos uma das ferramentas de locali-
zao.

Usando funes de traduo

CakePHP fornece vrias funes que o ajudaro a internacionalizar sua aplicao. O mais utilizado :php:func: __().
Esta funo usada para recuperar uma nica mensagem de traduo ou devolver a mesma String se no houver
traduo:

echo __('Popular Articles');

Se voc precisa agrupar suas mensagens, por exemplo, tradues dentro de um plugin, voc pode usar a funo
:php:func: __d() para buscar mensagens de outro domnio:

echo __d('my_plugin', 'Trending right now');

s vezes tradues de Strings podem ser ambguos para as pessoas traduzindo-os. Isso pode acontecer se duas sequn-
cias so idnticas, mas referem-se a coisas diferentes. Por exemplo, letter tem vrios significados em Ingls. Para
resolver esse problema, voc pode usar a funo :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.

Usando variveis em mensagens de traduo

Funes de traduo permitem que voc interpole variveis para as mensagens usando marcadores especiais definidos
na prpria mensagem ou na string traduzida:

Usando funes de traduo 271


CakePHP Cookbook Documentation, Release 3.next

echo __("Hello, my name is {0}, I'm {1} years old", ['Jefferson', 19]);

Marcadores so numricos, e correspondem s teclas na matriz passada. Voc pode tambm passar variveis como
argumentos independentes para a funo:

echo __("Small step for {0}, Big leap for {1}", 'Man', 'Humanity');

Todas as funes de traduo apoiam as substituies de espao reservado:

__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 cdigo de escape na mensagem de traduo. Todas as variveis entre aspas
simples no sero substitudos e tratado como texto literal. Por exemplo:

__("This variable '{0}' be replaced.", 'will not');

Ao usar duas aspas adjacentes suas variveis e sero substitudos adequadamente:

__("This variable ''{0}'' be replaced.", 'will');

Estas funes tiram vantagem do UTI MessageFormatter137 para que possa traduzir mensagens e localizar datas,
nmeros 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]
);

// Returns
Hi Charles, your balance on the Jan 13, 2014, 11:12 AM is $ 1,354.37

Os nmeros em espaos reservados podem ser formatados, bem como com o controle de gro fino da sada:

echo __(
'You have traveled {0,number,decimal} kilometers in {1,number,integer} weeks',
[5423.344, 5.1]
);

// Returns
You have traveled 5,423.34 kilometers in 5 weeks

echo __('There are {0,number,#,###} people on earth', 6.1 * pow(10, 8));

// Returns
There are 6,100,000,000 people on earth

Esta a lista de especificadores de formato que voc pode colocar aps a palavra number:
integer: Remove a parte Decimal
decimal: Formata o nmero como um float
currency: Coloca o local do smbolo de moeda e nmeros de casas decimais
percent: Formata o nmero como porcentagem
137 http://php.net/manual/en/messageformatter.format.php

272 Captulo 21. Internacionalizao e Localizao


CakePHP Cookbook Documentation, Release 3.next

Datas tambm pode ser formatadas usando a palavra date aps o nmero do espao reservado. Uma lista de opes
adicionais a seguir:
short
medium
long
full
A palavra time aps o nmero de espao reservado tambm aceito e compreende as mesmas opes que date.

Nota: Espaos reservados nomeados so suportados no PHP 5.5+ e so formatados como {name}. Ao usar espaos
reservados nomeados para passar as variveis em uma matriz usando pares de chave/valor, por exemplo ['name'
=> 'Jefferson','age' => 19].
Recomenda-se usar o PHP 5.5 ou superior ao fazer uso de recursos de internacionalizao no CakePHP. A ex-
tenso php5-intl deve ser instalada e a verso UTI deve estar acima 48.x.y (para verificar a verso UTI
Intl::getIcuVersion ()).

Plurais

Uma parte crucial de internacionalizar sua aplicao a pluralizao das suas mensagens corretamente, dependendo
do idioma que eles so mostrados. O CakePHP fornece algumas maneiras de selecionar corretamente plurais em suas
mensagens.

Usando UTI para Seleo de Plural

O primeiro est aproveitando o formato de mensagem ICU que vem por padro nas funes de traduo. Nos arquivos
de tradues voc pode ter as seguintes cadeias

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}}"

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}


}"

E na aplicao utilize o seguinte cdigo para a sada de uma das tradues para essa seqncia:

__('{0,plural,=0{No records found }=1{Found 1 record} other{Found # records}}', [0]);

// Returns "Ningn resultado" as the argument {0} is 0

__('{0,plural,=0{No records found} =1{Found 1 record} other{Found # records}}', [1]);

// Returns "1 resultado" because the argument {0} is 1

__('{placeholder,plural,=0{No records found} =1{Found 1 record} other{Found {1}


records}}', [0, 'many', 'placeholder' => 2])

// Returns "many resultados" because the argument {placeholder} is 2 and


// argument {1} is 'many'

Usando funes de traduo 273


CakePHP Cookbook Documentation, Release 3.next

Um olhar mais atento para o formato que acabamos utilizado tornar evidente como as mensagens so construdas:

{ [count placeholder],plural, case1{message} case2{message} case3{...} ... }

O [count placeholder] pode ser o nmero-chave de qualquer das variveis que voc passar para a funo de
traduo. Ele ser usado para selecionar o plural correto.
Note que essa referncia para [count placeholder] dentro de {message} voc tem que usar #.
Voc pode usar ids de mensagem mais simples se voc no deseja digitar a plena seqncia de seleo para plural em
seu cdigo

msgid "search.results"
msgstr "{0,plural,=0{Nenhum resultado} =1{1 resultado} other{{1} resultados}}"

Em seguida, use a nova string em seu cdigo:

__('search.results', [2, 2]);

// Returns: "2 resultados"

A ltima verso tem a desvantagem na qual existe uma necessidade de arquivar mensagens e precisa de traduo para
o idioma padro mesmo, mas tem a vantagem de que torna o cdigo mais legvel.
s vezes, usando o nmero de correspondncia direta nos plurais impraticvel. 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:

=0{No results} =1{...} other{...}

Voc pode fazer:

zero{No Results} one{One result} few{...} many{...} other{...}

Certifique-se de ler a Language Plural Rules Guide138 para obter uma viso completa dos aliases que voc pode usar
para cada idioma.

Usando Gettext para Seleo de Plural

O segundo formato para seleo de plural aceito a utilizao das capacidades embutidas de Gettext. Neste caso,
plurais ser armazenado nos arquivos .po, criando uma linha de traduo de mensagens separada por forma de plural:

# One message identifier for singular


msgid "One file removed"
# Another one for plural
msgid_plural "{0} files removed"
# Translation in singular
msgstr[0] "Un fichero eliminado"
# Translation in plural
msgstr[1] "{0} ficheros eliminados"

Ao usar este outro formato, voc obrigado a usar outra traduo de forma funcional:

// Returns: "10 ficheros eliminados"


$count = 10;
__n('One file removed', '{0} files removed', $count, $count);

138 http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html

274 Captulo 21. Internacionalizao e Localizao


CakePHP Cookbook Documentation, Release 3.next

// Tambm possvel utiliz-lo dentro de um domnio


__dn('my_plugin', 'One file removed', '{0} files removed', $count, $count);

O nmero dentro de msgstr[] o nmero atribudo pela Gettext para o plural na forma da lngua. Algumas lnguas
tm mais de duas formas plurais, para exemplo Croatian:

msgid "One file removed"


msgid_plural "{0} files removed"
msgstr[0] "{0} datoteka je uklonjena"
msgstr[1] "{0} datoteke su uklonjene"
msgstr[2] "{0} datoteka je uklonjeno"

Por favor visite a Launchpad languages page139 para uma explicao detalhada dos nmeros de formulrio de plurais
para cada idioma.

Criar seus prprios Tradutores

Se voc precisar a divergir convenes do CakePHP sobre onde e como as mensagens de traduo so armazenadas,
voc pode criar seu prprio carregador de mensagem de traduo. A maneira mais fcil de criar o seu prprio tradutor
atravs da definio de um carregador para um nico domnio e localidade:

use Aura\Intl\Package;

I18n::translator('animals', 'fr_FR', function () {


$package = new Package(
'default', // The formatting strategy (ICU)
'default' // The fallback domain
);
$package->setMessages([
'Dog' => 'Chien',
'Cat' => 'Chat',
'Bird' => 'Oiseau'
...
]);

return $package;
});

O cdigo acima pode ser adicionado ao seu config/bootstrap.php de modo que as tradues podem ser encontradas
antes de qualquer funo de traduo usada. O mnimo absoluto que necessrio para a criao de um tradutor
que a funo do carregador deve retornar um Aura\Intl\Package objeto. Uma vez que o cdigo no lugar que
voc pode usar as funes de traduo, como de costume:

I18n::locale('fr_FR');
__d('animals', 'Dog'); // Retorna "Chien"

Como voc v objetos, Package carregam mensagens de traduo como uma matriz. Voc pode passar o mtodo
setMessages() da maneira que quiser: com cdigo inline, incluindo outro arquivo, chamar outra funo, etc.
CakePHP fornece algumas funes da carregadeira que podem ser reutilizadas se voc s precisa mudar para onde as
mensagens so carregadas. Por exemplo, voc ainda pode usar .po, mas carregado de outro local:
139 https://translations.launchpad.net/+languages

Criar seus prprios Tradutores 275


CakePHP Cookbook Documentation, Release 3.next

use Cake\I18n\MessagesFileLoader as Loader;

// Load messages from src/Locale/folder/sub_folder/filename.po

I18n::translator(
'animals',
'fr_FR',
new Loader('filename', 'folder/sub_folder', 'po')
);

276 Captulo 21. Internacionalizao e Localizao


CAPTULO 22

Logging

Logging Configuration

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github140 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Formulrios sem Models ######################m


class Cake\Form\Form
Muitas vezes voc precisar ter formulrios associados ao ORM entities e ORM tables ou outras persistncia de dados,
mas h vezes quando voc precisar validar um campo de usurio e ento realizar uma ao se o dado vlido. O
exemplo mais comum para esta situao o formulrio de contato.

140 https://github.com/cakephp/docs

277
CakePHP Cookbook Documentation, Release 3.next

278 Captulo 22. Logging


CAPTULO 23

Criando o Formulrio

Geralmente quando se usa a classe Form ser necessrio utilizar uma sub-classe para definir seu formulrio. Isso
facilita o teste, e permite o reuso do formulrio. Formulrios ficam dentro de src/Form e comumente tem Form como
sufixo da classe. Por exemplo, um simples formulrio de contato poderia ficar assim:

// em src/Form/ContactForm.php
namespace App\Form;

use Cake\Form\Form;
use Cake\Form\Schema;
use Cake\Validation\Validator;

class ContactForm extends Form


{

protected function _buildSchema(Schema $schema)


{
return $schema->addField('name', 'string')
->addField('email', ['type' => 'string'])
->addField('body', ['type' => 'text']);
}

protected function _buildValidator(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',
]);
}

protected function _execute(array $data)


{
// Envie um email.
return true;
}
}

279
CakePHP Cookbook Documentation, Release 3.next

No exemplo acima vemos os 3 mtodos hooks que o formulrio fornece:


_buildSchema usado para definir o esquema de dados usado pelo FormHelper para criar um formulrio
HTML. Voc pode definir o tipo de campo, tamanho, e preciso.
_buildValidator Pega uma instncia do Cake\Validation\Validator que voc pode voc juntar
com os validadores.
_execute permite definir o comportamento desejado quando o execute() chamado e o dado vlido.
Voc sempre pode adicionar mtodos pblicos a sua maneira.

280 Captulo 23. Criando o Formulrio


CAPTULO 24

Processando Requisio de Dados

Uma vez definido o formulrio, possvel us-lo em seu controller para processar e validar os dados:

// No Controller
namespace App\Controller;

use App\Controller\AppController;
use App\Form\ContactForm;

class ContactController extends AppController


{
public function index()
{
$contact = new ContactForm();
if ($this->request->is('post')) {
if ($contact->execute($this->request->getData())) {
$this->Flash->success('We will get back to you soon.');
} else {
$this->Flash->error('There was a problem submitting your form.');
}
}
$this->set('contact', $contact);
}
}

No exemplo acima, usamos o mtodo execute() para chamar o nosso mtodo _execute() do formulrio ape-
nas quando o dado vlido, e definimos as mensagens flash adequadas. Poderamos tambm ter usado o mtodo
validate() apenas para validar a requisio de dados:

$isValid = $form->validate($this->request->getData());

281
CakePHP Cookbook Documentation, Release 3.next

282 Captulo 24. Processando Requisio de Dados


CAPTULO 25

Definindo os Valores do Formulrio

Na sequncia para definir os valores para os campos do formulrio sem modelo, basta apenas definir os valores usando
$this->request->getData(), como em todos os outros formulrios criados pelo FormHelper:

// Em um controller
namespace App\Controller;

use App\Controller\AppController;
use App\Form\ContactForm;

class ContactController extends AppController


{
public function index()
{
$contact = new ContactForm();
if ($this->request->is('post')) {
if ($contact->execute($this->request->getData())) {
$this->Flash->success('Retornaremos o contato em breve.');
} else {
$this->Flash->error('Houve um problema ao enviar seu formulrio.');
}
}

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');
}

$this->set('contact', $contact);
}
}

Valores devem apenas serem definidos se a requesio do tipo GET, caso contrrio voc sobreescrever os dados
anteriormente passados via POST que de certa forma poderiam estar incorretos e no salvos.

283
CakePHP Cookbook Documentation, Release 3.next

284 Captulo 25. Definindo os Valores do Formulrio


CAPTULO 26

Pegando os Erros do Formulrio

Uma vez sido validado, o formulrio pode recuperar seus prprios erros:

$errors = $form->errors();
/* $errors contains
[
'email' => ['A valid email address is required']
]
*/

285
CakePHP Cookbook Documentation, Release 3.next

286 Captulo 26. Pegando os Erros do Formulrio


CAPTULO 27

Invalidando Campos Individuais do


Formulrio no Controller

possvel invalidar campos nicos do controller sem o uso da classe Validator. O Uso mais comum neste caso
quando a validao feita no servidor remoto. Neste caso, voc deve manualmente invalidar os campos de acordo
com a resposta do servidor:

// em src/Form/ContactForm.php
public function setErrors($errors)
{
$this->_errors = $errors;
}

Conforme como a classe validadora poderia ter retornado os erros, $errors deve estar neste formato:

["fieldName" => ["validatorName" => "The error message to display"]]

Agora voc pode invalidar os campos determinar o fieldName, e ento definir as mensagens de erro:

// Em um controller
$contact = new ContactForm();
$contact->setErrors(["email" => ["_required" => "Seu email necessrio"]]);

Prossiga para Criao do HTML com o FormHelper para ver o resultado.

287
CakePHP Cookbook Documentation, Release 3.next

288 Captulo 27. Invalidando Campos Individuais do Formulrio no Controller


CAPTULO 28

Criando o HTML com FormHelper

Uma vez sido criado uma class Form, Once youve created a Form class, voc provavelmente vai querer criar um
formulrio HTML para isso. FormHelper compreende objetos Form apenas 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->button('Submit');
echo $this->Form->end();

O cdigo acima criar um formulrio HTML para o ContactForm definidos anteriormente. Formulrios HTML cri-
ados com FormHelper usar o esquema definido e validador para determinar os tipos de campos, tamanhos mximos,
e validao de erros.

289
CakePHP Cookbook Documentation, Release 3.next

290 Captulo 28. Criando o HTML com FormHelper


CAPTULO 29

Plugins

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github141 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

141 https://github.com/cakephp/docs

291
CakePHP Cookbook Documentation, Release 3.next

292 Captulo 29. Plugins


CAPTULO 30

REST

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github142 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

142 https://github.com/cakephp/docs

293
CakePHP Cookbook Documentation, Release 3.next

294 Captulo 30. REST


CAPTULO 31

Segurana

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github143 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Segurana

Choosing a Specific Crypto Implementation

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github144 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

143 https://github.com/cakephp/docs
144 https://github.com/cakephp/docs

295
CakePHP Cookbook Documentation, Release 3.next

296 Captulo 31. Segurana


CAPTULO 32

Sessions

Session Configuration

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github145 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

145 https://github.com/cakephp/docs

297
CakePHP Cookbook Documentation, Release 3.next

298 Captulo 32. Sessions


CAPTULO 33

Testing

O CakePHP vem com suporte interno para testes e integrao para o PHPUnit146 . Em adio aos recursos oferecidos
pelo PHPUnit, o CakePHP oferece alguns recursos adicionais para fazer testes mais facilmente. Esta seo abordar a
instalao do PHPUnit, comeando com testes unitrios e como voc pode usar as extenses que o CakePHP oferece.

Instalando o PHPUnit

O CakePHP usa o PHPUnit como framework de teste bsico. O PHPUnit um padro para testes unitrios em PHP.
Ele oferece um profundo e poderoso conjunto de recursos para voc ter certeza que o seu cdigo faz o que voc acha
que ele faz. O PHPUnit pode ser instalado usando o PHAR package147 ou Composer148 .

Instalando o PHPUnit com Composer

Para instalar o PHPUnit com Composer:

$ php composer.phar require --dev phpunit/phpunit

Isto adicionar a dependncia para a seo require-dev do seu composer.json, e depois instalar o PHPUnit
com qualquer outra dependncia.
Agora voc executa o PHPUnit usando:

$ vendor/bin/phpunit

Usando o arquivo PHAR

Depois de ter baixado o arquivo phpunit.phar , voc pode usar ele para executar seus testes:

php phpunit.phar

146 http://phpunit.de
147 http://phpunit.de/#download
148 http://getcomposer.org

299
CakePHP Cookbook Documentation, Release 3.next

Dica: Como convenincia voc pode deixar phpunit.phar disponivel globalmente em sistemas Unix ou Linux com os
comandos:

chmod +x phpunit.phar
sudo mv phpunit.phar /usr/local/bin/phpunit
phpunit --version

Por favor, consulte a documentao do PHPUnit para instrues sobre como instalar globalmente o PHPUnit PHAR
em sistemas Windows149 .

Configurao do banco de dados test

Lembre-se de ter o debug abilitado em seu arquivo config/app.php antes de executar qualquer teste. Antes de executar
quaisquer testes voc deve adicionar um datasourse test para o arquivo config/app.php. Esta configurao usada
pelo CakePHP para fixar tabelas e dados:

'Datasources' => [
'test' => [
'datasource' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'dbhost',
'username' => 'dblogin',
'password' => 'dbpassword',
'database' => 'test_database'
],
],

Running Tests

Fixtures

Controller Integration Testing

Testing Actions That Require Authentication

Testing Events

Nota: uma boa ideia usar bancos de dados diferentes para o banco de testes e para o banco de desenvolvimento.
Isto evitara erros mais tarde.

149 http://phpunit.de/manual/current/en/installation.html#installation.phar.windows

300 Captulo 33. Testing


CAPTULO 34

Validao

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github150 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

150 https://github.com/cakephp/docs

301
CakePHP Cookbook Documentation, Release 3.next

302 Captulo 34. Validao


CAPTULO 35

App Class

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github151 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

151 https://github.com/cakephp/docs

303
CakePHP Cookbook Documentation, Release 3.next

304 Captulo 35. App Class


CAPTULO 36

Collections (Colees)

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github152 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

152 https://github.com/cakephp/docs

305
CakePHP Cookbook Documentation, Release 3.next

306 Captulo 36. Collections (Colees)


CAPTULO 37

Arquivos & Pastas

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github153 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

153 https://github.com/cakephp/docs

307
CakePHP Cookbook Documentation, Release 3.next

308 Captulo 37. Arquivos & Pastas


CAPTULO 38

Hash

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github154 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

154 https://github.com/cakephp/docs

309
CakePHP Cookbook Documentation, Release 3.next

310 Captulo 38. Hash


CAPTULO 39

Http Client

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github155 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

155 https://github.com/cakephp/docs

311
CakePHP Cookbook Documentation, Release 3.next

312 Captulo 39. Http Client


CAPTULO 40

Inflector

class Cake\Utility\Inflector
A classe Inflector recebe uma string e a manipula afim de suportar variaes de palavas como pluralizaes ou
CamelCase e normalmente acessada estaticamente. Exemplo: Inflector::pluralize('example') retorna
examples.
Voc pode testar as inflexes em inflector.cakephp.org156 .

Resumo dos mtodos de Inflexo e Suas Sadas

Resumo rpido dos mtodos embutidos no Inflector e os resultados que produzem quando fornecidos um argumento
de palavra composta.
Method Argument Output
BigApple BigApples
pluralize()
big_apple big_apples
BigApples BigApple
singularize()
big_apples big_apple
big_apples BigApples
camelize()
big apple BigApple
BigApples big_apples
underscore()
Big Apples big apples
big_apples Big Apples
humanize()
bigApple BigApple
big_apples BigApple
classify()
big apple BigApple
BigApples big-apples
dasherize()
big apple big apple
BigApple big_apples
tableize()
Big Apple big apples
big_apple bigApple
variable()
big apples bigApples
Big Apple big-apple
slug()
BigApples BigApples
156 https://inflector.cakephp.org/

313
CakePHP Cookbook Documentation, Release 3.next

Criando as formas singulares e plurais

static Cake\Utility\Inflector::singularize($singular)
static Cake\Utility\Inflector::pluralize($singular)
Tanto pluralize() quanto singularize() funcionam para a maioria dos substantivos do Ingls. Caso seja
necessrio o suporte para outras lnguas, voc pode usar Configurao da inflexo para personalizar as regras usadas:

// Apples
echo Inflector::pluralize('Apple');

Nota: pluralize() pode no funcionar corretamente nos casos onde um substantivo j esteja em sua forma plural.

// Person
echo Inflector::singularize('People');

Nota: singularize() pode no funcionar corretamente nos casos onde um substantivo j esteja em sua forma
singular.

Criando as formas CamelCase e nome_sublinhado

static Cake\Utility\Inflector::camelize($underscored)
static Cake\Utility\Inflector::underscore($camelCase)
Estes mtodos so teis para a criao de nomes de classe ou de propriedades:

// ApplePie
Inflector::camelize('Apple_pie')

// apple_pie
Inflector::underscore('ApplePie');

importante ressaltar que underscore() ir converter apenas palavras formatadas em CamelCase. Palavras com
espaos sero convertidas para caixa baixa, mas no sero separadas por sublinhado.

Criando formas legveis para humanos

static Cake\Utility\Inflector::humanize($underscored)
Este mtodo til para converter da forma sublinhada para o Formato Ttulo para a leitura humana:

// Apple Pie
Inflector::humanize('apple_pie');

314 Captulo 40. Inflector


CakePHP Cookbook Documentation, Release 3.next

Criando formatos para nomes de tabelas e classes

static Cake\Utility\Inflector::classify($underscored)
static Cake\Utility\Inflector::dasherize($dashed)
static Cake\Utility\Inflector::tableize($camelCase)
Ao gerar o cdigo ou usar as convenes do CakePHP, voc pode precisar inferir os nomes das tabelas ou classes:

// UserProfileSettings
Inflector::classify('user_profile_settings');

// user-profile-setting
Inflector::dasherize('UserProfileSetting');

// user_profile_settings
Inflector::tableize('UserProfileSetting');

Criando nomes de variveis

static Cake\Utility\Inflector::variable($underscored)
Nomes de variveis geralmente so teis em tarefas de meta-programao que involvem a gerao de cdigo ou rotinas
baseadas em convenes:

// applePie
Inflector::variable('apple_pie');

Criando strings de URL seguras

static Cake\Utility\Inflector::slug($word, $replacement = -)


slug() converte caracteres especiais em suas verses normais e converte os caracteres no encontrados e espaos
em traos. O mtodo slug() espera que a codificao seja UTF-8:

// apple-puree
Inflector::slug('apple pure');

Nota: Inflector::slug() foi depreciado desde a verso 3.2.7. Procure usar Text::slug() de agora em
diante.

Configurao da inflexo

As convenes de nomes do CakePHP podem ser bem confortveis. 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 entrelaa todos estes conceitos atravs da inflexo das palavras em suas
formas singulares e plurais.

Criando formatos para nomes de tabelas e classes 315


CakePHP Cookbook Documentation, Release 3.next

Porm ocasionalmente (especialmente para os nossos amigos no Anglfonos) podem encontrar situaes onde o
infletor do CakePHP (a classe que pluraliza, singulariza, transforma em CamelCase e em nome_sublinhado) no
funciona como voc gostaria. Caso o CakePHP no reconhea seu quaisquer ou lpis, voc pode ensin-lo a
entender seus casos especiais.

Carregando inflexes personalizadas

static Cake\Utility\Inflector::rules($type, $rules, $reset = false)


Define novas inflexes e transliteraes para o Inflector usar. Geralmente este mtodo deve ser chamado no 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

As regras ditadas por este mtodo sero agregadas aos conjuntos de inflexo definidos em
Cake/Utility/Inflector, onde elas tero prioridade sobre as regras j declaradas por padro. Voc
pode usar Inflector::reset() para limpar todas as regras e retornar o Inflector para seu estado original.

316 Captulo 40. Inflector


CAPTULO 41

Nmero

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github157 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

157 https://github.com/cakephp/docs

317
CakePHP Cookbook Documentation, Release 3.next

318 Captulo 41. Nmero


CAPTULO 42

Objetos de Registro

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github158 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

158 https://github.com/cakephp/docs

319
CakePHP Cookbook Documentation, Release 3.next

320 Captulo 42. Objetos de Registro


CAPTULO 43

Texto

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github159 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

159 https://github.com/cakephp/docs

321
CakePHP Cookbook Documentation, Release 3.next

322 Captulo 43. Texto


CAPTULO 44

Tempo

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github160 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

160 https://github.com/cakephp/docs

323
CakePHP Cookbook Documentation, Release 3.next

324 Captulo 44. Tempo


CAPTULO 45

Xml

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github161 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

161 https://github.com/cakephp/docs

325
CakePHP Cookbook Documentation, Release 3.next

326 Captulo 45. Xml


CAPTULO 46

Constantes e Funes

A maior parte do seu trabalho dirio com o CakePHP ser feito utilizando classes e mtodos do core. O CakePHP
disponibiliza funes globais de convenincia que podem ajudar. Muitas dessas funes so usadas em classes do
CakePHP (carregando um model ou um component), mas outras tornam mais fcil o trabalho de lidar com arrays ou
strings.
Ns tambm vamos cobrir algumas das constantes existentes em aplicaes CakePHP. Constantes essas, que facilitam
upgrades e apontam convenientemente para arquivos e diretrios chaves da sua aplicao.

Funes globais

Aqui esto as funes disponveis globalmente no CakePHP. A maioria delas so wrappers de convenincia para
funcionalidades do CakePHP, como por exemplo, debug e localizao de contedo.
__(string $string_id[, $formatArgs ])
Essa funo lida com a localizao da sua aplicao. O $string_id identifica o ID usado para a traduo.
Strings so tratadas seguindo o formato usado no sprintf(). Voc pode fornecer argumentos adicionais para
substituir placeholders na sua string:

__('Voc tem {0} mensagens', $number);

Nota: Verifique a seo Internacionalizao e Localizao para mais informaes.

__d(string $domain, string $msg, mixed $args = null)


Permite sobrescrever o domnio atual por uma mensagem simples.
Muito til ao localizar um plugin: echo __d('PluginName','Esse meu plugin');
__dn(string $domain, string $singular, string $plural, integer $count, mixed $args = null)
Permite sobrescrever o domnio atual por uma mensagem no plural. Retorna a forma corrreta da mensagem no
plural identificada por $singular e $plural, pelo contador $count e pelo domnio $domain.
__dx(string $domain, string $context, string $msg, mixed $args = null)
Permite sobrescrever o domnio atual por uma mensagem simples. Tambm permite a especificao de um
contexto.
O contexto um identificador nico para as strings de traduo que a tornam nicas sob um mesmo domnio.

327
CakePHP Cookbook Documentation, Release 3.next

__dxn(string $domain, string $context, string $singular, string $plural, integer $count, mixed $args = null)
Permite sobrescrever o domnio atual por uma mensagem no plural. Tambm permite a especificao de um
contexto. Retorna a forma corrreta da mensagem no plural identificada por $singular e $plural, pelo
contador $count e pelo domnio $domain. Alguns idiomas tem mais de uma forma para o plural dependendo
do contador.
O contexto um identificador nico para as strings de traduo que a tornam nicas sob um mesmo domnio.
__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 domnio $domain. Alguns idiomas tem mais de uma forma para o plural dependendo do
contador.
__x(string $context, string $msg, mixed $args = null)
O contexto um identificador nico para as strings de traduo que a tornam nicas sob um mesmo domnio.
__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 domnio $domain. Alguns idiomas tem mais de uma forma para o plural dependendo do
contador.
O contexto um identificador nico para as strings de traduo que a tornam nicas sob um mesmo domnio.
collection(mixed $items)
Wrapper de convenincia para instanciar um novo objeto Cake\Collection\Collection, re-passando
o devido argumento. O parmetro $items recebe tanto um objeto Traversable quanto um array.
debug(mixed $var, boolean $showHtml = null, $showFrom = true)
Alterado na verso 3.3.0: Esse mtodo retorna a $var passada para que voc possa, por instncia, coloc-la em
uma declarao de retorno.
Se a varivel do core $debug for true, $var ser imprimida. Se $showHTML for true, ou for deixada
como null os dados sero renderizados formatados para melhor exibio em navegadores. Se $showFrom
no for definida como false, o debug comear a partir da linha em que foi chamado. Tambm veja Depurao
pr(mixed $var)
Alterado na verso 3.3.0: Chamar esse mtodo vai retornar a $var passada, ento, voc pode, por instncia,
coloc-la em uma declarao de retorno.
Wrapper de convenincia para print_r() com a adio das tags <pre> ao redor da sada.
pj(mixed $var)
Alterado na verso 3.3.0: Chamar esse mtodo vai retornar a $var passada, ento, voc pode, por instncia,
coloc-la em uma declarao de retorno.
Funo de convenincia para formatao de JSON, com a adio das tags <pre> ao redor da sada.
Deve ser usada com o intuito de debugar JSON de objetos e arrays.
env(string $key, string $default = null)
Alterado na verso 3.1.1: O parmetro $default ser adicionado.
Recebe uma varivel de ambiente de fontes disponveis. Usada como backup se $_SERVER ou $_ENV estive-
rem desabilitados.
Essa funo tambm emula PHP_SELF e DOCUMENT_ROOT em servidores no suportados. De fato, sem-
pre uma boa ideia usar env() ao invs de $_SERVER``ou ``getenv() (especialmente se voc planeja
distribuir o cdigo), pois um wrapper completo de emulao.
h(string $text, boolean $double = true, string $charset = null)
Wrapper de convenincia para htmlspecialchars().

328 Captulo 46. Constantes e Funes


CakePHP Cookbook Documentation, Release 3.next

pluginSplit(string $name, boolean $dotAppend = false, string $plugin = null)


Divide um nome de plugin que segue o padro de sintaxe de pontos e o transforma em um nome de classe ou do
plugin. Se $name no tem um ponto, ento o ndice 0 ser null.
Comumente usada assim: list($plugin,$name) = pluginSplit('Users.User');
namespaceSplit(string $class)
Divide o namespace do nome da classe.
Comumente usada assim: list($namespace,$className) = namespaceSplit('Cake\Core\App');

Constantes de definio do Core

A maior parte das constantes a seguir referem-se a caminhos da sua aplicao.


constant APP
Caminho absoluto para o diretrio de sua aplicao, incluindo a barra final.
constant APP_DIR
Igual a app ou ao nome do diretrio de sua aplicao.
constant CACHE
Caminho para o diretrio de arquivos de cache. Pode ser compartilhado entre hosts em uma configurao multi-
servidores.
constant CAKE
Caminho para o diretrio do CakePHP.
constant CAKE_CORE_INCLUDE_PATH
Caminho para o diretrio raiz de bibliotecas.
constant CONFIG
Caminho para o diretrio de configuraes.
constant CORE_PATH
Caminho para o diretrio raiz com contra-barra no final.
constant DS
Atalho para o DIRECTORY_SEPARATOR do PHP, que / no Linux e \\ no Windows.
constant LOGS
Caminho para o diretrio de logs.
constant ROOT
Caminho para o diretrio raiz.
constant TESTS
Caminho para o diretrio de testes.
constant TMP
Caminho para o diretrio de arquivos temporrios.
constant WWW_ROOT
Caminho completo para o diretrio webroot.

Constantes de definio de tempo


constant TIME_START
Timestamp unix em microsegundos como float de quando a aplicao comeou.

Constantes de definio do Core 329


CakePHP Cookbook Documentation, Release 3.next

constant SECOND
Igual a 1
constant MINUTE
Igual a 60
constant HOUR
Igual a 3600
constant DAY
Igual a 86400
constant WEEK
Igual a 604800
constant MONTH
Igual a 2592000
constant YEAR
Igual a 31536000

330 Captulo 46. Constantes e Funes


CAPTULO 47

Debug Kit

DebugKit um plugin suportado pelo time principal do CakePHP que oferece uma barra de ferramentas para auxiliar
na depurao de aplicaes do CakePHP.

Instalao

Por padro o DebugKit instalado com o esqueleto padro da aplicao. Se voc o removeu e gostaria de reinstal-lo,
voc pode executar o seguinte comando a partir do diretrio raiz da aplicao (onde o arquivo composer.json est
localizado):

php composer.phar require --dev cakephp/debug_kit "~3.0"

Ento, voc precisar habilitar o plugin ao executar o seguinte comando:

bin/cake plugin load DebugKit

Armazenamento do DebugKit

Por padro, o DebugKit usa um pequeno banco de dados SQLite no diretrio /tmp de sua aplicao para armazenar
os dados referentes ao painel de informaes. Se voc quiser que o DebugKit armazene seus dados em outro lugar,
necessrio configurar uma nova conexo com o nome debug_kit .

Configurao do banco de dados

Como informado anteriormente, por padro, o DebugKit armazenar os dados do painel em um banco de dados
SQLite no diretrio /tmp de sua aplicao. Se voc no puder instalar a extenso pdo_sqlite do PHP, voc pode
configurar o DebugKit para usar um banco de dados diferente ao definir uma conexo debug_kit em seu arquivo
config/app.php. Por exemplo:

/**
* A conexo debug_kit armazena meta-dados do DebugKit.
*/
'debug_kit' => [

331
CakePHP Cookbook Documentation, Release 3.next

'className' => 'Cake\Database\Connection',


'driver' => 'Cake\Database\Driver\Mysql',
'persistent' => false,
'host' => 'localhost',
//'port' => 'nonstandard_port_number',
'username' => 'dbusername', // Your DB username here
'password' => 'dbpassword', // Your DB password here
'database' => 'debug_kit',
'encoding' => 'utf8',
'timezone' => 'UTC',
'cacheMetadata' => true,
'quoteIdentifiers' => false,
//'init' => ['SET GLOBAL innodb_stats_on_metadata = 0'],
],

Uso da barra de ferramentas

A barra de ferramentas do DebugKit composta por vrios painis, que so exibidos ao clicar no cone do CakePHP
no canto inferior direito da janela do seu navegador. Uma vez que a barra de ferramentas aberta, voc dever ver
uma srie de botes. Cada um desses botes se expande em um painel de informaes relacionadas.
Cada painel permite a voc observar aspectos diferentes da sua aplicao:
Cache Exibe o uso de cache durante uma solicitao e limpa caches.
Environment Exibe variveis de ambiente relacionadas com PHP + CakePHP.
History Exibe uma lista de requisies anteriores, e permite que voc carregue e veja dados da barra de ferra-
mentas a partir de solicitaes anteriores.
Include Exibe os arquivos inclusos divididos por grupo.
Log Exibe todas as entradas feitas nos arquivos de log este pedido.
Request Exibe informaes sobre a requisio atual, GET, POST, informaes sobre a rota atual do Cake e
Cookies.
Session Exibe a informao atual da sesso.
Sql Logs Exibe logs SQL para cada conexo com o banco de dados.
Timer Exibe qualquer temporizador que fora definido durante a requisio com DebugKit\DebugTimer, e
memria utilizada coletada com DebugKit\DebugMemory.
Variables Exibe variveis de View definidas em um Controller.
Tipicamente, um painel manipula a recolha e apresentao de um nico tipo de informaes como logs ou informaes
de requisies. Voc pode optar por visualizar os painis padres da barra de ferramentas ou adicionar seus prprios
painis personalizados.

Usando o painel History

O painel History uma das caractersticas mais frequentemente confundidas do DebugKit. Ele oferece uma forma de
visualizar os dados de requisies anteriores na barra de ferramentas, incluindo erros e redirecionamentos.
Como voc pode ver, o painel contm uma lista de requisies. Na esquerda voc pode ver um ponto marcando
a requisio ativa. Clicar em qualquer requisio vai carregar os dados referentes a mesma no painel. Quando os

332 Captulo 47. Debug Kit


CakePHP Cookbook Documentation, Release 3.next

dados so carregados, os ttulos do painel vo sofrer uma transio para indicar que informaes alternativos foram
carregados.

Desenvolvendo seus prprios painis

Voc pode criar seus prprios painis customizados do DebugKit para ajudar na depurao de suas aplicaes.

Criando uma Panel Class

Panel Classes precisam ser colocadas no diretrio src/Panel. O nome do arquivo deve combinar com o nome da classe,
ento a classe MyCustomPanel deveria remeter ao nome de arquivo src/Panel/MyCustomPanel.php:

namespace App\Panel;

use DebugKit\DebugPanel;

/**
* My Custom Panel
*/
class MyCustomPanel extends DebugPanel
{
...
}

Perceba que painis customizados so necessrios para extender a classe DebugPanel.

Desenvolvendo seus prprios painis 333


CakePHP Cookbook Documentation, Release 3.next

Callbacks

Por padro objetos do painel possuem dois callbacks, permitindo-lhes acoplar-se na requisio atual. Painis
inscrevem-se aos eventos Controller.initialize e Controller.shutdown. Se o seu painel precisa
inscrever-se a eventos adicionais, voc pode usar o mtodo implementedEvents para definir todos os eventos
aos quais o seu painel possa precisar estar inscrito.
Voc deveria estudar os painis nativos para absorver alguns exemplos de como construir painis.

Elementos do painel

Cada painel deve ter um elemento view que renderiza o contedo do mesmo. O nome do elemento deve ser subli-
nhado e flexionado a partir do nome da classe. Por exemplo SessionPanel deve possuir um elemento nomeado
session_panel.ctp, e SqllogPanel deve possuir um elemento nomeado sqllog_panel.ctp. Estes elementos devem estar
localizados na raiz do seu diretrio src/Template/Element.

Ttulos personalizados e Elementos

Os painis devem relacionar o seu ttulo e o nome do elemento por conveno. No entanto, se voc precisa escolher
um nome de elemento personalizado ou ttulo, voc pode definir mtodos para customizar o comportamento do seu
painel:
title() - Configure o ttulo que exibido na barra de ferramentas.
elementName() - Configure qual elemento deve ser utilizada para um determinado painel.

Mtodos de captura

Voc tambm pode implementar os seguintes mtodos para customizar como o seu painel se comporta e se aparenta:
shutdown(Event $event) Esse mtodo coleta e prepara os dados para o painel. Os dados so geralmente
armazenados em $this->_data.
summary() Este mtodo retorna uma string de dados resumidos para serem exibidos na toolbar, mesmo
quando um painel est minimizado. Frequentemente, um contador ou um pequeno resumo de informaes.
data() Este mtodo retorna os dados do painel que sero usados como contexto para o elemento. Voc pode
manipular os dados coletados no mtodo shutdown(). Esse mtodo deve retornar dados que podem ser
serializados.

Painis em outros plugins

Painis disponibilizados por Plugins funcionam quase que totalmente como outros plugins, com uma pequena dife-
rena: Voc deve definir public $plugin como o nome do diretrio do plugin, com isso os elementos do painel
podero ser encontrados no momento de renderizao:

namespace MyPlugin\Panel;

use DebugKit\DebugPanel;

class MyCustomPanel extends DebugPanel


{
public $plugin = 'MyPlugin';

334 Captulo 47. Debug Kit


CakePHP Cookbook Documentation, Release 3.next

...
}

Para usar um plugin ou painel da aplicao, atualize a configurao do DebugKit de sua aplicao para incluir o painel:

Configure::write(
'DebugKit.panels',
array_merge(Configure::read('DebugKit.panels'), ['MyCustomPanel'])
);

O cdigo acima deve carregar todos os painis padro tanto como os outros painis customizados do MyPlugin.

Desenvolvendo seus prprios painis 335


CakePHP Cookbook Documentation, Release 3.next

336 Captulo 47. Debug Kit


CAPTULO 48

Migrations

Migrations um plugin suportado pela equipe oficial do CakePHP que ajuda voc a fazer mudanas no schema do
banco de dados utilizando arquivos PHP, que podem ser versionados utilizando um sistema de controle de verso.
Ele permite que voc atualize suas tabelas ao longo do tempo. Ao invs de escrever modificaes de schema via SQL,
este plugin permite que voc utilize um conjunto intuitivo de mtodos para fazer mudanas no seu banco de dados.
Esse plugin um wrapper para a biblioteca Phinx162 .

Instalao

Por padro o plugin instalado junto com o esqueleto da aplicao. Se voc o removeu e quer reinstal-lo, execute o
comando a seguir a partir do diretrio ROOT da sua aplicao (onde o arquivo composer.json est localizado):

$ php composer.phar require cakephp/migrations "@stable"

// Or if composer is installed globally

$ composer require cakephp/migrations "@stable"

Para usar o plugin voc precisa carreg-lo no arquivo config/bootstrap.php da sua aplicao. Voc pode usar o shell
de plugins do CakePHP para carregar e descarregar plugins do seu arquivo config/bootstrap.php:

$ bin/cake plugin load Migrations

Ou voc pode carregar o plugin editando seu arquivo config/bootstrap.php e adicionando a linha:

Plugin::load('Migrations');

Adicionalmente, voc precisar configurar o banco de dados padro da sua aplicao, no arquivo config/app.php
como explicado na seo Configurao de banco de dados.
162 https://phinx.org/

337
CakePHP Cookbook Documentation, Release 3.next

Viso Geral

Uma migrao basicamente um arquivo PHP que descreve as mudanas a serem feitas no banco de dados. Um
arquivo de migrao pode criar ou excluir tabelas, adicionar ou remover colunas, criar ndices e at mesmo inserir
dados em seu banco de dados.
Aqui segue um exemplo de migrao:

<?php
use Migrations\AbstractMigration;

class CreateProducts extends AbstractMigration


{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('products');
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
$table->addColumn('description', 'text', [
'default' => null,
'null' => false,
]);
$table->addColumn('created', 'datetime', [
'default' => null,
'null' => false,
]);
$table->addColumn('modified', 'datetime', [
'default' => null,
'null' => false,
]);
$table->create();
}
}

Essa migrao ir adicionar uma tabela chamada products ao banco de dados com as seguintes colunas:
id coluna do tipo integer como chave primria
name coluna do tipo string
description coluna do tipo text
created coluna do tipo datetime
modified coluna do tipo datetime

Dica: A coluna de chave primria id ser adicionada implicitamente.

338 Captulo 48. Migrations


CakePHP Cookbook Documentation, Release 3.next

Nota: Note que este arquivo descreve como o banco de dados deve ser aps a aplicao da migrao.
Neste ponto, a tabela products``ainda no existe no banco de dados,ns apenas criamos
um arquivo que capaz de criar a tabela ``products com seus devidos campos ou excluir a
tabela caso uma operao rollback seja executada.

Com o arquivo criado na pasta config/MIgrations, voc ser capaz de executar o comando abaixo para executar as
migraes no seu banco de dados:

bin/cake migrations migrate

O comando seguinte ir executar um rollback na migrao e ir excluir a tabela recm criada:

bin/cake migrations rollback

Criando migrations

Arquivos de migrao so armazeados no diretrio config/Migrations da sua aplicao. O nome dos arquivos de mi-
grao tm como prefixo a data em que foram criados, no formato YYYYMMDDHHMMSS_MigrationName.php.
Aqui esto exemplos de arquivos de migrao:
20160121163850_CreateProducts.php
20160210133047_AddRatingToProducts.php
A maneira mais fcil de criar um arquivo de migraes usando o Gerao de cdigo com o Bake a linha de comando.
Por favor, leia a documentao do Phinx <http://docs.phinx.org/en/latest/migrations.html> a fim de conhecer a lista
completa dos mtodos que voc pode usar para escrever os arquivos de migrao.

Nota: Ao gerar as migraes atravs do bake voc ainda pode alter-las antes da sua execuo, caso seja necessrio.

Sintaxe

A sintaxe do bake para a gerao de migraes segue o formato abaixo:

$ bin/cake bake migration CreateProducts name:string description:text created modified

Quando utilizar o bake para criar as migraes, voc normalmente precisar informar os seguintes dados:

* o nome da migrao que voc ir gerar (``CreateProducts`` por exemplo)


* as colunas da tabela que sero adicionadas ou removidas na migrao
(``name:string description:text created modified`` no nosso caso)

Devido s convenes, nem todas as alteraes de schema podem ser realizadas atravs destes comandos.
Alm disso, voc pode criar um arquivo de migrao vazio caso deseje ter um controle total do que precisa ser
executado. Para isto, apenas omita a definio das colunas:

$ bin/cake migrations create MyCustomMigration

Criando migrations 339


CakePHP Cookbook Documentation, Release 3.next

Nomenclatura de migrations

A nomenclatura das migraes pode seguir qualquer um dos padres apresentados a seguir:
(/^(Create)(.*)/) Cria a tabela especificada.
(/^(Drop)(.*)/) Exclui a tabela especificada. Ignora campos especificados nos argumentos
(/^(Add).*(?:To)(.*)/) Adiciona campos a tabela especificada
(/^(Remove).*(?:From)(.*)/) Remove campos de uma tabela especfica
(/^(Alter)(.*)/) Altera a tabela especificada. Um apelido para um CreateTable seguido de um AlterTable
Voc tambm pode usar underscore_form como nome das suas migrations. Ex.: create_products.
Novo na verso cakephp/migrations: 1.5.2
A partir da verso 1.5.2 do plugin migrations163 , o nome dos arquivos de migraes so colocados automati-
camente no padro camel case. Esta verso do plugin est disponvel apenas a partir da verso 3.1 do Ca-
kePHP. Antes disto, o padro de nomes do plugin migrations utilizava a nomenclatura baseada em underlines, ex.:
20160121164955_create_products.php.

Aviso: O nome das migraes so usados como nomes de classe, e podem colidir com outras migraes se o
nome das classes no forem nicos. Neste caso, pode ser necessrio sobreescrever manualmente os nomes mais
tarde ou simplesmente mudar os nomes que voc est especificando.

Definio de colunas

Quando utilizar colunas na linha de comando, pode ser til lembrar que eles seguem o seguinte padro:

fieldName:fieldType[length]:indexType:indexName

Por exemplo, veja formas vlidas de especificar um campo de e-mail:


email:string:unique
email:string:unique:EMAIL_INDEX
email:string[120]:unique:EMAIL_INDEX
O parmetro length para o fieldType opcional e deve sempre ser escrito entre colchetes
Os campos created e modified sero automaticamente definidos como datetime.
Os tipos de campos so genericamente disponibilizados pela biblioteca Phinx. Eles podem ser:
string
text
integer
biginteger
float
decimal
datetime
163 https://github.com/cakephp/migrations/

340 Captulo 48. Migrations


CakePHP Cookbook Documentation, Release 3.next

timestamp
time
date
binary
boolean
uuid
H algumas heursticas para a escolha de tipos de campos que no so especificados ou so definidos com valor
invlido. O tipo de campo padro string;
id: integer
created, modified, updated: datetime

Criando uma tabela

Voc pode utilizar o bake para criar uma tabela:

$ bin/cake bake migration CreateProducts name:string description:text created modified

A linha de comando acima ir gerar um arquivo de migrao parecido com este:

<?php
use Migrations\AbstractMigration;

class CreateProducts extends AbstractMigration


{
/**
* Change Method.
*
* More information on this method is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-change-method
* @return void
*/
public function change()
{
$table = $this->table('products');
$table->addColumn('name', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
]);
$table->addColumn('description', 'text', [
'default' => null,
'null' => false,
]);
$table->addColumn('created', 'datetime', [
'default' => null,
'null' => false,
]);
$table->addColumn('modified', 'datetime', [
'default' => null,
'null' => false,
]);
$table->create();

Criando migrations 341


CakePHP Cookbook Documentation, Release 3.next

}
}

Adicionando colunas a uma tabela existente

Se o nome da migrao na linha de comando estiver na forma AddXXXToYYY e for seguido por uma lista de nomes
de colunas e tipos, ento o arquivo de migrao com o cdigo para criar as colunas ser gerado:

$ bin/cake bake migration AddPriceToProducts price:decimal

A linha de comando acima ir gerar um arquivo com o seguinte contedo:

<?php
use Migrations\AbstractMigration;

class AddPriceToProducts extends AbstractMigration


{
public function change()
{
$table = $this->table('products');
$table->addColumn('price', 'decimal')
->update();
}
}

Adicionando uma coluna como indice a uma tabela

Tambm possvel adicionar ndices a colunas:

$ bin/cake bake migration AddNameIndexToProducts name:string:index

ir gerar:

<?php
use Migrations\AbstractMigration;

class AddNameIndexToProducts extends AbstractMigration


{
public function change()
{
$table = $this->table('products');
$table->addColumn('name', 'string')
->addIndex(['name'])
->update();
}
}

Especificando o tamanho do campo

Novo na verso cakephp/migrations: 1.4


Se voc precisar especificar o tamanho do campo, voc pode fazer isto entre colchetes logo aps o tipo do campo, ex.:

342 Captulo 48. Migrations


CakePHP Cookbook Documentation, Release 3.next

$ bin/cake bake migration AddFullDescriptionToProducts full_description:string[60]

Executar o comando acima ir gerar:

<?php
use Migrations\AbstractMigration;

class AddFullDescriptionToProducts extends AbstractMigration


{
public function change()
{
$table = $this->table('products');
$table->addColumn('full_description', 'string', [
'default' => null,
'limit' => 60,
'null' => false,
])
->update();
}
}

Se o tamanho no for especificado, os seguintes padres sero utilizados:


string: 255
integer: 11
biginteger: 20

Removendo uma coluna de uma tabela

Da mesma forma, voc pode gerar uma migrao para remover uma coluna utilizando a linha de comando, se o nome
da migrao estiver na forma RemoveXXXFromYYY:

$ bin/cake bake migration RemovePriceFromProducts price

Cria o arquivo:

<?php
use Migrations\AbstractMigration;

class RemovePriceFromProducts extends AbstractMigration


{
public function change()
{
$table = $this->table('products');
$table->removeColumn('price');
}
}

Gerando migraes a partir de uma base de dados existente

Se voc est trabalhando com um banco de dados pr-existente e quer comear a usar migraes, ou para versionar o
schema inicial da base de dados da sua aplicao, voc pode executar o comando migration_snapshot:

Gerando migraes a partir de uma base de dados existente 343


CakePHP Cookbook Documentation, Release 3.next

$ bin/cake bake migration_snapshot Initial

Isto ir gerar um arquivo de migrao chamado YYYYMMDDHHMMSS_Initial.php contendo todas as instrues


CREATE para todas as tabelas no seu banco de dados.
Por padro, o snapshot ser criado a partir da conexo default definida na configurao. Se voc precisar fazer o
bake de um snapshot de uma fonte de dados diferente, voc pode utilizar a opo --connection:

$ bin/cake bake migration_snapshot Initial --connection my_other_connection

Voc tambm pode definir que o snapshot inclua apenas as tabelas para as quais voc tenha definido models corres-
pendentes, utilizando a flag require-table:

$ bin/cake bake migration_snapshot Initial --require-table

Quando utilizar a flag --require-table, o shell ir olhar atravs das classes do diretrio Table da sua aplicao
e apenas ir adicionar no snapshot as tabelas l definidas.
A mesma lgica ser aplicada implicitamente se voc quiser fazer o bake de um snapshot para um plugin. Para fazer
isso, voc precisa usar a opo --plugin, veja a seguir:

$ bin/cake bake migration_snapshot Initial --plugin MyPlugin

Apenas as tabelas que tiverem um objeto Table definido sero adicionadas ao snapshot do seu plugin.

Nota: Quando fizer o bake de um snapshot para um plugin, os arquivos de migraes sero criados no diretrio
config/Migrations do seu plugin.

Fique atento que quando voc faz o bake de um snapshot, ele automaticamente adicionado ao log do phinx
como migrado.

Os Comandos

migrate : Aplicando migraes

Depois de ter gerado ou escrito seu arquivo de migrao, voc precisa executar o seguinte comando para aplicar as
mudanas a sua base de dados:

# Executa todas as migraes


$ bin/cake migrations migrate

# Execute uma migrao especfica utilizando a opo ``--target`` ou ``-t``


# O valor um timestamp que serve como prefixo para cada migrao::
$ bin/cake migrations migrate -t 20150103081132

# Por padro, as migraes ficam no diretrio **config/Migrations**. Voc


# pode especificar um diretrio utilizando a opo ``--source`` ou ``-s``.
# O comando abaixo executa as migraes no diretrio **config/Alternate**
$ bin/cake migrations migrate -s Alternate

# Voc pode executar as migraes de uma conexo diferente da ``default``


# utilizando a opo ``--connection`` ou ``-c``.
$ bin/cake migrations migrate -c my_custom_connection

344 Captulo 48. Migrations


CakePHP Cookbook Documentation, Release 3.next

# Migraes tambm podem ser executadas para plugins. Simplesmente utilize


# a opo ``--plugin`` ou ``-p``
$ bin/cake migrations migrate -p MyAwesomePlugin

rollback : Revertendo migraes

O comando rollback utilizado para desfazer migraes realizadas anteriormente pelo plugin Migrations. o inverso
do comando migrate:

# Voc pode desfazer uma migrao anterior utilizando o


# comando ``rollback``::
$ bin/cake migrations rollback

# Voc tambm pode passar a verso da migrao para voltar


# para uma verso especfica::
$ bin/cake migrations rollback -t 20150103081132

Voc tambm pode utilizar as opes --source, --connection e --plugin exatamente como no comando
migrate.

status : Status da migrao

O comando status exibe uma lista de todas as migraes juntamente com seu status. Voc pode utilizar este comando
para ver quais migraes foram executadas:

$ bin/cake migrations status

Voc tambm pode ver os resultados como JSON utilizando a opo --format (ou -f):

$ bin/cake migrations status --format json

Voc tambm pode utilizar as opes --source, --connection e --plugin exatamente como no comando
migrate.

mark_migrated : Marcando uma migrao como migrada

Novo na verso 1.4.0.


Algumas vezes pode ser til marcar uma lista de migraes como migrada sem efetivamente execut-las. Para fazer
isto, voc pode usar o comando mark_migrated. O comando bastante semelhante aos outros comandos.
Voc pode marcar todas as migraes como migradas utilizando este comando:

$ bin/cake migrations mark_migrated

Voc tambm pode marcar todas as migraes de uma verso especfica utilizando a opo --target:

$ bin/cake migrations mark_migrated --target=20151016204000

Se voc no quer marcar a migrao alvo como migrada durante o processo, voc pode utilizar a opo --exclude:

Os Comandos 345
CakePHP Cookbook Documentation, Release 3.next

$ bin/cake migrations mark_migrated --target=20151016204000 --exclude

Finalmente, se voc deseja marcar somente a migrao alvo como migrada, voc pode utilizar a opo --only:

$ bin/cake migrations mark_migrated --target=20151016204000 --only

Voc tambm pode utilizar as opes --source, --connection e --plugin exatamente como no comando
migrate.

Nota: Quando voc criar um snapshot utilizando o bake com o comando cake bake migration_snapshot,
a migrao criada ser automaticamente marcada como migrada.

Obsoleto desde a verso 1.4.0: A seguinte maneira de utilizar o comando foi depreciada. Use somente se voc estiver
utilizando uma verso do plugin inferior a 1.4.0.
Este comando espera um nmero de verso de migrao como argumento:

$ bin/cake migrations mark_migrated

Se voc deseja marcar todas as migraes como migradas, voc pode utilizar o valor especial all. Se voc o utilizar,
ele ir marcar todas as migraes como migradas:

$ bin/cake migrations mark_migrated all

seed : Populando seu banco de dados

A partir da verso 1.5.5, voc pode usar a shell de migrations para popular seu banco de dados. Essa fun-
o oferecida graas ao recurso de seed da biblioteca Phinx164 . Por padro, arquivos seed ficaro no diretrio
config/Seeds de sua aplicao. Por favor, tenha certeza de seguir as instrues do Phinx para construir seus
arquivos de seed165 .
Assim como nos migrations, uma interface do `bake oferecida para gerar arquivos de seed:

# This will create a ArticlesSeed.php file in the directory config/Seeds of your


application

# By default, the table the seed will try to alter is the "tableized" version of the
seed filename

$ bin/cake bake seed Articles

# You specify the name of the table the seed files will alter by using the ``--
table`` option

$ bin/cake bake seed Articles --table my_articles_table

# You can specify a plugin to bake into


$ bin/cake bake seed Articles --plugin PluginName

# You can specify an alternative connection when generating a seeder.


$ bin/cake bake seed Articles --connection connection

Para popular seu banco de dados, voc pode usar o subcomando seed:
164 http://docs.phinx.org/en/latest/seeding.html
165 http://docs.phinx.org/en/latest/seeding.html#creating-a-new-seed-class

346 Captulo 48. Migrations


CakePHP Cookbook Documentation, Release 3.next

# Without parameters, the seed subcommand will run all available seeders
# in the target directory, in alphabetical order.
$ bin/cake migrations seed

# You can specify only one seeder to be run using the `--seed` option
$ bin/cake migrations seed --seed ArticlesSeed

# You can run seeders from an alternative directory


$ bin/cake migrations seed --source AlternativeSeeds

# You can run seeders from a plugin


$ bin/cake migrations seed --plugin PluginName

# You can run seeders from a specific connection


$ bin/cake migrations seed --connection connection

Esteja ciente que, ao oposto das migrations, seeders no so versionados, o que significa que o mesmo seeder pode
ser aplicado diversas vezes.

Usando migrations em plugins

Plugins tambm podem oferecer migrations. Isso faz com que plugins que so planejados para serem distribudos
tornem-se muito mais prticos e fceis de instalar. Todos os comandos do plugin Migrations suportam a opo
--plugin ou -p, que por sua vez vai delegar a execuo da tarefa ao escopo relativo a um determinado plugin:

$ bin/cake migrations status -p PluginName

$ bin/cake migrations migrate -p PluginName

Executando migrations em ambientes fora da linha de comando

Novo na verso cakephp/migrations: 1.2.0


Desde o lanamento da verso 1.2 do plugin, voc pode executar migrations fora da linha de comando, diretamente
de uma aplicao, ao usar a nova classe Migrations. Isso pode ser muito til caso voc esteja desenvolvendo um
instalador de plugins para um CMS, para exemplificar.
A classe Migrations permite que voc execute os seguintes comandos disponveis na shell:
migrate
rollback
markMigrated
status
seed
Cada um desses comandos tem um mtodo definido na classe Migrations.
Veja como us-la:

use Migrations\Migrations;

Usando migrations em plugins 347


CakePHP Cookbook Documentation, Release 3.next

$migrations = new Migrations();

// Retornar um array de todos migrations e seus status


$status = $migrations->status();

// Retornar true se bem sucedido. Se um erro ocorrer, uma exceo ser lanada
$migrate = $migrations->migrate();

// Retornar true se bem sucedido. Se um erro ocorrer, uma exceo ser lanada
$rollback = $migrations->rollback();

// Retornar true se bem sucedido. Se um erro ocorrer, uma exceo ser lanada
$markMigrated = $migrations->markMigrated(20150804222900);

// Retornar true se bem sucedido. Se um erro ocorrer, uma exceo ser lanada
$seeded = $migrations->seed();

Os mtodos aceitam um array de parmetros que devem combinar com as opes dos comandos:

use Migrations\Migrations;

$migrations = new Migrations();

// Retornar um array de todos migrations e seus status


$status = $migrations->status(['connection' => 'custom', 'source' =>
'MyMigrationsFolder']);

Voc pode passar qualquer opo que esteja disponvel pelos comandos shell. A nica exceo o comando
markMigrated que espera um nmero de verso a ser marcado como migrado, como primeiro argumento. Passe o
array de parmetros como segundo argumento nesse caso.
Opcionalmente, voc pode passar esses parmetros pelo construtor da classe. Eles sero usados como padro evitando
que voc tenha que pass-los em cada chamada do mtodo:

use Migrations\Migrations;

$migrations = new Migrations(['connection' => 'custom', 'source' =>


'MyMigrationsFolder']);

// Todas as chamadas de mtodos sero executadas usando os parmetros passados pelo


construtor da classe

$status = $migrations->status();
$migrate = $migrations->migrate();

Se voc precisar sobrescrever um ou mais parmetros definidos previamente, voc pode pass-los para um mtodo:

use Migrations\Migrations;

$migrations = new Migrations(['connection' => 'custom', 'source' =>


'MyMigrationsFolder']);

// Essa chamada ser feita com a conexo "custom"


$status = $migrations->status();
// Essa chamada ser feita com a conexo "default"
$migrate = $migrations->migrate(['connection' => 'default']);

348 Captulo 48. Migrations


CakePHP Cookbook Documentation, Release 3.next

Dicas e truques

Criando chaves primrias customizadas

Se voc precisa evitar a criao automtica da chave primria id ao adicioanr novas tabelas ao banco de dados,
possvel usar o segundo argumento do mtodo table():

<?php
use Migrations\AbstractMigration;

class CreateProductsTable extends AbstractMigration


{
public function change()
{
$table = $this->table('products', ['id' => false, 'primary_key' => ['id']]);
$table
->addColumn('id', 'uuid')
->addColumn('name', 'string')
->addColumn('description', 'text')
->create();
}
}

O cdigo acima vai criar uma coluna CHAR(36) id que tambm a chave primria.

Nota: Ao especificar chaves primrias customizadas pela linha de comando, voc deve apont-las como chave
primria no campo id, caso contrrio voc pode receber um erro apontando campos diplicados, i.e.:

$ bin/cake bake migration CreateProducts id:uuid:primary name:string description:text


created modified

Adicionalmente, desde a verso 1.3, uma novo meio de lidar com chaves primrias foi introduzido. Para tal, sua classe
de migrao deve estender a nova classe Migrations\AbstractMigration.
Voc pode especificar uma propriedade autoId na sua classe e defini-la como false, o qu desabilitar a gera-
o automtica da coluna id. Voc vai precisar criar manualmente a coluna que ser usada como chave primria e
adicion-la declarao da tabela:

<?php
use Migrations\AbstractMigration;

class CreateProductsTable extends AbstractMigration


{

public $autoId = false;

public function up()


{
$table = $this->table('products');
$table
->addColumn('id', 'integer', [
'autoIncrement' => true,
'limit' => 11
])
->addPrimaryKey('id')

Dicas e truques 349


CakePHP Cookbook Documentation, Release 3.next

->addColumn('name', 'string')
->addColumn('description', 'text')
->create();
}
}

Comparado ao mtodo apresentado anteriormente de lidar com chaves primrias, nesse mtodo, temos a possibilidade
de ter maior controle sobre as definies da coluna da chave primria: unsigned, limit, comentrios, etc.
Todas as migrations e snapshots criadas pelo bake vo usar essa nova forma quando necessrio.

Aviso: Lidar com chaves primrias s possvel no momento de criao de tabelas. Isso devido a algumas
limitaes de alguns servidores de banco de dados que o plugin suporta.

Colaes

Se voc precisar criar uma tabela com colao diferente do padro do banco de dados, voc pode defini-la pelo mtodo
table(), como uma opo:

<?php
use Migrations\AbstractMigration;

class CreateCategoriesTable extends AbstractMigration


{
public function change()
{
$table = $this
->table('categories', [
'collation' => 'latin1_german1_ci'
])
->addColumn('title', 'string', [
'default' => null,
'limit' => 255,
'null' => false,
])
->create();
}
}

Note que isso s pode ser feito na criao da tabela : no h atualmente uma forma de adicionar uma coluna a uma
tabela existente com uma colao diferente do padro da tabela, ou mesmo do banco de dados. Apenas MySQL e
SqlServer suportam essa chave de configurao.

Atualizando nome de colunas e usando objetos de tabela

Se voc usa um objeto ORM Table do CakePHP para manipular valores do seu banco de dados, renomeando ou
removendo uma coluna, certifique-se de criar uma nova instncia do seu objeto depois da chamada do update(). O
registro do objeto limpo depois da chamada do update() para atualizar o schema que refletido e armazenado no
objeto Table paralelo instanciao.

350 Captulo 48. Migrations


CakePHP Cookbook Documentation, Release 3.next

Migrations e Deployment

Se voc usa o plugin ao fazer o deploy de sua aplicao, garanta que o cache ORM seja limpo para renovar os metada-
dos das colunas de suas tabelas. Caso contrrio, voc pode acabar recebendo erros relativos a colunas inexistentes ao
criar operaes nessas mesmas colunas. O core do CakePHP possui uma ORM Cache Shell que voc pode usar para
realizar essas operao:

$ bin/cake orm_cache clear

Leia a seo ORM Cache Shell do cookbook se voc quiser conhecer mais sobre essa shell.

Dicas e truques 351


CakePHP Cookbook Documentation, Release 3.next

352 Captulo 48. Migrations


CAPTULO 49

Apndices

Os apndices contm informaes sobre os novos recursos introduzidos em cada verso e a forma de executar a
migrao entre verses.

Guia de Migrao para a verso 3.x

3.x Migration Guide

Migration guides contain information regarding the new features introduced in each version and the migration path
between versions.

3.5 Migration Guide

3.5 Migration Guide

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github166 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

3.4 Migration Guide

3.4 Migration Guide

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github167 ou use o boto IMPROVE THIS DOC
166 https://github.com/cakephp/docs
167 https://github.com/cakephp/docs

353
CakePHP Cookbook Documentation, Release 3.next

para propor suas mudanas diretamente.


Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

3.3 Migration Guide

3.3 Migration Guide

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github168 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

3.2 Migration Guide

3.2 Guia de migrao

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github169 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

3.1 Migration Guide

3.1 Guia de migrao

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github170 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

168 https://github.com/cakephp/docs
169 https://github.com/cakephp/docs
170 https://github.com/cakephp/docs

354 Captulo 49. Apndices


CakePHP Cookbook Documentation, Release 3.next

3.0 Migration Guide

Guia de atualizao para o novo ORM

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github171 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

Informaes Gerais

Processo de desenvolvimento no CakePHP

Aqui tentamos explicar o processo utilizado no desenvolvimento com o framework CakePHP. Ns dependemos for-
temente da interao por tickets e no canal do IRC. O IRC o melhor lugar para encontrar membros do time de
desenvolvimento172 e discutir idias, o ultimo cdigo e fazer comentrios gerais. Se algo mais formal tem que ser
proposto ou exite um problema com uma verso, o sistema de tickets o melhor lugar para compartilhar seus pensa-
mentos.
Ns atualmente mantemos 4 verses do CakePHP.
verses tageadas : Verses tageadas so destinadas para produo onde uma estabilidade maior mais impor-
tante do que funcionalidades. Questes sobre verses tageadas sero resolvidas no branch relacionado e sero
parte do prximo release.
branch principal : Esses branches so onde todas as correes so fundidas. Verses estveis so rotuladas
apartir desses branches. master o principal branch para a verso atual. 2.x o branch de manuteno para
a verso 2.x. Se voc est usando verses estveis e precisa de correes que no chegaram em uma verso
tageada olhe aqui.
desenvolvimento : O branch de desenvolvimento contm sempre as ultimas correes e funcionalidades. Eles
so nomeados pela verso a qual se destinam, ex: 3.next. Uma vez que estas braches esto estveis elas so
fundidas na branch principal da verso.
branches de funcionalidades : Branches de funcionalidade contm trabalhos que esto sendo desenvolvidos ou
possivelmente instveis e so recomendadas apenas para usurios avanados interessados e dispostos a contribuir
com a comunidade. Branches de funcionalidade so nomeadas pela seguinte conveno verso-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 verso correta pra voc. Uma vez que escolhida a verso voc pode se
sentir compelido a reportar um erro ou fazer comentrios gerais no cdigo.
Se voc est usando uma verso estvel ou de manuteno, 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 comentrio e no 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 esto no ncleo do projeto.
171 https://github.com/cakephp/docs
172 https://github.com/cakephp?tab=members

Informaes Gerais 355


CakePHP Cookbook Documentation, Release 3.next

E sempre, se voc tiver alguma questo ou cometrios, nos visite no #cakephp no irc.freenode.net

Glossrio

Nota: Atualmente, a documentao desta pgina no suportada em portugus.


Por favor, sinta-se a vontade para nos enviar um pull request para o Github173 ou use o boto IMPROVE THIS DOC
para propor suas mudanas diretamente.
Voc pode consultar a verso em ingls deste tpico atravs do seletor de idiomas localizado ao lado direito do campo
de buscas da documentao.

routing array An array of attributes that are passed to Router::url(). They typically look like:

['controller' => 'Posts', 'action' => 'view', 5]

HTML attributes An array of key => values that are composed into HTML attributes. For example:

// Given
['class' => 'my-class', 'target' => '_blank']

// Would generate
class="my-class" target="_blank"

If an option can be minimized or accepts its name as the value, then true can be used:

// Given
['checked' => true]

// Would generate
checked="checked"

sintaxe plugin Plugin syntax refers to the dot separated class name indicating classes are part of a plugin:

// The plugin is "DebugKit", and the class name is "Toolbar".


'DebugKit.Toolbar'

// The plugin is "AcmeCorp/Tools", and the class name is "Toolbar".


'AcmeCorp/Tools.Toolbar'

dot notation Dot notation defines an array path, by separating nested levels with . For example:

Cache.default.engine

Would point to the following value:

[
'Cache' => [
'default' => [
'engine' => 'File'
]
]
]

173 https://github.com/cakephp/docs

356 Captulo 49. Apndices


CakePHP Cookbook Documentation, Release 3.next

CSRF Cross Site Request Forgery. Prevents replay attacks, double submissions and forged requests from other
domains.
CDN Content Delivery Network. A 3rd party vendor you can pay to help distribute your content to data centers
around the world. This helps put your static assets closer to geographically distributed users.
routes.php A file in config directory that contains routing configuration. This file is included before each request
is processed. It should connect all the routes your application needs so requests can be routed to the correct
controller + action.
DRY Dont repeat yourself. Is a principle of software development aimed at reducing repetition of information of all
kinds. In CakePHP DRY is used to allow you to code things once and re-use them across your application.
PaaS Platform as a Service. Platform as a Service providers will provide cloud based hosting, database and caching
resources. Some popular providers include Heroku, EngineYard and PagodaBox
DSN Data Source Name. A connection string format that is formed like a URI. CakePHP supports DSNs for Cache,
Database, Log and Email connections.

Informaes Gerais 357


CakePHP Cookbook Documentation, Release 3.next

358 Captulo 49. Apndices


PHP Namespace Index

c
Cake\Console, 233
Cake\Controller, 139
Cake\Core, 126
Cake\Core\Configure, 131
Cake\Core\Configure\Engine, 131
Cake\Error, 252
Cake\Form, 277
Cake\Mailer, 257
Cake\ORM, 202
Cake\Utility, 313
Cake\View, 151
Cake\View\Helper, 170

359
CakePHP Cookbook Documentation, Release 3.next

360 PHP Namespace Index


ndice

Symbols breakpoint() (global function), 251


() (Cake\Console\ method), 237, 238 buildFromArray() (Cake\Console\ConsoleOptionParser
:action, 135 method), 245
:controller, 135
:plugin, 135
C
$this->request, 137 CACHE (global constant), 329
__() (global function), 327 cache() (Cake\View\View method), 162
__d() (global function), 327 CAKE (global constant), 329
__dn() (global function), 327 CAKE_CORE_INCLUDE_PATH (global constant), 329
__dx() (global function), 327 Cake\Console (namespace), 233
__dxn() (global function), 327 Cake\Controller (namespace), 139
__n() (global function), 328 Cake\Core (namespace), 126
__x() (global function), 328 Cake\Core\Configure (namespace), 131
__xn() (global function), 328 Cake\Core\Configure\Engine (namespace), 131
Cake\Error (namespace), 252
A Cake\Form (namespace), 277
addArgument() (Cake\Console\ConsoleOptionParser Cake\Mailer (namespace), 257
method), 242 Cake\ORM (namespace), 173, 182, 202, 224
addArguments() (Cake\Console\ConsoleOptionParser Cake\Utility (namespace), 313
method), 242 Cake\View (namespace), 151
addOption() (Cake\Console\ConsoleOptionParser Cake\View\Helper (namespace), 167170
method), 243 camelize() (Cake\Utility\Inflector method), 314
addOptions() (Cake\Console\ConsoleOptionParser CDN, 357
method), 243 check() (Cake\Core\Configure method), 127
addSubcommand() (Cake\Console\ConsoleOptionParser classify() (Cake\Utility\Inflector method), 315
method), 244 collection() (global function), 328
afterFilter() (Cake\Controller\Controller method), 146 components (Cake\Controller\Controller property), 145
APP (global constant), 329 CONFIG (global constant), 329
app.php, 123 config() (Cake\Core\Configure method), 128
app.php.default, 123 ConfigEngineInterface (interface in
APP_DIR (global constant), 329 Cake\Core\Configure), 131
attachments() (Cake\Mailer\Email method), 262 configTransport() (Cake\Mailer\Email method), 259
configuration, 123
B Configure (classe em Cake\Core), 126
ConsoleOptionParser (classe em Cake\Console), 240
beforeFilter() (Cake\Controller\Controller method), 146
consume() (Cake\Core\Configure method), 128
beforeRender() (Cake\Controller\Controller method), 146
Controller (classe em Cake\Controller), 139
BreadcrumbsHelper (classe em Cake\View\Helper), 167
CORE_PATH (global constant), 329

361
CakePHP Cookbook Documentation, Release 3.next

CSRF, 357 HtmlHelper (classe em Cake\View\Helper), 168


humanize() (Cake\Utility\Inflector method), 314
D
dasherize() (Cake\Utility\Inflector method), 315 I
DAY (global constant), 330 Inflector (classe em Cake\Utility), 313
debug() (global function), 328 IniConfig (classe em Cake\Core\Configure\Engine), 131
Debugger (classe em Cake\Error), 252 initialize() (Cake\Console\ConsoleOptionParser method),
delete() (Cake\Core\Configure method), 128 248
delete() (Cake\ORM\Table method), 224
deleteAll() (Cake\ORM\Table method), 225 J
deleteOrFail() (Cake\ORM\Table method), 226 JsonConfig (classe em Cake\Core\Configure\Engine), 132
description() (Cake\Console\ConsoleOptionParser
method), 241 L
dirty() (Cake\ORM\Entity method), 177 load() (Cake\Core\Configure method), 129
doc (papel), 95 loadComponent() (Cake\Controller\Controller method),
dot notation, 356 145
drop() (Cake\Core\Configure method), 128 loadModel() (Cake\Controller\Controller method), 144
dropTransport() (Cake\Mailer\Email method), 260 log() (Cake\Error\Debugger method), 252
DRY, 357 LOGS (global constant), 329
DS (global constant), 329
DSN, 357 M
dump() (Cake\Core\Configure method), 129
MINUTE (global constant), 330
dump() (Cake\Core\Configure\ConfigEngineInterface
MONTH (global constant), 330
method), 131
dump() (Cake\Error\Debugger method), 252
N
E namespaceSplit() (global function), 329
NumberHelper (classe em Cake\View\Helper), 168
element() (Cake\View\View method), 159
Email (classe em Cake\Mailer), 257
Entity (classe em Cake\ORM), 173
P
env() (global function), 328 PaaS, 357
epilog() (Cake\Console\ConsoleOptionParser method), paginate() (Cake\Controller\Controller method), 145
242 PaginatorHelper (classe em Cake\View\Helper), 169
errors() (Cake\ORM\Entity method), 177 php:attr (diretiva), 96
excerpt() (Cake\Error\Debugger method), 253 php:attr (papel), 97
php:class (diretiva), 96
F php:class (papel), 97
php:const (diretiva), 96
find() (Cake\ORM\Table method), 183
php:const (papel), 97
FlashHelper (classe em Cake\View\Helper), 167
php:exc (papel), 97
Form (classe em Cake\Form), 277
php:exception (diretiva), 96
FormHelper (classe em Cake\View\Helper), 168
php:func (papel), 97
G php:function (diretiva), 96
php:global (diretiva), 96
get() (Cake\ORM\Entity method), 175 php:global (papel), 97
get() (Cake\ORM\Table method), 182 php:meth (papel), 97
getType() (Cake\Error\Debugger method), 253 php:method (diretiva), 96
greedy star, 135 php:staticmethod (diretiva), 96
PhpConfig (classe em Cake\Core\Configure\Engine), 131
H pj() (global function), 328
h() (global function), 328 pluginSplit() (global function), 328
helpers (Cake\Controller\Controller property), 146 pluralize() (Cake\Utility\Inflector method), 314
HOUR (global constant), 330 pr() (global function), 328
HTML attributes, 356

362 ndice
CakePHP Cookbook Documentation, Release 3.next

R View (classe em Cake\View), 151


read() (Cake\Core\Configure method), 127
read() (Cake\Core\Configure\ConfigEngineInterface W
method), 131 WEEK (global constant), 330
readOrFail() (Cake\Core\Configure method), 127 write() (Cake\Core\Configure method), 126
redirect() (Cake\Controller\Controller method), 143 WWW_ROOT (global constant), 329
ref (papel), 95
render() (Cake\Controller\Controller method), 142 Y
restore() (Cake\Core\Configure method), 130 YEAR (global constant), 330
RFC
RFC 2606, 110
ROOT (global constant), 329
routes.php, 357
routing array, 356
RssHelper (classe em Cake\View\Helper), 169
rules() (Cake\Utility\Inflector method), 316

S
save() (Cake\ORM\Table method), 215
saveMany() (Cake\ORM\Table method), 223
saveOrFail() (Cake\ORM\Table method), 222
SECOND (global constant), 330
SessionHelper (classe em Cake\View\Helper), 169
set() (Cake\Controller\Controller method), 141
set() (Cake\ORM\Entity method), 176
set() (Cake\View\View method), 153
setAction() (Cake\Controller\Controller method), 144
singularize() (Cake\Utility\Inflector method), 314
sintaxe plugin, 356
slug() (Cake\Utility\Inflector method), 315
stackTrace() (global function), 251
startup() (Cake\Console\ConsoleOptionParser method),
248
store() (Cake\Core\Configure method), 129

T
Table (classe em Cake\ORM), 182
tableize() (Cake\Utility\Inflector method), 315
TESTS (global constant), 329
TextHelper (classe em Cake\View\Helper), 169
TIME_START (global constant), 329
TimeHelper (classe em Cake\View\Helper), 170
TMP (global constant), 329
trace() (Cake\Error\Debugger method), 252
trailing star, 135

U
underscore() (Cake\Utility\Inflector method), 314
updateAll() (Cake\ORM\Table method), 223
UrlHelper (classe em Cake\View\Helper), 170

V
variable() (Cake\Utility\Inflector method), 315

ndice 363

You might also like