Xataface 2.0
Xataface Application Framework
Dataface/SearchForm.php
Go to the documentation of this file.
00001 <?php
00002 /*-------------------------------------------------------------------------------
00003  * Xataface Web Application Framework
00004  * Copyright (C) 2005-2008 Web Lite Solutions Corp (shannah@sfu.ca)
00005  * 
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * as published by the Free Software Foundation; either version 2
00009  * of the License, or (at your option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  * 
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  *-------------------------------------------------------------------------------
00020  */
00021 /*******************************************************************************
00022  * File:        Dataface/SearchForm.php
00023  * Author:      Steve Hannah
00024  * Description:
00025  *      An extension of HTML_QuickForm to auto-generate a form for a particular table
00026  *      in an SQL database.
00027  *      
00028  *******************************************************************************/
00029  
00030 require_once 'HTML/QuickForm.php';
00031 require_once 'Dataface/Table.php';
00032 require_once 'Dataface/Vocabulary.php';
00033 require_once 'Dataface/QueryBuilder.php';
00034 require_once 'Dataface/ResultController.php';
00035 require_once 'Dataface/ResultList.php';
00036 require_once 'Dataface/QueryTool.php';
00037 
00038 
00039 // Register our special types
00040 $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']['htmlarea'] = array('HTML/QuickForm/htmlarea.php', 'HTML_QuickForm_htmlarea');
00041 
00042 
00046 class Dataface_SearchForm extends HTML_QuickForm {
00047 
00048         var $tablename;
00049         
00050         var $db;
00051         
00052         var $_iniFile;
00053         
00054         var $_query;
00055         
00056         var $_exactMatches = false;
00057         
00058         var $_table;
00059         
00060         var $_resultSet;
00061 
00062         
00063         
00068         var $_fields = array();
00069         
00070         var $_isBuilt = false;
00071         
00072         function Dataface_SearchForm($tablename, $db='',  $query='', $fields=null){
00073                 $widgetTypes = array();
00074                 $this->tablename = $tablename;
00075                 $this->db = $db;
00076                 $this->_query = is_array($query) ? $query : array();
00077                 
00078                 if ( !isset( $this->_query['-cursor'] ) ){
00079                         $this->_query['-cursor'] = 0;
00080                 }
00081                 
00082                 $this->_resultSet =& Dataface_QueryTool::loadResult($tablename, $db, $this->_query);
00083                 
00084                 
00085                 parent::HTML_QuickForm($tablename, 'post');
00086                 
00087                 // Get column information directly from the database
00088                 
00089                 
00090                 $this->tablename = preg_replace('/ /', '', $this->tablename);
00091                 $this->_table =& Dataface_Table::loadTable($this->tablename, $this->db);
00092                 
00093                 $this->_fields = array();
00094                 if ( !isset($fields) ){
00095                         $fields = array_keys($this->_table->fields(false,true));
00096                         
00097                         foreach ($this->_table->relationships() as $relationship){
00098                                 if ( @$relationship->_schema['visibility'] and @$relationship->_schema['visibility']['find'] == 'hidden' ){
00099                                         continue;
00100                                 }
00101                                 $rfields = $relationship->fields(true);
00102                                 $fkeys = $relationship->getForeignKeyValues();
00103                                 $removedKeys = array();
00104                                 foreach($fkeys as $fkeyTable => $fkey){
00105                                         foreach (array_keys($fkey) as $fkeyKey){
00106                                                 $removedKeys[] = $fkeyTable.'.'.$fkeyKey;
00107                                         }
00108                                 }
00109 
00110                                 $rfields = array_diff($rfields, $removedKeys);
00111 
00112                                 foreach ($rfields as $rfield){
00113                                         list($rtable,$rfield) = explode('.',$rfield);
00114                                         $fields[] = $relationship->getName().'.'.$rfield;
00115                                 }
00116                                 unset($rfields);
00117                                 unset($relationship);
00118                                 
00119                         }
00120                 }
00121 
00122                 $this->_fields = array();
00123                 foreach ($fields as $fieldname){
00124                         $this->_fields[$fieldname] =& $this->_table->getField($fieldname);
00125                 }
00126                 
00127                 
00128                 
00129                 
00130 
00131                 
00132                 
00133                 
00134                 
00135 
00136         }
00137         
00138         
00139         
00140         
00141         
00142         
00143         
00144         
00145         function _build(){
00146                 if ( $this->_isBuilt ){
00147                         return;
00148                 }
00149                 $this->_isBuilt = true;
00150                 
00151                 $renderer =& $this->defaultRenderer();
00152                 foreach ($_REQUEST as $qkey=>$qval){
00153                         if ( strlen($qkey)>1 and $qkey{0} == '-' and strpos($qkey, '-findq:') !== 0){
00154                                 $this->addElement('hidden', $qkey);
00155                                 $this->setDefaults( array($qkey=>$qval));
00156                         }
00157                 }
00158                 
00159                 $this->addElement('hidden', '--find-submit');
00160                 $this->setConstants( array('--find-submit'=>1));
00161                 
00162                 $relatedSections=array(); // keeps track of which relationship sections have been started
00163                 
00164                 foreach ( $this->_fields as $name => $field ){
00165                         $table =& $this->_table;
00166                         if ( $this->_table->isPassword($name) ) continue;
00167                         if ( @$field['visibility']['find'] == 'hidden') continue;
00168                         // add the field to the form
00169                         $widget = $field['widget'];
00170                         if ( isset($widget['find']) ){
00171                                 $widget = $widget['find'];
00172                         }
00173                         $vocabulary = $field['vocabulary'];
00174                         
00175                         if ( $widget['type'] == 'meta' ) continue;
00176                         
00177                         $inputName = $field['name'];
00178                         
00179                         if ( strpos($name,'.') !== false ){
00180                                 unset($table);
00181 
00182                                 $table =& Dataface_Table::loadTable($field['tablename']);
00183                                 list($relationshipName,$name) = explode('.', $name);
00184                                 $inputName = $relationshipName.'/'.$name;
00185                                 
00186                                 if ( !isset($relatedSections[$relationshipName]) ){
00187                                         $relationship = $this->_table->getRelationship($relationshipName);
00188                                         if ( PEAR::isError($relationship) ){
00189                                                 die($relationship->toString());
00190                                         }
00191                                         $this->addElement('submit', '--submit', df_translate('scripts.GLOBAL.LABEL_SUBMIT', 'Submit'));
00192                                         $this->addElement('header',$relationshipName,$relationship->getLabel());
00193                                         $relatedSections[$relationshipName] = true;
00194                                 }
00195                         }
00196                         
00197                         if ( isset( $vocabulary) && $vocabulary ){
00198                                 //$vocab =& Dataface_Vocabulary::getVocabulary($vocabulary);
00199                                 //$options = $vocab->options();
00200                                 $options = $table->getValuelist($field['vocabulary']);
00201                                 if ( is_array($options) ){
00202                                         $opts = array(''=>df_translate('scripts.GLOBAL.FORMS.OPTION_PLEASE_SELECT', "Please Select..."));
00203                                         foreach ($options as $key=>$value){
00204                                                 $opts[$key] = $value;
00205                                         }
00206                                         $options = $opts;
00207                                 } 
00208                         }
00209                         
00210                         
00211                         if ( isset($field['vocabulary']) and $field['vocabulary'] ){
00212                                 $options = $table->getValuelist($field['vocabulary']);
00213                                 $boxes = array();
00214                                 
00215                                 $el =& $this->addElement('select', '-findq:'.$inputName, $widget['label'], $options, array('size'=>'5','multiple'=>1));
00216                                 $widgetTypes[$inputName] = 'select';
00217                                 $el->setFieldDef($field);
00218                                 if ( isset($field['repeat']) and $field['repeat']){
00219                                         
00220                                         $this->addElement('radio', '-find-op:'.$inputName, '',df_translate('scripts.Dataface_SearchForm.LABEL_MATCH_ALL', 'Match all selected'), 'AND');
00221                                 }
00222                                 
00223                                 $this->addElement('radio', '-find-op:'.$inputName,'',df_translate('scripts.Dataface_SearchForm.LABEL_MATCH_ANY', 'Match any selected'), 'OR');
00224                                 
00225                                 $this->addElement('radio', '-find-op:'.$inputName,'',df_translate('scripts.Dataface_SearchForm.LABEL_MATCH_NONE', 'Do not match selected'), 'None');
00226                         
00227 
00228                         } else {
00229                                 
00230                                 $el =& $this->addElement('text', '-findq:'.$inputName, $widget['label'], array('class'=>$widget['class'], 'id'=>$inputName) );
00231                                 $widgetTypes[$inputName] = 'text';
00232                                 $el->setFieldDef($field);
00233                         }
00234         
00235                 }
00236                 
00237 
00238                 $this->addElement('submit','--submit',df_translate('scripts.GLOBAL.LABEL_FIND', 'Find'));
00239                 $this->addElement('hidden', '-action');
00240                 $this->addElement('hidden', '-edit');
00241                 $this->addElement('hidden', '-table');
00242                 
00243                 $defaults = array();
00244                 foreach ($this->_query as $key=>$value){
00245                         if ( $key{0} != '-' ){
00246                                 if ( @$widgetTypes[$key] == 'select'){
00247                                         $parts = explode(' OR ', $value);
00248                                         $value = array();
00249                                         foreach ($parts as $part ){
00250                                                 while ( $part and in_array($part{0}, array('=','<','>','!') ) ) {
00251                                                         $part = substr($part,1);
00252                                                         //$value = array($value);
00253                                                 }
00254                                                 $value[] = $part;
00255                                         }
00256                                 }
00257                                 
00258                                 $defaults['-findq:'.$key] = $value;
00259                         } else {
00260                                 $defaults[$key] = $value;
00261                         }
00262                 }
00263                 
00264                 $this->setDefaults( $defaults);
00265                 $this->setConstants(array('-action'=>'find', '-edit'=>1, '-table'=>$this->tablename));
00266                 
00267                 
00268                 
00269         }
00270         
00271         function display(){
00272                 $this->_build();
00273                 
00274                 
00275                 $tableLabel = htmlspecialchars($this->_table->getLabel());
00276                 
00277                 df_display(array(
00278                         'tableLabel' => $tableLabel
00279                         ), 'Dataface_Search_Instructions.html'
00280                 );
00281                 
00282                 //parent::display();
00283                 import('Dataface/FormTool.php');
00284                 $ft =& Dataface_FormTool::getInstance();
00285                 $ft->display($this, 'Dataface_FindForm.html');
00286                 //echo '</div>';
00287         }
00288         
00289         
00293         function performFind($values){
00294                 $app =& Dataface_Application::getInstance();
00295                 $query = $app->getQuery();
00296 
00297                 if ( isset( $values['-find:result_action']) ){
00298                         $qstr = '-action='.$values['-find:result_action'];
00299                 } else {
00300                         $qstr = '-action=list';
00301                 }
00302                 if ( isset($values['-skip']) ) $values['-skip'] = 0;
00303                 if ( isset($values['-cursor']) ) $values['-cursor'] = 0;
00304                 // Checkbox groups with nothing selected may not be submitted with the form, 
00305                 // even though their accompanying 'None' radio button may be selected.  If none
00306                 // is selected, then we need to add a value
00307                 foreach ($values as $key=>$value){
00308                         if ( strpos($key, '-find-op:') === 0 ){
00309                                 $key = substr($key, 9);
00310                                 if ( !isset($values['-findq:'.$key]) or !is_array($values['-findq:'.$key]) ){
00311                                         $values['-findq:'.$key] = array('');
00312                                 }
00313                         }
00314                 }
00315                 foreach ($values as $key=>$value){
00316                         if ( strpos($key, '-findq:') === 0 ){
00317                                 $key = substr($key, 7);
00318                                 $field = $this->_table->getField(str_replace('/','.',$key));
00319                                 if ( PEAR::isError($field) ){
00320                                         echo "Failed to get field $key: ".$field->getMessage();
00321                                 }
00322                                 if ( is_array($value) and count($value) > 0){
00323                                         $op = ( (isset( $values['-find-op:'.$key] ) ) ? $values['-find-op:'.$key] : 'AND');
00324                                         if (!isset($field['repeat']) or !$field['repeat']) $op = 'OR';
00325                                         if ( isset($values['-find-op:'.$key]) and  $values['-find-op:'.$key] == 'None' ){
00326                                                 $qstr .= '&'.urlencode($key).'='.urlencode('=');
00327                                         } else {
00328                                                 $qstr .= '&'.urlencode($key).'='.urlencode('='.implode( ' '.$op.' =', $value));
00329                                         } 
00330                                 } else if ( !empty($value) ){
00331                                 
00332                                         $qstr .= '&'.urlencode($key).'='.urlencode($value);
00333                                 }
00334                                 unset($field);
00335                         } else if ( $key{0} == '-' and $key{1} != '-' and $key != '-action' and $key != '-search' and strpos($key, '-find') !== 0 ){
00336                                 $qstr .= '&'.urlencode($key).'='.urlencode($value);
00337                         }
00338                         
00339                 } 
00340                 
00341                 $url = $_SERVER['HOST_URI'].DATAFACE_SITE_HREF.'?'.$qstr;
00342                 $app->redirect($url);
00343         }
00344         
00345         function process($callback=null, $mergFiles=true){
00346                 if ( isset( $this->_query['--find-submit']) ){
00347                         return parent::process( array(&$this, 'performFind'));
00348                 } else {
00349                         return null;
00350                 }
00351         }
00352         
00353         function getKeys(){
00354                 $keys = array();
00355                 foreach ($this->_fields as $key=>$value){
00356                         if ( strtolower($value['Key']) == strtolower('PRI') ){
00357                                 $keys[$key] =& $this->_fields[$key];
00358                         }
00359                 }
00360                 return $keys;
00361         }
00362         
00363         function deserialize($field){
00364                 return Dataface_Table::_deserialize($field);
00365                 
00366                                         
00367         }
00368         
00369         function serialize($field){
00370         
00371                 return Dataface_Table::_serialize($field);
00372                 
00373                 
00374                 
00375         }
00376 }
 All Data Structures Namespaces Files Functions Variables Enumerations