SlideShare a Scribd company logo
THE STATE OF LITHIUM
li3_nyc::init() // 2012-02-07
SPONSORS
AGENDA
• State   of the framework

• New     features

• Upcoming     features

• Community         plugins

• Library   management & The Lab

• Tips   & tricks

• Q&A     / Demos!
STATE OF THE FRAMEWORK
PROJECT & COMMUNITY STATS

• ~130   plugin repositories on GitHub

• 350+   commits from 40+ contributors since 0.10

• 60+   commits to the manual since 0.10

• Closed   250+ issues since moving to GitHub

• 175   pull requests submitted since moving to GitHub
ROADMAP PROGRESS

• Cookie   signing / encryption

• CSRF    protection

• Error   Handling

• Manual   / automatic SQL result mapping

• Relationship   support
NEW FEATURES
ENCRYPT & SIGN COOKIES

Session::config(array('default' => array(
       'adapter' => 'Cookie',
       'strategies' => array(
           'Hmac' => array('secret' => '$f00bar$'),
           'Encrypt' => array('secret' => '$f00bar$')
       )
)));
NEST ROUTES
Router::connect("/admin/{:args}", array('admin' => true), array(
    'continue' => true
));

Router::connect("/{:locale:en|de|jp}/{:args}", array(), array(
    'continue' => true
));

Router::connect("/{:args}.{:type}", array(), array(
    'continue' => true
));
HANDLE ERRORS
$method = array(Connections::get('default'), 'read');

ErrorHandler::apply($method, array(), function($error, $params) {
    $queryParams = json_encode($params['query']);
    $msg = "Query error: {$error['message']}";

      Logger::warning("{$msg}, data: {$queryParams}");
      return new DocumentSet();
});
PROTECT FORMS
<?=$this->form->create(); ?>
    <?=$this->security->requestToken(); ?>
    <?=$this->form->field('title'); ?>
    <?=$this->form->submit('Submit'); ?>
<?=$this->form->end(); ?>


public function add() {
    if (
         $this->request->data &&
         !RequestToken::check($this->request)
    ) {
         // Badness!!
    }
}
UPCOMING FEATURES
HTTP SERVICE CLASSES
$http = new Http(array(
    ...
    'methods' => array(
        'do' => array('method' => 'post', 'path' => '/do')
    )
));
                                                POST /do HTTP/1.1
$response = $http->do(new Query(array(
                                                …
     'data' => array('title' => 'sup')
)));                                            title=sup
// var_dump($response->data());
FILTER / SORT COLLECTIONS

$users->find(array("type" => "author"))->sort("name");



$users->first(array("name" => "Nate"));
MULTIBYTE CLASS


• Supports   mbstring, intl, iconv & (womp, womp) plain PHP

• Only   one method right now: strlen()

• More   would be good… open a pull request
SCHEMA CLASS


• Arbitrary   data types

• Arbitrary   handlers

• Example: hash   modified passwords before writing

• Other   example: JSON en/decode arbitrary data for MySQL
PLUGINS
LI3_DOCTRINE2
                                Connections::add('default', array(
                                    'type' => 'Doctrine',
• Works   with Lithium stuff:       'driver' => 'pdo_mysql',
                                    'host' => 'localhost',
                                    'user' => 'root',
 • Connections                      'password' => 'password',
                                    'dbname' => 'my_db'
                                ));
 • Authentication               /**
                                 * @Entity
                                 * @Table(name="users")

 • Forms                         */
                                class User extends li3_doctrine2modelsBaseEntity {
                                    /**
                                     * @Id

 • Sessions                          * @GeneratedValue
                                     * @Column(type="integer")
                                     */
                                    private $id;

 • Validation                       /**
                                     * @Column(type="string",unique=true)
                                     */
                                    private $email;
                                    ...
                                }
LI3_FILESYSTEM
use li3_filesystemstorageFileSystem;

FileSystem::config(array(
    'default' => array(
        'adapter' => 'File'
    ),
    'ftp' => array(
        'adapter' => 'Stream',
        'wrapper' => 'ftp',
        'path' => 'user:password@example.com/pub/'
    }
));

FileSystem::write('default', '/path/to/file', $data);
LI3_ACCESS
Access::config(array(
    'asset' => array(
        'adapter' => 'Rules',
        'allowAny' => true,
        'default' => array('isPublic', 'isOwner', 'isParticipant'),
        'user'     => function() { return Accounts::current(); },
        'rules'    => array(
            'isPublic' => function($user, $asset, $options) {
                    ...
               },
               'isOwner' => function($user, $asset, $options) {
                    ...
               },
               'isParticipant' => function($user, $asset, $options) {
                    ...
               }
           )
     )
     ...
);
LI3_ACCESS
Access::config(array(
    ...
    'action' => array(
        'adapter' => 'Rules',
        'default' => array('isPublic', 'isAuthenticated'),
        'allowAny' => true,
        'user'      => function() { return Accounts::current(); },
        'rules'     => array(
            'isPublic' => function($user, $request, array $options) {
                ...
            },
            'isAuthenticated' => function($user, $request, array $options) {
                ...
            },
            'isAdmin' => function($user, $asset, $options) {
                ...
            }
        )
    )
);
LI3_ACCESS
Dispatcher::applyFilter('_call', function($self, $params, $chain) {
    $opts    = $params['params'];
    $request = $params['request'];
    $ctrl    = $params['callable'];

      if ($access = Access::check('action', null, $ctrl, $opts)) {
          // Reject
      }
      if ($access = Access::check('action', null, $ctrl, array('rules' => 'isAdmin') + $opts)) {
          // Reject
      }
      return $chain->next($self, $params, $chain);
});




class PostsController extends Base {

      public $publicActions = array('index', 'view');
}
http://bit.ly/li3plugins
THE LAB
TIPS & TRICKS
RETURN ON REDIRECT

class PostsController extends Base {

    public function view($post) {
        if (!$post) {
            $this->redirect("Posts::index");
        }
        // Herp derp
    }
}
FAT FILTERS == BAD
Dispatcher::applyFilter('run', function($self, $params, $chain) {
    // Herp
    // Derp
    // Herp
    // Derp
    // Herp
    // Derp
    // Herp
    // Derp
    // Herp
    // Derp
    // Herp
    (repeat x100)
});
DEFINE YOUR SCHEMA!

{
      count: 5,
      ...
}
...
{
      count: "5",
      ...
}
DON’T FEAR THE SUBCLASS
class Base extends lithiumdataModel {

    public function save($entity, $data = null, array $options = array()) {
        if ($data) {
            $entity->set($data);
        }
        if (!$entity->exists()) {
            $entity->created = new MongoDate();
        }
        $entity->updated = new MongoDate();
        return parent::save($entity, null, $options);
    }
}

class Posts extends Base {
    ...
}
QUICK & DIRTY ADMIN
Dispatcher::config(array('rules' => array(
     'admin' => array(
         'action' => 'admin_{:action}'
    )
)));
                                   class PostsController extends Base {
Router::connect(
                                      public function admin_index() {
    '/admin/{:args}',
                                          ...
    array('admin' => true),
                                      }
    array('continue' => true)
);
                                      public function index() {
                                          ...
                                      }
                                  }
Q&A / DEMOS
THANKS!

More Related Content

PDF
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
PDF
Building Lithium Apps
PDF
Lithium: The Framework for People Who Hate Frameworks
PDF
The Zen of Lithium
PDF
The Origin of Lithium
PDF
PHP 5.3 and Lithium: the most rad php framework
PDF
Dependency Injection IPC 201
PDF
Dependency injection-zendcon-2010
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Building Lithium Apps
Lithium: The Framework for People Who Hate Frameworks
The Zen of Lithium
The Origin of Lithium
PHP 5.3 and Lithium: the most rad php framework
Dependency Injection IPC 201
Dependency injection-zendcon-2010

What's hot (20)

PDF
Design Patterns avec PHP 5.3, Symfony et Pimple
PDF
The History of PHPersistence
PDF
Database Design Patterns
PDF
Silex meets SOAP & REST
KEY
Lithium Best
PDF
Dependency injection in PHP 5.3/5.4
PDF
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
PDF
Dependency Injection with PHP and PHP 5.3
PDF
Symfony2 - WebExpo 2010
PDF
Be RESTful (Symfony Camp 2008)
ODP
Rich domain model with symfony 2.5 and doctrine 2.5
PDF
Advanced Querying with CakePHP 3
ODP
Symfony2, creare bundle e valore per il cliente
PDF
Agile database access with CakePHP 3
PDF
New in cakephp3
PDF
Doctrine fixtures
PDF
PHP Data Objects
PDF
Future of HTTP in CakePHP
PDF
SPL: The Missing Link in Development
PDF
CakeFest 2013 keynote
Design Patterns avec PHP 5.3, Symfony et Pimple
The History of PHPersistence
Database Design Patterns
Silex meets SOAP & REST
Lithium Best
Dependency injection in PHP 5.3/5.4
Decouple Your Code For Reusability (International PHP Conference / IPC 2008)
Dependency Injection with PHP and PHP 5.3
Symfony2 - WebExpo 2010
Be RESTful (Symfony Camp 2008)
Rich domain model with symfony 2.5 and doctrine 2.5
Advanced Querying with CakePHP 3
Symfony2, creare bundle e valore per il cliente
Agile database access with CakePHP 3
New in cakephp3
Doctrine fixtures
PHP Data Objects
Future of HTTP in CakePHP
SPL: The Missing Link in Development
CakeFest 2013 keynote
Ad

Viewers also liked (7)

PDF
Measuring Your Code
PDF
Measuring Your Code 2.0
PDF
Practical PHP 5.3
PDF
Building Apps with MongoDB
KEY
PHP, Lithium and MongoDB
KEY
Taking PHP To the next level
PPT
Lithium PHP Meetup 0210
Measuring Your Code
Measuring Your Code 2.0
Practical PHP 5.3
Building Apps with MongoDB
PHP, Lithium and MongoDB
Taking PHP To the next level
Lithium PHP Meetup 0210
Ad

Similar to The State of Lithium (20)

PDF
関西PHP勉強会 php5.4つまみぐい
PDF
Dependency Injection
PDF
ACL in CodeIgniter
PDF
Command-Oriented Architecture
PDF
YiiConf 2012 - Alexander Makarov - Yii2, what's new
PDF
Your code sucks, let's fix it - DPC UnCon
PDF
Doctrator Symfony Live 2011 San Francisco
PDF
Object Oriented Programming with PHP 5 - More OOP
PDF
symfony on action - WebTech 207
PDF
You code sucks, let's fix it
PDF
CakePHP Fundamentals - 1.2 @ OCPHP
PDF
Dependency injection - phpday 2010
PDF
Dependency Injection
PDF
Dependency Injection - ConFoo 2010
PDF
CakePHP 3.0: Embracing the future
PDF
Doctrine For Beginners
PPT
Writing Friendly libraries for CodeIgniter
PPT
Synapseindia reviews sharing intro cakephp
PDF
Dependency Injection with PHP 5.3
KEY
IoC with PHP
関西PHP勉強会 php5.4つまみぐい
Dependency Injection
ACL in CodeIgniter
Command-Oriented Architecture
YiiConf 2012 - Alexander Makarov - Yii2, what's new
Your code sucks, let's fix it - DPC UnCon
Doctrator Symfony Live 2011 San Francisco
Object Oriented Programming with PHP 5 - More OOP
symfony on action - WebTech 207
You code sucks, let's fix it
CakePHP Fundamentals - 1.2 @ OCPHP
Dependency injection - phpday 2010
Dependency Injection
Dependency Injection - ConFoo 2010
CakePHP 3.0: Embracing the future
Doctrine For Beginners
Writing Friendly libraries for CodeIgniter
Synapseindia reviews sharing intro cakephp
Dependency Injection with PHP 5.3
IoC with PHP

Recently uploaded (20)

PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Cloud computing and distributed systems.
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
Big Data Technologies - Introduction.pptx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Empathic Computing: Creating Shared Understanding
PDF
Encapsulation theory and applications.pdf
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
cuic standard and advanced reporting.pdf
PDF
KodekX | Application Modernization Development
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
DOCX
The AUB Centre for AI in Media Proposal.docx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Cloud computing and distributed systems.
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
20250228 LYD VKU AI Blended-Learning.pptx
Big Data Technologies - Introduction.pptx
Unlocking AI with Model Context Protocol (MCP)
Reach Out and Touch Someone: Haptics and Empathic Computing
Mobile App Security Testing_ A Comprehensive Guide.pdf
Empathic Computing: Creating Shared Understanding
Encapsulation theory and applications.pdf
“AI and Expert System Decision Support & Business Intelligence Systems”
Chapter 3 Spatial Domain Image Processing.pdf
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
cuic standard and advanced reporting.pdf
KodekX | Application Modernization Development
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
The AUB Centre for AI in Media Proposal.docx

The State of Lithium

  • 1. THE STATE OF LITHIUM li3_nyc::init() // 2012-02-07
  • 3. AGENDA • State of the framework • New features • Upcoming features • Community plugins • Library management & The Lab • Tips & tricks • Q&A / Demos!
  • 4. STATE OF THE FRAMEWORK
  • 5. PROJECT & COMMUNITY STATS • ~130 plugin repositories on GitHub • 350+ commits from 40+ contributors since 0.10 • 60+ commits to the manual since 0.10 • Closed 250+ issues since moving to GitHub • 175 pull requests submitted since moving to GitHub
  • 6. ROADMAP PROGRESS • Cookie signing / encryption • CSRF protection • Error Handling • Manual / automatic SQL result mapping • Relationship support
  • 8. ENCRYPT & SIGN COOKIES Session::config(array('default' => array( 'adapter' => 'Cookie', 'strategies' => array( 'Hmac' => array('secret' => '$f00bar$'), 'Encrypt' => array('secret' => '$f00bar$') ) )));
  • 9. NEST ROUTES Router::connect("/admin/{:args}", array('admin' => true), array( 'continue' => true )); Router::connect("/{:locale:en|de|jp}/{:args}", array(), array( 'continue' => true )); Router::connect("/{:args}.{:type}", array(), array( 'continue' => true ));
  • 10. HANDLE ERRORS $method = array(Connections::get('default'), 'read'); ErrorHandler::apply($method, array(), function($error, $params) { $queryParams = json_encode($params['query']); $msg = "Query error: {$error['message']}"; Logger::warning("{$msg}, data: {$queryParams}"); return new DocumentSet(); });
  • 11. PROTECT FORMS <?=$this->form->create(); ?> <?=$this->security->requestToken(); ?> <?=$this->form->field('title'); ?> <?=$this->form->submit('Submit'); ?> <?=$this->form->end(); ?> public function add() { if ( $this->request->data && !RequestToken::check($this->request) ) { // Badness!! } }
  • 13. HTTP SERVICE CLASSES $http = new Http(array( ... 'methods' => array( 'do' => array('method' => 'post', 'path' => '/do') ) )); POST /do HTTP/1.1 $response = $http->do(new Query(array( … 'data' => array('title' => 'sup') ))); title=sup // var_dump($response->data());
  • 14. FILTER / SORT COLLECTIONS $users->find(array("type" => "author"))->sort("name"); $users->first(array("name" => "Nate"));
  • 15. MULTIBYTE CLASS • Supports mbstring, intl, iconv & (womp, womp) plain PHP • Only one method right now: strlen() • More would be good… open a pull request
  • 16. SCHEMA CLASS • Arbitrary data types • Arbitrary handlers • Example: hash modified passwords before writing • Other example: JSON en/decode arbitrary data for MySQL
  • 18. LI3_DOCTRINE2 Connections::add('default', array( 'type' => 'Doctrine', • Works with Lithium stuff: 'driver' => 'pdo_mysql', 'host' => 'localhost', 'user' => 'root', • Connections 'password' => 'password', 'dbname' => 'my_db' )); • Authentication /** * @Entity * @Table(name="users") • Forms */ class User extends li3_doctrine2modelsBaseEntity { /** * @Id • Sessions * @GeneratedValue * @Column(type="integer") */ private $id; • Validation /** * @Column(type="string",unique=true) */ private $email; ... }
  • 19. LI3_FILESYSTEM use li3_filesystemstorageFileSystem; FileSystem::config(array( 'default' => array( 'adapter' => 'File' ), 'ftp' => array( 'adapter' => 'Stream', 'wrapper' => 'ftp', 'path' => 'user:password@example.com/pub/' } )); FileSystem::write('default', '/path/to/file', $data);
  • 20. LI3_ACCESS Access::config(array( 'asset' => array( 'adapter' => 'Rules', 'allowAny' => true, 'default' => array('isPublic', 'isOwner', 'isParticipant'), 'user' => function() { return Accounts::current(); }, 'rules' => array( 'isPublic' => function($user, $asset, $options) { ... }, 'isOwner' => function($user, $asset, $options) { ... }, 'isParticipant' => function($user, $asset, $options) { ... } ) ) ... );
  • 21. LI3_ACCESS Access::config(array( ... 'action' => array( 'adapter' => 'Rules', 'default' => array('isPublic', 'isAuthenticated'), 'allowAny' => true, 'user' => function() { return Accounts::current(); }, 'rules' => array( 'isPublic' => function($user, $request, array $options) { ... }, 'isAuthenticated' => function($user, $request, array $options) { ... }, 'isAdmin' => function($user, $asset, $options) { ... } ) ) );
  • 22. LI3_ACCESS Dispatcher::applyFilter('_call', function($self, $params, $chain) { $opts = $params['params']; $request = $params['request']; $ctrl = $params['callable']; if ($access = Access::check('action', null, $ctrl, $opts)) { // Reject } if ($access = Access::check('action', null, $ctrl, array('rules' => 'isAdmin') + $opts)) { // Reject } return $chain->next($self, $params, $chain); }); class PostsController extends Base { public $publicActions = array('index', 'view'); }
  • 26. RETURN ON REDIRECT class PostsController extends Base { public function view($post) { if (!$post) { $this->redirect("Posts::index"); } // Herp derp } }
  • 27. FAT FILTERS == BAD Dispatcher::applyFilter('run', function($self, $params, $chain) { // Herp // Derp // Herp // Derp // Herp // Derp // Herp // Derp // Herp // Derp // Herp (repeat x100) });
  • 28. DEFINE YOUR SCHEMA! { count: 5, ... } ... { count: "5", ... }
  • 29. DON’T FEAR THE SUBCLASS class Base extends lithiumdataModel { public function save($entity, $data = null, array $options = array()) { if ($data) { $entity->set($data); } if (!$entity->exists()) { $entity->created = new MongoDate(); } $entity->updated = new MongoDate(); return parent::save($entity, null, $options); } } class Posts extends Base { ... }
  • 30. QUICK & DIRTY ADMIN Dispatcher::config(array('rules' => array( 'admin' => array( 'action' => 'admin_{:action}' ) ))); class PostsController extends Base { Router::connect( public function admin_index() { '/admin/{:args}', ... array('admin' => true), } array('continue' => true) ); public function index() { ... } }