Location: PHPKode > projects > Porque - PHP object automation > porque-0.1.3/docsrc/porque.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- -*- DocBook -*- -->
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
		  "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<book>
  <title>Porque</title>
  <bookinfo>
    <author>
      <firstname>Ben</firstname>
      <surname>Peter</surname>
      <email>hide@address.com</email>
    </author>
  </bookinfo>
  <chapter>
    <title>What Porque is</title>
    <para>Porque is an automation engine for rapid development of typical PHP web applications. From an xml-defined data schema, it creates a database schema for use with MySQL 3.23.x and a set of PHP classes for use with PHP 4.2.1 and above.</para>
    <para>Porque is different from other engines of the kind, like phpGem: it does not create a ready-made web application which is hard to customize, but an API. This API includes<itemizedlist>
        <listitem>
          <para>Getters and setters for the attributes of your classes.</para>
        </listitem>
        <listitem>
          <para>Database persistence functions (load(), save()), which transparently load an object from the database and save it back (or create a new one, if it is not there).</para>
        </listitem>
        <listitem>
          <para>HTML Templating which allows you to present the data of your objects in any way you want.</para>
        </listitem>
      </itemizedlist>
    </para>
    <para>Porque features a lot of different types for your data (pk-auto, int, string, date, time, datetime, flag, 1:n references, n:m references) and handles these types consistently both with the database persistence functions and with the HTML templates. Once you have your schema defined, everything is ready and in place to add the semantics of your application.</para>
    <section>
      <title>A quick example</title>
      <para>
        <indexterm>
          <primary>Examples</primary>
          <secondary>XML-definition</secondary>
        </indexterm>
			   To give you a quick idea of what porque does, here is a quick example of input and output of porque, how to use it, and what you can do with it.</para>
      <section>
        <title>Input</title>
        <example>
          <title>The XML input file</title>
          <programlisting><![CDATA[<db name="porque">
	   <table name="product">
	    <column name="id" type="pk-auto"/>
	    <column name="title" type="string" precision="60"/>
	    <column name="description" type="string" precision="6000"/>
	    <column name="type" type="ref" ref="product_group" visibility="both" rightname="products"/>
	   </table>

	   <table name="product_group">
	    <column name="id" type="pk-auto"/>
	    <column name="name" type="string" precision="100"/>
	    <column name="managers" type="refmn" ref="person" visibility="both" rightname="product_groups"/>
	   </table>

	   <table name="person">
	    <column name="id" type="pk-auto"/>
	    <column name="name" type="string" precision="20"/>
	    <column name="birthday" type="date"/>
	    <column name="contract" type="flag"/>
	   </table>
   </db>
   ]]></programlisting>
        </example>
      </section>
      <section>
        <title>Output</title>
        <para>This will create the following files:

			   <variablelist>
            <varlistentry>
              <term>tables.sql</term>
              <listitem>
                <para>
							   This file contains the SQL schema definition. You can pipe these SQL statements 
							   to MySQL and your schema will be created. There will be a table for each of the
							   <literal><![CDATA[<table>]]></literal> elements in the input file, as well as a table that tracks the 
							   m:n relation between product groups and managers.
						   </para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>base_product.class.inc, base_product_group.class.inc, base_person.class.inc</term>
              <listitem>
                <para>These classes implement the object management logic, the database persistence functions, and the functions used for HTML Form templating.</para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>product.class.inc, product_group.class.inc, person.class.inc</term>
              <listitem>
                <para>These classes extend the classes metioned above and are otherwise empty - they are for you to change, as they will not be overwritten when you change the XML definition file and recreate everything.</para>
              </listitem>
            </varlistentry>
            <varlistentry>
              <term>product_form_template.tpl, product_group_form_template.tpl, person_form_template.tpl</term>
              <listitem>
                <para>Form templates for each class. These are automatically generated examples and can be used as a starting point.</para>
              </listitem>
            </varlistentry>
          </variablelist>
        </para>
      </section>
      <section>
        <title>How to use the output</title>
        <para>The following example shows how to create a very simple page for editing entry data,
	   as well as creating new entries.</para>
        <example>
          <title>Creating a bare-bone screen for editing persons</title>
          <programlisting><![CDATA[
       <?
       include_once('output/person.class.inc');

   (1) $persons = person::load_all();
       if (count($persons)) foreach($persons as $person) {
	   echo "<a href=\"./personform.php?id=".$person->get_id()."\">";
	   echo htmlentities($person->get_name())."</a><br>";
       }
       echo "<a href=\"./personform.php\">New entry</a><br><hr>";

   (2) $u = new person($_GET['id']);

       echo "Editing " . ($_GET['id'] ? htmlentities($u->get_name()) : 'New entry').'<br><hr>';

       if (array_key_exists('submit', $_POST)) {	
   (3)	$errors = $u->takein_values($_POST);
	   if ( !(is_array($errors) && count($errors))) {		
   (4) 		$u->save();
	   }
       }

       $u->show_html_form($errors, './personform.php');
       ?>      
	   ]]></programlisting>
          <para>This will give you the following html page:</para>
          <graphic fileref="images/personform-empty.gif" format="GIF"/>
          <para>(1) Each generated class has a static function <methodname>load_all($clause='')</methodname>, which loads an array list of objects of that class and returns it. The optional <literal>$clause</literal> parameter can contain SQL that is added after the <computeroutput>SELECT [columnlist] FROM [tablelist]</computeroutput> part of the query.</para>
          <para>The ensuing lines loop through the list and print a line for each person already in the 
	     table, creating a link that is passing the person's id as the <literal>GET</literal> parameter 
	     <literal>id</literal>.
	     </para>
          <para>
	     (2) If an id is passed to the constructor of a porque-generated class, the object will be
	     loaded from the database before the constructor returns. Otherwise, an empty object is created.
	     </para>
          <para>
	     (3) The <methodname>takein_values()</methodname> function scans the data in the 
	     <literal>POST</literal> parameters and propagates the data to the object.
	     </para>
          <para>
	     (4) The <methodname>save()</methodname> function will save an existing object or create a new
	     object, depending on whether the classes primary key property is set or no. 
	     </para>
        </example>
      </section>
    </section>
  </chapter>
  <chapter>
    <title>Planned features and bugfixes</title>
    <para>There are obviously still a lot of things to do. Here is a list of what porque <emphasis>might</emphasis> be able to do in the future. 
 </para>
    <section>
      <title>Short-term TODO list</title>
      <section>
        <title>Release 0.1.1</title>
        <itemizedlist>
          <listitem>
            <para>
Make <quote>passthrough</quote> the default display style for primary keys. (done)
</para>
          </listitem>
          <listitem>
            <para>Add display parameters for all common html attributes to the various types' <methodname>porque_html_form_value_in_&lt;type&gt;()</methodname> functions. (done)
</para>
          </listitem>
          <listitem>
            <para>Add dropdown display options to datetime and time (already standard in date) types. (done)
</para>
          </listitem>
          <listitem>
            <para>Fix display bug in <methodname>porque_html_form_value_in_refmn()</methodname> (creates database error if the current object is a new one, i.e. has the primary key column unset.) (done)
</para>
          </listitem>
          <listitem>
            <para>Add standard checks for <methodname>porque_html_form_value_out_&lt;type&gt;()</methodname> functions. 
</para>
<para>Done, or rather: won't be done - would create a lot of overhead and I cannot clearly see how this should best be done. I'll need to be working with this a bit longer to make a decision.
</para>
          </listitem>
          <listitem>
            <para>Place <methodname>porque_checkpoint()</methodname> in <methodname>porque_html_form_value_out_&lt;type&gt;()</methodname> functions so that the check is made on the <emphasis>final</emphasis> value, not on the <literal>$_POST</literal> input. (done)
</para>
          </listitem>
          <listitem>
            <para>Implement <literal>method:</literal> checks. (done)
</para>
          </listitem>
          <listitem>
            <para>Change <methodname>porque_html_form_value_out_&lt;type&gt;()</methodname> functions to accept the source array (e.g. <literal>$_POST</literal>) as a parameter and display the values from there, if available. (done)
</para>
            <para>As it is now, if a check fails, the erroneously entered data does not show, but the previous value, as <methodname>porque_html_form_value_in_&lt;type&gt;()</methodname> will not propagate the faulty input to the object.
</para>
          </listitem>
<listitem>
<para>
Add parameters to date, time, and datetime types for putting separators between the dropdowns and between date and time selector in datetime. (done)
</para>
</listitem>
        </itemizedlist>
      </section>
    </section>
    <section>
      <title>Planned features</title>
      <variablelist>
        <varlistentry>
          <term>XML attributes propagation for columns and tables.</term>
          <listitem>
            <para>Add a variable <varname>$attributes</varname> to the table class and a variable <varname>$_&lt;columnname&gt;_attributes</varname> for each column which hold the attributes as given in the XML definition file. This will allow for any extra parameters that you might need to pass through to the live object.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>Object history tracking</term>
          <listitem>
            <para>Automatic creation of tables where every change in an object is tracked, so that later it is possible to see how an object came to a certain state and what the states were at other times.</para>
          </listitem>
        </varlistentry>
        <varlistentry>
          <term>Object comparison</term>
          <listitem>
            <para>A function for the generated classes which allow comparing the current object with another of the same class, generating a sort of<quote>diff</quote>.</para>
          </listitem>
        </varlistentry>
      </variablelist>
    </section>
  </chapter>
</book>
Return current item: Porque - PHP object automation