the state of lithium

32
THE STATE OF LITHIUM li3_nyc::init() // 2012-02-07

Upload: nate-abele

Post on 10-May-2015

2.671 views

Category:

Technology


4 download

DESCRIPTION

An update on the state of the Lithium PHP framework, given at the inaugural Lithium NYC meetup, Feb. 7th, 2012.

TRANSCRIPT

Page 1: The State of Lithium

THE STATE OF LITHIUMli3_nyc::init() // 2012-02-07

Page 2: The State of Lithium

SPONSORS

Page 3: The State of Lithium

AGENDA• State of the framework

• New features

• Upcoming features

• Community plugins

• Library management & The Lab

• Tips & tricks

• Q&A / Demos!

Page 4: The State of Lithium

STATE OF THE FRAMEWORK

Page 5: The State of Lithium

PROJECT & COMMUNITY STATS

• ~130 plugin repositories on GitHub

• 350+ commits from 40+ contributors since 0.10

• 60+ commits to the manual since 0.10

• Closed 250+ issues since moving to GitHub

• 175 pull requests submitted since moving to GitHub

Page 6: The State of Lithium

ROADMAP PROGRESS

• Cookie signing / encryption

• CSRF protection

• Error Handling

• Manual / automatic SQL result mapping

• Relationship support

Page 7: The State of Lithium

NEW FEATURES

Page 8: The State of Lithium

ENCRYPT & SIGN COOKIES

Session::config(array('default' => array( 'adapter' => 'Cookie', 'strategies' => array( 'Hmac' => array('secret' => '$f00bar$'), 'Encrypt' => array('secret' => '$f00bar$') ))));

Page 9: The State of Lithium

NEST ROUTESRouter::connect("/admin/{:args}", array('admin' => true), array( 'continue' => true));

Router::connect("/{:locale:en|de|jp}/{:args}", array(), array( 'continue' => true));

Router::connect("/{:args}.{:type}", array(), array( 'continue' => true));

Page 10: The State of Lithium

HANDLE ERRORS

$method = array(Connections::get('default'), 'read');

ErrorHandler::apply($method, array(), function($error, $params) { $queryParams = json_encode($params['query']); $msg = "Query error: {$error['message']}";

Logger::warning("{$msg}, data: {$queryParams}"); return new DocumentSet();});

Page 11: The State of Lithium

PROTECT FORMS<?=$this->form->create(); ?> <?=$this->security->requestToken(); ?> <?=$this->form->field('title'); ?> <?=$this->form->submit('Submit'); ?><?=$this->form->end(); ?>

public function add() { if ( $this->request->data && !RequestToken::check($this->request) ) { // Badness!! }}

Page 12: The State of Lithium

UPCOMING FEATURES

Page 13: The State of Lithium

HTTP SERVICE CLASSES

$http = new Http(array( ... 'methods' => array( 'do' => array('method' => 'post', 'path' => '/do') )));

$response = $http->do(new Query(array( 'data' => array('title' => 'sup'))));// var_dump($response->data());

POST /do HTTP/1.1…

title=sup

Page 14: The State of Lithium

FILTER / SORT COLLECTIONS

$users->find(array("type" => "author"))->sort("name");

$users->first(array("name" => "Nate"));

Page 15: The State of Lithium

MULTIBYTE CLASS

• Supports mbstring, intl, iconv & (womp, womp) plain PHP

• Only one method right now: strlen()

• More would be good… open a pull request

Page 16: The State of Lithium

SCHEMA CLASS

• Arbitrary data types

• Arbitrary handlers

• Example: hash modified passwords before writing

• Other example: JSON en/decode arbitrary data for MySQL

Page 17: The State of Lithium

PLUGINS

Page 18: The State of Lithium

LI3_DOCTRINE2

• Works with Lithium stuff:

• Connections

• Authentication

• Forms

• Sessions

• Validation

Connections::add('default', array( 'type' => 'Doctrine', 'driver' => 'pdo_mysql', 'host' => 'localhost', 'user' => 'root', 'password' => 'password', 'dbname' => 'my_db'));/** * @Entity * @Table(name="users") */class User extends \li3_doctrine2\models\BaseEntity { /** * @Id * @GeneratedValue * @Column(type="integer") */ private $id;

/** * @Column(type="string",unique=true) */ private $email; ...}

Page 19: The State of Lithium

LI3_FILESYSTEMuse li3_filesystem\storage\FileSystem;

FileSystem::config(array( 'default' => array( 'adapter' => 'File' ), 'ftp' => array( 'adapter' => 'Stream', 'wrapper' => 'ftp', 'path' => 'user:[email protected]/pub/' }));

FileSystem::write('default', '/path/to/file', $data);

Page 20: The State of Lithium

LI3_ACCESSAccess::config(array( 'asset' => array( 'adapter' => 'Rules', 'allowAny' => true, 'default' => array('isPublic', 'isOwner', 'isParticipant'), 'user' => function() { return Accounts::current(); }, 'rules' => array( 'isPublic' => function($user, $asset, $options) { ... }, 'isOwner' => function($user, $asset, $options) { ... }, 'isParticipant' => function($user, $asset, $options) { ... } ) ) ...);

Page 21: The State of Lithium

LI3_ACCESSAccess::config(array( ... 'action' => array( 'adapter' => 'Rules', 'default' => array('isPublic', 'isAuthenticated'), 'allowAny' => true, 'user' => function() { return Accounts::current(); }, 'rules' => array( 'isPublic' => function($user, $request, array $options) { ... }, 'isAuthenticated' => function($user, $request, array $options) { ... }, 'isAdmin' => function($user, $asset, $options) { ... } ) ));

Page 22: The State of Lithium

LI3_ACCESSDispatcher::applyFilter('_call', function($self, $params, $chain) { $opts = $params['params']; $request = $params['request']; $ctrl = $params['callable'];

if ($access = Access::check('action', null, $ctrl, $opts)) { // Reject } if ($access = Access::check('action', null, $ctrl, array('rules' => 'isAdmin') + $opts)) { // Reject } return $chain->next($self, $params, $chain);});

class PostsController extends Base {

public $publicActions = array('index', 'view');}

Page 23: The State of Lithium

http://bit.ly/li3plugins

Page 24: The State of Lithium

THE LAB

Page 25: The State of Lithium

TIPS & TRICKS

Page 26: The State of Lithium

RETURN ON REDIRECT

class PostsController extends Base {

public function view($post) { if (!$post) { $this->redirect("Posts::index"); } // Herp derp }}

Page 27: The State of Lithium

FAT FILTERS == BADDispatcher::applyFilter('run', function($self, $params, $chain) { // Herp // Derp // Herp // Derp // Herp // Derp // Herp // Derp // Herp // Derp // Herp (repeat x100)});

Page 28: The State of Lithium

DEFINE YOUR SCHEMA!

{ count: 5, ...}...{ count: "5", ...}

Page 29: The State of Lithium

DON’T FEAR THE SUBCLASSclass Base extends \lithium\data\Model {

public function save($entity, $data = null, array $options = array()) { if ($data) { $entity->set($data); } if (!$entity->exists()) { $entity->created = new MongoDate(); } $entity->updated = new MongoDate(); return parent::save($entity, null, $options); }}

class Posts extends Base { ...}

Page 30: The State of Lithium

QUICK & DIRTY ADMIN

Dispatcher::config(array('rules' => array( 'admin' => array(

'action' => 'admin_{:action}' )

)));

Router::connect( '/admin/{:args}', array('admin' => true), array('continue' => true));

class PostsController extends Base {

public function admin_index() { ... }

public function index() { ... }}

Page 31: The State of Lithium

Q&A / DEMOS

Page 32: The State of Lithium

THANKS!