Example #1
0
 /**
  * The recursive part of the algorithm to make equivalence labels.  See 
  * Table::_makeEquivalenceLabels()
  * @param labels Out param to map field names to labels.
  * @param values Out param to map labels to values
  * @param root Reference to a node of the parse tree that we are currently dealing with.
  * @param parser_wrapper Reference to the parser wrapper that can be used to operate on and query
  * 		  the parsed sql data structure (as returned by SQL_Parser::parse()
  */
 function _makeEquivalenceLabels_rec(&$labels, &$values, &$root, &$parser_wrapper)
 {
     if (isset($root['op'])) {
         if ($root['op'] == '=') {
             $label = '';
             $value = null;
             $fields = array();
             $existingLabels = 0;
             $oldLabel = null;
             // keep track of the number of existing labels.
             foreach (array('arg_1', 'arg_2') as $arg) {
                 switch ($root[$arg]['type']) {
                     case 'ident':
                         $field_name = Dataface_Table::absoluteFieldName($parser_wrapper->resolveColumnName($root[$arg]['value']), $parser_wrapper->_data['table_names']);
                         if (!is_string($field_name)) {
                             echo "Field name is not a string.";
                             echo get_class($field_name);
                             if (is_a($field_name, 'PEAR_Error')) {
                                 echo $field_name->toString();
                             }
                         }
                         $fields[] = $field_name;
                         // If this column already has a label, then we use it as the common label
                         if (isset($labels[$field_name])) {
                             $existingLabels++;
                             if ($existingLabels > 1) {
                                 // If the other column already had a label, then we keep track of it
                                 $oldLabel = $label;
                             }
                             $label = $labels[$field_name];
                         }
                         break;
                     case 'text_val':
                     case 'int_val':
                     case 'real_val':
                         $value = $root[$arg]['value'];
                         break;
                 }
             }
             // Assert (count($fields) == 1 or count($fields) == 2)
             // Assert (count($fields) == 1 => $value !== null )
             // Assert (count($fields) == 2 => $value === null )
             $label = $label ? $label : $fields[0];
             // Obtain the label for these columns.  If there are 2 columns, they must have the same label
             foreach ($fields as $field) {
                 if (!isset($labels[$field])) {
                     $labels[$field] = $label;
                 }
             }
             // Now we have to change labels of all fields that contained the old label.
             if ($oldLabel !== null) {
                 foreach ($labels as $field_name => $field_label) {
                     if ($field_label == $oldLabel) {
                         $labels[$field_name] = $label;
                     }
                 }
             }
             // Now we update the value for the label if there is a value.
             if ($value !== null) {
                 $values[$label] = $value;
             }
         }
     }
     foreach ($root as $key => $value) {
         if (is_array($value)) {
             $this->_makeEquivalenceLabels_rec($labels, $values, $value, $parser_wrapper);
         }
     }
 }
 /**
  * Builds the form.
  */
 function _build()
 {
     if ($this->_built) {
         return true;
     }
     $r =& $this->_relationship->_schema;
     $t =& $this->_parentTable;
     $fkCols = $this->_relatedRecord->getForeignKeyValues();
     if (PEAR::isError($fkCols)) {
         $fkCols->addUserInfo("Error getting foreign key columns while building Related Record Form");
         error_log($fkCols->toString());
         return $fkCols;
     }
     //echo "<h1>fkcols</h1>";print_r($fkCols);
     //$cols =& $r['columns'];
     $cols =& $this->_fieldNames;
     $dummyRecords = array();
     // to hold records that will allow us to get permissions information form existing data.
     foreach ($cols as $col) {
         list($tablename, $fieldname) = explode('.', $col);
         if (!isset($dummyRecords[$tablename])) {
             $dummyRecords[$tablename] = new Dataface_Record($tablename, array());
         }
     }
     foreach (array_keys($dummyRecords) as $dummyTable) {
         if (isset($fkCols[$dummyTable])) {
             $dummyRecords[$dummyTable]->setValues($fkCols[$dummyTable]);
         }
     }
     $quickForms = array();
     // array for each quickform object.. one for each table in relationship.
     //$permissions = $t->getRelationshipPermissions($this->_relationshipName);
     $permissions = $this->_record->getPermissions(array('relationship' => $this->_relationshipName));
     if (isset($permissions['add new related record']) and $permissions['add new related record']) {
         // We are allowed to add a new related record, so we will create a mask to allow this.
         $mask = array('edit' => 1, 'new' => 1, 'view' => 1);
     } else {
         $mask = array();
     }
     $groupsStarted = array();
     $fieldDefs = array();
     foreach ($cols as $col) {
         $absFieldname = Dataface_Table::absoluteFieldName($col, $r['tables']);
         if (PEAR::isError($absFieldname)) {
             $absFieldname->addUserInfo("Error obtaining absolute field name for field '{$col}' while building Related Record Form ");
             return $absFieldname;
         }
         list($tablename, $fieldname) = explode('.', $absFieldname);
         $thisTable =& Dataface_Table::loadTable($tablename);
         //echo $absFieldname;
         if (array_key_exists($tablename, $fkCols) and array_key_exists($fieldname, $fkCols[$tablename])) {
             // This column is already specified by the foreign key relationship so we don't need to pass
             // this information using the form.
             // Actually - this isn't entirely true.  If there is no auto-incrementing field
             // associated with this foreign key, then
             if ($this->_relationship->isNullForeignKey($fkCols[$tablename][$fieldname])) {
                 $furthestField = $fkCols[$tablename][$fieldname]->getFurthestField();
                 if ($furthestField != $absFieldname) {
                     // We only display this field if it is the furthest field of the key
                     continue;
                 }
             } else {
                 continue;
             }
         }
         $field =& $this->_parentTable->getTableField($col);
         if (@$field['grafted'] && !@$field['transient']) {
             continue;
         }
         $fieldDefs[$absFieldname] =& $field;
         unset($field);
         unset($thisTable);
     }
     //foreach ($cols as $col){
     $formTool =& Dataface_FormTool::getInstance();
     $groups = $formTool->groupFields($fieldDefs);
     $firstGroup = true;
     // Let's see if we need to use tabs
     foreach ($groups as $sectionName => $fields) {
         unset($group);
         $firstField = reset($fields);
         if (!$firstField) {
             continue;
         }
         $thisTable =& Dataface_Table::loadTable($firstField['tablename']);
         $group =& $thisTable->getFieldgroup($sectionName);
         if (PEAR::isError($group)) {
             $group = array('label' => df_translate('scripts.Dataface_QuickForm.LABEL_EDIT_DETAILS', 'Edit Details'), 'order' => 1);
         }
         $groupEmpty = true;
         // A flag to check when the group has at least one element
         foreach ($fields as $field) {
             $tablename = $field['tablename'];
             $fieldname = $field['name'];
             $absFieldname = $tablename . '.' . $fieldname;
             unset($thisTable);
             $thisTable =& Dataface_Table::loadTable($tablename);
             if (isset($r[$thisTable->tablename]['readonly'])) {
                 continue;
             }
             if (!isset($this->_quickForms[$tablename])) {
                 $this->_quickForms[$tablename] = new Dataface_QuickForm($tablename, '', '', '', true);
             }
             if (isset($quickForm)) {
                 unset($quickForm);
             }
             $quickForm =& $this->_quickForms[$tablename];
             if (array_key_exists($tablename, $fkCols) and array_key_exists($fieldname, $fkCols[$tablename])) {
                 // This column is already specified by the foreign key relationship so we don't need to pass
                 // this information using the form.
                 // Actually - this isn't entirely true.  If there is no auto-incrementing field
                 // associated with this foreign key, then
                 if ($this->_relationship->isNullForeignKey($fkCols[$tablename][$fieldname])) {
                     $furthestField = $fkCols[$tablename][$fieldname]->getFurthestField();
                     if ($furthestField != $absFieldname) {
                         // We only display this field if it is the furthest field of the key
                         continue;
                     }
                 } else {
                     continue;
                 }
                 //continue;
             }
             //$field =& $this->_parentTable->getTableField($col);
             $widget =& $field['widget'];
             $perms = $dummyRecords[$tablename]->getPermissions(array('field' => $fieldname, 'recordmask' => $mask));
             if (!Dataface_PermissionsTool::view($perms)) {
                 continue;
             }
             $el = $quickForm->_buildWidget($field, $perms);
             if (PEAR::isError($el)) {
                 error_log($el->toString() . "\n" . implode("\n", $el->getBacktrace()));
                 throw new Exception("Failed to build widget for {$fieldname}.  See error log for details.", E_USER_ERROR);
             }
             if ($groupEmpty and @$field['widget']['type'] !== 'hidden') {
                 // This is the first field in the group, so we add a header for the
                 // group.
                 if (!$firstGroup) {
                     $this->addElement('submit', '', df_translate('save_button_label', 'Save'));
                 }
                 $headerel =& $this->addElement('header', $group['label'], $group['label']);
                 $headerel->setFieldDef($group);
                 unset($headerel);
                 $groupEmpty = false;
                 $firstGroup = false;
             }
             $this->addElement($el);
             // set default value
             $defaultValue = $thisTable->getDefaultValue($fieldname);
             if (isset($defaultValue)) {
                 $defaults = array($fieldname => $defaultValue);
                 $this->setDefaults($defaults);
             }
             /*
              *
              * If there are any validation options set for the field, we must add these rules to the quickform
              * element.
              *
              */
             $validators = $field['validators'];
             foreach ($validators as $vname => $validator) {
                 /*
                  *
                  * $validator['arg'] would be specified in the INI file.
                  * Example ini file listing:
                  * -------------------------
                  * [FirstName]
                  * widget:label = First name
                  * widget:description = Enter your first name
                  * validators:regex = "/[0-9a-zA-Z/"
                  *
                  * This would result in $validator['arg'] = "/[0-9a-zA-Z/" in this section
                  * and $vname == "regex".  Hence it would mean that a regular expression validator
                  * is being placed on this field so that only Alphanumeric characters are accepted.
                  * Please see documentation for HTML_QuickForm PEAR class for more information
                  * about QuickForm validators.
                  *
                  */
                 $this->addRule($fieldname, $validator['message'], $vname, $validator['arg'], 'client');
             }
             unset($field);
             unset($widget);
             unset($grp);
             unset($thisTable);
             unset($el);
         }
     }
     $factory = new HTML_QuickForm('factory');
     $keyEls = array();
     $keyDefaults = array();
     foreach (array_keys($this->_parentTable->keys()) as $key) {
         $keyEls[] = $factory->addElement('hidden', $key);
     }
     $this->addGroup($keyEls, '__keys__');
     $keyvals = array();
     foreach (array_keys($this->_parentTable->keys()) as $key) {
         $keyvals[$key] = $this->_record->getValueAsString($key);
     }
     $this->setDefaults(array('__keys__' => $keyvals));
     $this->addElement('hidden', '-table');
     $this->addElement('hidden', '-relationship');
     $this->addElement('hidden', '-action');
     $this->addElement('submit', '-Save', df_translate('save_button_label', 'Save'));
     $this->setDefaults(array('-table' => $this->_parentTable->tablename, '-relationship' => $this->_relationshipName, '-action' => "new_related_record"));
     /*
      * There may be some default values specified in the relationship schema.
      */
     if (isset($r['new'])) {
         $this->setDefaults($r['new']);
     }
     $this->_built = true;
 }