OO Form Framework Seeks Assistance (Open Source)

Looking for volunteers to join your project? Need help with a script but can't afford to pay? Want to offer your services as a volunteer to build up your portfolio? This is the place for you...

Moderator: General Moderators

Post Reply
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

OO Form Framework Seeks Assistance (Open Source)

Post by Ollie Saunders »

I've been working on this package (strictly PHP 5) for generating/validating web forms its currently called 'OsisForms' after my company name.

Areas Requiring Assistance
  • Feature Suggestion / Critique
    Anyone with enough experience to, understand the common difficulties PHP form developers can face. The ability to know which problems deserve to be solved and suggest better ways of doing things.
  • OO Design esp. Pattern Integration
    Someone with experience writing OO code and making use of design patterns who can guide on how to best tackle the design issues I am facing as the package grows and assist with some of the more important design/functionality decisions.
  • Testing esp. Unit Testing
    I am interested in anybody who can either advice on how to go about Unit Testing a package or is interested in actually doing it themselves.
  • Documentation
    Someone to create documentation :)
In the end, if you can write good PHP 5 code and communicate effectively I am interested in hearing from you. You may work as much or as little as you like and will be contributing to the Open Source / PHP Community! This is also a great opportunity to improve your skills as a PHP software developer.

If you are not interested but know someone who that may be, please make them aware of this project, Thanks.
If you are interested PM me!


My Aspiration

My primary reason for beginning work on OsisForms was the simple fact that I couldn't find a good, freely available, package for generating / validating web forms. It is a task that all of us do, some of us do it a lot and yet everything I managed to find for this task was either overly complex, not object oriented, not easily extended, or poorly documented.

My aspirations for OsisForms are as follows:
  • Fill the gap in the market and create something of high quality that thousands of developers could benefit from.
  • Make more complex, user-friendly forms programmer friendly too and improve the quality of the average form found on the web for the benefit of all web users.
  • Get Zend other companies interested and become famous!
What is ole's idea of high quality then?

Excellent question. The final version of OsisForms hopes to fulfill all my desires:
  • Remove the repetition
    This is an obvious one that anyone who has written any amount of procedural web form code will know all too well. Lots of the idiosyncrasies of HTML, user agents and the sheer number of tiny decisions that have to be made can make the process of creating forms really dull and repetitive. Often that little extra bit of quality or flexibility gets left behind because we just can't be bothered.
  • Insulate the programmer from HTML and by doing so guarantee standards compliant, CSS-friendly, flexible output
    Imagine how useful it would be to some development houses to be able to refer their junior staff (who may not know or a have a poor knowledge of HTML) to OsisForms safe in the knowledge that only really nice XHTML output will come out.
  • Provide an accompanying CSS and JavaScript library
    This is really just an extension of the last point. Obviously it is not possible to insultate the developer from CSS because they are obviously going to want to tweak so here we provide modular and well documented standard library that makes things look acceptable to the widest possible audience and allow it to be tweaked however desired. A standard JS library also greatly increases the level of usability OsisForms is able to provide and its possible applications and once again we can ensure a very high minimum standard of JavaScript.
  • Make it rich enough for web applications
    There are two parts to this. One is that is must be possible for OsisForms to fit into the MVC pattern and the second that it provides a rich enough feature pallet to cover at least 80% of all possible scenarios.
  • Keep it simple
    I don't want OsisForms to overstep its scope boundaries, it is supposed to make producing web forms easier and more fun. One very important decision I have made is that OsisForms will not do the validation for you. Validation == logic and logic can be used to express/model any behaviour. Attempting to replace logic with "ValidationRules" and "ConditionalValidationRules" is not where I want to go. Instead OsisForms provides everything to make validation logic simpler and more readable by
    • Handling all repopulation
    • Providing predefined extendible classes for testing and filtering data
    • Providing a simple but powerful mechanism for informing users of errors and checking end validity
    Most of this is already in completed.
  • Encourage security awareness
    Security conscious developers will make fewer security critical mistakes by using OsisForms. Developers unaware of security issues will be forced to confront their ignorance. Of course code using OsisForms does not guarantee code security it just makes it easier to obtain and harder to ignore.
I'm thinking of also of features for creating fields/forms directly from database structure (via interrogation) or XML.

Existing Features

Currently OsisForms is about 40% complete. All the major groundwork is in place and it is already capable of generating/validating medium complexity forms. I have implemented 34 classes in all (some of them quite small).

The OsisForm's Class Hierarchy
Image
Some of the names need changing so that the major object appears first and the hierarchy structure itself is undergoing work

The remainder of this post shows examples of some of the things that can be already be achieved with OsisForms:

Simplest Possible Form

Code: Select all

require 'OF_Autoload.php';

$f = new OF_Form('f');
{
    $txtName = new OF_SmallText('txtName', 'Name');
    $butSubmit = new OF_Button('butSubmit', 'Submit');
    $f->addEntities($txtName, $butSubmit);
}
if ($f->submitted()) {
    print_r($f->getInput());
}
echo $f->render();
Getting information about a person

Code: Select all

require_once 'OF.php';
OF::setCharacterEncoding('UTF-8');
/* BEGIN: This is the contents of OF_Autoload.php */
function __autoload($class) {
	if (OF::isDecendentClass($class)) {
		OF::loadClass($class);
	} else {
		// any existing autoload code you had
	}
}
/* END */

$f = new OF_Form('f');
{
    $fsPersonal = new OF_Fieldset('fsPersonal', 'Personal');
    {
        $txtFirstName = new OF_SmallText('txtFirstName', 'First name');
        $txtFirstName->addFilter('getAlpha');
        $txtSurname = new OF_SmallText('txtSurname', 'Surname');
        $txtSurname->addFilter('getAlpha');

        $dateDob = new OF_DateTime('dateDob', 'Date of Birth');

        $fsPersonal->addEntities($txtFirstName, $txtSurname, $dateDob);
        $fsPersonal->set('width', 10); // set width attrib on everything in fsPersonal
    }

    $butSubmit = new OF_Button('butSubmit', 'Submit', OF_Button::TYPE_SUBMIT);

    $f->addEntities($fsPersonal, $butSubmit);
}

if ($f->submitted()) {
    // validation
    if ($txtFirstName->isEqualTo('Fred')) {
        $txtFirstName->addError('I told you, you\'re barred!');
    }
    $input[] = $dateDob->getInputAsIso();
    $input[] = $txtSurname->getInput();

    if (!$f->getNumErrors()) {
        // insert into db and redirect away
        echo 'No errors!';
    }
}
echo $f->render();
if (isset($input)) print_r($input);
With a bit of CSS, you get:
Image
Here's the code:

Code: Select all

<form method="post" action="." class="entity" id="f"><fieldset class="entity" id="fsPersonal"><legend>Personal</legend><div class="field"><ul class="valerror"><li>I told you, you're barred!</li></ul><label for="txtFirstName">First name</label><input type="text" size="10" id="txtFirstName" name="txtFirstName" class="entity" value="Fred" /></div><div class="field"><label for="txtSurname">Surname</label><input type="text" size="10" id="txtSurname" name="txtSurname" class="entity" value="2433Bloggs" /></div><div class="field"><label for="dateDob">Date of Birth</label><div id="dateDob" class="datetime"><input type="text" id="dateDob1" name="dateDob1" maxlength="4" size="3" title="4-digit Year" onfocus="this.select()" value="1986" /> - <select name="dateDob2" id="dateDob2" title="Month of Year"><option value="0">&nbsp;</option><option value="1">January</option><option value="2" selected="selected">February</option><option value="3">March</option><option value="4">April</option><option value="5">May</option><option value="6">June</option><option value="7">July</option><option value="8">August</option><option value="9">September</option><option value="10">October</option><option value="11">November</option><option value="12">December</option></select> - <input type="text" id="dateDob4" name="dateDob4" maxlength="2" size="1" title="Day of Month (0-31)" onfocus="this.select()" value="1" /></div></div></fieldset><div class="button"><button type="submit" id="butSubmit" class="entity" name="butSubmit" value="1">Submit</button><input type="hidden" name="hid_butSubmit" value="1" /></div></form>Array
(
    [0] => 1986-02-01 00:00:00
    [1] => Bloggs
)
The array object

Code: Select all

require 'OF_Autoload.php';

$f = new OF_Form('f');
{
    $txt = new OF_SmallText('txt');            // normal field
    $txt->width = 10;

    $arrayTxt = new OF_Array('arrayTxt');      // an array
    // appends the array with 9 cloned instances of $txt
    $arrayTxt->populate($txt, 9);

    // OF_Arrays are strongly typed, they can only stored one kind of
    // field. The field type they store is determined by the first field entered
    // into the array. So this next command will throw an exception because it is
    // not a SmallText
    try {
        $arrayTxt->populate(new OF_Button('button'), 1);
    } catch (OF_Exception $e) {
        // ignore
    }

    // OF_Array implements ArrayAccess, Iterator and Countable so you can
    // do this:
    $arrayTxt[] = $txt;
    $arrayTxt[5]->width = 20;
    unset($arrayTxt[4]);
    $arrayTxtLen = count($arrayTxt);

    $butSubmit = new OF_Button('butSubmit', 'submit');
    $f->addEntities($arrayTxt, $butSubmit);
}
$f->submitted();
echo $f->render();

if ($f->submitted()) {
    // Once the array has been checked for submission you can get information out
    // of it:
    echo 'Num true:' . $arrayTxt->getNumTrue() . ' of ' . $arrayTxtLen . '<br />';
    echo 'Num false:'. $arrayTxt->getNumFalse() . ' of  ' . $arrayTxtLen . '<br /><br />';
    echo 'Input: ' . print_r($arrayTxt->getInput());
}
Finally, DB insertion. getInputDb() does all the quoting, escaping and cleaning for you

Code: Select all

if (!$f->getNumErrors()) {
    $db->createReport($f->getInputDb());
}
class DB
{
    public function createReport(OF_StdInputDb $f) {
        $q = "
           INSERT INTO `Report` (
               `title`,
               `description`,
               `guestPassword`,
               `isComparative`
           ) VALUES (
               {$f->fsIdentity->txtTitle},
               {$f->fsIdentity->txtDescription},
               {$f->fsSecurity->txtGuestPass},
               {$f->fsIdentity->selComparative}
           )";
           ...
Last edited by Ollie Saunders on Thu Aug 17, 2006 11:56 am, edited 2 times in total.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

^^ big update
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

I'd be interested in helping with this. PM me plz.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Post by Ollie Saunders »

Here's my latest list of things to do. I'm one busy boy.
Bold is what I'm doing this week. Green is for big stuff that comes later.
  • Unit tests everything written so far (done 206 at time of this post)
  • Officially define the scope of this project
  • OF_FieldsetCollapsible
  • OF_Tabular (a container that uses HTML tables for adjacent fields and fields matrixes etc.)

    Code: Select all

    <TR>
    +------------------------------------+
    |<TD>              <TD>              |
    |+-----------------+----------------+|
    || First |xxxxxxx| | Sur |xxxxxxxx| ||
    |+-----------------+----------------+|
    +------------------------------------+
  • Get hosted on sourceforge with subversion respository
  • Unicode UTF-8 support!
  • JS MaxLength for OF_TextLarge
  • OF_SelectMulti
  • Completely new types of field utilizing some more advanced client side scripting (OF_ColorSelect is one idea)
  • Search and fix all the @todos, many of them require consideration
  • Hover help on labels. Possibilty something like this:

    Code: Select all

    $field->label = new OF_Label($label, $hoverHelp);
  • OF_FileUpload
  • setFocus()
  • Already got internal events (onSubmit, onValid and onInvalid) but these are just simple assignments at the moment. I'd like proper event bubbling, multiple handlers per event with bind() unbind() that kind of stuff.
  • CAPTCHA (gd)
  • XForms output?
  • XML form definitions:

    Code: Select all

    <form source="$_POST" id="form">
        <fieldset label="Order Food" id="order">
            <smallText id="txtNumHams" label="How many hams would you like?"
                       size="4" maxlength="4" filter="int" class="text_field" />
            <check id="chkExtraSpam" label="Extra Spammy?" output="true" />
            <button type="submit" id="butSub" label="Submit" />
        </fieldset>
    </form>
  • Instant forms from table definitions (once PDO is done)
  • Support for PDO (very nice database abstraction). Will retain direct support for MySQL via Mysqli.
  • JS framework (mainly abstracting variances in browser JS Implementations. I've got a book to help with this)
    • Events
    • AJAX
    • Detection
    • More later
  • Complete set of tutorials
  • User Documentation
  • CSS
    • Baseline CSS
    • Complete style sheets
Ninja is on board now. He's helping me work out what other features OsisForms should have. Thanks Ninja!
I can't stress how cool this is going to be, so get involved already!
Post Reply