Lithium Best

1,799 views

Published on

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,799
On SlideShare
0
From Embeds
0
Number of Embeds
45
Actions
Shares
0
Downloads
59
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide
  • \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

    1. 1. Lithium (#li3)The framework with the best of both worlds
    2. 2. 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
    3. 3. Frameworks
    4. 4. I’ve seen it✦ Symfony 2 ✦ Merb✦ Zend Framework ✦ Sinatra✦ CakePHP ✦ Spring✦ Code Igniter ✦ Stripes (Java)✦ Drupal 6&7 ✦ Django Wordpress✦ Silex ✦✦ Rails
    5. 5. manyframeworksarelikethis
    6. 6. Each software solution should be in proportion tothe problem being solved.
    7. 7. Each software solution should be in proportion tothe problem being solved. -some lazy bugger
    8. 8. Each software solution should be in proportion tothe problem being solved. -some lazy bugger me
    9. 9. <?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"); }}
    10. 10. 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
    11. 11. 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
    12. 12. Developer Happy-nessAny fool can write code that a computer can understand. Goodprogrammers write code that humans can understand. –Martin Fowler
    13. 13. Light Footprint
    14. 14. Light Footprint
    15. 15. Looking for a hackers Framework?Light Footprint
    16. 16. Fast, Flexible and Rad
    17. 17. World 1Full Stack Framework Convention Over Configuration
    18. 18. github.com/UnionOfRad/framework
    19. 19. The Photo Blog Tutorial github.com/nateabele/photoblog
    20. 20. 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); }}
    21. 21. 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); }}
    22. 22. 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); }}
    23. 23. 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(); ?>
    24. 24. 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(); ?>
    25. 25. 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(); ?>
    26. 26. <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%" )); ?>
    27. 27. <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%" )); ?>
    28. 28. <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%" )); ?>
    29. 29. 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); }
    30. 30. 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); }
    31. 31. 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); }
    32. 32. 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);}
    33. 33. 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);}
    34. 34. 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));}
    35. 35. 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));}
    36. 36. 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));}
    37. 37. Structure
    38. 38. 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
    39. 39. Boring
    40. 40. Now for some fun!
    41. 41. World 2Kick-ass de-coupled hacker happy framework
    42. 42. Are you aslave to yourframework?
    43. 43. Flexible, transparent boostrap process
    44. 44. Databasenamespace models;class Posts extends lithiumdataModel {}
    45. 45. 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();
    46. 46. 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();
    47. 47. 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();
    48. 48. 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();
    49. 49. 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();
    50. 50. 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));
    51. 51. 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));
    52. 52. 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));
    53. 53. 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));
    54. 54. /cool-root/4
    55. 55. /cool-root/4$router->connect(/cool-root/{:application_id:[0-9]{1}}, array(controller => Yea));
    56. 56. /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)
    57. 57. 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;}
    58. 58. 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;}
    59. 59. 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();
    60. 60. 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();
    61. 61. 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();
    62. 62. 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();
    63. 63. 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();
    64. 64. 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();
    65. 65. 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();
    66. 66. 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();
    67. 67. Filters
    68. 68. 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();
    69. 69. 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();
    70. 70. 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();
    71. 71. 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();
    72. 72. 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();
    73. 73. 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();
    74. 74. 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();
    75. 75. Find
    76. 76. Cache Find
    77. 77. LogCache Find
    78. 78. LogCache Find
    79. 79. LogCache Find
    80. 80. LogCache Find
    81. 81. 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;});
    82. 82. 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;});
    83. 83. 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;});
    84. 84. 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;});
    85. 85. 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;});
    86. 86. 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;});
    87. 87. 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;});
    88. 88. 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]; }}
    89. 89. 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]; }}
    90. 90. 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]; }}
    91. 91. 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());
    92. 92. 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());
    93. 93. 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());
    94. 94. Media Class
    95. 95. 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
    96. 96. 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));
    97. 97. 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));
    98. 98. 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
    99. 99. Error Handling
    100. 100. 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();
    101. 101. 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();
    102. 102. 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();
    103. 103. 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();
    104. 104. 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
    105. 105. 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
    106. 106. 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
    107. 107. 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; });
    108. 108. 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
    109. 109. 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
    110. 110. $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());
    111. 111. 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());
    112. 112. $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());
    113. 113. $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
    114. 114. Recap
    115. 115. ★ Hackers framework Recap
    116. 116. ★ Hackers framework Recap★ Light, fast & fun
    117. 117. ★ Hackers framework Recap★ Light, fast & fun★ Services have adaptable base
    118. 118. ★ Hackers framework Recap★ Light, fast & fun★ Services have adaptable base★ Filters are awesome/powerful
    119. 119. ★ Hackers framework Recap★ Light, fast & fun★ Services have adaptable base★ Filters are awesome/powerful★ Everything is a library
    120. 120. ★ 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
    121. 121. ★ 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
    122. 122. Thanksgithub.com/mackstar/phpnw-li3 @mackstar | #mackstar

    ×