Successfully reported this slideshow.

Less Time, Less Code, Less Headache

14

Share

Upcoming SlideShare
Lithium Best
Lithium Best
Loading in …3
×
1 of 49
1 of 49

Less Time, Less Code, Less Headache

14

Share

Download to read offline

Learn how developing with the Lithium framework for PHP 5.3+ not only allows you to develop applications on tighter deadlines, but how Lithium's unique, superior architecture allows much-improved maintainability over the life of your apps.

Learn how developing with the Lithium framework for PHP 5.3+ not only allows you to develop applications on tighter deadlines, but how Lithium's unique, superior architecture allows much-improved maintainability over the life of your apps.

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Less Time, Less Code, Less Headache

  1. LESS TIME LESS CODE LESS HEADACHE Lithium: the framework that tries to suck less
  2. THE GOAL • Posting with photo upload • RSS updates • Geo-tagged images & geo-spatial search • Logging?
  3. $ git clone git://dev.lithify.me/lithium.git photoblog Bonus Points – add the li3 command to your system PATH: http://bit.ly/li3path
  4. http://path/to/web/photoblog
  5. $ cd photoblog/app $ chmod -R 777 resources/
  6. http://path/to/web/photoblog
  7. photoblog/config/bootstrap.php require __DIR__ . '/bootstrap/connections.php'; photoblog/config/bootstrap/connections.php use lithiumdataConnections; Connections::add('default', array( 'type' => 'MongoDb', 'host' => 'localhost', 'database' => 'photoblog' ));
  8. ALTERNATIVES... photoblog/config/bootstrap/connections.php use lithiumdataConnections; Connections::add('default', array( 'type' => 'http', 'adapter' => 'CouchDb', 'host' => 'localhost', 'database' => 'app' ));
  9. ALTERNATIVES... photoblog/config/bootstrap/connections.php use lithiumdataConnections; Connections::add('default', array( 'type' => 'database', 'adapter' => 'MySql', 'host' => 'localhost', 'login' => 'web', 'password' => 'sekrit', 'database' => 'app' ));
  10. $ li3 create Photos Photos created in appmodels. PhotosController created in appcontrollers. PhotosTest created in apptestscasesmodels. PhotosControllerTest created in apptestscasescontrollers.
  11. http://path/to/web/photoblog/photos
  12. photoblog/controllers/PhotosController.php class PhotosController extends lithiumactionController { public function index() { $photos = Photos::all(); return compact('photos'); } // ... }
  13. photoblog/views/photos/index.html.php <?php if (!count($photos)): ?> <em>No photos</em>. <?=$this->html->link('Add one', 'Photos::add'); ?>. <?php endif ?>
  14. http://path/to/web/photoblog/photos
  15. photoblog/controllers/PhotosController.php public function add() { $photo = Photo::create(); if (($this->request->data) && $photo->save($this->request->data)) { $this->redirect(array('Photos::view', 'id' => $photo->_id)); $this->redirect(array('Photos::view', 'id' => $photo->_id)); } $this->_render['template'] = 'edit'; return compact('photo'); }
  16. photoblog/views/photos/edit.html.php <?=$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 } ?> <?=$this->form->submit('Save'); ?> <?=$this->form->end(); ?>
  17. http://path/to/web/photoblog/photos/add
  18. photoblog/models/Photos.php class Photo extends lithiumdataModel { public $validates = array(); protected $_meta = array('source' => 'fs.files'); }
  19. http://path/to/web/photoblog/photos/add
  20. http://path/to/web/photoblog/photos/add
  21. photoblog/config/routes.php Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}.{:type}', array('id' => null)); Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}');
  22. photoblog/config/routes.php Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}.{:type}', array('id' => null)); Router::connect('/{:controller}/{:action}/{:id:[0-9a-f]{24}}'); {:id:[0-9a-f]{24}}
  23. http://path/to/web/photoblog/photos/view/...
  24. photoblog/views/photos/view.html.php <h1><?=$photo->title; ?></h1> <p><?=$photo->description; ?></p> <p> <?=$this->html->link('Edit', array('Photos::edit', 'id' => $photo->_id)); ?> </p> <?=$this->html->image("/photos/view/{$photo->_id}.jpg", array( 'alt' => $photo->title, 'width' => 500 )); ?>
  25. http://path/to/web/photoblog/photos/view/...
  26. photoblog/config/bootstrap.php /** * This file contains configurations for handling different * content types within the framework, including converting data to * and from different formats, and handling static media assets. */ require __DIR__ . '/bootstrap/media.php'; photoblog/config/bootstrap/media.php Media::type('jpg', 'image/jpeg', array( 'cast' => false, 'encode' => function($data) { return $data['photo']->file->getBytes(); } ));
  27. http://path/to/web/photoblog/photos/view/...
  28. Router::connect('/.../{:id:[0-9a-f]{24}}. {:type} {:type}', array(...)); Controller $photo Media HTML JSON JPEG templateView => array( ) Media type handler View Layout json_encode( )
  29. photoblog/config/routes.php use appmodelsPhotos; use lithiumactionResponse; Router::connect('/photos/view/{:id:[0-9a-f]{24}}.jpg', array(), function($request) { return new Response(array( 'headers' => array('Content-type' => 'image/jpeg'), 'body' => Photos::first($request->id)->file->getBytes() )); });
  30. photoblog/views/photos/index.html.php <ul> <?php foreach ($photos as $photo): ?> <li> <?=$this->html->link($photo->title, array( 'controller' => 'photos', 'action' => 'view', 'id' => $photo->_id )); ?> </li> <?php endforeach ?> </ul>
  31. http://path/to/web/photoblog/photos
  32. photoblog/views/photos/index.html.php <ul> <?php foreach ($photos as $photo): ?> <li> <?=$this->html->image( "/photos/view/{$photo->_id}.jpg", array('width'=> 100) ); ?> <?=$this->html->link( $photo->title, array('Photos::view', 'id' => $photo->_id) array('Photos::view', 'id' => $photo->_id) ); ?> </li> <?php endforeach ?> </ul>
  33. http://path/to/web/photoblog/photos
  34. photoblog/config/bootstrap/media.php Media::type('rss', 'application/rss+xml');
  35. photoblog/views/layouts/default.rss.php <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel> <title>Photos</title> <pubDate> <?=date("D, j M Y H:i:s", gmmktime()) . ' GMT'; ?> </pubDate> <?=$this->content(); ?> </channel> </rss>
  36. photoblog/views/photos/index.rss.php <?php foreach ($photos as $photo): ?> <item> <title><?=$photo->title; ?></title> <link><?=$this->url(array('Photos::view', 'id' => $photo->_id)); ?></link> <description><?=$photo->description; ?></description> </item> <?php endforeach; ?>
  37. http://path/to/web/photoblog/photos.rss
  38. http://path/to/web/photoblog/photos.json [{ "photo": { "_id": "4d70c5017675ab4de900001f", "title": "FML", "description": "How the subway schedule sometimes makes me feel.", "filename": "FML.jpg", "uploadDate": 1299236097, "length": 452751, "chunkSize": 262144, "md5": "e74c961185efdd69acbccaa59b7b13c0", "file": { ... } } }]
  39. $ cd libraries/ $ git clone code@dev.lithify.me:li3_geo.git Note – you will need an account. Sign up here: http://dev.lithify.me/users/add
  40. photoblog/config/bootstrap/libraries.php /** * Add some plugins */ Libraries::add('li3_geo');
  41. photoblog/models/Photos.php use li3_geoextensionsGeocoder; use li3_geoextensionsdatabehaviorLocatable; class Photos extends lithiumdataModel { // ... public static function __init() { parent::__init(); Locatable::bind(__CLASS__, array('fields' => array( 'location.latitude', 'location.longitude' ))); } }
  42. photoblog/models/Photos.php public function save($entity, $data = null, array $options = array()) { if ($data) { $entity->set($data); } if (!$entity->exists() && isset($entity->file->tmp_name)) { $entity->location = Geocoder::exifCoords( exif_read_data($entity->file->tmp_name) ); } return parent::save($entity, null, $options); }
  43. photoblog/controllers/PhotosController.php use li3_geoextensionsGeocoder; // ... public function near($place = null) { $this->_render['template'] = 'index'; $location = Geocoder::find('google', $place); $photos = Photos::near($location, array('limit' => 5)); return compact('photos'); }
  44. http://.../photos/near/New+York,+NY
  45. photoblog/config/bootstrap/logging.php use lithiumanalysisLogger; use lithiumdataConnections; Logger::config(array( 'default' => array('adapter' => 'File') ));
  46. photoblog/config/bootstrap/logging.php Connections::get('default')->applyFilter('read', function($self, $params, $chain) { $query = $params['query']; Logger::debug( 'Read: ' . $query->source() . ': ' . json_encode($query->conditions()) ); return $chain->next($self, $params, $chain); });
  47. photoblog/config/bootstrap/logging.php Connections::get('default')->applyFilter('update', function($self, $params, $chain) { $query = $params['query']; $data = json_encode($query->conditions()) . ', ' . json_encode($query->data()); Logger::debug('Update: ' . $query->source() . ": {$data}"); return $chain->next($self, $params, $chain); });
  48. photoblog/resources/tmp/logs/debug.log 2011-03-04 18:37:07 Read: fs.files: {"location":{"$near":{"latitude": 40.7143528,"longitude":-74.0059731}}} 2011-03-04 18:37:07 Read: fs.files: {"_id":"4d710afc7675ab95d0000004"}
  49. Thanks, y’all! Getting connected AOP Resources lithify.me bit.ly/aop-design github.com/UnionOfRAD bit.ly/aop-gwoo #li3 on irc.freenode.net bit.ly/aop-li3 @nateabele bit.ly/aop-oop @UnionOfRAD bit.ly/mwop-aop

Editor's Notes

  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • ×