Your SlideShare is downloading. ×
Less Time, Less Code, Less Headache
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Less Time, Less Code, Less Headache

8,962
views

Published on

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 …

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.

Published in: Technology

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

No Downloads
Views
Total Views
8,962
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
110
Comments
0
Likes
13
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

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

    • 1. LESS TIME LESS CODE LESS HEADACHELithium: 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 photoblogBonus 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.phprequire __DIR__ . /bootstrap/connections.php;photoblog/config/bootstrap/connections.phpuse lithiumdataConnections;Connections::add(default, array( type => MongoDb, host => localhost, database => photoblog));
    • 8. ALTERNATIVES...photoblog/config/bootstrap/connections.phpuse lithiumdataConnections;Connections::add(default, array( type => http, adapter => CouchDb, host => localhost, database => app));
    • 9. ALTERNATIVES...photoblog/config/bootstrap/connections.phpuse lithiumdataConnections;Connections::add(default, array( type => database, adapter => MySql, host => localhost, login => web, password => sekrit, database => app));
    • 10. $ li3 create PhotosPhotos 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.phpclass 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.phpclass 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.phpRouter::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.phpRouter::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.phpMedia::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 handlerView Layout json_encode( )
    • 29. photoblog/config/routes.phpuse 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.phpMedia::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.gitNote – 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.phpuse 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.phpuse 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.phpuse lithiumanalysisLogger;use lithiumdataConnections;Logger::config(array( default => array(adapter => File)));
    • 46. photoblog/config/bootstrap/logging.phpConnections::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.phpConnections::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.log2011-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 Resourceslithify.me bit.ly/aop-designgithub.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