Tryag File Manager
Home
-
Turbo Force
Current Path :
/
home
/
cluster1
/
data
/
bu01
/
1121861
/
html
/
jlex
/
php4
/
Upload File :
New :
File
Dir
//home/cluster1/data/bu01/1121861/html/jlex/php4/query_object.php4
<? include_once("char_classes_parser.php4"); include_once("schema_loader.php4"); include_once("project_defaults.php4"); /** * @package JLex * @author Jonathan Dick */ class query_object { /**#@+ * The values for these variables are expected to be suppplied by the HTML form calling this script. * However, these variables should also exist in the defaults.xml configuration file associated * with the given project. If values to these variables are not supplied by the form, * they are extracted from defaults.xml. * @access public * */ /** * The name of the project which will be queried. * @var string */ var $project; /** * The type of query, regular or advanced, which will be generated. * * This module allows for the user to provide two sets of information to form the database query. * For the regular query, the user will provide information in the following order:<BR> * fields, regular expression, connective<BR> * For the advanced query, the user provides informaiton in the following order: <BR> * operator/connective, fields, regular expression, operator/connective.<BR><BR> * Each field must be contained by some table within the project.<BR> * The regular expression must be a valid MySQL regular expression. The word 'field' is used to indicate * where the field will be in the regular expression. The '~' sign serves as a place * holder indicating where data will be filled in to the regular expression. For example, to search for * "name" fields starting with the value "Jon" the following values would be supplied:<BR> * fields: "name"<BR> * regular expression: "field REGEXP '^~'"<BR> * The end result will be: "name REGEXP '^Jon'". (with the exception that the field will be * indexed to correspond to the number of columns in the table containing the field. See below for further * explanation. */ var $query_type; /** * The maximum number of condition sets allowed. * * The developer of the form can specify how many subqueries to allow in each query to the database. * A subquery is something like: "name REGEXP '^Jon'". If the maximum number of subqueries is 2 * then the largest a query could be for example is, "name REGEXP '^Jon' AND dob REGEXP '1979'". * The value of this tells how many conditions to look for when parsing the results of the html * form. * @var integer */ var $max_conditions; /** * If this is set to true, then if a field is searched on and that field creates a stripped/modified * equivalent in the table, the stripped/modified field will also be searched. * @var boolean */ var $search_stripped_fields; /** * The name of the schema file associated with this project. * * The schema file is expected to be located in the project directory for the given projext. Relative * path names are used with this expectation in mind. * @var string */ var $schema; /** * The file location of the default style sheet which will be used to process the xml generated from * the query request. * * The path of this file is assumed to be in reference to the project directory. */ var $stylesheet; /** * The current page number in the set of results to be presented to the end user. * * The number of hits per page is set using the $max_results variable. The total number pages * is determined by dividing the total number of hits by the $max_results. * @var integer */ var $page; /** * The maximum number of hits that can be returned to the user for a give query. * @var integer */ var $max_results; /** * The location of the script used to preprocess the query before it is sent to MySQL. * * The location of this script assumed to be relative to the project directory. * The purpose of this script is to provide an easy mechanism for manipulating the HTML form data which * calls this script. In hindsight, this doesn't follow good programming technique. Technically, * if a project owner wishes to affect the form data before calling the query_result.php4 script, * he should instantiate the query_result class and pass it the modified variables. The query_result class * should contain a query function which takes as a paramter a $query_object. This currently does not exist. * Instead, as it's currently implement, this ordering if confused the query_result class allows a php script * to be run within it. I think this should be changed in the next version. * @todo In the query_result class, provide a query_database function which takes a $query_object as a parameter * Remove this variable from this class. * @var string */ var $pre_processing_script; /** * The location of the script used to process the results of a query to MySQL. * * Like $pre_processing_script, allowing this functionality violates good programming technique. * JLex should provide a mechanism for querying and returning data from the MySQL database. If the search * result is to be manipulated, this should be done within another php script which instantiates the * $query_result class. The script then ought to make the changes and take control of returning results * to the user. * @todo Remove this variable from the next version of JLex. */ var $post_processing_script; /**#@-*/ /** * A comma seperated list of fields dictating the sort order. * * The value of this variable will be directly appended on to SQL queries. Consequently, the * fields within the $sort_order must exist in the tables being searched. A function exists, * set_sort_order which takes in a comma delimited list of fields, and indexes each field * according to the number of columns associated with that field. See $set_sort_order for more information.<BR> * Note that for an implementation of xml with multiple values per column, the MySQL sort is more or less nullified * as far as I can tell. There may be available work arounds. * * @var string */ var $sort_order; //Array Vars supplied through search form /**#@+ * The values in equivalently indexed positions in the variables $db_cols, $reg_exps, and $strings make up * the values for a condition set to be searched on. When the "regular" query_type is used, the nth position * in the $connectives array succeeds the nth condition set. When the "advanced" query_type is used, * the nth position in the $connectives array precedes the nth condition set.<BR><BR> * The values for these variables are received from the HTML form calling for the query. The method provided by * this class fills each variable by expecting the form variables to be equivalently named but indexed as well. * Thus, all variables for the first condition set should be indexed "_0", e.g. "db_cols_0". Otherwise, these * variables will not be filled. */ /** * An array containing space seperated strings of field names which will be used to search the database. * * Note that the fill_query_object function expects to receive the english * phrase associated with a set of fields rather than the actual fields. In other words, the * function expects to receive a value like "Customer name" rather than "fname lname". It then looks up * which set of fields is associated with that english phrase. Recall that the fields used * should exist in an XML file called "phrases_and_fields.xml". The class menu_parser_items is an XML parser which * extracts the field and corresponding value for an XML file following the schema described in XXXXX. * * @var array */ var $db_cols; /** * An array containing the regular expression to be used for the condition set. * * Each field will substitute for the 'field' word in the regular expression. * The regular expression must * use a '~' to indicate where the string goes and the word 'field' to indicate where the field being searched on * goes. For example, "field REGEXP '~'". Note that the fill_query_object function expects to receive the english * phrase associated with a regular expression rather than the actual regular expression. In other words, the * function expects to receive a value like "contains" rather than "field REGEXP '~'". It then looks up * which regular expression is associated with that english phrase. Recall that the regular expressions used * should exist in an XML file called "reg_exps.xml". The class menu_parser_items is an XML parser which * extracts the field and corresponding value for an XML file following the schema described in XXXXX. * * @var array * @todo Provide an explanation somewhere of the use of the reg_exps.xml file. */ var $reg_exps; /** * An array of strings containing end user content supplied to the HTML form. * * This data will substitute for the '~' in the regular expression. * @var array */ var $strings; /** * An array of the connectives which will be used to concatenate the subqueries. * * Note that the only connectives allowed are "AND" and "OR". If the "NOT" connective is used * it will be incorrectly appended to the query being produced. The available connectives are * specified in the "connectives.xml" file and obey the same schema as that for "reg_exps.xml" * and "phrases_and_fields.xml". Please see XXXX for a description of this schema.<BR><BR> * An example of how to use "advanced". The logic we want is: name is Jonathan and (Joseph or Robert). * connectives_0 = (<BR> * db_cols_0 = name<BR> * reg_exps_0 = field REGEXP (~)<BR> * strings_0 = Jonathan<BR> * connectives_1 = ) AND (<BR> * db_cols_1 = name<BR> * reg_exps_1 = field REGEXP (~)<BR> * strings_1 = Joseph<BR> * connectives_2 = OR <BR> * db_cols_2 = name<BR> * reg_exps_2 = field REGEXP (~)<BR> * strings_2 = Robert<BR> * connectives_3 = )<BR> * * @var array */ var $connectives; /**#@-*/ /** * A list of character classes provided through the HTML form. * * This allows the end user to specify a set of character classes for use in the SQL queries. * A character class is the following: X = (set of symbols). The fill_query_object expects the values * to come from a textbox where each line contains one character class and thus character classes * are seperated by a carriage return. So for example, a user could * create a single symbol to stand for all vowels, e.g. X = [aeiou]. Note that the substitution set * must be a valid regular expression observing the MySQL rules for regular expressions. In effect, * JLex simply replaces the symbol each time it is encountered in a string in the $strings array with the * substitution set. If a regular expression is not used, e.g. "aeiou" instead of "[aeiou]", the intended * results will (obviously) not follow. * * @var string */ var $user_char_classes; /** * The name of the file of character classes for the given project. * * This file should be located within the project directory. Please see the documentation at XXXX * for the schema of this XML file. * * @todo Provide a link to the documentation for the schema for character classes. */ var $xml_char_classes; /**#@+ * The variables $query, $link, $xml and $main_ids are filled following a query to the database. */ /** * The last query attempted on the database. * * The last query is saved in case the user wants to see the actual query. The main purpose of this * variable is for debugging. * @var string */ var $query; /** * An http link which would produce the results for the current query. * * The purpose of this is to allow project owners the opportunity to provide a link directly to a set of * results to a particular query. The link could then be embedded in text elsewhere and thus provides * the opportunity to integrate the database with other web pages. It should be noted that a query can be * submitted to the query_result script by providing the following key-value pairs:<BR> * project=project_name<BR> * db_cols_i<BR> * reg_exp_i<BR> * string_i<BR> * connective_i (though only truly necessary if more than one condition is set is provided)<BR> * For example: http://www.balsas-nahuatl.org/jlex/php4/query_result.php4?project=nahuatl&db_cols_0=lxam®_exp_0=field REGEXP '^~'&string_0=cho:?ka:?&connective_0=AND * * @var string */ var $link; /** * The xml formatted response to the query contained represented in this object. * * The function convert_resultset_to_xml() belonging to the class mysql_to_xml stores the result of a query * in this variable and returns a query_object rather that the xml itself. This is done to support the * concept of using a query_object as a wrapper object for all communication between classes querying the * database.<BR> * @var string */ var $xml; /** * An array containg the main_ids returned by the query contained in this object. * * The result set to the mysql_to_xml method, query_database(), is an array containing the main_ids of those * entries matching the query's conditions. The result set could be hundreds or even more. Consequently, it's likely * that you would not want to return the complete xml structure for every hit. Instead, the set of main ids * are stored in this variable. Rather than requerying the database each time the user wants to see a different * page of hits, the ids for the relevant set of hits can be retrieved from this variable and converted * into xml via the mysql_to_xml.convert_resultset_to_xml(). * @var array */ var $main_ids; /**#@-*/ /** * This array contains the names of HTML form variables. It is initialized in the constructor. * * This exists to facilitate filling this object from values contained in the HTML form data. * Each global variable has an associated method for setting the value to that variable in the form * "set_variablename($value)". By creating an array of the names, I can iterate through * the variable set rather than writing out each function call for setting a given variable. * <BR> * Note though that this can not be done for every variable as the result from some variables * are preprocessed before setting them in this object. For example, the sort_order must * be indexed before it is assigned. * * @var array */ var $string_var_names; function query_object() { $this->project = ""; $this->max_conditions = ""; $this->max_results = ""; $this->page = ""; $this->pre_processing_script = ""; $this->post_processing_script = ""; $this->query_type = ""; $this->schema = ""; $this->search_stripped_fields = false; $this->stylesheet = ""; $this->xml_char_classes = ""; $this->string_var_names = array("max_conditions","max_results","pre_processing_script", "post_processing_script","query_type","schema", "search_stripped_fields","stylesheet"); $this->sort_order = ""; $this->connectives = array(); $this->db_cols = array(); $this->reg_exps = array(); $this->strings = array(); $this->user_char_classes = array(); $this->main_ids = array(); $this->query = ""; $this->xml = ""; $this->link = ""; } /** * Set the $project variable. * @param string $project * @see query_object::$project * @return void */ function set_project($project) { $this->project = $project; } /** * Accessor function for $project variable. * @see query_object::$project * @return string */ function get_project() { return $this->project; } /** * Set the $query_type variable. * @param string $query_type * @see query_object::$query_type * @return void */ function set_query_type($query_type) { $this->query_type = $query_type; } /** * Accessor function for $query_type variable. * @see query_object::$query_type * @return string */ function get_query_type() { return $this->query_type; } /** * Set the $max_conditions variable. * @param integer $max_conditions * @see query_object::$max_conditions * @return void */ function set_max_conditions($max_conditions) { $this->max_conditions = $max_conditions; } /** * Accessor function for $max_conditions variable. * @see query_object::$max_conditions * @return integer */ function get_max_conditions() { return $this->max_conditions; } /** * Sets the variables $db_cols, $reg_exps, $strings and $connectives to empty arrays, essentially * erasing the query information contained within this object. * * It may be convenient to reuse the same query_object for performing multiple queries. In this way you avoid * having to reload any default values for necessary variables. Instead you can replace the query condition * information and then the results to that query. * @see query_object::$db_cols * @see query_object::$reg_exps * @see query_object::$strings * @see query_object::$connectives * @return void */ function reset_condition_set() { $this->db_cols = array(); $this->reg_exps = array(); $this->strings = array(); $this->connectives = array(); } /** * Add the values to be used to create the SQL query to the database. * * A condition set requires a set of columns, a regular expression and a search string. This function adds * each value to the back of its corresponding array, starting at index 0 of each array. The function facilitates * the use of iteration for reading in an HTML form. For example, as each variable is indexed in the search * form, we can cycle through by index appending each condition set one at a time. * * @param string $db_cols The columns to be searched for a subquery * @param string $reg_exps The regular expressions for each subquery * @param string $string The string to be search for. * @return void * @see query_object::$db_cols * @see query_object::$reg_exps * @see query_object::$strings */ function add_condition_set($db_cols,$reg_exp,$string) { $this->db_cols[] = $db_cols; $this->reg_exps[] = $reg_exp; $this->strings[] = $string; } /** * Accessor function for retreiving a particular set of search columns. * * @param integer $i The index of the search columns to be retreived. * @return mixed If the index exists, that set of columns is returned. Otherwise the boolean false is returned. * @see query_object::$db_cols */ function get_db_cols($i) { if(count($this->db_cols) > $i) { return $this->db_cols[$i]; } else return false; } /** * Set the $db_cols variable. * @param array $db_cols * @see query_object::$db_cols * @return void */ function set_db_cols($db_cols) { $this->db_cols = $db_cols; } /** * Accessor function for retreiving the regular expression for a particular condition set. * * @param integer $i The index of the condition set from which the regular expression is to be retreived. * @return mixed If the index exists, that regular expression is returned. Otherwise the boolean false is returned. * @see query_object::$reg_exps */ function get_reg_exp($i) { if(count($this->reg_exps) > $i) { return $this->reg_exps[$i]; } else return false; } /** * Set the $reg_exps variable. * @param array $reg_exps * @see query_object::$reg_exps * @return void */ function set_reg_exps($reg_exps) { $this->reg_exps = $reg_exps; } /** * Accessor function for retreiving the string for a particular condition set. * * @param integer $i The index of the condition set from which the string is to be retreived. * @return mixed If the index exists, that string is returned. Otherwise the boolean false is returned. * @see query_object::$strings */ function get_string($i) { if(count($this->strings) > $i) { return $this->strings[$i]; } else return false; } /** * Set the $strings variable. * @param array $strings * @see query_object::$strings * @return void */ function set_strings($strings) { $this->strings = $strings; } /** * Add a connective to the end of the $connectives array. * * @param string $connective * @see query_object::$connectives * @return void */ function add_connective($connective) { $this->connectives[] = $connective; } /** * Accessor function for retreiving the connective for a particular condition set. * * @param integer $i The index of the connective to be retreived. * @return mixed If the index exists, that connective is returned. Otherwise the boolean false is returned. * @see query_object::$connectives */ function get_connective($i) { if(count($this->connectives) > $i) { return $this->connectives[$i]; } else return false; } function get_last_connective() { return end($this->connectives); } /******************************* search_stripped_fields ****************************/ function get_search_stripped_fields() { return $this->search_stripped_fields; } function set_search_stripped_fields($search_stripped_fields) { $this->search_stripped_fields = $search_stripped_fields; } /******************************* stylesheet ****************************/ function get_stylesheet() { return $this->stylesheet; } function set_stylesheet($stylesheet) { $this->stylesheet = $stylesheet; } /******************************* schema ****************************/ function get_schema() { return $this->schema; } function set_schema($schema) { $this->schema = $schema; } /******************************* sort_order ****************************/ function get_sort_order() { return $this->sort_order; } /** * For now, this function takes a comma delimited string of non-indexed fields, e.g. lxa,lxo not lxa_0,lxo_0; */ function set_sort_order($sort_order) { $sort_fields = explode(",",$sort_order); if(count($sort_fields) != 0) { $sort_order = ""; $sl = new schema_loader(); $schema = $this->schema; if($this->schema == "") { $schema = "../$this->project/schema.xml"; } else { $schema = "../$this->project/$schema"; } if(!file_exists($schema)) { die("No schema file in project folder $this->project"); } $group = $sl->create_group_structure($schema,""); foreach($sort_fields as $field) { $field = trim($field); if(array_key_exists($field,$group->fields)) { $num_fields = $group->fields[$field]; for($i=0;$i<$num_fields;$i++) { $sort_order .= $field."_".$i.","; } } } $this->sort_order = substr($sort_order,0,-1); } else $this->sort_order = ""; } /******************************* char_classes ****************************/ function get_char_classes() { $char_classes = array(); if((count($this->xml_char_classes) != 0) || (count($this->user_char_classes) != 0)) { $char_classes = array_merge($this->xml_char_classes, $this->user_char_classes); } return $char_classes; } /******************************* user_char_classes ****************************/ function load_user_char_classes($user_char_classes) { if($user_char_classes != "") { $ccp = new char_classes_parser(); $user_char_classes = explode("\n",$user_char_classes); $ucc = $ccp->load_user_char_classes($user_char_classes); unset($ccp); $this->user_char_classes = $ucc; } } /******************************* xml_char_classes ****************************/ function get_xml_char_classes() { return $this->xml_char_classes; } function set_xml_char_classes($xml_char_classes) { $this->xml_char_classes = "../".$this->get_project()."/".$xml_char_classes; } function load_xml_char_classes($xml_char_classes) { if($xml_char_classes != "") { $ccp = new char_classes_parser(); $xcc = $ccp->get_xml_char_classes($xml_char_classes); unset($ccp); $this->xml_char_classes = $xcc; } } /******************************* page ****************************/ function get_page() { return $this->page; } function set_page($page) { $this->page = $page; } /******************************* main_ids ****************************/ function get_main_ids() { return $this->main_ids; } function set_main_ids($main_ids) { $this->main_ids = $main_ids; } /******************************* max_results ****************************/ function get_max_results() { return $this->max_results; } function set_max_results($max_results) { $this->max_results = $max_results; } /******************************* xml ****************************/ function get_xml() { return $this->xml; } function set_xml($xml) { $this->xml = $xml; } /******************************* pre_processing_script ****************************/ function get_pre_processing_script() { return $this->pre_processing_script; } function set_pre_processing_script($pre_processing_script) { $this->pre_processing_script = $pre_processing_script; } /******************************* post_processing_script ****************************/ function get_post_processing_script() { return $this->post_processing_script; } function set_post_processing_script($post_processing_script) { $this->post_processing_script = $post_processing_script; } /******************************* num_conditions ****************************/ function get_num_conditions() { return count($this->strings); } /******************************* subqueries ****************************/ function get_query() { return $this->query; } function set_query($query) { $this->query = $query; } /******************************* link ****************************/ function get_link() { return $this->link; } function set_link($link) { $this->link = $link; } /******************************* group ****************************/ function get_group() { $project = $this->get_project(); $schema = $this->get_schema(); if($schema == "") $schema = "../$project/schema.xml"; else $schema = "../$project/$schema"; $sl = new schema_loader(); $group = $sl->create_group_structure($schema,""); return $group; } /******************************* print_values ****************************/ function print_values() { echo "Project: $this->project <BR>"; echo "Query Type: $this->query_type<BR>"; echo "Max Conditions: $this->max_conditions<BR>"; echo "Db_cols:<BR>"; foreach($this->db_cols as $i=>$cols) { echo "$i: $cols<BR>"; } echo "Reg_exps:<BR>"; foreach($this->reg_exps as $i=>$reg) { echo "$i: $reg<BR>"; } echo "Strings:<BR>"; foreach($this->strings as $i=>$string) { echo "$i: $string<BR>"; } echo "Connectives:<BR>"; foreach($this->connectives as $i=>$con) { echo "$i: $con<BR>"; } echo "Search Stripped Fields: $this->search_stripped_fields<BR>"; echo "Schema: $this->schema<BR>"; echo "Sort Order: $this->sort_order<BR>"; echo "Stylesheet: $this->stylesheet<BR>"; echo "XML Char Classes:<BR>"; foreach($this->xml_char_classes as $k=>$c) { echo "$k: $c<BR>"; } echo "User Char Classes:<BR>"; foreach($this->user_char_classes as $k=>$c) { echo "$k: $c<BR>"; } echo "Page: $this->page<BR>"; echo "Main Ids:<BR>"; foreach($this->main_ids as $id) { echo "$id "; } echo "<BR>"; echo "Max Results: $this->max_results<BR>"; echo "xml: $this->xml<BR>"; echo "Pre-processing Script: $this->pre_processing_script<BR>"; echo "Post-processing Script: $this->post_processing_script<BR>"; echo "Query: $this->query<BR>"; echo "Link: $this->link<BR>"; } /******************************* assign_value ****************************/ function assign_value($form_vars, $defaults, $var_name) { $var = trim($form_vars[$var_name]); if($var == "") { $function = "get_$var_name"; $var = $this->$function(); if($var == "") { $var = $defaults[$var_name]; } } $function = "set_$var_name"; $this->$function($var); } /******************************* get_project_defaults ****************************/ function get_project_defaults($defaults_xml) { $pd = new project_defaults(); $defaults = $pd->get_project_defaults($defaults_xml); return $defaults; } /******************************* fill_query_object ****************************/ //Order of precedence: $form_vars > current > defaults function fill_query_object($form_vars,$defaults) { $project = $form_vars["project"]; $this->set_project($project); if((count($defaults) == 0) || ($defaults=="")) { $defaults_file = "../$project/defaults.xml"; $defaults = array(); if(file_exists($defaults_file)) { $defaults = $this->get_project_defaults($defaults_file); } } foreach($this->string_var_names as $var_name) { $this->assign_value($form_vars,$defaults,$var_name); } $page = trim($form_vars["page"]); $this->set_page($page); if($defaults["xml_char_classes"] != "") { $xml_char_classes = "../$project/".$defaults["xml_char_classes"]; $this->load_xml_char_classes($xml_char_classes); } if($form_vars["user_char_classes"] != "") { $user_char_classes = $form_vars["user_char_classes"]; $this->load_user_char_classes($user_char_classes); } $sort_order = strtolower(trim($form_vars["sort_order"])); if($sort_order == "") { $sort_order = $defaults["sort_order"]; } $this->set_sort_order($sort_order); $mip = new menu_items_parser(); $reg_exps = $mip->get_menu_items("../$project/reg_exps.xml"); $phrases_and_fields = $mip->get_menu_items("../$project/phrases_and_fields.xml"); $address = getenv("SERVER_NAME"); $script = getenv("REQUEST_URI"); $script = ereg_replace("[?].*","",$script); $link = "http://".$address.$script."?project=$project"; $max_conditions = $this->get_max_conditions(); $this->reset_condition_set(); for($i=0;$i<$max_conditions;$i++) { $db_cols_var = "db_cols_".$i; $db_cols = trim($form_vars[$db_cols_var]); if(array_key_exists($db_cols,$phrases_and_fields)) { $db_cols = $phrases_and_fields[$db_cols]; } $reg_exp_var = "reg_exp_".$i; $reg_exp = stripslashes($form_vars[$reg_exp_var]); if(array_key_exists($reg_exp,$reg_exps)) { $reg_exp = $reg_exps[$reg_exp]; } $string_var = "string_".$i; $string = trim($form_vars[$string_var]); $string = ereg_replace("[+]","\\\+",$string); $connective_var = "connective_".($i); $connective = trim($form_vars[$connective_var]); if($string != "" || ereg("<>", $reg_exp)) { $link .= "&$db_cols_var=$db_cols&$reg_exp_var=$reg_exp&$string_var=$string&$connective_var=$connective"; $this->add_condition_set($db_cols,$reg_exp,$string); $this->add_connective($connective); } } $link = ereg_replace("&","&",$link); $link = ereg_replace("<","<",$link); $link = ereg_replace(">",">",$link); $this->set_link($link); } } ?>