Lightweight PHP Web Application Framework

October 30, 2013

TAL on-error attribute

<dl class="definition_design clearfix">
<dt tal:condition="reg_reply">Reg. Status</dt>
<dd tal:condition="reg_reply" 
 tal:on-error="string:No status"   
 tal:content="reg_reply/status"></dd>		
</dl>

Posted by pj at 11:49 AM | Comments (0)

April 15, 2009

Building Application DB Tables with tables.ini and create_database.php

The framework requires that each table in the database has a core set of columns in order to work. Also, there are some rules about how tables should be defined.

  1. Primary and foreign key columns should be set as int(10) and listed at the top.
  2. All columns apart from the primary key should be set as null by default.
  3. Date columns are set as int(20) and dates should be inserted as unix timestamps.
  4. Varchar columns are always set as varchar(255).
  5. Enumerations shouldn't be used with the framework.
  6. Every table should contain an expired_date column which will normally be set to null. If you want to remove a row from view, set the expired_date to a timestamp.

For speed tables for an application can be defined with a couple of framework tools. In each application directory, there is an /sql sub-directory. You will find two files in here, create_database.php and tables.ini.

The script parses the tables.ini file which contains the table definitions in Windows .ini format and prints the SQL necessary to create the tables out to the browser.

N.B. The script does not create the tables, it only generates the SQL to do so. This can then be pasted into PHPMyAdmin.

The tables.ini file looks like this:

[table_list]
panel = 0
panel_group = 0
panel_content = 0
panel_location = 0


; The above defines the tables to be created. The 1 or 0 value is 
; significant. 1 means that a corresponding type table is created and 
; a foreign key column for it is included in the main table.
; 0 means that no type table is created. Also the type table foreign
; key column is dropped after the table is created thus:
; alter table `panel` drop `panel_type_id`;


[panel_location]
panel_location_name = text;

[link_tables]
panel:panel_group = 0
user:panel_group = 0
panel:panel_content = 0
panel_group:panel_content = 0


; If you want to create link tables between others defined herein, you 
; can using the syntax shown above. Table names are separated by a 
; colon.


[panel]
panel_location_id = "int(10)"
panel_name = "varchar(255)"
panel_description = text
ip_address = "varchar(255)"


; Each table has a section which defines extra columns to be included
; above and beyond the default. In the resulting SQL these columns are 
; indented to differenciate them from the defaults:
;
;    drop table if exists `panel`;
;    create table `panel`
;    (
;    `panel_id` int(10) primary key auto_increment not null, 
;    `panel_type_id` int(10) default null, 
;	`panel_location_id` int(10) default null,
;	`panel_name` varchar(255) default null,
;	`panel_description` text default null,
;	`ip_address` varchar(255) default null,
;    `insert_by` int(10) default null,
;    `insert_date` int(20) default null,
;    `update_by` int(10) default null,
;    `update_date` int(20) default null,
;    `expired_date` int(20) default null );
; 
 


[panel_group]
panel_group_name = "varchar(255)"
panel_group_description = text

[panel_content]
panel_id = "int(10)"
panel_group_id = "int(10)"
content_title = text
content_description = text
content_html = text
content_html_url = text
content_stylesheet_url = text
content_image_url = text
content_image_type = "varchar(255)"
content_image_name = text
content_image_size = "int(20)"
content_image_data = longblob
priority "int(1)"
start_date = "int(20)"
end_date = "int(20)"

This generates the following output:



    drop table if exists `panel`;
    create table `panel`
    (
    `panel_id` int(10) primary key auto_increment not null, 
    `panel_type_id` int(10) default null, 
	`panel_location_id` int(10) default null,
	`panel_name` varchar(255) default null,
	`panel_description` text default null,
	`ip_address` varchar(255) default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );



alter table `panel` drop `panel_type_id`;




    drop table if exists `panel_group`;
    create table `panel_group`
    (
    `panel_group_id` int(10) primary key auto_increment not null, 
    `panel_group_type_id` int(10) default null, 
	`panel_group_name` varchar(255) default null,
	`panel_group_description` text default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );



alter table `panel_group` drop `panel_group_type_id`;




    drop table if exists `panel_content`;
    create table `panel_content`
    (
    `panel_content_id` int(10) primary key auto_increment not null, 
    `panel_content_type_id` int(10) default null, 
	`panel_id` int(10) default null,
	`panel_group_id` int(10) default null,
	`content_title` text default null,
	`content_description` text default null,
	`content_html` text default null,
	`content_html_url` text default null,
	`content_stylesheet_url` text default null,
	`content_image_url` text default null,
	`content_image_type` varchar(255) default null,
	`content_image_name` text default null,
	`content_image_size` int(20) default null,
	`content_image_data` longblob default null,
	`priority` int(1) default null,
	`start_date` int(20) default null,
	`end_date` int(20) default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );



alter table `panel_content` drop `panel_content_type_id`;




    drop table if exists `panel_location`;
    create table `panel_location`
    (
    `panel_location_id` int(10) primary key auto_increment not null, 
    `panel_location_type_id` int(10) default null, 
	`panel_location_name` text default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );



alter table `panel_location` drop `panel_location_type_id`;




    drop table if exists `panel_panel_group_link`;   
    create table `panel_panel_group_link`
    (
    `panel_panel_group_link_id` int(10) primary key auto_increment not null,
    `panel_id` int(10) default null,
    `panel_group_id` int(10) default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );


    drop table if exists `user_panel_group_link`;   
    create table `user_panel_group_link`
    (
    `user_panel_group_link_id` int(10) primary key auto_increment not null,
    `user_id` int(10) default null,
    `panel_group_id` int(10) default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );


    drop table if exists `user_panel_link`;   
    create table `user_panel_link`
    (
    `user_panel_link_id` int(10) primary key auto_increment not null,
    `user_id` int(10) default null,
    `panel_id` int(10) default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );


    drop table if exists `panel_panel_content_link`;   
    create table `panel_panel_content_link`
    (
    `panel_panel_content_link_id` int(10) primary key auto_increment not null,
    `panel_id` int(10) default null,
    `panel_content_id` int(10) default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );


    drop table if exists `panel_group_panel_content_link`;   
    create table `panel_group_panel_content_link`
    (
    `panel_group_panel_content_link_id` int(10) primary key auto_increment not null,
    `panel_group_id` int(10) default null,
    `panel_content_id` int(10) default null,
    `insert_by` int(10) default null,
    `insert_date` int(20) default null,
    `update_by` int(10) default null,
    `update_date` int(20) default null,
    `expired_date` int(20) default null );

Note the drop table statement before each creation statement. If you want to change the structure of a table after the fact, ensure you dump the data out before you do otherwise it will be destroyed.

Posted by pj at 11:19 AM | Comments (0)

Using prototype.js For Faster JS Development and AJAX

The prototype.js JavaScript framework is used extensively throughout the framework. Further information can be found on the website:

http://www.prototypejs.org/learn

The single most useful feature is the $('blah') function which replaces document.getElementById('blah').

Posted by pj at 11:04 AM | Comments (0)

April 14, 2009

Using JavaScript Validation For Mandatory Form Elements

When forms are built using the interface_functions.php functions a mandatory red asterisk is added to the markup but hidden in the HTML this can be used to flag mandatory elements and also for validation checking:

<script type="text/javascript">

var els = new Object();

els['start'] = 'Start Time';

els['duration'] = 'Duration';

els['purpose'] = 'Purpose of booking';

els['course_code'] = 'Course Code';

els['booker_name'] = 'Your Name';

els['email1'] = 'Your email address';

function check_mandatory(els){

    var popper = new Array();

    for(i in els){ if($(i).value == ''){ popper.push("<strong>" + els[i] + "</strong>"); $(i).style.border = '1px solid red'; } }
    
    if(popper.length > 0){ poppy("<p>You must provide the following information:</p><ol><li>" + popper.join('</li><li>') + "</li></ol><p>[Click in this box to hide it.]</p>"); return false; }

    else{ return true; }

    }

</script>

Call the function with an onsubmit="" event handler:

<form
    class="content nothing_added"
    style="width: 900px; text-align: left; height: 320px; vertical-align: top; clear: both; display: block;"
    action="booking_details_doozer.php"
    method="post"
    id="booking_details_form"
    onsubmit="return check_mandatory(els)"
    >

To mark the required form elements as mandatory use the following code (make sure your JS is called after all the relevant form elements have been rendered, i.e. at the bottom of the page):


<script type="text/javascript">

for(i in els){ $(i + '_mandatory').style.display = 'inline'; }

</script>

Posted by pj at 02:29 PM | Comments (0)

Populating Select Element Option Lists with option_switcher.php

<select/> form elements that are included with a select or select_noadd directive in a .skini need to be populated with options.

This is achieved via the common_php/option_switcher.php script and the options_switcher() function.

    switch($form){
        
        case 'room_details':

        switch($label){
    
            case 'Location': return get_options(just_sql("select ID as location_id, name from location order by name"), "location_id", "name");
            case 'Bookable?' : return '<option value="1"/> Yes'."\n".'<option value="-1"/> Staff Only';
            case 'Equipment': return get_options(just_sql("select * from equipment where expired_date is null order by name"), "equipment_id", "name");
            case 'Remove from view?' : return '<option value="'.mktime().'" style="color: red;"/> Yes'."\n".'<option value="nulled"/> No';
            
            }
            
        case 'booking_details':

        switch($label){
    
            case 'Start Time': return get_start_times($day);
            
            case 'Duration': return get_durations();
            
            case 'Your email address' : return '<option value="@cumbria.ac.uk" selected="true"/> @cumbria.ac.uk';
            
            }
...........................
    }

You will need to add a case with your .skini file name stump and then a switch / case block for each of the select form elements in the form. These are designated by the label you gave them in the .skini file.

Most of the examples you will come across make use of the get_options(just_sql("select * from blah"), $value, $label) function. This takes a just_sql() function call reply and an argument for the column names in the results which go to populate the option value and label respectively.

Posted by pj at 11:53 AM | Comments (0)

March 31, 2009

Building Forms With interface_functions.php & .skini Files

There are a set of functions for rapidly building web forms to work with the SQL functions. These are found in the common_php/interface_functions.php.

The build_form($form_name, $entity) Function

This is the guts of the interface system and allows you to build web forms quickly and consistently and avoids problems caused by typos in hand coded mark-up.

The function takes a filehandle for a skins/blah.skini file, and a hash to populate the form with values if required. I have avoided doing this however, in favour of using AJAX for populating forms when required instead.

build_form('panel_form');

This will look for and read a file in the skins directory called panel_form.skini and build the form based upon the settings found therein.

The .skini Configuration File Format

These files are in Windows .ini format:


; Each form element should have its own section block.
;
; Sections must be uniquely named as id attributes are assigned 
; based upon them
;
; A 1 means that the section is displayed as a block and 0
; means it is displayed inline. Inline display is trixy and 
; requires extra CSS jiggery pokery more often than not.

[sections]
current_panels = 1
name_section = 1
description_section = 1
location_section = 1
ip_address_section = 1


; For each item under the 'sections' heading there needs to be a 
; separate configuration block.
; 
; The block description should include a label entry (usually label_italic)
; and then the form element included in that section. 


[current_panels]
label_italic = "Edit Existing Panel"
current_panel_id = select_noadd
panel_id = hidden


; If you want to add extra attributes to a form element's tag then 
; you can by defining a section headed as below. This is useful for 
; adding classes, style attributes or JS event handlers:


[current_panel_id]
class = four_c
onchange = "get_panel_details()"

[name_section]
label_italic = "Panel Name"
panel_name = text

[panel_name]
class = four_c

[description_section]
label_italic = "Panel Description"
panel_description = textarea

[panel_description]
class = four_c

[location_section]
label_italic = "Panel Location"
panel_location_id = select_noadd

[panel_location_id]
class = four_c

[ip_address_section]
label_italic = "IP Address"
ip_address = text

[ip_address]
class = four_c

The build_repeating_form($form_name, $entity, $the_count) Function

If you need to build more than one instance of the same form in a single document then you should use this function. This adds the value passed into the third parameter onto the end of all id attributes in the form, separated by an underscore. This is so that we don't duplicate ids.

The get_hour_options() & get_minute_options() Function

To be used along with common_php/option_switcher.php for when you need to choose hours and minutes from <select/> elements.

Posted by pj at 12:51 PM | Comments (0)

Common Header & Footer Includes

All the applications in the framework share the same header and footer with a simple PHP include, although this is not mandatory, but the header sets up all sorts of JavaScripty and CSS goodness required for the framework.

The files are held in the root.

Posted by pj at 11:56 AM | Comments (0)

March 30, 2009

Doing Database "Create Review Update Delete" With Functions In add_update.php

There are a set of functions for abstracting DB CRUD functions in the common_php/add_update_functions.php script.

The add_new_row($table_name) function

This function adds a new row into the table specified, populating only the insert_by and insert_date columns and returning the new primary key value.

The update_table($table_name, $r, $primary_key) Function

This function is for applying updates to individual rows in a table. It is typically used to update a row with the $r / $_REQUEST hash from a form submission. The last argument is the primary key of the row in question, which may have been derived from calling the add_new_row() function.

In the following doozer example code snippet, the same piece of code can be used to either insert a new row or update an existing one depending on whether or not a primary key has been passed in the request:

if(!$r['page_id']){ $r['page_id'] = add_new_row('simple_page'); }

$reply = update_table('simple_page', $r, $r['page_id']);

This function can also be used to delete / expire a row thus:

$reply = update_table('simple_page', array('expired_date' => mktime()), $r['page_id']);

If you want to set a NULL value in a column, for example to undelete / unexpire a row, use:

$reply = update_table('simple_page', array('expired_date' => 'nulled'), $r['page_id']);

This function can also be used to delete / expire a row thus:

$reply = update_table('simple_page', array('expired_date' => mktime()), $r['page_id']);

The update_table_extra($table_name, $r, $where, $primary_key) Function

This function behaves in the same way as the above but allows you to add an extra where clause into the SQL.

$reply = update_table('simple_page', array('expired_date' => mktime()), "page_tags not like '%Public%Document%'", $r['page_id']);

This code expires a particular row in the simple_pages table but only if it hasn't been tagged as a public document.

The date_splitter('publication_date') Function

The interface code returns dates in dd/mm/yyyy format and this needs to be turned into a unix timestamp for storage (date columns should be set as int(20)).

This function takes a date in the $r hash and converts it into a timestamp. The function call is a little unusual in that the function doesn't return anything. So where you have a date in $r['publication_date'] call:

date_spliter('publication_date');
$reply = update_table('my_pages', $r, $page_id);

The call above extracts the date from $r and resets the value with the corresponding timestamp:

function date_splitter($key){

    global $r;

    $b = explode('/', $r[$key]);

    $ts = mktime(0,0,0, $b[1], $b[0], $b[2]);
    
    $r[$key] = $ts;
    
    //print_r($r);
    
    }

The get_options($reply, $value_column, $label_column) Function

This functions more properly belongs in the interface_functions.php file as it is related to form building. Its purpose is to populate <select/> form elements with a list of options.

It takes a reply hash from just_sql() as it's first argument, the second two parameters are the column names you want to map to the value and label of the option respectively. The function can be called like so:

return get_options(just_sql("select * from panel_group where expired_date is null order by panel_group_name"), "panel_group_id", "panel_group_name");

The function is used extensively in option_switcher.php which determines what the option list should be for any <select/> elements in forms generated by build_form($skini_handle).

Posted by pj at 04:05 PM | Comments (0)

Authentication (Login / Logout) & Sessions

Authentication runs of off one table called user and is based upon email address and a password stored as a hash. Once authenticated the user_id from the table is passed around using PHP's $_SESSION variable and relies on cookies.

Sessions are trixy in PHP and you may benefit from referring to the manual - http://uk.php.net/session. You have no real control over the session timeout length for example and currently the user can get unceremoniously dumped out to the login page when the session expires.

The login_doozer.php script handles registration of new users too. This invloves the user being provided with a registration key from the system administrator. If you wish to change your password or have forgotten it, this same mechanism will do the job. Your old row will be expired and a new one created. The system would benefit from an email verification function.

Once you have logged in your user_id from the user table will be used as insert_by and update_by values when doing DB inserts and updates from the system and is encoded in the $user_id variable.

See the login_doozer.php and logout.php scripts in one of the example applications for more details.

For an authenticated script your should include the following lines:

<?
include("paths.inc.php");

session_start();

if(!$_SESSION['user_id']){ header('Location: login.php'); }

$user_id = $_SESSION['user_id'];
................................
?>

Posted by pj at 03:18 PM | Comments (0)

The just_sql() Function & The $reply Hash

The SQL facility for querying the database and getting results back has been abstracted into one function. This presumes that your application has its tables in a single database. If this is not the case you can use the do_sql($db, $sql, $debug) function to specify which db credentials .ini file to use for the query where it is different from the value set in $db_name.

The main function for running a query is just_sql(sprintf("select * from foo where bar = %d", $bar_id)). I tend to use this function in conjunction for sprintf() for extra security.

The $reply Hash

The following code:

$reply = just_sql("select * from equipment where expired_date is null order by update_date desc limit 3");

$rows = $reply['rows'];

header('Content-type: text/plain');

print_r($reply);

produces the following reply hash:

Array
(
    [num_of_rows] => 3
    [rows] => Array
        (
            [0] => Array
                (
                    [equipment_id] => 31
                    [name] => DVD Player
                    [description] => 
                    [insert_by] => 1
                    [insert_date] => 1228746274
                    [update_by] => 1
                    [update_date] => 1228746274
                    [expired_date] => 
                )

            [1] => Array
                (
                    [equipment_id] => 30
                    [name] => Portable Video Conferencing Equipment
                    [description] => 
                    [insert_by] => 1
                    [insert_date] => 1226590805
                    [update_by] => 1
                    [update_date] => 1226590805
                    [expired_date] => 
                )

            [2] => Array
                (
                    [equipment_id] => 29
                    [name] => 7 X PCs
                    [description] => 
                    [insert_by] => 1
                    [insert_date] => 1226327521
                    [update_by] => 1
                    [update_date] => 1226327521
                    [expired_date] => 
                )

        )

    [first_row] => Array
        (
            [equipment_id] => 31
            [name] => DVD Player
            [description] => 
            [insert_by] => 1
            [insert_date] => 1228746274
            [update_by] => 1
            [update_date] => 1228746274
            [expired_date] => 
        )

    [status] => 1
    [message] => OK
    [sql] => select * from equipment where expired_date is null order by update_date desc limit 3
)

N.B. The where clause of the query includes expired_date is null. Every table should have a number of common columns, including an expired_date. This is set with a unix_timestamp() when the row is to be deleted from the DB. In other words, no rows are ever truly deleted, merely expired. You need this test in your where clauses to exclude "deleted" rows.

The result rows are found in $reply['rows'] as a list of hashes. The first row is found in $reply['first_row'] too in case that's all you need. $reply['num_of_rows'] tells you how many rows were returned and the original query SQL is included in $reply['sql'] for easier debugging of dynamic queries.

Posted by pj at 01:52 PM | Comments (0)

The $r / $_REQUEST Shortcut

Each web application built with the framework has its own paths.inc.php file for setting up common variables and paths for the application.

paths.inc.php should be the first include in any application script. One of the roles it performs is to alias the $_REQUEST global variable. A copy of this variable is created and named $r. This is for the sake of pith and saves typing as much as anything else.

$r is used quite extensively in the SQL functions. Elements in application web forms should be named the same as their corresponding DB columns. That way the $_REQUEST/$r hash can then be passed to the SQL functions to do quick and easy inserts and updates such as in the example below for adding a new user:

$userid = add_new_row('user');
        
$r['user_password'] = sha1($r['user_password']);
        
$reply = update_table('user', $r, $userid);

Posted by pj at 12:17 PM | Comments (0)

March 27, 2009

Setting Up Database Connection Credentials With .ini Files

Database credentials are stored in the common_php directory in Windows .ini format files.

[connection_parameters]

user = youruser
password = yourpasswordhere
host = localhost
type = mysql
db = blah

This file should be saved as a .ini file in common_php, and usually with the name of your DB. So for a db named blah, you would name the file blah.ini, and also set $db_name = 'blah'; in your applications paths.inc.php file.

If for extra security you want to name your .ini file something else then that's fine as long as to set $db_name to that.

When the just_sql() function is called it looks for a .ini file named after whatever $db_name is set to, and then parses the contents of that file into a hash to extract the connection credentials and open up a connection before performing the SQL transaction.

The .ini files are protected from view from the webserver using a .htaccess file:

<Files *.ini>
order deny,allow
deny from all
</Files>

Posted by pj at 05:22 PM | Comments (0)

Setting Environment Paths With paths.inc.php

Paths for each individual application are set withing the application directory itself in a file called paths.inc.php.

<?php

$r = $_REQUEST;

global $debug;

$paths = array();

if(file_exists("H:\\xampp\\htdocs\\")){ $docroot = "H:\\xampp\\htdocs\\"; }
if(file_exists("/Applications/xampp/htdocs/")){ $docroot = "/Applications/xampp/htdocs/"; }
if(file_exists("/userdata/home/depts/lis/")){ $docroot ="/userdata/home/depts/lis/"; }

$paths["host"] = $_SERVER["HTTP_HOST"];

$paths["baseref"] = "http://".$paths["host"]."/lis/simple_pages/";

$paths["js"] = "http://".$paths["host"]."/lis/js/";

$paths["js_path"] = $docroot."js/";

$paths["images"] = "http://".$paths["host"]."/lis/images/";

$paths["docroot"] = $docroot;

$config['BaseAddress'] = $paths['baseref'];

$asterix = '<span class="mandatory" style="color: red;">*</span>';

$db_name = 'libfaq';

$user_id = 1;

?>

This should be the first include in any application script:

<?

include("paths.inc.php");

session_start();

if(!$_SESSION['user_id']){ header('Location: login.php'); }

header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past

# Turn off warnings

error_reporting(E_ERROR | E_PARSE);

$debug = false;

$title = "LIS Simple Pages Site - Table of Contents";
.........

The script does several things. Firstly, it creates the $paths hash. Secondly, it aliases $_REQUEST to $r. N.B. If your name any other variable $r things will go bady for you. $r can be used with the add / update functions to add and update rows in a table where the column names match the web form elements.

$booking_id = add_new_row('booking);

$reply = update_table('booking', $r, $booking_id);

The $db_name filehandle is also set here (as opposed to in db_name.inc.php as previously). This refers to the .ini file name stump where your DB settings and credentials are stored. This is usually named after the database itself, but doesn't have to be.

Note also that a default $user_id is set here too. This is important for the add / update functions to work in applications where no user_id is set in the session. Normally this is picked up from the session after login and is the user_id from the user table, in which case this value gets overwritten.

Posted by pj at 11:34 AM | Comments (0)

March 23, 2009

The common_php directory

The common_php directory contains a number of common function files that need to be included in each script in any application. It includes PHP files with one or more functions related either to the application framework or to individual web applications.

add_update_functions.php
book_request_functions.php
calendar.php
calendar_style.css
check_url.php
cip_functions.php
convert_line_breaks.php
date_parser.php
db_name.inc.php
do_sql.php
email_functions.php
has_value.php
interface_functions.php
is_even.php
kpi_functions.php
libfaq.ini
option_switcher.php
quote_me.php
read_config.php
read_file.php
round_me.php
target_use_attributes.php
upload_file.php
user_functions.php
Framework Specific Files

Posted by pj at 04:43 PM | Comments (0)

File Structure of the Framework

The file structure for the framework is quite shallow. The root includes the following files and folders:

common_php/
js/
skins/
upload_temp/
header.php
footer.php

Posted by pj at 03:54 PM | Comments (0)

Lightweight PHP Web Application Framework - Contents

File Structure of the Framework

Function Include Files in common_php

Setting Environment Paths With paths.inc.php

Setting Up Database Connection Credentials With .ini Files

The $r / $_REQUEST Shortcut

The just_sql() Function & The $reply Hash

Authentication (Login / Logout) & Sessions

Doing Database "Create Review Update Delete" With Functions In add_update.php

Common Header & Footer Includes

Building Forms With interface_functions.php & .skini Files

Populating select Element Option Lists with option_switcher.php

Using the poppy() JavaScript Function For Application Alerting

Using JavaScript Validation For Mandatory Form Elements

Using prototype.js For Faster JS Development and AJAX

Building Application DB Tables with tables.ini and create_database.php

Posted by pj at 03:41 PM | Comments (0)