SlideShare a Scribd company logo
1 of 49
LESS TIME
      LESS CODE
    LESS HEADACHE
Lithium: the framework that tries to suck less
THE GOAL
• Posting   with photo upload

• RSS   updates

• Geo-tagged      images & geo-spatial search

• Logging?
$ git clone 
  git://dev.lithify.me/lithium.git 
  photoblog



Bonus Points – add the li3 command to your system PATH:
http://bit.ly/li3path
http://path/to/web/photoblog
$ cd photoblog/app
$ chmod -R 777 resources/
http://path/to/web/photoblog
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'
));
ALTERNATIVES...
photoblog/config/bootstrap/connections.php
use lithiumdataConnections;

Connections::add('default', array(
    'type' => 'http',
    'adapter' => 'CouchDb',
    'host' => 'localhost',
    'database' => 'app'
));
ALTERNATIVES...
photoblog/config/bootstrap/connections.php
use lithiumdataConnections;

Connections::add('default', array(
    'type' => 'database',
    'adapter' => 'MySql',
    'host' => 'localhost',
    'login' => 'web',
    'password' => 'sekrit',
    'database' => 'app'
));
$ li3 create Photos
Photos created in appmodels.
PhotosController created in appcontrollers.
PhotosTest created in apptestscasesmodels.
PhotosControllerTest created in apptestscasescontrollers.
http://path/to/web/photoblog/photos
photoblog/controllers/PhotosController.php
class PhotosController extends lithiumactionController {

    public function index() {
        $photos = Photos::all();
        return compact('photos');
    }

    // ...
}
photoblog/views/photos/index.html.php
<?php if (!count($photos)): ?>
    <em>No photos</em>.
    <?=$this->html->link('Add one', 'Photos::add'); ?>.
<?php endif ?>
http://path/to/web/photoblog/photos
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');
  }
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(); ?>
http://path/to/web/photoblog/photos/add
photoblog/models/Photos.php
class Photo extends lithiumdataModel {

    public $validates = array();

    protected $_meta = array('source' => 'fs.files');

}
http://path/to/web/photoblog/photos/add
http://path/to/web/photoblog/photos/add
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}}');
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}}
http://path/to/web/photoblog/photos/view/...
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
)); ?>
http://path/to/web/photoblog/photos/view/...
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();
    }
));
http://path/to/web/photoblog/photos/view/...
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( )
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()
    ));
});
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>
http://path/to/web/photoblog/photos
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>
http://path/to/web/photoblog/photos
photoblog/config/bootstrap/media.php

Media::type('rss', 'application/rss+xml');
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>
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; ?>
http://path/to/web/photoblog/photos.rss
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": { ... }
     }
}]
$ 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
photoblog/config/bootstrap/libraries.php
/**
 * Add some plugins
 */
Libraries::add('li3_geo');
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'
        )));
    }
}
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);
   }
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');
    }
http://.../photos/near/New+York,+NY
photoblog/config/bootstrap/logging.php
use lithiumanalysisLogger;
use lithiumdataConnections;

Logger::config(array(
    'default' => array('adapter' => 'File')
));
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);
});
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);
});
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"}
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

More Related Content

Viewers also liked

INFLIGHT LUXURY web
INFLIGHT LUXURY webINFLIGHT LUXURY web
INFLIGHT LUXURY web
Ana Zeković
 

Viewers also liked (19)

Introducing Zend Studio 10 Japanese Edition
Introducing Zend Studio 10 Japanese EditionIntroducing Zend Studio 10 Japanese Edition
Introducing Zend Studio 10 Japanese Edition
 
Measuring Your Code 2.0
Measuring Your Code 2.0Measuring Your Code 2.0
Measuring Your Code 2.0
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 
Building Apps with MongoDB
Building Apps with MongoDBBuilding Apps with MongoDB
Building Apps with MongoDB
 
City of Salina Brochure - Tenants Know Your Rights (Spanish)
City of Salina Brochure - Tenants Know Your Rights (Spanish)City of Salina Brochure - Tenants Know Your Rights (Spanish)
City of Salina Brochure - Tenants Know Your Rights (Spanish)
 
INFLIGHT LUXURY web
INFLIGHT LUXURY webINFLIGHT LUXURY web
INFLIGHT LUXURY web
 
Telefono ladrillo
Telefono ladrilloTelefono ladrillo
Telefono ladrillo
 
Cadison R10
Cadison  R10Cadison  R10
Cadison R10
 
ExperienceGuru - ASAE Meetings Journey Mapping
ExperienceGuru - ASAE Meetings Journey MappingExperienceGuru - ASAE Meetings Journey Mapping
ExperienceGuru - ASAE Meetings Journey Mapping
 
O trem e a cidade
O trem e a cidadeO trem e a cidade
O trem e a cidade
 
Prevención, detección y contención de ataques de denegación de servicio
Prevención, detección y contención de ataques de denegación de servicioPrevención, detección y contención de ataques de denegación de servicio
Prevención, detección y contención de ataques de denegación de servicio
 
El ejercicio es salud
El ejercicio es saludEl ejercicio es salud
El ejercicio es salud
 
Danske Kommuner
Danske KommunerDanske Kommuner
Danske Kommuner
 
Reino Plantae
Reino PlantaeReino Plantae
Reino Plantae
 
Que es-ingenieria (1)
Que es-ingenieria (1)Que es-ingenieria (1)
Que es-ingenieria (1)
 
Connectivism and Connected Knowledge 2012
Connectivism and Connected Knowledge 2012Connectivism and Connected Knowledge 2012
Connectivism and Connected Knowledge 2012
 
Eleva tu Estilo con Calvin Klein - Campaña
Eleva tu Estilo con Calvin Klein - CampañaEleva tu Estilo con Calvin Klein - Campaña
Eleva tu Estilo con Calvin Klein - Campaña
 
FINANCIACION Y SUBVENCIONES SECTOR HOTELEROS
FINANCIACION Y SUBVENCIONES SECTOR HOTELEROSFINANCIACION Y SUBVENCIONES SECTOR HOTELEROS
FINANCIACION Y SUBVENCIONES SECTOR HOTELEROS
 
Iftm university prospectus 2016 17 educationiconnect.com 7862004786
Iftm university prospectus 2016 17 educationiconnect.com 7862004786Iftm university prospectus 2016 17 educationiconnect.com 7862004786
Iftm university prospectus 2016 17 educationiconnect.com 7862004786
 

Recently uploaded

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 

Recently uploaded (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 

Less Time, Less Code, Less Headache

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n