SlideShare a Scribd company logo
Rapid Prototyping with PEAR
                    ...using DataObject and
                    FormBuilder




Markus Wolff
Rapid Prototyping with PEAR

The principles of Rapid Prototyping
   Show results to the customer quickly
   Discuss neccessary changes early
   Refine the prototype until customer is
  happy with the application
   Either refactor until a clean codebase is
  reached or reprogram cleanly based on the
  approved prototype's features
Rapid Prototyping with PEAR

The PEAR packages that aid us
   DB (database API abstraction layer)
   DB_DataObject (object-relational
  mapping)
   HTML_QuickForm (building and validating
  of HTML forms)
   DB_DataObject_FormBuilder (auto-
  generates forms from DataObjects)
The concept
   What must my application do?
   What kind of data entities do I need?
   How are the entities related?
   GOAL: Reach an object-oriented
    approach to the data – think of every
    data entity as a class
Example: Bookstore application
 What it must do:
   Store book data (titles, authors, formats)
   Store customer data (name, adress)
   Store customer reviews (did it suck?)
Bookstore data entities
 ...this translates to the following entities:
  Book, Format, Customer, Review
 Rule of thumb:
   If one entity has a property that can have
    more than two values, make this another
    entity (especially if values can change)!
   Your database models should always be
    properly normalized.
Use an ERD tool
 Better understanding of relations
  between entities
 Changes can be done quickly
 Database is always documented
 DBMS independence (depending on the
  tool)
The entity relationship model




 Keep naming scheme consistent
  wherever possible
 Use pl. txt fld & tbl names, av. abbr.!
Introducing DataObject
 PEAR::DB_DataObject...
   maps database tables to PHP classes
   provides easy access to common SQL
    functions like select, insert, update, delete...
   allows developers with weak knowledge of
    SQL to write database-aware code
   encourages clean distinction between
    presentation and business logic
Configuring DataObject
 Uses one simple .ini file:
 [DB_DataObject]
 database = mysql://user:pw@localhost/demo
 schema_location = /dataobjects/schema/
 class_location = /dataobjects/
 require_prefix = /dataobjects/
 extends_location = DB/DataObject.php
 extends = DB_DataObject
 ...or, you can use plain PHP arrays.
Creating classes from tables...



$> createTables.php /path/to/DataObject.ini

 ...creates five files:
  Format.php, Book.php, Review.php,
  Customer.php, demo.ini
Class anatomy
Generated sourcecode
<?php
/**
 * Table Definition for format
 */
require_once 'DB/DataObject.php';

class Format extends DB_DataObject
{

     ###START_AUTOCODE
     /* the code below is auto generated do not remove the above tag */

     var $__table = 'format';              // table name
     var $format_id;                       // int(4) not_null primary_key unique_key
     unsigned auto_increment
     var $title;                           // string(40)

     /* ZE2 compatibility trick*/
     function __clone() { return $this;}

     /* Static get */
     function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Format',$k,$v);
     }

     /* the code above is auto generated do not remove the tag below */
     ###END_AUTOCODE
}
?>
Generated database file
 DO puts the database model into simple
  config file named „demo.ini“
[book]
book_id = 129
title = 130
description = 66
isbn = 130
format_id = 129

[book__keys]
book_id = N

[customer]
customer_id = 129
name = 130
street = 2
zip = 2
city = 2

[customer__keys]
customer_id = N

[format]
format_id = 129
title = 2
...
Working with DataObjects (1)
 How to get a book record by primary key:
<?php
require_once('DB/DataObject.php');
require('config.php');

$book = DB_DataObject::factory('book');
$book->get(42);
echo 'This book is called: '.$book->title;
?>
Working with DataObjects (2)
 Getting all books having a specific
  format:
$book = DB_DataObject::factory('book');
$book->format_id=23;
$num = $book->find();
$i = 1;
while ($book->fetch()) {
    echo quot;Book: $i of $num: {$book->title}<br>quot;;
    $i++;
}
Working with DataObjects (3)
 Adding your own WHERE clauses:
$book = DB_DataObject::factory('book');
$book->whereAdd(quot;book.title LIKE 'PHP%'quot;);
$num = $book->find();
$i = 1;
while ($book->fetch()) {
    echo quot;Book: $i of $num: {$book->title}<br>quot;;
    $i++;
}
Working with DataObjects (4)
 Insert, update, delete...
$book = DB_DataObject::factory('book');
$book->title = 'Advanced PHP Programming';
$book->format_id = 23;
$book_id = $book->insert();

$book->description = 'Great book ;-)';
$book->update();

$aBook = DB_DataObject::factory('book');
$aBook->book_id = $book_id;
$aBook->delete();
Working with DataObjects (5)
 Set up table relations using another
  config file: demo.links.ini
[book]
format_id = format:format_id

[review]
book_id = book:book_id
customer_id = customer:customer_id
Working with DataObjects (6)
 After setting up relationships, you can
  join table objects:
$review = DB_DataObject::factory('review');
$customer = DB_DataObject::factory('customer');
$review->book_id=4711;
$review->joinAdd($customer, 'INNER');
$review->selectAdd('customer.name');
$review->find();
while ($review->fetch()) {
    echo $review->title.' (a review by '.
         $review->name.')<br>';
    echo $review->description.'<hr>';
}
Working with DataObjects (7)
 Emulating triggers, encapsulating
  business logic, embracing inheritance:
function delete()
{
    if ($GLOBALS['user']->checkRight(MAY_DELETE_HERE)) {
        $this->cleanUpStuff();
        return parent::delete();
    }
    return false;
}
Working with DataObjects (8)
Overloading
 Automatic set/get methods
 Breaks pass-by-reference in PHP4
 Recommend not to use in PHP4

<?php
define('DB_DATAOBJECT_NO_OVERLOAD', 1);
require_once('DB/DataObject.php');
Adding forms – the simple way
 DB_DataObject_FormBuilder...
   ...creates forms from DataObjects
   ...allows configuring form generation
    through setting reserved properties in
    DataObjects
   ...triggers callback methods for further form
    manipulation
   ...handles form processing and
    inserting/updating data in the database
Creating a form for a review
require_once('DB/DataObject/FormBuilder.php');
require('config.php');

$review = DB_DataObject::factory('review');
$builder =& DB_DataObject_FormBuilder::create($review);
$form =& $builder->getForm();

if ($form->validate()) {
     $form->process(array(&$builder,'processForm'),
   false);
     echo 'New review ID: '.$review->review_id;
}
echo $form->toHtml();
The generated form
Using the form to update data
require_once('DB/DataObject.php');
require_once('DB/DataObject/FormBuilder.php');
require('config.php');

$review = DB_DataObject::factory('review');
$review->get(13);
$builder =& DB_DataObject_FormBuilder::create($review);
$form =& $builder->getForm();

if ($form->validate()) {
     $form->process(array(&$builder,'processForm'),
   false);
     echo 'Review updated!';
}
echo $form->toHtml();
Configuring FormBuilder
 Add some lines to DataObject.ini:
[DB_DataObject_FormBuilder]
linkDisplayFields = title


 Add one line to the config include file:
$_DB_DATAOBJECT_FORMBUILDER['CONFIG'] =
            $config['DB_DataObject_FormBuilder'];
The new form output




 Customer still not displayed... no „title“!
Tweaking the customer class

class Customer extends DB_DataObject
{
    ###START_AUTOCODE
    /* some code omitted */
    ###END_AUTOCODE

    // Use the 'name' property to display records
    // whenever this class is used as the source for
    // a select box!
    // Overrides the default in the ini file.
    var $fb_linkDisplayFields = array('name');
}
Customers on display
Tweaking the form (labels)
 To define custom labels, use the
  'fieldLabels' property:
class Customer extends DB_DataObject
{
    ###START_AUTOCODE
    /* some code omitted */
    ###END_AUTOCODE

    var $fb_fieldLabels = array(
             'customer_id' => 'Customer',
             'book_id'     => 'Book');
}
Tweaking the form (labels)
Tweaking the form (elements)
 Defining textareas... the old-fashioned
  way:
class Customer extends DB_DataObject
{
    ###START_AUTOCODE
    /* some code omitted */
    ###END_AUTOCODE

    var $fb_textFields   = array('review');
}
Tweaking the form (elements)
Tweaking the form (elements)
 Use the preGenerateForm() callback
  method and 'preDefElements' property to
  define your own element types for
  specific fields:
function preGenerateForm(&$fb) {
    $el = HTML_QuickForm::createElement('hidden',
                                        'customer_id');
    $this->fb_preDefElements['customer_id'] = $el;
}
Tweaking the form (elements)
Tweaking the form (rules)
 Use the postGenerateForm() callback
  method to add form validation rules and
  input filters:
function postGenerateForm(&$form) {
    $form->addRule('title', 'Please enter a title',
                   'required');
    $form->addRule('review', 'Please at least try...',
                   'minlength', 10);

    $form->applyFilter('__ALL__', 'trim');
}
Tweaking the form (rules)
Defining custom forms
 You can make your own forms if...
   ...the form requires more than just
    „tweaking“
   ...you want better model / view separation
 Just define your own getForm() method
 pre- and postGenerateForm() will still be
  triggered!
 FormBuilder can still process the input
Defining custom forms
class CustomerForm extends HTML_QuickForm {
    function CustomerForm($formName='CustomerForm',
                  $method='post', $action='',
                  $target='_self', $attributes=null) {
        parent::HTML_QuickForm($formName, $method, $action,
                               $target, $attributes);

        $this->addElement('text', 'name', 'Customer name');
        $this->addElement('text', 'street','Street');
        $this->addElement('text', 'zip',   'ZIP');
        $this->addElement('text', 'city', 'City');
        $this->addElement('submit', 'submit', 'Submit');

        $this->addRule('name', 'Please enter a name',
                       'required');
        $this->applyFilter('__ALL__', 'trim');
    }
}
Defining custom forms
class Customer extends DB_DataObject
{
    function &getForm($action=false, $target='_self',
                   $formName='CustomerForm', $method='post')
    {
        if (!$action) {
            $action = $_SERVER['REQUEST_URI'];
        }
        include_once('forms/CustomerForm.php');
        $form =& new CustomerForm($formName, $method, $action,
                                  $target);

        return $form;
    }
}
But...
FormBuilder has lots of
 options. Check the
 documentation and ask
 questions before resorting to
 your own form
Processing the form
 Usually done automatically:
$form->process(array(&$builder,'processForm'),
               false);

 You can also force a specific data
  handling method:
$builder->forceQueryType(
  DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT
                         );
Processing the form
 Callback methods available:
   preProcessForm()
   postProcessForm()
 Common uses:
   Event notification
   Generating changelogs (before / after)
Nested forms
 To make just one form for data from two
  different tables:
$review = DB_DataObject::factory('review');
$customer = DB_DataObject::factory('customer');
$customer->createSubmit = false;
$reviewBuilder =&
           DB_DataObject_FormBuilder::create($review);
$customerBuilder =&
           DB_DataObject_FormBuilder::create($customer);
$customerBuilder->elementNamePrefix = 'customer';
$customerForm =& $customerBuilder->getForm();
$reviewBuilder->elementNamePrefix = 'review';
$reviewBuilder->useForm($customerForm);
$combinedForm =& $reviewBuilder->getForm();
Nested forms
FormBuilder Evolves...
 Features released since this talk:
   Support for crosslink tables (m:n)
   Support for custom elements as global
    replacements for standard ones:
  elementTypeMap =
        date:jscalendar,longtext:htmlarea
   Many others!
Application template
// FILE: index.php
require('config.php');

if (!isset($_GET['table'])) {
    die ('Please specify quot;tablequot; parameter');
}

$table = $_GET['table'];

$do = DB_DataObject::factory($table);
if (PEAR::isError($do)) {
    die($do->getMessage());
}
Application template
// Find primary key
$keys = $do->keys();
if (is_array($keys)) {
    $primaryKey = $keys[0];
}

// Find title field
$titleFields =
   $_DB_DATAOBJECT_FORMBUILDER['CONFIG']['linkDisplayFields'];

if (isset($do->fb_linkDisplayFields)) {
    $titleFields = $do->fb_linkDisplayFields;
}
Application template
$do->find();

while ($do->fetch()) {
   foreach($titleFields as $fieldName){
      $titleValues[$fieldName] = $do->$fieldName;
   }
    echo sprintf('<a href=quot;details.php?id=%s&table=%squot;>
                 %s</a><br>',
                 $do->$primaryKey,
                 $table,
                 implode(' ', $titleValues);
}
echo '<hr><a href=quot;details.php?table='.
     $table.'quot;>Add new</a>';
// EOF: index.php
Application template
Application template
// FILE: details.php
require('config.php');
if (!isset($_GET['table'])) {
    die ('Please specify quot;tablequot; parameter');
}
$table = $_GET['table'];

$do = DB_DataObject::factory($table);
if (PEAR::isError($do)) {
    die($do->getMessage());
}
if (isset($_GET['id'])) {
    $do->get($_GET['id']);
}
Application template
$builder =& DB_DataObject_FormBuilder::create($do);
$form = $builder->getForm($_SERVER['REQUEST_URI']);

if ($form->validate()) {
    $res = $form->process(array($builder,'processForm'),
                           false);
    if ($res) {
        header('Location: index.php?table='.$table);
    }
    echo quot;Something went wrong...<br>quot;;
}

echo $form->toHtml();
// EOF: details.php
Application template
Famous last words
 To sum-up, aforementioned packages...
   ...unify form and data handling
   ...make it easy to train new project members
   ...speed up application development by at
    least a factor of three
   ...make it easy to create universal
    application frameworks, where new
    functionality can easily be plugged in
The end

 Thank you for your
  attention!

 ANY QUESTIONS ?

More Related Content

What's hot

Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
ddiers
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
Azim Kurt
 
Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片
cfc
 
ZG PHP - Specification
ZG PHP - SpecificationZG PHP - Specification
ZG PHP - Specification
Robert Šorn
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2
zfconfua
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
Marco Vito Moscaritolo
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
Michelangelo van Dam
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Colin O'Dell
 
Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
Mohamed Mosaad
 
Migrating to dependency injection
Migrating to dependency injectionMigrating to dependency injection
Migrating to dependency injection
Josh Adell
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
Ruby on Rails For Java Programmers
Ruby on Rails For Java ProgrammersRuby on Rails For Java Programmers
Ruby on Rails For Java Programmers
elliando dias
 
Polymer
PolymerPolymer
Polymer
Cyril Balit
 
Web2py Code Lab
Web2py Code LabWeb2py Code Lab
Web2py Code Lab
Colin Su
 
Zend framework 04 - forms
Zend framework 04 - formsZend framework 04 - forms
Zend framework 04 - forms
Tricode (part of Dept)
 
Apache Con Us2007 Apachei Batis
Apache Con Us2007 Apachei BatisApache Con Us2007 Apachei Batis
Apache Con Us2007 Apachei Batis
day
 
WooCommerce CRUD and Data Store by Akeda Bagus
WooCommerce CRUD and Data Store by Akeda BagusWooCommerce CRUD and Data Store by Akeda Bagus
WooCommerce CRUD and Data Store by Akeda Bagus
WordCamp Indonesia
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
Andrea Giuliano
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
Bernhard Schussek
 
Hibernate working with criteria- Basic Introduction
Hibernate working with criteria- Basic IntroductionHibernate working with criteria- Basic Introduction
Hibernate working with criteria- Basic Introduction
Er. Gaurav Kumar
 

What's hot (20)

Drupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary EditionDrupal - dbtng 25th Anniversary Edition
Drupal - dbtng 25th Anniversary Edition
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片Contagion的Ruby/Rails投影片
Contagion的Ruby/Rails投影片
 
ZG PHP - Specification
ZG PHP - SpecificationZG PHP - Specification
ZG PHP - Specification
 
Doctrine 2
Doctrine 2Doctrine 2
Doctrine 2
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
 
Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
 
Migrating to dependency injection
Migrating to dependency injectionMigrating to dependency injection
Migrating to dependency injection
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Ruby on Rails For Java Programmers
Ruby on Rails For Java ProgrammersRuby on Rails For Java Programmers
Ruby on Rails For Java Programmers
 
Polymer
PolymerPolymer
Polymer
 
Web2py Code Lab
Web2py Code LabWeb2py Code Lab
Web2py Code Lab
 
Zend framework 04 - forms
Zend framework 04 - formsZend framework 04 - forms
Zend framework 04 - forms
 
Apache Con Us2007 Apachei Batis
Apache Con Us2007 Apachei BatisApache Con Us2007 Apachei Batis
Apache Con Us2007 Apachei Batis
 
WooCommerce CRUD and Data Store by Akeda Bagus
WooCommerce CRUD and Data Store by Akeda BagusWooCommerce CRUD and Data Store by Akeda Bagus
WooCommerce CRUD and Data Store by Akeda Bagus
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
 
Leveraging Symfony2 Forms
Leveraging Symfony2 FormsLeveraging Symfony2 Forms
Leveraging Symfony2 Forms
 
Hibernate working with criteria- Basic Introduction
Hibernate working with criteria- Basic IntroductionHibernate working with criteria- Basic Introduction
Hibernate working with criteria- Basic Introduction
 

Viewers also liked

Roadmap to WordPress Accessibility CSUN 2014
Roadmap to WordPress Accessibility CSUN 2014Roadmap to WordPress Accessibility CSUN 2014
Roadmap to WordPress Accessibility CSUN 2014
Los Angeles Accessibility and Inclusive Design Group
 
My Life
My LifeMy Life
My Life
jade.smith
 
Donor Appreciation
Donor AppreciationDonor Appreciation
Donor Appreciation
TotalAwards
 
This Month In Real Estate April 2009
This Month In Real Estate April 2009This Month In Real Estate April 2009
This Month In Real Estate April 2009
Michael Walker
 
This Month In Real Estate April 2009
This Month In Real Estate April 2009This Month In Real Estate April 2009
This Month In Real Estate April 2009
Michael Walker
 
This Month In Real Estate March 2009
This Month In Real Estate March 2009This Month In Real Estate March 2009
This Month In Real Estate March 2009
Michael Walker
 
Red Eye Removal
Red Eye RemovalRed Eye Removal
Red Eye Removal
tonyl32
 
Target Organizher 2010 Line Plan
Target Organizher 2010 Line PlanTarget Organizher 2010 Line Plan
Target Organizher 2010 Line Plan
hkessen
 
LTM - Part2[zhianova18070978]
LTM - Part2[zhianova18070978]LTM - Part2[zhianova18070978]
LTM - Part2[zhianova18070978]
zhianov
 
Presentation D U O Art
Presentation  D U O ArtPresentation  D U O Art
Presentation D U O Art
daricasillas
 
Telling The Birth Story Cbs
Telling The Birth Story CbsTelling The Birth Story Cbs
Telling The Birth Story Cbs
caitlinrleague
 
Cities: Making Free Accessible WordPress Themes
Cities: Making Free Accessible WordPress ThemesCities: Making Free Accessible WordPress Themes
Cities: Making Free Accessible WordPress Themes
Los Angeles Accessibility and Inclusive Design Group
 
Educational Games
Educational GamesEducational Games
Educational Games
guestb09f79
 
Art Portfolio
Art PortfolioArt Portfolio
Art Portfolio
rkmcnair
 
Educational Games
Educational GamesEducational Games
Educational Games
guestb09f79
 

Viewers also liked (17)

Roadmap to WordPress Accessibility CSUN 2014
Roadmap to WordPress Accessibility CSUN 2014Roadmap to WordPress Accessibility CSUN 2014
Roadmap to WordPress Accessibility CSUN 2014
 
2 Tenori
2 Tenori2 Tenori
2 Tenori
 
My Life
My LifeMy Life
My Life
 
Donor Appreciation
Donor AppreciationDonor Appreciation
Donor Appreciation
 
Tugas
TugasTugas
Tugas
 
This Month In Real Estate April 2009
This Month In Real Estate April 2009This Month In Real Estate April 2009
This Month In Real Estate April 2009
 
This Month In Real Estate April 2009
This Month In Real Estate April 2009This Month In Real Estate April 2009
This Month In Real Estate April 2009
 
This Month In Real Estate March 2009
This Month In Real Estate March 2009This Month In Real Estate March 2009
This Month In Real Estate March 2009
 
Red Eye Removal
Red Eye RemovalRed Eye Removal
Red Eye Removal
 
Target Organizher 2010 Line Plan
Target Organizher 2010 Line PlanTarget Organizher 2010 Line Plan
Target Organizher 2010 Line Plan
 
LTM - Part2[zhianova18070978]
LTM - Part2[zhianova18070978]LTM - Part2[zhianova18070978]
LTM - Part2[zhianova18070978]
 
Presentation D U O Art
Presentation  D U O ArtPresentation  D U O Art
Presentation D U O Art
 
Telling The Birth Story Cbs
Telling The Birth Story CbsTelling The Birth Story Cbs
Telling The Birth Story Cbs
 
Cities: Making Free Accessible WordPress Themes
Cities: Making Free Accessible WordPress ThemesCities: Making Free Accessible WordPress Themes
Cities: Making Free Accessible WordPress Themes
 
Educational Games
Educational GamesEducational Games
Educational Games
 
Art Portfolio
Art PortfolioArt Portfolio
Art Portfolio
 
Educational Games
Educational GamesEducational Games
Educational Games
 

Similar to Rapid Prototyping with PEAR

Framework
FrameworkFramework
Framework
Nguyen Linh
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
leo lapworth
 
Agile Data concept introduction
Agile Data   concept introductionAgile Data   concept introduction
Agile Data concept introduction
Romans Malinovskis
 
Php frameworks
Php frameworksPhp frameworks
Php frameworks
Anil Kumar Panigrahi
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
Dirk Haun
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept Implementation
Abdul Malik Ikhsan
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with example
Katy Slemon
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
Kacper Gunia
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised content
Michael Peacock
 
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
Benjamin Eberlei
 
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
Alexandru Badiu
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
Bo-Yi Wu
 
Mysocial databasequeries
Mysocial databasequeriesMysocial databasequeries
Mysocial databasequeries
Program in Interdisciplinary Computing
 
Mysocial databasequeries
Mysocial databasequeriesMysocial databasequeries
Mysocial databasequeries
Program in Interdisciplinary Computing
 
Doctrine for NoSQL
Doctrine for NoSQLDoctrine for NoSQL
Doctrine for NoSQL
Benjamin Eberlei
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicate
Kiev ALT.NET
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
Gordon Forsythe
 
blog_db_interface.phpphpinclude_once(blog_exceptions.
blog_db_interface.phpphpinclude_once(blog_exceptions.blog_db_interface.phpphpinclude_once(blog_exceptions.
blog_db_interface.phpphpinclude_once(blog_exceptions.
ChantellPantoja184
 
10.Local Database & LINQ
10.Local Database & LINQ10.Local Database & LINQ
10.Local Database & LINQ
Nguyen Tuan
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
Mike Subelsky
 

Similar to Rapid Prototyping with PEAR (20)

Framework
FrameworkFramework
Framework
 
DBIx::Class beginners
DBIx::Class beginnersDBIx::Class beginners
DBIx::Class beginners
 
Agile Data concept introduction
Agile Data   concept introductionAgile Data   concept introduction
Agile Data concept introduction
 
Php frameworks
Php frameworksPhp frameworks
Php frameworks
 
Using Geeklog as a Web Application Framework
Using Geeklog as a Web Application FrameworkUsing Geeklog as a Web Application Framework
Using Geeklog as a Web Application Framework
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept Implementation
 
Laravel 8 export data as excel file with example
Laravel 8 export data as excel file with exampleLaravel 8 export data as excel file with example
Laravel 8 export data as excel file with example
 
PHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4DevelopersPHPSpec - the only Design Tool you need - 4Developers
PHPSpec - the only Design Tool you need - 4Developers
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised content
 
Doctrine and NoSQL
Doctrine and NoSQLDoctrine and NoSQL
Doctrine and NoSQL
 
What's new in the Drupal 7 API?
What's new in the Drupal 7 API?What's new in the Drupal 7 API?
What's new in the Drupal 7 API?
 
CodeIgniter PHP MVC Framework
CodeIgniter PHP MVC FrameworkCodeIgniter PHP MVC Framework
CodeIgniter PHP MVC Framework
 
Mysocial databasequeries
Mysocial databasequeriesMysocial databasequeries
Mysocial databasequeries
 
Mysocial databasequeries
Mysocial databasequeriesMysocial databasequeries
Mysocial databasequeries
 
Doctrine for NoSQL
Doctrine for NoSQLDoctrine for NoSQL
Doctrine for NoSQL
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicate
 
Zend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_ToolZend Framework 1.9 Setup & Using Zend_Tool
Zend Framework 1.9 Setup & Using Zend_Tool
 
blog_db_interface.phpphpinclude_once(blog_exceptions.
blog_db_interface.phpphpinclude_once(blog_exceptions.blog_db_interface.phpphpinclude_once(blog_exceptions.
blog_db_interface.phpphpinclude_once(blog_exceptions.
 
10.Local Database & LINQ
10.Local Database & LINQ10.Local Database & LINQ
10.Local Database & LINQ
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 

Recently uploaded

TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
TrustArc
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
alexjohnson7307
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
Ivanti
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
panagenda
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
Shinana2
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
akankshawande
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
GDSC PJATK
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
Pravash Chandra Das
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Safe Software
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Alpen-Adria-Universität
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
MichaelKnudsen27
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
Trusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process MiningTrusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process Mining
LucaBarbaro3
 
Letter and Document Automation for Bonterra Impact Management (fka Social Sol...
Letter and Document Automation for Bonterra Impact Management (fka Social Sol...Letter and Document Automation for Bonterra Impact Management (fka Social Sol...
Letter and Document Automation for Bonterra Impact Management (fka Social Sol...
Jeffrey Haguewood
 
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptxOcean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
SitimaJohn
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
Dinusha Kumarasiri
 

Recently uploaded (20)

TrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy SurveyTrustArc Webinar - 2024 Global Privacy Survey
TrustArc Webinar - 2024 Global Privacy Survey
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
leewayhertz.com-AI in predictive maintenance Use cases technologies benefits ...
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
June Patch Tuesday
June Patch TuesdayJune Patch Tuesday
June Patch Tuesday
 
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAUHCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
HCL Notes und Domino Lizenzkostenreduzierung in der Welt von DLAU
 
dbms calicut university B. sc Cs 4th sem.pdf
dbms  calicut university B. sc Cs 4th sem.pdfdbms  calicut university B. sc Cs 4th sem.pdf
dbms calicut university B. sc Cs 4th sem.pdf
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development ProvidersYour One-Stop Shop for Python Success: Top 10 US Python Development Providers
Your One-Stop Shop for Python Success: Top 10 US Python Development Providers
 
Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!Finale of the Year: Apply for Next One!
Finale of the Year: Apply for Next One!
 
Operating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptxOperating System Used by Users in day-to-day life.pptx
Operating System Used by Users in day-to-day life.pptx
 
Driving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success StoryDriving Business Innovation: Latest Generative AI Advancements & Success Story
Driving Business Innovation: Latest Generative AI Advancements & Success Story
 
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing InstancesEnergy Efficient Video Encoding for Cloud and Edge Computing Instances
Energy Efficient Video Encoding for Cloud and Edge Computing Instances
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Nordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptxNordic Marketo Engage User Group_June 13_ 2024.pptx
Nordic Marketo Engage User Group_June 13_ 2024.pptx
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
Trusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process MiningTrusted Execution Environment for Decentralized Process Mining
Trusted Execution Environment for Decentralized Process Mining
 
Letter and Document Automation for Bonterra Impact Management (fka Social Sol...
Letter and Document Automation for Bonterra Impact Management (fka Social Sol...Letter and Document Automation for Bonterra Impact Management (fka Social Sol...
Letter and Document Automation for Bonterra Impact Management (fka Social Sol...
 
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptxOcean lotus Threat actors project by John Sitima 2024 (1).pptx
Ocean lotus Threat actors project by John Sitima 2024 (1).pptx
 
Azure API Management to expose backend services securely
Azure API Management to expose backend services securelyAzure API Management to expose backend services securely
Azure API Management to expose backend services securely
 

Rapid Prototyping with PEAR

  • 1. Rapid Prototyping with PEAR ...using DataObject and FormBuilder Markus Wolff
  • 2. Rapid Prototyping with PEAR The principles of Rapid Prototyping  Show results to the customer quickly  Discuss neccessary changes early  Refine the prototype until customer is happy with the application  Either refactor until a clean codebase is reached or reprogram cleanly based on the approved prototype's features
  • 3. Rapid Prototyping with PEAR The PEAR packages that aid us  DB (database API abstraction layer)  DB_DataObject (object-relational mapping)  HTML_QuickForm (building and validating of HTML forms)  DB_DataObject_FormBuilder (auto- generates forms from DataObjects)
  • 4. The concept  What must my application do?  What kind of data entities do I need?  How are the entities related?  GOAL: Reach an object-oriented approach to the data – think of every data entity as a class
  • 5. Example: Bookstore application  What it must do:  Store book data (titles, authors, formats)  Store customer data (name, adress)  Store customer reviews (did it suck?)
  • 6. Bookstore data entities  ...this translates to the following entities: Book, Format, Customer, Review  Rule of thumb:  If one entity has a property that can have more than two values, make this another entity (especially if values can change)!  Your database models should always be properly normalized.
  • 7. Use an ERD tool  Better understanding of relations between entities  Changes can be done quickly  Database is always documented  DBMS independence (depending on the tool)
  • 8. The entity relationship model  Keep naming scheme consistent wherever possible  Use pl. txt fld & tbl names, av. abbr.!
  • 9. Introducing DataObject  PEAR::DB_DataObject...  maps database tables to PHP classes  provides easy access to common SQL functions like select, insert, update, delete...  allows developers with weak knowledge of SQL to write database-aware code  encourages clean distinction between presentation and business logic
  • 10. Configuring DataObject  Uses one simple .ini file: [DB_DataObject] database = mysql://user:pw@localhost/demo schema_location = /dataobjects/schema/ class_location = /dataobjects/ require_prefix = /dataobjects/ extends_location = DB/DataObject.php extends = DB_DataObject  ...or, you can use plain PHP arrays.
  • 11. Creating classes from tables... $> createTables.php /path/to/DataObject.ini  ...creates five files: Format.php, Book.php, Review.php, Customer.php, demo.ini
  • 13. Generated sourcecode <?php /** * Table Definition for format */ require_once 'DB/DataObject.php'; class Format extends DB_DataObject { ###START_AUTOCODE /* the code below is auto generated do not remove the above tag */ var $__table = 'format'; // table name var $format_id; // int(4) not_null primary_key unique_key unsigned auto_increment var $title; // string(40) /* ZE2 compatibility trick*/ function __clone() { return $this;} /* Static get */ function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Format',$k,$v); } /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE } ?>
  • 14. Generated database file  DO puts the database model into simple config file named „demo.ini“ [book] book_id = 129 title = 130 description = 66 isbn = 130 format_id = 129 [book__keys] book_id = N [customer] customer_id = 129 name = 130 street = 2 zip = 2 city = 2 [customer__keys] customer_id = N [format] format_id = 129 title = 2 ...
  • 15. Working with DataObjects (1)  How to get a book record by primary key: <?php require_once('DB/DataObject.php'); require('config.php'); $book = DB_DataObject::factory('book'); $book->get(42); echo 'This book is called: '.$book->title; ?>
  • 16. Working with DataObjects (2)  Getting all books having a specific format: $book = DB_DataObject::factory('book'); $book->format_id=23; $num = $book->find(); $i = 1; while ($book->fetch()) { echo quot;Book: $i of $num: {$book->title}<br>quot;; $i++; }
  • 17. Working with DataObjects (3)  Adding your own WHERE clauses: $book = DB_DataObject::factory('book'); $book->whereAdd(quot;book.title LIKE 'PHP%'quot;); $num = $book->find(); $i = 1; while ($book->fetch()) { echo quot;Book: $i of $num: {$book->title}<br>quot;; $i++; }
  • 18. Working with DataObjects (4)  Insert, update, delete... $book = DB_DataObject::factory('book'); $book->title = 'Advanced PHP Programming'; $book->format_id = 23; $book_id = $book->insert(); $book->description = 'Great book ;-)'; $book->update(); $aBook = DB_DataObject::factory('book'); $aBook->book_id = $book_id; $aBook->delete();
  • 19. Working with DataObjects (5)  Set up table relations using another config file: demo.links.ini [book] format_id = format:format_id [review] book_id = book:book_id customer_id = customer:customer_id
  • 20. Working with DataObjects (6)  After setting up relationships, you can join table objects: $review = DB_DataObject::factory('review'); $customer = DB_DataObject::factory('customer'); $review->book_id=4711; $review->joinAdd($customer, 'INNER'); $review->selectAdd('customer.name'); $review->find(); while ($review->fetch()) { echo $review->title.' (a review by '. $review->name.')<br>'; echo $review->description.'<hr>'; }
  • 21. Working with DataObjects (7)  Emulating triggers, encapsulating business logic, embracing inheritance: function delete() { if ($GLOBALS['user']->checkRight(MAY_DELETE_HERE)) { $this->cleanUpStuff(); return parent::delete(); } return false; }
  • 22. Working with DataObjects (8) Overloading  Automatic set/get methods  Breaks pass-by-reference in PHP4  Recommend not to use in PHP4 <?php define('DB_DATAOBJECT_NO_OVERLOAD', 1); require_once('DB/DataObject.php');
  • 23. Adding forms – the simple way  DB_DataObject_FormBuilder...  ...creates forms from DataObjects  ...allows configuring form generation through setting reserved properties in DataObjects  ...triggers callback methods for further form manipulation  ...handles form processing and inserting/updating data in the database
  • 24. Creating a form for a review require_once('DB/DataObject/FormBuilder.php'); require('config.php'); $review = DB_DataObject::factory('review'); $builder =& DB_DataObject_FormBuilder::create($review); $form =& $builder->getForm(); if ($form->validate()) { $form->process(array(&$builder,'processForm'), false); echo 'New review ID: '.$review->review_id; } echo $form->toHtml();
  • 26. Using the form to update data require_once('DB/DataObject.php'); require_once('DB/DataObject/FormBuilder.php'); require('config.php'); $review = DB_DataObject::factory('review'); $review->get(13); $builder =& DB_DataObject_FormBuilder::create($review); $form =& $builder->getForm(); if ($form->validate()) { $form->process(array(&$builder,'processForm'), false); echo 'Review updated!'; } echo $form->toHtml();
  • 27. Configuring FormBuilder  Add some lines to DataObject.ini: [DB_DataObject_FormBuilder] linkDisplayFields = title  Add one line to the config include file: $_DB_DATAOBJECT_FORMBUILDER['CONFIG'] = $config['DB_DataObject_FormBuilder'];
  • 28. The new form output  Customer still not displayed... no „title“!
  • 29. Tweaking the customer class class Customer extends DB_DataObject { ###START_AUTOCODE /* some code omitted */ ###END_AUTOCODE // Use the 'name' property to display records // whenever this class is used as the source for // a select box! // Overrides the default in the ini file. var $fb_linkDisplayFields = array('name'); }
  • 31. Tweaking the form (labels)  To define custom labels, use the 'fieldLabels' property: class Customer extends DB_DataObject { ###START_AUTOCODE /* some code omitted */ ###END_AUTOCODE var $fb_fieldLabels = array( 'customer_id' => 'Customer', 'book_id' => 'Book'); }
  • 32. Tweaking the form (labels)
  • 33. Tweaking the form (elements)  Defining textareas... the old-fashioned way: class Customer extends DB_DataObject { ###START_AUTOCODE /* some code omitted */ ###END_AUTOCODE var $fb_textFields = array('review'); }
  • 34. Tweaking the form (elements)
  • 35. Tweaking the form (elements)  Use the preGenerateForm() callback method and 'preDefElements' property to define your own element types for specific fields: function preGenerateForm(&$fb) { $el = HTML_QuickForm::createElement('hidden', 'customer_id'); $this->fb_preDefElements['customer_id'] = $el; }
  • 36. Tweaking the form (elements)
  • 37. Tweaking the form (rules)  Use the postGenerateForm() callback method to add form validation rules and input filters: function postGenerateForm(&$form) { $form->addRule('title', 'Please enter a title', 'required'); $form->addRule('review', 'Please at least try...', 'minlength', 10); $form->applyFilter('__ALL__', 'trim'); }
  • 38. Tweaking the form (rules)
  • 39. Defining custom forms  You can make your own forms if...  ...the form requires more than just „tweaking“  ...you want better model / view separation  Just define your own getForm() method  pre- and postGenerateForm() will still be triggered!  FormBuilder can still process the input
  • 40. Defining custom forms class CustomerForm extends HTML_QuickForm { function CustomerForm($formName='CustomerForm', $method='post', $action='', $target='_self', $attributes=null) { parent::HTML_QuickForm($formName, $method, $action, $target, $attributes); $this->addElement('text', 'name', 'Customer name'); $this->addElement('text', 'street','Street'); $this->addElement('text', 'zip', 'ZIP'); $this->addElement('text', 'city', 'City'); $this->addElement('submit', 'submit', 'Submit'); $this->addRule('name', 'Please enter a name', 'required'); $this->applyFilter('__ALL__', 'trim'); } }
  • 41. Defining custom forms class Customer extends DB_DataObject { function &getForm($action=false, $target='_self', $formName='CustomerForm', $method='post') { if (!$action) { $action = $_SERVER['REQUEST_URI']; } include_once('forms/CustomerForm.php'); $form =& new CustomerForm($formName, $method, $action, $target); return $form; } }
  • 42. But... FormBuilder has lots of options. Check the documentation and ask questions before resorting to your own form
  • 43. Processing the form  Usually done automatically: $form->process(array(&$builder,'processForm'), false);  You can also force a specific data handling method: $builder->forceQueryType( DB_DATAOBJECT_FORMBUILDER_QUERY_FORCEINSERT );
  • 44. Processing the form  Callback methods available:  preProcessForm()  postProcessForm()  Common uses:  Event notification  Generating changelogs (before / after)
  • 45. Nested forms  To make just one form for data from two different tables: $review = DB_DataObject::factory('review'); $customer = DB_DataObject::factory('customer'); $customer->createSubmit = false; $reviewBuilder =& DB_DataObject_FormBuilder::create($review); $customerBuilder =& DB_DataObject_FormBuilder::create($customer); $customerBuilder->elementNamePrefix = 'customer'; $customerForm =& $customerBuilder->getForm(); $reviewBuilder->elementNamePrefix = 'review'; $reviewBuilder->useForm($customerForm); $combinedForm =& $reviewBuilder->getForm();
  • 47. FormBuilder Evolves...  Features released since this talk:  Support for crosslink tables (m:n)  Support for custom elements as global replacements for standard ones: elementTypeMap = date:jscalendar,longtext:htmlarea  Many others!
  • 48. Application template // FILE: index.php require('config.php'); if (!isset($_GET['table'])) { die ('Please specify quot;tablequot; parameter'); } $table = $_GET['table']; $do = DB_DataObject::factory($table); if (PEAR::isError($do)) { die($do->getMessage()); }
  • 49. Application template // Find primary key $keys = $do->keys(); if (is_array($keys)) { $primaryKey = $keys[0]; } // Find title field $titleFields = $_DB_DATAOBJECT_FORMBUILDER['CONFIG']['linkDisplayFields']; if (isset($do->fb_linkDisplayFields)) { $titleFields = $do->fb_linkDisplayFields; }
  • 50. Application template $do->find(); while ($do->fetch()) { foreach($titleFields as $fieldName){ $titleValues[$fieldName] = $do->$fieldName; } echo sprintf('<a href=quot;details.php?id=%s&table=%squot;> %s</a><br>', $do->$primaryKey, $table, implode(' ', $titleValues); } echo '<hr><a href=quot;details.php?table='. $table.'quot;>Add new</a>'; // EOF: index.php
  • 52. Application template // FILE: details.php require('config.php'); if (!isset($_GET['table'])) { die ('Please specify quot;tablequot; parameter'); } $table = $_GET['table']; $do = DB_DataObject::factory($table); if (PEAR::isError($do)) { die($do->getMessage()); } if (isset($_GET['id'])) { $do->get($_GET['id']); }
  • 53. Application template $builder =& DB_DataObject_FormBuilder::create($do); $form = $builder->getForm($_SERVER['REQUEST_URI']); if ($form->validate()) { $res = $form->process(array($builder,'processForm'), false); if ($res) { header('Location: index.php?table='.$table); } echo quot;Something went wrong...<br>quot;; } echo $form->toHtml(); // EOF: details.php
  • 55. Famous last words  To sum-up, aforementioned packages...  ...unify form and data handling  ...make it easy to train new project members  ...speed up application development by at least a factor of three  ...make it easy to create universal application frameworks, where new functionality can easily be plugged in
  • 56. The end  Thank you for your attention!  ANY QUESTIONS ?