Xataface  2.0alpha2
Xataface Application Framework
 All Data Structures Namespaces Files Functions Variables Groups Pages
QuickForm.php
Go to the documentation of this file.
1 <?php
2 /*-------------------------------------------------------------------------------
3  * Xataface Web Application Framework
4  * Copyright (C) 2005-2008 Web Lite Solutions Corp (shannah@sfu.ca)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *-------------------------------------------------------------------------------
20  */
21 
22 /*******************************************************************************
23  * File: Dataface/QuickForm.php
24  * Author: Steve Hannah
25  * Description:
26  * An extension of HTML_QuickForm to auto-generate a form for a particular table
27  * in an SQL database.
28  *
29  *******************************************************************************/
30 
31 import( 'HTML/QuickForm.php');
32 import( 'Dataface/Table.php');
33 import( 'Dataface/Vocabulary.php');
34 import( 'Dataface/QueryBuilder.php');
35 import( 'Dataface/QueryTool.php');
36 import( 'Dataface/IO.php');
37 import( 'Dataface/SkinTool.php');
38 import('HTML/QuickForm/Renderer/Dataface.php');
39 import( 'Dataface/PermissionsTool.php');
40 import('Dataface/FormTool.php');
41 
42 
43 // Register our special types
44 $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']['htmlarea'] = array('HTML/QuickForm/htmlarea.php', 'HTML_QuickForm_htmlarea');
45 $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']['table'] = array('HTML/QuickForm/table.php', 'HTML_QuickForm_table');
46 $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']['calendar'] = array('HTML/QuickForm/calendar.php', 'HTML_QuickForm_calendar');
47 $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']['time'] = array('HTML/QuickForm/time.php', 'HTML_QuickForm_time');
48 $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']['webcam'] = array('HTML/QuickForm/webcam.php', 'HTML_QuickForm_webcam');
49 $GLOBALS['HTML_QUICKFORM_ELEMENT_TYPES']['portal'] = array('HTML/QuickForm/portal.php', 'HTML_QuickForm_portal');
50 define( 'QUICKFORM_AMBIGUOUS_FIELD_ERROR', 2);
51 define( 'QUICKFORM_NO_SUCH_FIELD_ERROR',3);
52 
57 class Dataface_QuickForm extends HTML_QuickForm {
58 
59  public static $TRACK_SUBMIT = true;
60 
65 
69  var $db;
70 
75  var $_iniFile;
76 
80  var $_query;
81 
85  var $_exactMatches = false;
86 
90  var $_table;
91 
95  var $_record;
96 
101 
105  var $_attributes = array();
106 
111 
115  var $_new = false;
116 
122  var $overrideNoQuery = false;
123 
124 
129  var $_fields = array();
130 
135  var $_isBuilt = false;
136 
137  var $_fieldnames = null;
138 
139  var $_lang;
140 
145  var $_changed_fields=array();
146 
147 
151  var $tab;
152 
153  var $app;
154 
155 
156  var $submitLabel = null;
157 
175  function Dataface_QuickForm($tablename, $db='', $query='', $formname='', $new=false, $fieldnames=null, $lang=null){
177  $this->app =& $app;
178  $appQuery =& $app->getQuery();
179  if ( !isset($lang) && !isset($this->_lang) ){
180  $this->_lang = $app->_conf['lang'];
181  } else if ( isset($lang) ){
182  $this->_lang = $lang;
183  }
184  if ( is_a($tablename, 'Dataface_Record') ){
185  if ( !$this->formSubmitted() ){
186  $this->_record =& $tablename;
187  $this->tablename = $this->_record->_table->tablename;
188  $this->_table =& $this->_record->_table;
189  unset($tablename);
191  } else {
192  $this->_record =& Dataface_QuickForm::getRecord();
193  $this->tablename = $tablename;
194  $this->_table =& Dataface_Table::loadTable($this->tablename);
195  }
196 
197  } else if ( !$new ){
198  if ( $tablename == $appQuery['-table'] ){
199  $this->_record =& Dataface_QuickForm::getRecord();
200  } else if ( $query ){
201  $this->_record =& df_get_record($tablename, $query);
202  }
203  if ( !$this->_record ) $this->_record = new Dataface_Record($tablename, array());
204 
205  $this->tablename = $tablename;
206 
207  $this->_table =& Dataface_Table::loadTable($this->tablename);
208 
209  //$tablename = $this->tablename;
210  } else {
211  $this->tablename = $tablename;
212  $this->_table =& Dataface_Table::loadTable($this->tablename, $this->db);
213  $this->_record = new Dataface_Record($this->tablename, array());
214  }
215 
216  $this->_new = $new;
217  if ( !$formname ) {
218  if ( $new ){
219  $formname = "new_".$tablename."_record_form";
220  } else {
221  $formname = "existing_".$tablename."_record_form";
222  }
223 
224  }
225  if ( !$db and defined('DATAFACE_DB_HANDLE') ){
226 
227  $db = DATAFACE_DB_HANDLE;
228  } else {
229  $db = $app->_db;
230  }
231 
232  $this->db = $db;
233  $this->_query = is_array($query) ? $query : array();
234  // The cursor tells us which record in the dataset we will be editing.
235  if ( !isset( $this->_query['-cursor'] ) ){
236  $this->_query['-cursor'] = 0;
237  }
238 
239  // Load the results of the query.
240  $this->_resultSet =& Dataface_QueryTool::loadResult($tablename, $db, $this->_query);
241 
242  parent::HTML_QuickForm($formname, 'post', df_absolute_url($_SERVER['PHP_SELF']),'',array('accept-charset'=>$app->_conf['ie']),self::$TRACK_SUBMIT);
243 
244  //$this->_fields =& $this->_table->fields(false,false,true);
245  $this->_fields =& $this->_table->formFields(false,true);
246 
247 
248  //$this->_record = new Dataface_Record($this->_table->tablename, array());
249  $this->_renderer = new HTML_QuickForm_Renderer_Dataface($this); //$this->defaultRenderer();
250  $this->_renderer->setFormTemplate($this->getFormTemplate());
251  $this->_requiredNote = '';
252 
253 
254  if ( is_array($fieldnames) ){
255  /*
256  * $fieldnames were specified in the parameters. We will use the provided
257  * field names but we must make sure that the fields exist.
258  */
259  $this->_fieldnames = array();
260  foreach ($fieldnames as $fieldname){
261  if ( isset($this->_fields[$fieldname]) ){
262  $this->_fieldnames[] = $fieldname;
263  }
264  }
265  }
266 
267  //$this->_build();
268 
269 
270  }
271 
272 
273  function formSubmitted(){
274  return ( isset( $_POST['__keys__']) and isset( $_POST['-table']) );
275  }
276 
277  function &getRecord(){
278 
280  $record = new Dataface_Record($_POST['-table'], array());
281  $io = new Dataface_IO($_POST['-table']);
282  $query = $_POST['__keys__'];
283 
284  if ( is_array($query) ){
285  foreach ( array_keys($query) as $postKey ){
286  if ( $query[$postKey]{0} != '=' ){
287  $query[$postKey] = '='.$query[$postKey];
288  }
289  }
290  }
291  $io->read($query, $record);
292  return $record;
293  } else {
294 
296 
297  $qt =& Dataface_QueryTool::loadResult($app->_currentTable);
298 
299  $curr =& $qt->loadCurrent();
300 
301  return $curr;
302  }
303  }
304 
312  function setSubmitLabel($label){
313  $this->submitLabel = $label;
314  }
315 
324  function getSubmitLabel(){
325  return $this->submitLabel;
326  }
327 
328 
333  function _fillArray( &$arr1, $arr2 ){
334  $keys = array_keys($arr2);
335  foreach ($keys as $key){
336  if ( !isset( $arr1[ $key ] ) ){
337  $arr1[ $key ] = $arr2[ $key ];
338  } else if ( is_array( $arr1[ $key ] ) and is_array( $arr2[ $key ] ) ){
339  $this->_fillArray( $arr1[$key], $arr2[$key]);
340  }
341  }
342  }
343 
344 
354  function _buildWidget(&$field){
355  global $myctr;
356 
357  if ( func_num_args() > 1 ){
358  /*
359  *
360  * A second argument is present. It must be a permissions array.
361  *
362  */
363  $permissions = func_get_arg(1);
364 
365  } else {
366  /*
367  *
368  * No permissions were specified so we give Global permissions by default.
369  *
370  */
371  $permissions = Dataface_PermissionsTool::ALL();
372  }
373 
374 
375 
376  $formTool =& Dataface_FormTool::getInstance();
377  $el =& $formTool->buildWidget($this->_record, $field, $this, $field['name'], $this->_new, $permissions);
378 
379 
380  return $el;
381 
382 
383 
384  }
385 
395  function tagFormAndSession(){
396  if ( session_id() ){
397 
398  }
399 
400  }
401 
402 
408  function _build(){
409  if ( $this->_isBuilt ){
410  /*
411  *
412  * We only need to build the form once. If it is already build, just return.
413  *
414  */
415  return;
416  }
417 
418 
419  /*
420  * Now to figure out which fields will be displayed on the form.
421  */
422  if ($this->_fieldnames === null or !is_array($this->_fieldnames) or count($this->_fieldnames)==0 ){
423  /*
424  * No fieldnames were explicitly provided (or they were improperly provided
425  * so we use all of the fields in the table.
426  */
427  // if ( isset( $query['--tab'] ) and !$new ){
428  // $flds =& $this->_table->fields(true);
429 
430  // $this->_fieldnames = array_keys($flds[$query['--tab']]);
431  // } else {
432  $this->_fieldnames = array();
433  foreach ($this->_fields as $field){
434  if ( isset($this->tab) and ($this->tab != @$field['tab']) /*and ($this->tab != @$group['tab'])*/ ) continue;
435  // If we are using tabs, and this field isn't in the current tab, then
436  // we skip it.
437  $this->_fieldnames[] = $field['name'];
438  //$this->_fieldnames = array_keys($this->_fields);
439  }
440  //}
441  }
442 
443 
444 
445 
446  $this->_isBuilt = true;
447  // set flag to indicate that the form has already been built.
448 
449  if ( !$this->_record || !is_a($this->_record, 'Dataface_Record') ){
450  return PEAR::raiseError(
452  'Cannot build quickform with no record',
453  'Attempt to build quickform with no record set.'
454  ),
455  E_USER_ERROR
456  );
457  }
458 
459  $relationships =& $this->_table->relationships();
460  // reference to relationship descriptors for this table.
461 
462 
463  $formTool =& Dataface_FormTool::getInstance();
464  $groups = $formTool->groupFields($this->_fields);
465  foreach ( $groups as $sectionName => $fields ){
466  unset($group);
467  $group =& $this->_record->_table->getFieldgroup($sectionName);
468  if ( PEAR::isError($group) ){
469  unset($group);
470  $group = array('label'=>df_translate('scripts.Dataface_QuickForm.LABEL_EDIT_DETAILS', 'Edit Details'), 'order'=>1);
471 
472  }
473 
474  $groupEmpty = true; // A flag to check when the group has at least one element
475  if ( !$fields ) continue;
476  foreach ( $fields as $field){
477  if ( !in_array($field['name'], $this->_fieldnames) ) continue;
478  //if ( isset($this->tab) and ($this->tab != @$field['tab']) and ($this->tab != @$group['tab']) ) continue;
479  // If we are using tabs, and this field isn't in the current tab, then
480  // we skip it.
481 
482 
483  $name = $field['name'];
484  // reference to field descriptor array.
485  $widget =& $field['widget'];
486  // reference to widget descriptor array
487  $vocabulary = $field['vocabulary'];
488  // reference to field's vocabulary
489 
490  /*
491  *
492  * If the user does not have permission to view this field, we should not generate this widget.
493  *
494  */
495  if ( !Dataface_PermissionsTool::view($this->_record, array('field'=>$name))
496  and !($this->_new and Dataface_PermissionsTool::checkPermission('new',$this->_record->getPermissions(array('field'=>$name))))
497  ){
498  unset($widget);
499  continue;
500 
501  }
502 
503  if ( $groupEmpty ){
504  // This is the first field in the group, so we add a header for the
505  // group.
506  $headerel =& $this->addElement('header', $group['label'], $group['label']);
507  $headerel->setFieldDef($group);
508  unset($headerel);
509  $groupEmpty = false;
510  }
511 
512  /*
513  *
514  * Build the widget for this field. Note that we pass the permissions array
515  * to the method to help it know which widget to build.
516  *
517  */
518  $el = $this->_buildWidget($field, $this->_record->getPermissions(array('field'=>$name)));
519  if ( PEAR::isError($el) ){
520  $el->addUserInfo(
521  df_translate(
522  'scripts.Dataface.QuickForm._build.ERROR_FAILED_TO_BUILD_WIDGET',
523  "Failed to build widget for field $name ",
524  array('name'=>$name,'line'=>0,'file'=>'_')
525  )
526  );
527  return $el;
528  }
529 
530 
531 
532  //$this->addElement($el);
533 
534  unset($field);
535  unset($el);
536  unset($widget);
537 
538  }
539  } // end foreach $groups
540  /*
541  *
542  * We need to add elements to the form to specifically store the keys for the current
543  * record. These elements should not be changeable by the user as they are used upon
544  * submission to find out which record is currently being updated. We will store
545  * the keys for this record in a group of hidden fields where a key named "ID" would
546  * be stored in a hidden field as follows:
547  * <input type="hidden" name="__keys__[ID]" value="10"/> (assuming the value of the ID field for this record is 10)
548  *
549  */
550  $factory = new HTML_QuickForm('factory');
551  // a dummy quickform object to be used tgo create elements.
552  $keyEls = array();
553  //
554  $keyDefaults = array();
555  foreach ( array_keys($this->_table->keys()) as $key ){
556  $keyEls[] = $factory->addElement('hidden', $key);
557 
558  }
559  $this->addGroup($keyEls,'__keys__');
560 
561  /*
562  *
563  * We add a field to flag whether or not we are creating a new record.
564  * This does not mean that we are always creating a new record. That will
565  * depend on the value that is placed in this field as a default.
566  *
567  */
568  $this->addElement('hidden','-new');
569 
570  $this->setDefaults(array('-new'=>$this->_new));
571  if ( ($this->_new and Dataface_PermissionsTool::checkPermission('new',$this->_table) ) or
572  (!$this->_new and Dataface_PermissionsTool::edit($this->_record) ) ){
573  $saveButtonLabel = df_translate('tables.'.$this->_table->tablename.'.save_button_label', '');
574  if ( !$saveButtonLabel ) $saveButtonLabel = df_translate('save_button_label','Save');
575  $this->addElement('submit','--session:save',$saveButtonLabel);
576  //$this->addGroup($formTool->createRecordButtons($this->_record, $this->tab));
577  }
578 
579  if ( $this->_new and !$this->overrideNoQuery){
580 
581  $this->addElement('hidden','--no-query',1);
582  }
583  // add the submit button.
584 
585 
586 
587 
588  /*
589  *
590  * We need to set the default values for this form now.
591  *
592  */
593 
594  $keys = $this->getKeys();
595  // may not be necessary -- not sure....
596 
597  if ( $this->isSubmitted() and !$this->_new){
598  /*
599  *
600  * This part is unnecessary because the record is not populated
601  * in the Dataface_QuickForm constructor.
602  *
603  */
604  $key_vals = $this->exportValues('__keys__');
605  $query = $key_vals['__keys__'];
606  //$io = new Dataface_IO($this->tablename, $this->db);
607  //$io->read($query, $this->_record);
608 
609  } else if ( !$this->_new ){
610  /*
611  *
612  * The form has not been submitted yet and we are not creating a new
613  * record, so we need to populate the form with values from the record.
614  *
615  */
616  foreach ( array_keys($this->_table->keys()) as $key ){
617  $keyDefaults[$key] = $this->_record->strval($key);
618 
619  }
620 
621  $this->setConstants( array('__keys__'=>$keyDefaults) );
622  $this->pull();
623 
624 
625  } else { // $this->_new
626  $defaults = array();
627  foreach ( array_keys($this->_fields) as $key ){
628  $defaultValue = $this->_table->getDefaultValue($key);
629  if ( isset($defaultValue) ){
630  //if ( isset($this->_fields[$key]['group']) and $this->_fields[$key]['group'] ){
631 
632  // $defaults[$this->_fields[$key]['group']][$key] = $defaultValue;
633  //} else {
634  $defaults[$key] = $defaultValue;
635  //}
636  }
637  }
638 
639  $this->setDefaults($defaults);
640  }
641 
642  }
643 
644 
645 
654  $field =& $this->_table->getField($fieldname);
655 
656  $formTool =& Dataface_FormTool::getInstance();
657  $el =& $formTool->getElement($this, $field, $fieldname);
658  return $el;
659  }
660 
669  // Step 1: Load references to objects that we will need to use
670  $s =& $this->_table;
671  // Reference to the table
672  $field =& $s->getField($fieldname);
673 
674  $formTool =& Dataface_FormTool::getInstance();
675  $res = $formTool->pullField($this->_record, $field, $this, $fieldname, $this->_new);
676  return $res;
677 
678 
679  }
680 
687  function pull(){
688  //$fields = array_keys($this->_fields);
690  foreach ($fields as $field){
691  $res = $this->pullField($field);
692  if ( PEAR::isError($res) ){
693  continue;
694 
695 
696  }
697 
698  }
699  return true;
700 
701  }
702 
703 
704 
715  function push(){
716  //$fields = array_keys($this->_fields);
718  //$ctr = 0;
719  foreach ($fields as $field){
720 
721  $res = $this->pushField($field);
723  /*
724  *
725  * The user does not have permission to set this value for this field.
726  * We return an error, that should result in a "PERMISSION DENIED" page if
727  * if is propogated up properly.
728  *
729  */
730  return $res;
731  }
732  if (PEAR::isError($res) ){
733 
734 
735 
736  continue;
737  $res->addUserInfo(
738  df_translate(
739  'scripts.Dataface.QuickForm.push.ERROR_PUSHING_DATA',
740  "Error pushing data onto field $field in QuickForm::push()",
741  array('field'=>$field,'line'=>0,'file'=>'_')
742  )
743  );
744  throw new Exception($res->toString(), E_USER_ERROR);
745 
746  }
747  }
748 
749  return true;
750 
751  }
752 
753 
760  function validate(){
761  $this->_build();
762  //$this->push();
763  if ( $this->isSubmitted() ){
765  $res = $app->fireEvent('Dataface_QuickForm_before_validate');
766  if ( PEAR::isError($res) ){
767 
768  $this->_errors[] = $res->getMessage();
769  }
770  /*
771  *
772  * We only need to validate if the form was submitted.
773  *
774  */
775  //foreach ( array_keys($this->_fields) as $field ){
776  $rec = new Dataface_Record($this->_record->_table->tablename, $this->getSubmitValues());
777  $rec->pouch = $this->_record->pouch;
778  foreach ($this->_fieldnames as $field){
779  /*
780  *
781  * Go through each field (corresponding to a record field) in the form
782  * and validate against the record's validation script.
783  *
784  */
785  $el =& $this->getElementByFieldName($field);
786  if ( PEAR::isError($el) ){
787  unset($el);
788  continue;
789  }
790 
791 
792  $params = array('message'=>df_translate('scripts.GLOBAL.MESSAGE.PERMISSION_DENIED',"Permission Denied"));
793  // default error message to be displayed beside the field.
794 
795  $res = $rec->validate($field, $el->getValue(), $params );
796  if ( !$res){
797  /*
798  *
799  * The default validate() method checks to see if the form validates based
800  * on the size of the _errors array. (If it has count = 0, then it validates.
801  * Adding an error to this array will cause the parent's validate method to return
802  * false.
803  *
804  */
805 
806  $this->_errors[$el->getName()] = $params['message'];
807  }
808 
809 
810  unset($params);
811  }
812  }
813 
814 
815 
816  /*
817  *
818  * Now that we have done our work, we can let the default validate method do the rest
819  * of the work.
820  *
821  */
822  return parent::validate();
823 
824  }
825 
833 
834  $formTool =& Dataface_FormTool::getInstance();
835  $field =& $this->_table->getField($fieldname);
836 
837  $res = $formTool->pushField($this->_record, $field, $this, $fieldname, $this->_new);
838 
839  return $res;
840 
841  }
842 
849 
850 
851  }
852 
856  function pushValue($fieldname, &$metaValues, $element=null){
857 
858  $formTool =& Dataface_FormTool::getInstance();
859  $field =& $this->_table->getField($fieldname);
860  if ( !isset($element) ) $element =& $formTool->getElement($this, $field, $fieldname);
861 
862  $res = $formTool->pushValue($this->_record, $field, $this, $element, $metaValues);
863  return $res;
864 
865  }
866 
867 
868 
869 
870  function display(){
871  if ( $this->_resultSet->found()>0 || $this->_new ){
872  $res = $this->_build();
873  if ( PEAR::isError($res) ){
874  return $res;
875  }
876  else {
877  //$this->displayTabs();
878  if ( !$this->_new and !Dataface_PermissionsTool::edit($this->_record) ){
879  $this->freeze();
880  }
881 
882  if ( $this->_new and !Dataface_PermissionsTool::checkPermission('new',$this->_table) ){
883  $this->freeze();
884  }
885  $formTool =& Dataface_FormTool::getInstance();
886 
887 
888  if ( $this->_new || Dataface_PermissionsTool::view($this->_record) ){
889  //echo $this->_renderer->toHtml();
890  echo $formTool->display($this);
891  } else {
892  echo "<p>".df_translate('scripts.GLOBAL.INSUFFICIENT_PERMISSIONS_TO_VIEW_RECORD','Sorry you have insufficient permissions to view this record.')."</p>";
893  }
894  //parent::display();
895  }
896  } else {
897  echo "<p>".df_translate('scripts.GLOBAL.NO_RECORDS_MATCHED_REQUEST','No records matched your request.')."</p>";
898  }
899  }
900 
901 
902  function displayTabs(){
903 
904  if ( isset($this->_record) ){
905  echo "<ul id=\"quick-form-tabs\">";
906  foreach ( $this->_record->_table->getTabs() as $tab ){
907  echo "<li><a href=\"".$this->app->url('-tab='.$tab)."\">".$tab."</a></li>";
908  }
909  echo "</ul>";
910  }
911  }
912 
913  function getElementTemplate($fieldName=''){
915 
916  if ( $fieldName && isset($this->_fields[$fieldName]) && isset($this->_fields[$fieldName]['widget']['description']) ){
917  $widget = $this->_fields[$fieldName]['widget'];
918  $description = $widget['description'];
919 
920  } else {
921  $description = '';
922  }
923 
924  $o = "<div class=\"field\">
925  <label>{label}</label>
926  <!-- BEGIN required --><span style=\"color: #ff0000\" class=\"fieldRequired\" title=\"required\">*</span><!-- END required -->
927  <!-- BEGIN error --><div class=\"fieldError\" style=\"color: #ff0000\">{error}</div><!-- END error -->
928  <div class=\"formHelp\">$description</div>
929  {element}
930  </div>
931  ";
932  return $o;
933 
934  }
935 
936  function getFormTemplate(){
937  $atts =& $this->_table->attributes();
938  $formname = $this->getAttribute('name');
939  return <<<END
940  <script language="javascript" type="text/javascript"><!--
941  function Dataface_QuickForm(){
942 
943  }
944  Dataface_QuickForm.prototype.setFocus = function(element_name){
945  document.{$formname}.elements[element_name].focus();
946  document.{$formname}.elements[element_name].select();
947  }
948  var quickForm = new Dataface_QuickForm();
949  //--></script>
950 
951  <form{attributes}>
952  <fieldset>
953  <legend>{$atts['label']}</legend>
954  <table width="100%" class="Dataface_QuickForm-table-wrapper">
955 
956  {content}
957  </table>
958  </fieldset>
959  </form>
960 END;
961  }
962 
963  function getFieldGroupTemplate($name){
964  $name = $this->_formatFieldName($name);
965  $group =& $this->_table->getFieldgroup($name);
966 
967 
968  $o = "<tr><td colspan=\"2\"><fieldset class=\"fieldgroup\" style=\"border: 1px solid #8cacbb; margin: 0.5em;\">
969  <legend>".$group['label']."</legend>
970  <div class=\"formHelp\">".$group['description']."</div>
971  <table width=\"100%\" border=\"0\" class=\"Dataface_QuickForm-group-table-wrapper\">
972  {content}
973  </table>
974 
975  </fieldset></td></tr>";
976  return $o;
977  }
978 
979  function getGroupTemplate($name){
980  $name = $this->_formatFieldName($name);
981  $group =& $this->_table->getField($name);
982 
983  $context = array( 'group'=>&$group, 'content'=>'{content}');
984  $skinTool =& Dataface_SkinTool::getInstance();
985  ob_start();
986  $skinTool->display($context, 'Dataface_Quickform_group.html');
987  $o = ob_get_contents();
988  ob_end_clean();
989 
990  return $o;
991  }
992 
993  function getGroupElementTemplate($groupName=''){
994  $groupName = $this->_formatFieldName($groupName);
995  $group =& $this->_table->getFieldgroup($groupName);
996  if ( PEAR::isError($group) ){
997  $group->addUserInfo(
998  df_translate(
999  'scripts.Dataface.QuickForm.getGroupElementTemplate.ERROR_GETTING_FIELD_GROUP',
1000  "Error getting field group '$groupName' in QuickForm::getGroupElementTemplate() ",
1001  array('groupname'=>$groupName,'line'=>0,'file'=>'_')
1002  )
1003  );
1004  return $group;
1005  }
1006 
1007  $description = '';
1008  $label = '';
1009 
1010  if ( $group['element-description-visible'] ){
1011  $description = "<div class=\"formHelp\" style=\"display: inline\">".$group['description']."</div>";
1012  }
1013 
1014  if ( $group['element-lavel-visible'] ){
1015  $label = '';
1016  }
1017 
1018  if ( $fieldName && isset($this->_fields[$fieldName]) && isset($this->_fields[$fieldName]['widget']['description']) ){
1019  $widget = $this->fields[$fieldName]['widget'];
1020  $description = $widget['description'];
1021 
1022  } else {
1023  $description = '';
1024  }
1025 
1026  $o = "<div class=\"field\">
1027  <label>{label}</label>
1028  <!-- BEGIN required --><span style=\"color: #ff0000\" class=\"fieldRequired\" title=\"required\">*</span><!-- END required -->
1029  <!-- BEGIN error --><div class=\"fieldError\" style=\"color: #ff0000\">{error}</div><!-- END error -->
1030  <div class=\"formHelp\">$description</div>
1031  {element}
1032  </div>
1033  ";
1034 
1035  return $o;
1036 
1037  }
1038 
1039  function save( $values ){
1040 
1041  // First let's find out if we should SAVE the data or if we should just be
1042  // storing it in the session or if we are saving the data to the database
1043 
1044 
1045  if (!$this->_new){
1046  // Make sure that the correct form is being submitted.
1047  if ( !isset( $values['__keys__'] ) ){
1048  throw new Exception(
1049  df_translate(
1050  'scripts.Dataface.QuickForm.save.ERROR_SAVING_RECORD',
1051  "Error saving record in QuickForm::save().\n<br>"
1052  ), E_USER_ERROR);
1053  }
1054  if ( array_keys($values['__keys__']) != array_keys($this->_table->keys()) ){
1055  throw new Exception(
1056  df_translate(
1057  'scripts.Dataface.QuickForm.save.ERROR_SAVING_RECORD',
1058  "Error saving record in QuickForm::save().\n<br>"
1059  ), E_USER_ERROR);
1060  }
1061  }
1062 
1063  if ( $this->_new ){
1064 
1065  $this->_record->clearValues();
1066  }
1067 
1068  $res = $this->push();
1069 
1070  if ( !$this->_new ){
1071  if ( $this->_record->snapshotExists() ){
1072 
1073  $tempRecord = new Dataface_Record($this->_record->_table->tablename, $this->_record->getSnapshot());
1074  } else {
1075  $tempRecord =& $this->_record;
1076  }
1077  if ( $values['__keys__'] != $tempRecord->strvals(array_keys($this->_record->_table->keys())) ){
1078  throw new Exception(
1079  df_translate(
1080  'scripts.Dataface.QuickForm.save.ERROR_SAVING_RECORD',
1081  "Error saving record in QuickForm::save().\n<br>"
1082  ), E_USER_ERROR);
1083  }
1084  }
1085 
1086 
1087  if (PEAR::isError($res) ){
1088 
1089 
1090  $res->addUserInfo(
1091  df_translate(
1092  'scripts.Dataface.QuickForm.save.ERROR_PUSHING_DATA',
1093  "Error pushing data from form onto table in QuickForm::save() ",
1094  array('line'=>0,'file'=>"_")
1095  )
1096  );
1097 
1098 
1099  return $res;
1100  }
1101 
1102 
1103  // Let's take an inventory of which fields were changed.. because
1104  // we are going to make their values available in the htmlValues()
1105  // method which is used by the ajax form to gather updates.
1106  foreach ( $this->_fields as $changedfield ){
1107  if ( $this->_record->valueChanged($changedfield['name']) ){
1108  $this->_changed_fields[] = $changedfield['name'];
1109  }
1110  }
1111 
1112  $io = new Dataface_IO($this->tablename, $this->db);
1113  $io->lang = $this->_lang;
1114  if ( $this->_new ) $keys = null;
1115  else $keys = $values['__keys__'];
1116 
1117  $res = $io->write($this->_record,$keys,null,true /*Adding security!!!*/);
1118  if ( PEAR::isError($res) ){
1119  if ( Dataface_Error::isDuplicateEntry($res) ){
1120  /*
1121  * If this is a duplicate entry (or just a notice - not fatal), we will propogate the exception up to let the application
1122  * decide what to do with it.
1123  */
1124  return $res;
1125  }
1126  if ( Dataface_Error::isNotice($res) ){
1127  return $res;
1128  }
1129 
1130  $res->addUserInfo(
1131  df_translate(
1132  'scripts.Dataface.QuickForm.save.ERROR_SAVING_RECORD',
1133  "Error saving form in QuickForm::save()",
1134  array('line'=>0,'file'=>"_")
1135  )
1136  );
1137  throw new Exception($res->toString(), E_USER_ERROR);
1138 
1139  }
1140 
1141 
1142 
1143  if ( isset( $io->insertIds[$this->tablename]) and $this->_table->getAutoIncrementField() ){
1144  $this->_record->setValue($this->_table->getAutoIncrementField(), $io->insertIds[$this->tablename]);
1145  $this->_record->setSnapshot();
1146 
1147  }
1148 
1149  return true;
1150 
1151 
1152 
1153  }
1154 
1155 
1159  function getKeys(){
1160  $keys = array();
1161  foreach ($this->_fields as $key=>$value){
1162  if ( strtolower($value['Key']) == strtolower('PRI') ){
1163  $keys[$key] =& $this->_fields[$key];
1164  }
1165  }
1166  return $keys;
1167  }
1168 
1169 
1173  function deserialize($field){
1174  return Dataface_Table::_deserialize($field);
1175 
1176 
1177  }
1178 
1179 
1183  function serialize($field){
1184 
1185  return Dataface_Table::_serialize($field);
1186 
1187 
1188 
1189  }
1190 
1195  return $fieldname;
1196  //return str_replace(':','.', $fieldname);
1197  }
1198 
1199 
1224  public static function &createNewRecordForm($tablename, $fieldnames=null){
1225 
1226  $form = new Dataface_QuickForm($tablename, '','','',true, $fieldnames);
1227  return $form;
1228 
1229 
1230  }
1231 
1258  public static function &createEditRecordForm(&$tablenameOrRecord, $fieldnames=null){
1259  $form = new Dataface_QuickForm($tablenameOrRecord, '','','',false,$fieldnames);
1260  return $form;
1261  }
1262 
1263  function htmlValues(){
1264  $vals = array();
1265  $record =& $this->_record;
1266  foreach ($this->_changed_fields as $fieldname){
1267  $vals[$fieldname] = $record->htmlValue($fieldname);
1268  }
1269  $vals['__id__'] = $record->getId();
1270  $vals['__url__'] = $record->getURL('-action=view');
1271  return $vals;
1272  }
1273 
1274 }