• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Lithium Best
 

Lithium Best

on

  • 1,265 views

 

Statistics

Views

Total Views
1,265
Views on SlideShare
1,236
Embed Views
29

Actions

Likes
3
Downloads
33
Comments
0

3 Embeds 29

http://protalk.me 15
https://twitter.com 8
http://www.php-talks.com 6

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • \n
  • Union of Rad - worked with Nate\nTalk to me about japan\n
  • Thank you - engine yard sponsors Lithium - php 5.4\n
  • Lets talk about frameworks - there are too many\n
  • People like to fight about their framework choice\n
  • My favorites\nMy Least favorites\n
  • Bloated\nCarry too much bulk - Symfony/Doctrine - VHeavy\nJava programmers\n
  • \n
  • \n
  • Any body else find this odd?\n
  • \n
  • What drives us -\nIt is important to love the code you write - rails has had a big influence\n
  • Our feelings count\nI don’t think we should need a high powered ide\n
  • Lithium is really light 1mb tests 1mb - no bulk\n
  • Lithium is really light 1mb tests 1mb - no bulk\n
  • It is fast to develop in, it will speed up your development time. \nCompare Symfony, ZF, Drupal\n
  • World one - every one familiar with this phrase?\n
  • The repo - skeleton\n
  • Great way to familiarize yourself - next few slides are taken from this project\n
  • Example model - Save override to save tags\n
  • Example model - Save override to save tags\n
  • Example model - Save override to save tags\n
  • View helpers\nCan override these\n
  • View helpers\nCan override these\n
  • View helpers\nCan override these\n
  • <?= escaping\nLink routes\nimage url helper\n
  • <?= escaping\nLink routes\nimage url helper\n
  • <?= escaping\nLink routes\nimage url helper\n
  • Easy to read controllers - simple methods\n
  • Easy to read controllers - simple methods\n
  • Easy to read controllers - simple methods\n
  • Geo-code is here - still really simple\n
  • 1.Completely avoids the framework stack\nCan also use with JSON end points\n2. Its PHP, you can do what you want \n
  • 1.Completely avoids the framework stack\nCan also use with JSON end points\n2. Its PHP, you can do what you want \n
  • 1.Completely avoids the framework stack\nCan also use with JSON end points\n2. Its PHP, you can do what you want \n
  • testing important\neverything is a library\n
  • command line\n
  • But this alone is not massively different to what is out there - like fuel\n
  • It gets more interesting from here\n
  • world 2\n
  • Sky - no framework - create it from scratch - framework constraints\n
  • maybe we feel a bit like this\n
  • Not just 1 programming paradigm - php is very flexible\n
  • \n
  • Make a simple model\n
  • Decoupled example\njust add lithium library - low overhead - all the code you need\nEasily added to DB - These are working examples\n
  • Decoupled example\njust add lithium library - low overhead - all the code you need\nEasily added to DB - These are working examples\n
  • Decoupled example\njust add lithium library - low overhead - all the code you need\nEasily added to DB - These are working examples\n
  • Decoupled example\njust add lithium library - low overhead - all the code you need\nEasily added to DB - These are working examples\n
  • Decoupled example\njust add lithium library - low overhead - all the code you need\nEasily added to DB - These are working examples\n
  • Decoupled example\njust add lithium library - low overhead - all the code you need\nEasily added to DB - These are working examples\n
  • Decoupled example\njust add lithium library - low overhead - all the code you need\nEasily added to DB - These are working examples\n
  • Instantiate request and router\nSet routes - regex - now works (request contains correct controller)\nFull path matching\n\n\n
  • Instantiate request and router\nSet routes - regex - now works (request contains correct controller)\nFull path matching\n\n\n
  • Instantiate request and router\nSet routes - regex - now works (request contains correct controller)\nFull path matching\n\n\n
  • Instantiate request and router\nSet routes - regex - now works (request contains correct controller)\nFull path matching\n\n\n
  • Instantiate request and router\nSet routes - regex - now works (request contains correct controller)\nFull path matching\n\n\n
  • We have an end point, \nfollowing route, \nparses the request object to contain\n
  • We have an end point, \nfollowing route, \nparses the request object to contain\n
  • We have an end point, \nfollowing route, \nparses the request object to contain\n
  • Make simplest adaptable class\n
  • We tell the Lithium where the app and adapters live -normally not needed\n-note emails same as where highlighted in the class \nSet the environment and use the adapter\n
  • We tell the Lithium where the app and adapters live -normally not needed\n-note emails same as where highlighted in the class \nSet the environment and use the adapter\n
  • We tell the Lithium where the app and adapters live -normally not needed\n-note emails same as where highlighted in the class \nSet the environment and use the adapter\n
  • We tell the Lithium where the app and adapters live -normally not needed\n-note emails same as where highlighted in the class \nSet the environment and use the adapter\n
  • We tell the Lithium where the app and adapters live -normally not needed\n-note emails same as where highlighted in the class \nSet the environment and use the adapter\n
  • This time we write it a little more differently\nset up environment aware config\nSending is easy. Base of lithium services. Strategy implementation, very testable. DI in proportion\n
  • This time we write it a little more differently\nset up environment aware config\nSending is easy. Base of lithium services. Strategy implementation, very testable. DI in proportion\n
  • This time we write it a little more differently\nset up environment aware config\nSending is easy. Base of lithium services. Strategy implementation, very testable. DI in proportion\n
  • This time we write it a little more differently\nset up environment aware config\nSending is easy. Base of lithium services. Strategy implementation, very testable. DI in proportion\n
  • This time we write it a little more differently\nset up environment aware config\nSending is easy. Base of lithium services. Strategy implementation, very testable. DI in proportion\n
  • The real fun part, this is a real high point of lithiums architecture.\n
  • Write a method that doesn’t really do anything, but this is a filterable class\nEcho-ing is non-sense\n
  • Write a method that doesn’t really do anything, but this is a filterable class\nEcho-ing is non-sense\n
  • Write a method that doesn’t really do anything, but this is a filterable class\nEcho-ing is non-sense\n
  • We deal with dependencies that have nothing to do with role\nLogger\n
  • We deal with dependencies that have nothing to do with role\nLogger\n
  • We deal with dependencies that have nothing to do with role\nLogger\n
  • We deal with dependencies that have nothing to do with role\nLogger\n
  • We deal with dependencies that have nothing to do with role\nLogger\n
  • Find Example\n
  • Find Example\n
  • Find Example\n
  • Find Example\n
  • Find Example\n
  • Find Example\n
  • It would look like this\n
  • It would look like this\n
  • It would look like this\n
  • Cache is an adaptable class\nBAD - filter classes that relates to itself\n
  • Cache is an adaptable class\nBAD - filter classes that relates to itself\n
  • Cache is an adaptable class\nBAD - filter classes that relates to itself\n
  • Cache is an adaptable class\nBAD - filter classes that relates to itself\n
  • Cache is an adaptable class\nBAD - filter classes that relates to itself\n
  • Override content render - I am doing this\n
  • Override content render - I am doing this\n
  • Override content render - I am doing this\n
  • \n
  • \n
  • \n
  • How controller render works\n
  • Ajax paths - types \n
  • Handle media returned from the controller - images, json, encoding handlers\nHappens in controllers render method\n
  • Handle media returned from the controller - images, json, encoding handlers\nHappens in controllers render method\n
  • Handle media returned from the controller - images, json, encoding handlers\nHappens in controllers render method\n
  • Granular control of exception handling\n
  • Granular control of exception handling\n
  • Granular control of exception handling\n
  • Granular control of exception handling\n
  • Granular control of exception handling\n
  • Granular control of exception handling\n
  • Real example - setting up error handling\n
  • Real example - setting up error handling\n
  • Real example - setting up error handling\n
  • \n
  • \n
  • Set up stuff required by library - do demo\n
  • Set up stuff required by library - do demo\n
  • Set up stuff required by library - do demo\n
  • Set up stuff required by library - do demo\n
  • Set up stuff required by library - do demo\n
  • Recap -really fast development\n
  • Recap -really fast development\n
  • Recap -really fast development\n
  • Recap -really fast development\n
  • Recap -really fast development\n
  • Recap -really fast development\n
  • Recap -really fast development\n
  • \n

Lithium Best Lithium Best Presentation Transcript

  • Lithium (#li3)The framework with the best of both worlds
  • Richard McIntyre: @mackstar★ Lithium core team★ Freelancer - Leeds/Manchester★ Most recently at BBC, Mamas & Papas, UOR★ Engineer on BBC Olympics App★ Lived in Japan 15 years★ Done PHP for donkeys
  • Frameworks
  • I’ve seen it✦ Symfony 2 ✦ Merb✦ Zend Framework ✦ Sinatra✦ CakePHP ✦ Spring✦ Code Igniter ✦ Stripes (Java)✦ Drupal 6&7 ✦ Django Wordpress✦ Silex ✦✦ Rails
  • manyframeworksarelikethis
  • Each software solution should be in proportion tothe problem being solved.
  • Each software solution should be in proportion tothe problem being solved. -some lazy bugger
  • Each software solution should be in proportion tothe problem being solved. -some lazy bugger me
  • <?phpuse BehatMinkExtensionContextMinkContext;class FeatureContext extends MinkContext{ /** * @Then /^I wait for the suggestion box to appear$/ */ public function myNameHasAMeaninglessExistance() { $this->getSession()->wait(5000, "$(.suggestions-results).children().length >0"); }}
  • All problems in computer science can be solvedby another level of indirection. Except for theproblem of too many layers of indirection. Butler Lampson, David Wheeler
  • Code Sexy-nessThere’s nothing like the look of beautiful Ruby code in the morning.Gracefully colored by TextMate and rendered in Bitstream Vera pt 12.@dhh
  • Developer Happy-nessAny fool can write code that a computer can understand. Goodprogrammers write code that humans can understand. –Martin Fowler
  • Light Footprint
  • Light Footprint
  • Looking for a hackers Framework?Light Footprint
  • Fast, Flexible and Rad
  • World 1Full Stack Framework Convention Over Configuration
  • github.com/UnionOfRad/framework
  • The Photo Blog Tutorial github.com/nateabele/photoblog
  • Modelnamespace photoblogmodels;class Photos extends lithiumdataModel { public $validates = array(); protected $_meta = array(source => fs.files); public function save($entity, $data = null, array $options = array()) { if ($data) { $entity->set($data); } if ($entity->tags && !is_array($entity->tags)) { $entity->tags = array_map(trim, explode(,, $entity->tags)); } return parent::save($entity, null, $options); }}
  • Modelnamespace photoblogmodels;class Photos extends lithiumdataModel { public $validates = array(); protected $_meta = array(source => fs.files); public function save($entity, $data = null, array $options = array()) { if ($data) { $entity->set($data); } if ($entity->tags && !is_array($entity->tags)) { $entity->tags = array_map(trim, explode(,, $entity->tags)); } return parent::save($entity, null, $options); }}
  • Modelnamespace photoblogmodels;class Photos extends lithiumdataModel { public $validates = array(); protected $_meta = array(source => fs.files); public function save($entity, $data = null, array $options = array()) { if ($data) { $entity->set($data); } if ($entity->tags && !is_array($entity->tags)) { $entity->tags = array_map(trim, explode(,, $entity->tags)); } return parent::save($entity, null, $options); }}
  • Views<?=$this->form->create($photo, array(type => file)); ?> <?=$this->form->field(title); ?> <?=$this->form->field(description); ?> <?php if (!$photo->exists()): ?> <?=$this->form->field(file, array(type => file)); ?> <?php endif; ?> <?=$this->form->field(tags, array(label => Add tags separated by commas)); ?> <?=$this->form->submit(Save); ?><?=$this->form->end(); ?>
  • Views<?=$this->form->create($photo, array(type => file)); ?> <?=$this->form->field(title); ?> <?=$this->form->field(description); ?> <?php if (!$photo->exists()): ?> <?=$this->form->field(file, array(type => file)); ?> <?php endif; ?> <?=$this->form->field(tags, array(label => Add tags separated by commas)); ?> <?=$this->form->submit(Save); ?><?=$this->form->end(); ?>
  • Views<?=$this->form->create($photo, array(type => file)); ?> <?=$this->form->field(title); ?> <?=$this->form->field(description); ?> <?php if (!$photo->exists()): ?> <?=$this->form->field(file, array(type => file)); ?> <?php endif; ?> <?=$this->form->field(tags, array(label => Add tags separated by commas)); ?> <?=$this->form->submit(Save); ?><?=$this->form->end(); ?>
  • <h1> <?=$this->title($photo->title); ?> <em>[ <?=$this->html->link( edit, array(Photos::edit, id => $photo->_id) ); ?> ]</em></h1><p><?=$photo->description; ?></p><?php if ($photo->tags): ?> Tags: <?php foreach ($photo->tags as $tag): ?> <?=$this->html->link( $tag, array(Photos::index, args => array($tag)) ); ?> <?php endforeach; ?><?php endif; ?><?=$this->html->image( "/photos/view/{$photo->_id}.jpeg", array( alt => $photo->title, width => "100%" )); ?>
  • <h1> <?=$this->title($photo->title); ?> <em>[ <?=$this->html->link( edit, array(Photos::edit, id => $photo->_id) ); ?> ]</em></h1><p><?=$photo->description; ?></p><?php if ($photo->tags): ?> Tags: <?php foreach ($photo->tags as $tag): ?> <?=$this->html->link( $tag, array(Photos::index, args => array($tag)) ); ?> <?php endforeach; ?><?php endif; ?><?=$this->html->image( "/photos/view/{$photo->_id}.jpeg", array( alt => $photo->title, width => "100%" )); ?>
  • <h1> <?=$this->title($photo->title); ?> <em>[ <?=$this->html->link( edit, array(Photos::edit, id => $photo->_id) ); ?> ]</em></h1><p><?=$photo->description; ?></p><?php if ($photo->tags): ?> Tags: <?php foreach ($photo->tags as $tag): ?> <?=$this->html->link( $tag, array(Photos::index, args => array($tag)) ); ?> <?php endforeach; ?><?php endif; ?><?=$this->html->image( "/photos/view/{$photo->_id}.jpeg", array( alt => $photo->title, width => "100%" )); ?>
  • Controllernamespace photoblogcontrollers;use photoblogmodelsPhotos;use li3_geoextensionsGeocoder;class PhotosController extends lithiumactionController { public function index($tags = null) { $conditions = $tags ? compact(tags) : array(); $photos = Photos::all(compact(conditions)); return compact(photos); } public function view() { $photo = Photos::first($this->request->id); return compact(photo); }
  • Controllernamespace photoblogcontrollers;use photoblogmodelsPhotos;use li3_geoextensionsGeocoder;class PhotosController extends lithiumactionController { public function index($tags = null) { $conditions = $tags ? compact(tags) : array(); $photos = Photos::all(compact(conditions)); return compact(photos); } public function view() { $photo = Photos::first($this->request->id); return compact(photo); }
  • Controllernamespace photoblogcontrollers;use photoblogmodelsPhotos;use li3_geoextensionsGeocoder;class PhotosController extends lithiumactionController { public function index($tags = null) { $conditions = $tags ? compact(tags) : array(); $photos = Photos::all(compact(conditions)); return compact(photos); } public function view() { $photo = Photos::first($this->request->id); return compact(photo); }
  • public function near($place = null) { $this->_render[template] = index; $coords = Geocoder::find(google, $place); $photos = Photos::within(array($coords, $coords), array(limit => 1)); return compact(photos);}public function add() { $photo = Photos::create(); if (($this->request->data) && $photo->save($this->request->data)) { $this->redirect(array(Photos::view, id => $photo->_id)); } $this->_render[template] = edit; return compact(photo);}public function edit() { $photo = Photos::find($this->request->id); if (!$photo) { $this->redirect(Photos::index); } if (($this->request->data) && $photo->save($this->request->data)) { $this->redirect(array(Photos::view, id => $photo->_id)); } return compact(photo);}
  • public function near($place = null) { $this->_render[template] = index; $coords = Geocoder::find(google, $place); $photos = Photos::within(array($coords, $coords), array(limit => 1)); return compact(photos);}public function add() { $photo = Photos::create(); Geo Location if (($this->request->data) && $photo->save($this->request->data)) { $this->redirect(array(Photos::view, id => $photo->_id)); } $this->_render[template] = edit; return compact(photo);}public function edit() { $photo = Photos::find($this->request->id); if (!$photo) { $this->redirect(Photos::index); } if (($this->request->data) && $photo->save($this->request->data)) { $this->redirect(array(Photos::view, id => $photo->_id)); } return compact(photo);}
  • Routesuse lithiumnethttpRouter;use lithiumcoreEnvironment;use lithiumactionResponse;use photoblogmodelsPhotos;Router::connect(/photos/view/{:id:[0-9a-f]{24}}.jpeg, array(), function($request) { return new Response(array( headers => array(Content-type => image/jpeg), body => Photos::first($request->id)->file->getBytes() ));});/** * Connect the testing routes. */if (!Environment::is(production)) { Router::connect(/test/{:args}, array(controller => lithiumtestController)); Router::connect(/test, array(controller => lithiumtestController));}
  • Routesuse lithiumnethttpRouter;use lithiumcoreEnvironment;use lithiumactionResponse;use photoblogmodelsPhotos;Router::connect(/photos/view/{:id:[0-9a-f]{24}}.jpeg, array(), function($request) { return new Response(array( headers => array(Content-type => image/jpeg), body => Photos::first($request->id)->file->getBytes() ));});/** * Connect the testing routes. By-Passes */if (!Environment::is(production)) { the framework Router::connect(/test/{:args}, array(controller => lithiumtestController)); Router::connect(/test, array(controller => lithiumtestController));}
  • Routesuse lithiumnethttpRouter;use lithiumcoreEnvironment;use lithiumactionResponse;use It’s PHP you can photoblogmodelsPhotos;Router::connect(/photos/view/{:id:[0-9a-f]{24}}.jpeg, array(), function($request) { return new Response(array( you doarray(Content-type => image/jpeg), what headers => want body => Photos::first($request->id)->file->getBytes() ));});/** * Connect the testing routes. */if (!Environment::is(production)) { Router::connect(/test/{:args}, array(controller => lithiumtestController)); Router::connect(/test, array(controller => lithiumtestController));}
  • Structure
  • Features✦ Full stack MVC ✦ Object based record- sets✦ Logger ✦ Command Line✦ Caching Framework✦ Sessions/Cookies ✦ Authentication✦ Full templating suite ✦ Validator✦ Integrated TDD suite ✦ Http Services
  • Boring
  • Now for some fun!
  • World 2Kick-ass de-coupled hacker happy framework
  • Are you aslave to yourframework?
  • Flexible, transparent boostrap process
  • Databasenamespace models;class Posts extends lithiumdataModel {}
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);use lithiumdataConnections;Connections::add(default, array( type => MongoDb, database => phpnw, host => localhost));Libraries::add(models, array(path => __DIR__ . /models));use modelsPosts;$posts = Posts::create(array(title => Hi Guys));$posts->save();
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium); Simple lithium setupuse lithiumdataConnections;Connections::add(default, array( type => MongoDb, database => phpnw, host => localhost));Libraries::add(models, array(path => __DIR__ . /models));use modelsPosts;$posts = Posts::create(array(title => Hi Guys));$posts->save();
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);use lithiumdataConnections;Connections::add(default, array( type => MongoDb, database => phpnw, DB Config host => localhost));Libraries::add(models, array(path => __DIR__ . /models));use modelsPosts;$posts = Posts::create(array(title => Hi Guys));$posts->save();
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);use lithiumdataConnections;Connections::add(default, array( type => MongoDb, database => phpnw, host => localhost)); Add models ‘app’Libraries::add(models, array(path => __DIR__ . /models));use modelsPosts;$posts = Posts::create(array(title => Hi Guys));$posts->save();
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);use lithiumdataConnections;Connections::add(default, array( type => MongoDb, database => phpnw, host => localhost)); DB SaveLibraries::add(models, array(path => __DIR__ . /models));use modelsPosts;$posts = Posts::create(array(title => Hi Guys));$posts->save();
  • Routesdefine(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);use lithiumnethttpRouter;use lithiumactionRequest;$request = new Request();$router = new Router();$router->connect(/cool-root, array(controller => Yea));$router->connect(/cool-root/{:application_id:[0-9]{1}}, array(controller => Yea));$router->parse($request);echo Router::match(Yea::index);echo Router::match(array(Yea::index, application_id => 1));
  • Routesdefine(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);use lithiumnethttpRouter;use lithiumactionRequest;$request = new Request();$router = new Router();$router->connect(/cool-root, array(controller => Yea));$router->connect(/cool-root/{:application_id:[0-9]{1}}, array(controller => Yea));$router->parse($request);echo Router::match(Yea::index);echo Router::match(array(Yea::index, application_id => 1));
  • Routesdefine(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);use lithiumnethttpRouter;use lithiumactionRequest;$request = new Request();$router = new Router();$router->connect(/cool-root, array(controller => Yea));$router->connect(/cool-root/{:application_id:[0-9]{1}}, array(controller => Yea));$router->parse($request);echo Router::match(Yea::index);echo Router::match(array(Yea::index, application_id => 1));
  • Routesdefine(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);use lithiumnethttpRouter;use lithiumactionRequest;$request = new Request();$router = new Router();$router->connect(/cool-root, array(controller => Yea));$router->connect(/cool-root/{:application_id:[0-9]{1}}, array(controller => Yea));$router->parse($request);echo Router::match(Yea::index);echo Router::match(array(Yea::index, application_id => 1));
  • /cool-root/4
  • /cool-root/4$router->connect(/cool-root/{:application_id:[0-9]{1}}, array(controller => Yea));
  • /cool-root/4$router->connect(/cool-root/{:application_id:[0-9]{1}}, array(controller => Yea)); object(lithiumactionRequest)[1] public url => string /cool-root/4 (length=12) public params => array (size=3) application_id => string 4 (length=1) controller => string Yea (length=3) action => string index (length=5)
  • Adaptable Classesdefine(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);define(LITHIUM_APP_PATH, __DIR__);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;require LITHIUM_LIBRARY_PATH . /lithium/core/Object.php;require LITHIUM_LIBRARY_PATH . /lithium/core/StaticObject.php;require LITHIUM_LIBRARY_PATH . /lithium/core/Environment.php;require LITHIUM_LIBRARY_PATH . /lithium/core/Adaptable.php;use lithiumcoreAdaptable;class Email extends Adaptable{ protected static $_configurations = array(); protected static $_adapters = emails;}
  • Adaptable Classesdefine(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);define(LITHIUM_APP_PATH, __DIR__);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;require LITHIUM_LIBRARY_PATH . /lithium/core/Object.php;require LITHIUM_LIBRARY_PATH . /lithium/core/StaticObject.php;require LITHIUM_LIBRARY_PATH . /lithium/core/Environment.php;require LITHIUM_LIBRARY_PATH . /lithium/core/Adaptable.php;use lithiumcoreAdaptable;class Email extends Adaptable{ protected static $_configurations = array(); protected static $_adapters = emails;}
  • namespace adapters;use lithiumcoreLibraries;Libraries::add(lithium); class EmailTestLibraries::add(adapters, { array(path => __DIR__ . /adapters)); public function send() {Libraries::paths( echo email test send; array(emails => array( } {:library}{:name}))); }Email::config(array( development => array( adapter => EmailReal ), namespace adapters; test => array( adapter => EmailTest class EmailReal ), {)); public function send() { echo email real send;use lithiumcoreEnvironment; } }Environment::set(test);$env = Environment::get();Email::adapter($env)->send();
  • namespace adapters;use lithiumcoreLibraries;Libraries::add(lithium); class EmailTestLibraries::add(adapters, { array(path => __DIR__ . /adapters)); public function send() {Libraries::paths( echo email test send; array(emails => array( } {:library}{:name}))); }Email::config(array( development => array( adapter => EmailReal ), namespace adapters; test => array( adapter => EmailTest class EmailReal ), {)); public function send() { echo email real send;use lithiumcoreEnvironment; } }Environment::set(test);$env = Environment::get();Email::adapter($env)->send();
  • namespace adapters;use lithiumcoreLibraries;Libraries::add(lithium); class EmailTestLibraries::add(adapters, { array(path => __DIR__ . /adapters)); public function send() {Libraries::paths( echo email test send; array(emails => array( } {:library}{:name}))); }Email::config(array( development => array( adapter => EmailReal ), namespace adapters; test => array( adapter => EmailTest class EmailReal ), {)); public function send() { echo email real send;use lithiumcoreEnvironment; } }Environment::set(test);$env = Environment::get();Email::adapter($env)->send();
  • namespace adapters;use lithiumcoreLibraries;Libraries::add(lithium); class EmailTestLibraries::add(adapters, { array(path => __DIR__ . /adapters)); public function send() {Libraries::paths( echo email test send; array(emails => array( } {:library}{:name}))); }Email::config(array( development => array( adapter => EmailReal ), namespace adapters; test => array( adapter => EmailTest class EmailReal ), {)); public function send() { echo email real send;use lithiumcoreEnvironment; } }Environment::set(test);$env = Environment::get();Email::adapter($env)->send();
  • Environment::set(development);class EmailAnother extends Adaptable{ Already protected static $_configurations = array(); protected static $_adapters = emails; Environment public static function send() { static::adapter(default)->send(); Aware }}EmailAnother::config(array( default => array( test => array ( adapter => EmailTest ), development => array( adapter => EmailReal ), )));EmailAnother::send();
  • Environment::set(development);class EmailAnother extends Adaptable{ Already protected static $_configurations = array(); protected static $_adapters = emails; Environment public static function send() { static::adapter(default)->send(); Aware }}EmailAnother::config(array( default => array( test => array ( adapter => EmailTest ), development => array( adapter => EmailReal ), )));EmailAnother::send();
  • Environment::set(development);class EmailAnother extends Adaptable{ Already protected static $_configurations = array(); protected static $_adapters = emails; Environment public static function send() { static::adapter(default)->send(); Aware }}EmailAnother::config(array( default => array( test => array ( adapter => EmailTest ), development => array( adapter => EmailReal ), )));EmailAnother::send();
  • Environment::set(development);class EmailAnother extends Adaptable{ Already protected static $_configurations = array(); protected static $_adapters = emails; Environment public static function send() { static::adapter(default)->send(); Aware }}EmailAnother::config(array( default => array( test => array ( adapter => EmailTest ), development => array( adapter => EmailReal ), )));EmailAnother::send();
  • Filters
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Object.php;require LITHIUM_LIBRARY_PATH . /lithium/util/Collection.php;require LITHIUM_LIBRARY_PATH . /lithium/util/collection/Filters.php;class Action extends lithiumcoreObject { public function doSomethingStupid() { return $this->_filter(__METHOD__, $params, function($self, $params) { $result = ‘Your girlfriend is angry at you’; return $result; }); }}$action = new Action;$action->applyFilter(doSomethingStupid, function($self, $params, $chain) { echo About to do something stupid,; $result = $chain->next($self, $params, $chain); echo You IDIOT!!!!!; return $result;});$action->doSomthingStupid();
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Object.php;require LITHIUM_LIBRARY_PATH . /lithium/util/Collection.php;require LITHIUM_LIBRARY_PATH . /lithium/util/collection/Filters.php;class Action extends lithiumcoreObject { public function doSomethingStupid() { return $this->_filter(__METHOD__, $params, function($self, $params) { $result = ‘Your girlfriend is angry at you’; return $result; } }); Make} Filterable$action = new Action;$action->applyFilter(doSomethingStupid, function($self, $params, $chain) { echo About to do something stupid,; $result = $chain->next($self, $params, $chain); echo You IDIOT!!!!!; return $result;});$action->doSomthingStupid();
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Object.php;require LITHIUM_LIBRARY_PATH . /lithium/util/Collection.php;require LITHIUM_LIBRARY_PATH . /lithium/util/collection/Filters.php;class Action extends lithiumcoreObject { public function doSomethingStupid() { return $this->_filter(__METHOD__, $params, function($self, $params) { $result = ‘Your girlfriend is angry at you’; return $result; }); }}$action = new Action;$action->applyFilter(doSomethingStupid, function($self, $params, $chain) { echo About to do something stupid,; $result = $chain->next($self, $params, $chain); echo You IDIOT!!!!!; return $result;});$action->doSomthingStupid();
  • use lithiumanalysisLogger;Logger::config(array( default => array( adapter => File, path => __DIR__ . /crap/logs/ )));$action = new Action;$action->applyFilter(doSomethingStupid, function($self, $params, $chain) { Logger::debug(date("D M j G:i:s") . " " . About to do something stupid,); $result = $chain->next($self, $params, $chain); Logger::debug(date("D M j G:i:s") . " " . You total moron!); return $result;});$action->doSomthingStupid();
  • use lithiumanalysisLogger;Logger::config(array( default => array( adapter => File, path => __DIR__ . /crap/logs/ )));$action = new Action;$action->applyFilter(doSomethingStupid, function($self, $params, $chain) { Logger::debug(date("D M j G:i:s") . " " . About to do something stupid,); $result = $chain->next($self, $params, $chain); Logger::debug(date("D M j G:i:s") . " " . You total moron!); return $result;});$action->doSomthingStupid();
  • use lithiumanalysisLogger;Logger::config(array( default => array( adapter => File, path => __DIR__ . /crap/logs/ )));$action = new Action;$action->applyFilter(doSomethingStupid, function($self, $params, $chain) { Logger::debug(date("D M j G:i:s") . " " . About to do something stupid,); $result = $chain->next($self, $params, $chain); Logger::debug(date("D M j G:i:s") . " " . You total moron!); return $result;});$action->doSomthingStupid();
  • use lithiumanalysisLogger;Logger::config(array( default => array( adapter => File, path => __DIR__ . /crap/logs/ )));$action = new Action;$action->applyFilter(doSomethingStupid, function($self, $params, $chain) { Logger::debug(date("D M j G:i:s") . " " . About to do something stupid,); $result = $chain->next($self, $params, $chain); Logger::debug(date("D M j G:i:s") . " " . You total moron!); return $result;});$action->doSomthingStupid();
  • Find
  • Cache Find
  • LogCache Find
  • LogCache Find
  • LogCache Find
  • LogCache Find
  • Posts::applyFilter(find, function($self, $params, $chain) { $result = $chain->next($self, $params, $chain); $search = http_build_query($params[options]); Logger::debug( Search for: . $search . returned . $result->to(json) ); return $result;});Posts::applyFilter(find, function($self, $params, $chain) { $key = // Make a cache key from params[options] if ($result = Cache::read(default, $key)) { return $result; } $result = $chain->next($self, $params, $chain); Cache::write(default, $key, $result)); return $result;});
  • Posts::applyFilter(find, function($self, $params, $chain) { $result = $chain->next($self, $params, $chain); $search = http_build_query($params[options]); Logger::debug( Search for: . $search . returned . $result->to(json) ); return $result;}); Logging FilterPosts::applyFilter(find, function($self, $params, $chain) { $key = // Make a cache key from params[options] if ($result = Cache::read(default, $key)) { return $result; } $result = $chain->next($self, $params, $chain); Cache::write(default, $key, $result)); return $result;});
  • Posts::applyFilter(find, function($self, $params, $chain) { $result = $chain->next($self, $params, $chain); $search = http_build_query($params[options]); Logger::debug( ); Caching Filter Search for: . $search . returned . $result->to(json) return $result;});Posts::applyFilter(find, function($self, $params, $chain) { $key = // Make a cache key from params[options] if ($result = Cache::read(default, $key)) { return $result; } $result = $chain->next($self, $params, $chain); Cache::write(default, $key, $result)); return $result;});
  • Full Page CachingCache::config(array( default => array( adapter => lithiumstoragecacheadapter . ($apcEnabled ? Apc : File) )));Dispatcher::applyFilter(run, function($self, $params, $chain) { $key = md5(LITHIUM_APP_PATH) . .app.cache..md5($params[request]->url); if($cache = Cache::read(default, $key)) { return $cache; } $result = $chain->next($self, $params, $chain); Cache::write(default, $key, $result, +1 day); return $result;});
  • Full Page Caching Set Cache ConfigurationCache::config(array( default => array( adapter => lithiumstoragecacheadapter . ($apcEnabled ? Apc : File) )));Dispatcher::applyFilter(run, function($self, $params, $chain) { $key = md5(LITHIUM_APP_PATH) . .app.cache..md5($params[request]->url); if($cache = Cache::read(default, $key)) { return $cache; } $result = $chain->next($self, $params, $chain); Cache::write(default, $key, $result, +1 day); return $result;});
  • Full Page CachingCache::config(array( default => array( adapter => lithiumstoragecacheadapter . ($apcEnabled ? Apc : File) )));Dispatcher::applyFilter(run, function($self, $params, $chain) { $key = md5(LITHIUM_APP_PATH) . .app.cache..md5($params[request]->url); if($cache = Cache::read(default, $key)) { return $cache; } $result = $chain->next($self, $params, $chain); Filter on Dispatcher::run Cache::write(default, $key, $result, +1 day); Checks for cache w/key return $result;});
  • Full Page CachingCache::config(array( default => array( adapter => lithiumstoragecacheadapter . ($apcEnabled ? Apc : File) ))); w/out cache content carry onDispatcher::applyFilter(run, function($self, $params, $chain) { $key = md5(LITHIUM_APP_PATH) . .app.cache..md5($params[request]->url); running - saving to cache if($cache = Cache::read(default, $key)) { return $cache; } $result = $chain->next($self, $params, $chain); Cache::write(default, $key, $result, +1 day); return $result;});
  • Content Renderingnamespace dispatcher_appcontrollers;class YeaController extends lithiumactionController{ public function index() { $yeah = true; return compact(yeah); } public function render(array $options = array()) { return The response of Yeah is: . $this->_render[data][yeah]; }}
  • Content Renderingnamespace dispatcher_appcontrollers;class YeaController extends lithiumactionController{ public function index() { $yeah = true; return compact(yeah); } public function render(array $options = array()) { return The response of Yeah is: . $this->_render[data][yeah]; }}
  • Content Renderingnamespace dispatcher_appcontrollers;class YeaController extends lithiumactionController{ public function index() { $yeah = true; Overwrite ‘render’ method return compact(yeah); } public function render(array $options = array()) { return The response of Yeah is: . $this->_render[data][yeah]; }}
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);Libraries::add(dispatcher_app, array(path => __DIR__ . /dispatcher_app));use lithiumnethttpRouter;$router = new Router();Router::connect(/cool-root, array(controller => Yea, library => dispatcher_app));echo lithiumactionDispatcher::run( new lithiumactionRequest());
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium); Create RoutingLibraries::add(dispatcher_app, array(path => __DIR__ . /dispatcher_app));use lithiumnethttpRouter;$router = new Router();Router::connect(/cool-root, array(controller => Yea, library => dispatcher_app));echo lithiumactionDispatcher::run( new lithiumactionRequest());
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;Libraries::add(lithium);Libraries::add(dispatcher_app, array(path => __DIR__ . /dispatcher_app));use lithiumnethttpRouter;$router = new Router(); Run DispatcherRouter::connect(/cool-root, array(controller => Yea, library => dispatcher_app));echo lithiumactionDispatcher::run( new lithiumactionRequest());
  • Media Class
  • Media::type(ajax, array(application/xhtml+xml, text/html), array( view => lithiumtemplateView, paths => array( template => array( {:library}/views/{:controller}/{:template}.ajax.php, {:library}/views/{:controller}/{:template}.html.php ), layout => {:library}/views/layouts/default.ajax.php ), conditions => array(ajax => true))); Easily setup template paths
  • Media::type(jpg, image/jpeg, array(cast => false, encode => function($data) { return $data[photo]->file->getBytes();}));Media::type(json, application/json, array(cast => false, encode => function($data) { return json_encode($data);}));Media::type(json, application/json, array( cast => false, encode => json_encode));
  • Media::type(jpg, image/jpeg, array(cast => false, encode => function($data) { return $data[photo]->file->getBytes();})); Handle ImagesMedia::type(json, application/json, array(cast => false, encode => function($data) { return json_encode($data);}));Media::type(json, application/json, array( cast => false, encode => json_encode));
  • Media::type(jpg, image/jpeg, array(cast => false, encode => function($data) { return $data[photo]->file->getBytes();}));Media::type(json, application/json, array(cast => false, encode => function($data) { return json_encode($data);}));Media::type(json, application/json, array( cast => false, encode => json_encode)); Handle JSON
  • Error Handling
  • Error Handlinguse lithiumcoreErrorHandler;use lithiumcoreStaticObject;class IThrowAnException{ public function method() { throw new Exception(Yo); }}class IDontThrow extends StaticObject{ public static function method($bar) { static::_filter(__FUNCTION__, $params, function($self, $params) { $object = new IThrowAnException; $object->method(); }); }}ErrorHandler::apply(IDontThrow::method, array(), function($info, $params) { echo Exception raised with message - . $info[exception]->getMessage();});IDontThrowAnException::method();
  • Error Handlinguse lithiumcoreErrorHandler;use lithiumcoreStaticObject;class IThrowAnException{ public function method() { throw new Exception(Yo); }}class IDontThrow extends StaticObject{ public static function method($bar) { static::_filter(__FUNCTION__, $params, function($self, $params) { $object = new IThrowAnException; $object->method(); }); }}ErrorHandler::apply(IDontThrow::method, array(), function($info, $params) { echo Exception raised with message - . $info[exception]->getMessage();});IDontThrowAnException::method();
  • Error Handlinguse lithiumcoreErrorHandler;use lithiumcoreStaticObject;class IThrowAnException{ public function method() { throw new Exception(Yo); } Filterable}class IDontThrow extends StaticObject{ public static function method($bar) { static::_filter(__FUNCTION__, $params, function($self, $params) { $object = new IThrowAnException; $object->method(); }); }}ErrorHandler::apply(IDontThrow::method, array(), function($info, $params) { echo Exception raised with message - . $info[exception]->getMessage();});IDontThrowAnException::method();
  • Error Handlinguse lithiumcoreErrorHandler;use lithiumcoreStaticObject;class IThrowAnException{ public function method() { throw new Exception(Yo); }}class IDontThrow extends StaticObject{ public static function method($bar) { static::_filter(__FUNCTION__, $params, function($self, $params) { $object = new IThrowAnException; $object->method(); }); }}ErrorHandler::apply(IDontThrow::method, array(), function($info, $params) { echo Exception raised with message - . $info[exception]->getMessage();});IDontThrowAnException::method();
  • ErrorHandler::apply(lithiumactionDispatcher::run, array(), function($info, $params) { $response = new Response(array( request => $params[request], status => $info[exception]->getCode(), trace => $info[exception]->getTrace(), )); Media::render($response, compact(info, params), array( controller => errors, template => default, layout => default, library => golf, request => $params[request], )); return $response;}); Example
  • CreateErrorHandler::apply(lithiumactionDispatcher::run, array(), function($info, $params) { Response $response = new Response(array( request => $params[request], status => $info[exception]->getCode(), trace => $info[exception]->getTrace(), )); Media::render($response, compact(info, params), array( controller => errors, template => default, layout => default, library => golf, request => $params[request], )); return $response;}); Example
  • ErrorHandler::apply(lithiumactionDispatcher::run, array(), function($info, $params) { $response = new Response(array( request => $params[request], status => $info[exception]->getCode(), trace => $info[exception]->getTrace(), )); Media::render($response, compact(info, params), array( controller => errors, template => default, layout => default, library => golf, Media request => $params[request], Render )); return $response;}); Example
  • Zendy LoveLibraryies::add( prefix => Zend_, includePath => /htdocs/libraries/Zend/trunk/library, bootstrap => Loader/Autoloader.php, loader => array(Zend_Loader_Autoloader, autoload), transform => function($class) { return str_replace(_, /, $class) . .php; });
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);define(LITHIUM_APP_PATH, __DIR__ . /templates);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries;use lithiumcoreEnvironment;use lithiumactionDispatcher;use lithiumg11nMessage;use lithiumnethttpMedia;Libraries::add(lithium);Libraries::add(li3_docs);Libraries::add(templates, array(path => __DIR__ . /templates, default => true));Libraries::add(adapters, array(path => __DIR__ . /adapters));Libraries::add(li3_docs, array( index => array(lithium, adapters))); Libraries Example
  • define(LITHIUM_LIBRARY_PATH, dirname(__DIR__) . /libraries);define(LITHIUM_APP_PATH, __DIR__ . /templates);require LITHIUM_LIBRARY_PATH . /lithium/core/Libraries.php;use lithiumcoreLibraries; Sets upuse lithiumcoreEnvironment;useuse lithiumactionDispatcher; lithiumg11nMessage; Librariesuse lithiumnethttpMedia;Libraries::add(lithium);Libraries::add(li3_docs);Libraries::add(templates, array(path => __DIR__ . /templates, default => true));Libraries::add(adapters, array(path => __DIR__ . /adapters));Libraries::add(li3_docs, array( index => array(lithium, adapters))); Libraries Example
  • $locale = en;$locales = array(en => English);Environment::set(development, compact(locale, locales));Environment::set(development); } $file = "{$config[path]}/config/routes.php"; file_exists($file) ? call_user_func(function() use ($file) { include $file; }) : null; } return $chain->next($self, $params, $chain);});Media::applyFilter(_handle, function($self, $params, $chain) { $params[handler] += array(outputFilters => array()); $params[handler][outputFilters] += Message::aliases(); return $chain->next($self, $params, $chain);});echo lithiumactionDispatcher::run(new lithiumactionRequest());
  • Locale &$locale = en; Routes$locales = array(en => English);Environment::set(development, compact(locale, locales));Environment::set(development); } $file = "{$config[path]}/config/routes.php"; file_exists($file) ? call_user_func(function() use ($file) { include $file; }) : null; } return $chain->next($self, $params, $chain);});Media::applyFilter(_handle, function($self, $params, $chain) { $params[handler] += array(outputFilters => array()); $params[handler][outputFilters] += Message::aliases(); return $chain->next($self, $params, $chain);});echo lithiumactionDispatcher::run(new lithiumactionRequest());
  • $locale = en;$locales = array(en => English);Environment::set(development, compact(locale, locales));Environment::set(development); } $file = "{$config[path]}/config/routes.php"; file_exists($file) ? call_user_func(function() use ($file) { include $file; }) : null; } return $chain->next($self, $params, $chain);});Media::applyFilter(_handle, function($self, $params, $chain) { $params[handler] += array(outputFilters => array()); $params[handler][outputFilters] += Message::aliases(); return $chain->next($self, $params, $chain); Gets}); translationsecho lithiumactionDispatcher::run(new lithiumactionRequest());
  • $locale = en;$locales = array(en => English);Environment::set(development, compact(locale, locales));Environment::set(development); } $file = "{$config[path]}/config/routes.php"; file_exists($file) ? call_user_func(function() use ($file) { include $file; }) : null; } return $chain->next($self, $params, $chain);});Media::applyFilter(_handle, function($self, $params, $chain) { $params[handler] += array(outputFilters => array()); $params[handler][outputFilters] += Message::aliases(); return $chain->next($self, $params, $chain);});echo lithiumactionDispatcher::run(new lithiumactionRequest()); Go
  • Recap
  • ★ Hackers framework Recap
  • ★ Hackers framework Recap★ Light, fast & fun
  • ★ Hackers framework Recap★ Light, fast & fun★ Services have adaptable base
  • ★ Hackers framework Recap★ Light, fast & fun★ Services have adaptable base★ Filters are awesome/powerful
  • ★ Hackers framework Recap★ Light, fast & fun★ Services have adaptable base★ Filters are awesome/powerful★ Everything is a library
  • ★ Hackers framework Recap★ Light, fast & fun★ Services have adaptable base★ Filters are awesome/powerful★ Everything is a library★ As much or as little framework as you need
  • ★ Hackers framework Recap★ Light, fast & fun★ Services have adaptable base★ Filters are awesome/powerful★ Everything is a library★ As much or as little framework as you need★ Great balance weight/power/simplicity
  • Thanksgithub.com/mackstar/phpnw-li3 @mackstar | #mackstar