/** * 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; }