PHP Classes

File: result.inc

Recommend this page to a friend!
  Classes of Jesse Estevez   Result Class - Rule-based system for processing data tied to a DB result id.   result.inc   Download  
File: result.inc
Role: ???
Content type: text/plain
Description: Source Code ( lots of comments )
Class: Result Class - Rule-based system for processing data tied to a DB result id.
Author: By
Last change:
Date: 22 years ago
Size: 14,772 bytes
 

Contents

Class file image Download
<? /*******************************************************************/ class result { /*=================================================================== CLASS SUMMARY Class Name: result Author: jestevez Created on: 5/22/00 4:09 PM Last Change: 6/15/00 9:33 PM Version: 0.1 This is a beta. For complete documentation, please see the Result Class User Guide. Things you need to change... (1) Property: $path_to_templates (2) Constructor: result() (3) Method: parse_rule_element() You can find them by looking for CHANGE in the code below. ===================================================================*/ // PROPERTIES // CHANGE (1) // You must set the value below to the path to your result templates. The path must end with '/'. var $path_to_templates = ''; // String. The path to your result class templates. var $result_id = FALSE; // Boolean A db result id passed to the contructor. var $debug = FALSE; // Boolean If TRUE, messages will output to screen. var $num_rows = 0; // Integer Number of returned DB as referenced by result id. var $offset = 0; // Integer The default offset. var $all_rules = array (); // Array Holds all rules. var $html_buffer = ''; // String Buffers HTML for return. var $dominant_rule = ''; // String Which ever rule correctly specifies the num_rows. /*=================================================================*/ // CONSTRUCTOR function result ( $result_id ) // Use the result_id to get the number of rows. // If the result_id isn't set or is false, kick an error. // 5/28/00 10:31 AM by Pippen { if ( $result_id ) { $this->result_id = $result_id; // CHANGE (2) // Change the line below one that works with your database! // The line should return the number of rows associated with the passed $result_id. $this->num_rows = db_numrows ( $this->result_id ); return ( TRUE ); } // You might want to set an error here: set_error ( DB_ERROR, 'Result class passed a result_id that was not valid.' ); } /*=================================================================*/ // METHODS /*-----------------------------------------------------------------*/ function set_result_rule ( $rule ) // 6/6/00 9:13 AM by jestevez // Take the rule and see if it specifies a test. // If it does, run the test and return false if the test is not passed. // Otherwise, add the control. // The return value is not significant to the class, but may // be useful to the programmer. { // Check to see if the input is an array: assert_array ( $rule ); $is_test = in_array ( 'test', array_keys ( $rule ) ); $test_OK = $rule['test']; if ( $is_test and ! $test_OK ) { return ( FALSE ); } $name = $rule['name']; $this->all_rules[$name] = $rule; return ( TRUE ); } /*-----------------------------------------------------------------*/ function unset_result_rule ( $rule_name, $test = 1 ) // 6/6/00 9:13 AM by jestevez // If the test passes, delete the rule. // The default test always passes. // The return value is not significant to the class, but may // be useful to the programmer. { if ( ! $test ) { return ( FALSE ); } unset ( $this->all_rules[$rule_name] ); return ( TRUE ); } /*-----------------------------------------------------------------*/ function get_result_html ( ) // Find a rule that applies to the number of rows returned. // Apply that rule. { $num_rows = $this->num_rows; $this->debug ( "Num rows is $num_rows." ); foreach ( $this->all_rules as $rule_name => $rule_value ) { $max = (int) $rule_value['max']; $min = (int) $rule_value['min']; $redirect = (string) $rule_value['redirect']; if ( $min <= $num_rows and $num_rows <= $max ) { // If we are inside this clause it is because we found a rule that // applies to the number of results returned by result_id passed to the class. // Some rules ask us to redirect. if ( $redirect ) { // This will not work if any output has already been sent to the browser. header ( "Location: $redirect" ); exit; } $this->dominant_rule = $rule_value; $this->apply_dominant_rule ( ); break; // ... because only one rule should be used. } } return ( $this->html_buffer ); } /*-----------------------------------------------------------------*/ function include_template ( $template ) // In order to include elements, we need to first include their parent template. // If we can't include the parent template, we're in trouble, so kick errors. // 5/26/00 2:30 PM by jestevez { // IMPORTANT: Change the line below to point make sure it points to your template. $template_path = $this->path_to_templates . $template . '.tpl'; if ( ! is_readable ( $template_path ) ) { $this->debug ( "Error trying to use template $template_path" ); // Put in code to log error? return ( FALSE ); } include ( $template_path ); $this->debug ( "Template '$template' is OK" ); return ( TRUE ); } /*-----------------------------------------------------------------*/ function debug ( $message ) // If debugging is on, output a debugging message. // 5/26/00 4:56 PM by jestevez { if ( $this->debug ) { print ("<BR><B>Result Class Debugging:</B> $message."); } } /*-----------------------------------------------------------------*/ function parse_rule_element ( $element, $arguments, $type = '' ) /*-------------- NOTE: This function is recursive in 2 ways. i. It keeps calling itself until the $element passed is not an array. ii. If the element passed needs data from the DB, the function gets that data, adds it to the $arguments, and calls itself again. 5/26/00 2:51 PM by jestevez --------------*/ { if ( is_string ( $type ) AND $type == 'data' ) { // This element expects data from the database. // Loop through the data from the db, merge it with any rule specified $arguments. // For each row, send the element back to this function, // but this time, set type to 0 so no data is fetched from db. // But before we actually loop through the data, lets put up // control the widgets that let the user 'page' through results from a query. $this->prepare_scroll_controls (); $offset = $this->offset; $last = $this->last; $this->generate_scroll_controls (); $this->debug ( "Offset is $offset." ); $this->debug ( "Last is $last." ); for ($i = $offset; $i < $last; $i++ ) { // CHANGE (3) // Change the call to db_fetch_array to one that // returns an assoc array of col names and values of the row $i of your db result! $row = db_fetch_array($this->result_id, $i, PGSQL_ASSOC ); $element_arguments = array_merge ( (array) $arguments, (array) $row ); $this->parse_rule_element ( $element, $element_arguments, '' ); unset ( $element_arguments ); } // unset ( $type ); return ( TRUE ); } // If we've gotten this far then $arguments has any data needed from DB. // We are now free to go ahead and process the element. if ( is_array ( $element ) ) { foreach ( $element as $this_element ) { $this->parse_rule_element ( $this_element, $arguments, $type ); } return ( TRUE ); } // If we have gotten this far, then $element has complete $arguments // and is not an array. We can now include the element. // To include an element we need to know which template it is in, // so get the template name and then include the element. // Some elements might specify a template. // If they do, they are of form "template.element". // If that is the case, then break the element apart into $template and $element. // If that isn't the case, use the template set by the dominant rule. if ( strstr ( $element, '.' ) ) { list ( $template, $element ) = explode ( '.', $element ); } else { $template = $this->dominant_rule['template']; } $fully_specified_element = $template . '_' . $element; // If the function isn't defined, we need to include the template for it. if ( ! function_exists ( $fully_specified_element ) ) { // The rule format depends on functions in the rule template. // So, we have to try to include the template. // If we can't, we have a problem. if ( ! $this->include_template ( $template ) ) { return ( FALSE ); } } $this->include_element ( $fully_specified_element, $arguments ); return ( TRUE ); } /*-----------------------------------------------------------------*/ function include_element ( $fully_specified_element, $arguments ) /*-------------------------------- 6/13/00 4:05 PM by jestevez Execute a template function ( a $fully_specified_element ) and send any returned values to HTML buffer. Arguments includes any info from the database and any explicit arguments specified by a rule. All content comes through this function. --------------------------------*/ { if ( function_exists ( $fully_specified_element ) ) { $this->debug ( "Including element $fully_specified_element."); $this->html_buffer .= $fully_specified_element ( $arguments ); return ( TRUE ); } $this->debug ( "Element $fully_specified_element does not exist." ); // Put in code to log error? return ( FALSE ); } /*-----------------------------------------------------------------*/ function apply_dominant_rule ( ) // Use the dominant rule to return HTML. // 5/22/00 4:09 PM by psuda { $rule = (array) $this->dominant_rule; $name = (string) $rule['name']; $template = (string) $rule['template']; $format = $rule['format']; $arguments = $rule['arguments']; $this->debug ( "Applying rule \"$name\"" ); // The rule format specifies which functions of the template to use. // Take the format elements one at a time and parse them. // This is where they have a chance to generate output, talk to database, etc... foreach ( $format as $type => $element ) { $this->parse_rule_element ( $element, $arguments, $type ); } } /*-----------------------------------------------------------------*/ function generate_scroll_controls ( ) // This function produces links "Next" and "Prev" // which let the user "scroll" through a set of results. // 6/7/00 12:04 PM by jestevez { $offset = $this->offset; $num_rows = $this->num_rows; $rule = $this->dominant_rule; $scroll_args = $rule['scroll_args']; $limit = $this->limit; // If there is no limit, we don't need no stinkin' scroll controls. if ( ! $limit ) { return ( TRUE ); } // If the total number of rows is less than the limit, we don't need no stinkin' controls. if ( $num_rows < $limit ) { return ( TRUE ); } // Scroll arguments will be appended to the "next" and "prev" links. // Passing the query is too dangerous, so we pass along variables that the page will use // to reassemble the query. Collectively we call these the 'scroll args'. // Not all pages will have scroll arguments, so only build them if there are some. if ( count ( $scroll_args ) ) { foreach ( $scroll_args as $name ) { // We only grab values from global scope, // because all url values get dumped to global scope anyway. global $$name; $value = $$name; $buffer[] = $name . '=' . urlencode ( $value ); } $scroll_args = implode ( '&', $buffer ); } // Build "Next" link. if ( $offset + $limit < $num_rows ) { // If we don't get here, there are no more results to show, so no link. $next_offset = $offset + $limit; $next_link = '[' . html_a ( "?offset=$next_offset&$scroll_args", 'Next' ) . ']'; } // Build "Prev" link. if ( $offset - $limit > -1 ) { // If we don't get here, there are no results in front of the current results, so no link. $prev_offset = $offset - $limit; $prev_link = '[' . html_a ( "?offset=$prev_offset&$scroll_args", 'Prev' ) . ']'; } // Figure out the current rows being displayed. $first = (string) $offset + 1; $last = (string) $offset + $limit; // Adjust $last to handle the "end" exception. if ( $last > $num_rows ) { $last = $num_rows; } // Handle the case where first = last. if ( $first == $last ) { $first_last_message = "<b>result $first</b>"; } else { $first_last_message = "results <B>$first to $last</b>"; } //Take the final message and add it to the result HTML buffer. $message = "Showing $first_last_message [of $num_rows found]"; $this->html_buffer .= "<P>$prev_link $message $next_link<P>"; } /*-----------------------------------------------------------------*/ function prepare_scroll_controls () // To loop through db results we need an offset and a last row. // The last row is based on the limit. // So, we get an offset and limit first. They are used to get the last row. { $this->get_offset (); $this->get_limit ( ); $this->get_last ( ); } /*-----------------------------------------------------------------*/ function get_offset ( ) // Get a safe value for an offset. // If there is no offset, set it to 0. { $offset = $this->dominant_rule['offset']; if ( $offset == '' ) { $offset = 0; } $this->offset = $offset; } /*-----------------------------------------------------------------*/ function get_limit ( ) // Figure out a safe value for a limit. // We don't want to go past num_rows. { $limit = $this->dominant_rule['limit']; if ( $limit == '' ) { $limit = $this->num_rows; } $this->limit = $limit; } /*-----------------------------------------------------------------*/ function get_last ( ) // Figure out the last row of results to display. // Make sure the last row is not greater than the total number of rows. { $offset = $this->offset; $limit = $this->limit; $num_rows = $this->num_rows; if ( $offset + $limit > $num_rows ) { $last = $num_rows; } else { $last = $offset + $limit; } $this->last = $last; } /*-----------------------------------------------------------------*/ } /*******************************************************************/ ?>