Faster develoment with CakePHP 3

33

description

 

Transcript of Faster develoment with CakePHP 3

Page 1: Faster develoment with CakePHP 3

Faster applicationdevelopment with

CakePHP 3.0

1 / 33

Page 2: Faster develoment with CakePHP 3

Agenda1. A short story2. Grandpas3. Overview of CakePHP 34. Des raisons pour dire ouaou5. Let's get Baking

2 / 33

Page 3: Faster develoment with CakePHP 3

A Short StoryCakePHP as a project was created in late 2004.

You were probably wearing diapers at the time.

3 / 33

Page 4: Faster develoment with CakePHP 3

More than a grown upCakePHP is already a grandpa in the frameworks world

4 / 33

Page 5: Faster develoment with CakePHP 3

Types of Grandpas

The dormant

All cool kids make fun of him.

5 / 33

Page 6: Faster develoment with CakePHP 3

Types of Grandpas

The bad inluence

All cool kids want to be like him. They do not end well.

6 / 33

Page 7: Faster develoment with CakePHP 3

Types of Grandpas

The magic one

Has a great deal of experience, helps people in their journeys.

7 / 33

Page 8: Faster develoment with CakePHP 3

Why CakePHP 3?Very mature. Experience from lots of development years is added into the mix.

Extremely powerful, flexible and lightweight ORM.

Beautifully simple Form generator for single and multiple entities.

Built-in Internationalization, that actually makes sense.

Middleware oriented stack, without sacrificing familiarity and readability.

Solves the 80% problem and stays out of the way.

Outstanding documentation.

Requires less code!

8 / 33

Page 9: Faster develoment with CakePHP 3

Use it separatelyInteroperability with the rest of the PHP ecosystem

Separate components that you can use in other projects

cakephp/cache

cakephp/event

cakephp/validation

cakephp/collection...

use Cake\Collection\Collection;$items = [ ['id' => 1, 'name' => 'foo', 'parent' => 'a'], ['id' => 2, 'name' => 'bar', 'parent' => 'b'], ['id' => 3, 'name' => 'baz', 'parent' => 'a'],];

$combined = (new Collection($items))->combine('id', 'name', 'parent');

// Result will look like this when converted to array[ 'a' => [1 => 'foo', 3 => 'baz'], 'b' => [2 => 'bar']];

9 / 33

Page 10: Faster develoment with CakePHP 3

Quick ORM OverviewEverything can be an expression

$query = $users->find()->select(['id'])->where(['is_active' => true]);$anotherQuery->innerJoin(['stuff' => $query]);$anotherQuery->where(['id IN' => $query]);

Queries can be composed

$premium = $users->find('active')->find('premium')->each(function($user) { echo $user->name;});

$subscribers = $users->find('active')->find('subscribedToNewsletter');

Queries have access to powerful collection methods

$recipients = $premium->append($subscribers)->extract('email');

10 / 33

Page 11: Faster develoment with CakePHP 3

Quick ORM OverviewFiltering by associations

public function findWithCitiesBiggerThanDenmark(Query $query) { $denmarkPopulation = $this->find() ->select(['population']) ->where(['name' => 'Denmark']);

return $query ->matching('Cities', function($q) use ($denmarkPopulation) { return $q->where(['Cities.population >' => $denmarkPopulation]); });}

11 / 33

Page 12: Faster develoment with CakePHP 3

Quick ORM OverviewLazy results post-processing

public function findInContinentGroups(Query $query) { $query->formatResults(function($results) { return $results->groupBy('continent'); }); return $query;}

"Africa": [ { "name": "Angola" }, { "name": "Burundi" }, { "name": "Benin" }, { "name": "Burkina Faso" }"America": [...

12 / 33

Page 13: Faster develoment with CakePHP 3

Quick ORM OverviewLazy result processing pipelines

public function findInRegionalGroups(Query $query) { $query ->formatResults(function($results) { return $results->groupBy('continent'); }) ->formatResults(function($results) { return $results->map(function($continent) { return collection($continent)->groupBy('region'); }); }); return $query;}

"North America": { "Caribbean": [ { "name": "Aruba" }, { "name": "Anguilla" }, { "name": "Netherlands Antilles" } ...

13 / 33

Page 14: Faster develoment with CakePHP 3

MOAR!Map-Reduce

Intelligent count operations

Complex pagination one-liners

Automatic saving of associations

Flexible association strategies

Result streaming

Query caching

Finder callbacks

Composite Primary Key searches

Methods for finding in Tree structures

14 / 33

Page 15: Faster develoment with CakePHP 3

MOAR!

Find more ORM examples at

https://github.com/lorenzo/cakephp3-examples

15 / 33

Page 16: Faster develoment with CakePHP 3

Let's Get Baking

16 / 33

Page 17: Faster develoment with CakePHP 3

Install CakePHPcomposer create-project --prefer-dist -s dev cakephp/app

cd app && bin/cake server

Virtual environment available: https://github.com/FriendsOfCake/vagrant-chef

17 / 33

Page 18: Faster develoment with CakePHP 3

Initial database migration$this->table('bookmarks') ->addColumn('user_id', 'integer') ->addColumn('title', 'string', ['limit' => 50]) ->addColumn('description', 'text') ->addColumn('url', 'text') ->addColumn('created', 'datetime') ->addColumn('modified', 'datetime') ->create();

$this->table('tags') ->addColumn('title', 'string', ['limit' => 100]) ->addColumn('created', 'datetime') ->addColumn('modified', 'datetime') ->create();...

$ bin/cake migrations create Initial$ bin/cake migrations migrate

Reversible migrations provided by http://phinx.org

18 / 33

Page 19: Faster develoment with CakePHP 3

Put the Cake in the Oven$ bin/cake bake all users$ bin/cake bake all bookmarks$ bin/cake bake all tags

19 / 33

Page 20: Faster develoment with CakePHP 3

That's it

The End

20 / 33

Page 21: Faster develoment with CakePHP 3

DebugKitCakePHP 3 comes with a debug toolbar pre-installed:

21 / 33

Page 22: Faster develoment with CakePHP 3

Next level RADThe code in the controllers looks repetitive, how do we fix this?

How can we have both a Web + REST interface ?

Can we make this without sacrificing readability and flexibility?

Enter the CRUD Plugin

Dynamic Event-Driven Scaffolding

Automatic REST API generation

Actions Classes

Debugging Enhancements

22 / 33

Page 23: Faster develoment with CakePHP 3

Install the CRUD plugincomposer require friendsofcake/crud:dev-cake3

class AppController extends Controller {

use \Crud\Controller\ControllerTrait;

public function initialize() { $this->loadComponent('Crud.Crud', [ 'actions' => [ 'Crud.Index', 'Crud.Add', 'Crud.Edit', 'Crud.View', 'Crud.Delete' ] ]); }}

Remove all the code from your controllers.

Piece of Cake!

23 / 33

Page 24: Faster develoment with CakePHP 3

Creating a REST API// config/routes.php

$routes->extensions(['json', 'xml']); // optional

public function initialize() { ... $this->loadComponent('RequestHandler'); $this->Crud->addListener('Crud.Api');}

$ curl -X GET localhost:8765/tags.json

Seriously, that's it

Converts all actions into a web service able to respond in JSON and XML.

Takes care of error handling and validation errors.

Automatically adds a "layout" to your responses (useful for pagination)

Wins you fame and glory beyond your wildest dreams. 24 / 33

Page 25: Faster develoment with CakePHP 3

Adding Debug info to APIpublic function initialize() { ... $this->Crud->addListener('Crud.Api'); $this->Crud->addListener('Crud.ApiQueryLog');}

25 / 33

Page 26: Faster develoment with CakePHP 3

Authentication

Hash Passwords

// src/Model/Entity/User.php

use Cake\Auth\DefaultPasswordHasher;...protected function _setPassword($password) { $hasher = new DefaultPasswordHasher(); return $hasher->hash($value);}

Enable Authentication

public function initialize() { $this->loadComponent('Auth');}

Make sure you create a user before this last step.

You will now be prompted for login on all actions. 26 / 33

Page 27: Faster develoment with CakePHP 3

The Login Action// 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.'); }}

And its template

// src/Template/Users/login.ctp<h2>Login</h2><?= $this->Form->create() ?><?= $this->Form->input('username') ?><?= $this->Form->input('password') ?><?= $this->Form->button('Login') ?><?= $this->Form->end() ?>

27 / 33

Page 28: Faster develoment with CakePHP 3

Permissions

Create the permissions handler

// src/Auth/BookmarksAuthorizeclass BookmarksAuthorize { public function authorize($user, Request $request) { $action = $request->action;

// The add and index actions are always allowed. if (in_array($action, ['index', 'add'])) { return true; }

// All other actions require an id. if (empty($request->params['pass'])) { return false; }

// Check that the bookmark belongs to the current user. $id = $request->params['pass'][0]; $bookmark = $this->registry->getController()->Bookmarks->get($id); if ($bookmark->user_id == $user['id']) { return true; } }}

28 / 33

Page 29: Faster develoment with CakePHP 3

Permissions

Attach the permissions handler

// src/Controller/BookmarksController.php

public function initialize() { $this->Auth->config('authorize.Bookmarks', [ 'className' => 'App\Auth\BookmarksAuthorize' ]);}

Users will now be able to only see Bookmarks they created themselves.

Yes, that easy.

No, I'm not kidding.

29 / 33

Page 30: Faster develoment with CakePHP 3

Event Based Crud

Limiting the records by user

// src/Controller/BookmarksController.php$this->Crud->on('beforePaginate', function() { $this->paginate['conditions'] = ['Bookmarks.user_id' => $this->Auth->user('id')];});

Remembering the Bookmark creator

// src/Controller/BookmarksController.php

$this->Crud->on('beforeSave', function($e) { $e->subject->entity->user_id = $this->Auth->user('id');});

30 / 33

Page 31: Faster develoment with CakePHP 3

Custom Finders

Bookmarks tagged with...

public function findTagged(Query $query, $options) { return $query->matching('Tags', function($q) use ($options) { return $q->where(['Tags.title' => $options['tag']]); });}

Find

$bookmarks->find('tagged', ['tag' => 'awesome']);

31 / 33

Page 32: Faster develoment with CakePHP 3

Thanks

Find examples at

https://github.com/lorenzo/cakephp3-bookmarkr

https://github.com/lorenzo/cakephp3-examples

32 / 33

Page 33: Faster develoment with CakePHP 3

Rate the talk!https://joind.in/talk/view/11946

33 / 33