Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Lithium Best

1,946 views

Published on

  • Be the first to comment

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

×