![]() |
Xataface 2.0
Xataface Application Framework
|
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 }