Example #1
0
 function &buildWidget(&$record, &$field, &$form, $formFieldName, $new = false)
 {
     /*
      *
      * This field uses a table widget.
      *
      */
     $table =& $record->_table;
     $formTool =& Dataface_FormTool::getInstance();
     $factory =& Dataface_FormTool::factory();
     $widget =& $field['widget'];
     $el =& $factory->addElement('table', $formFieldName, $widget['label']);
     if (isset($widget['fields'])) {
         $widget_fields =& $widget['fields'];
         foreach ($widget_fields as $widget_field) {
             $widget_field =& Dataface_Table::getTableField($widget_field, $this->db);
             if (PEAR::isError($widget_field)) {
                 return $widget_field;
             }
             $widget_widget = $formTool->buildWidget($record, $widget_field, $factory, $widget_field['name']);
             $el->addField($widget_widget);
         }
     } else {
         if (isset($field['fields'])) {
             foreach (array_keys($field['fields']) as $field_key) {
                 $widget_widget = $formTool->buildWidget($record, $field['fields'][$field_key], $factory, $field['fields'][$field_key]['name']);
                 $el->addField($widget_widget);
                 unset($widget_widget);
             }
         }
     }
     return $el;
 }
Example #2
0
 /**
  * Gets the values of the foreign keys of a particular relationship.  This returns an associative
  * array with the following structure:
  *   Array(
  *			"table1" => Array( "field1"=>"value1", "field2"=>"value2", ... ),
  *			"table2" => Array( "field1"=>"value1", "field2"=>"value2", ... ),
  *			...
  *	);
  * @param relationship_name The name of the relationship
  * @param values Supplementary values passed as array with keys = absolute field names, values = serialized values.
  * @param sql If provided, this will be used as the select statement that we dissect.
  * @parseValues If true we parse out variables.  If false, we simply return the variables to be parsed later.
  * @throws PEAR_Error if there is insufficient values supplied for the foreign key to work.
  *
  */
 function getForeignKeyValues($values = null, $sql = null, $record = null)
 {
     if (is_object($record)) {
         $record_id = $record->getId();
     }
     if (!isset($values) and !isset($sql) and !isset($record) and isset($this->_cache[__FUNCTION__])) {
         return $this->_cache[__FUNCTION__];
     }
     if (!isset($values) and !isset($sql) and is_object($record) and isset($this->_cache[__FUNCTION__ . $record_id])) {
         return $this->_cache[__FUNCTION__ . $record_id];
     }
     // Strategy:
     // ----------
     // 1. Label all fields involved in the foreign key so that fields that are equal have the
     //    same label.  Eg: In the query:
     // 		select *
     //			from Students
     //			inner join Student_Courses
     //				on Students.id = Student_Courses.studentid
     //			inner join Courses
     //				on Student_Courses.courseid = Courses.id
     //		where
     //			Students.id = '$id'
     //
     //	In the above query Students.id and Student_Course.studentid would have the same label, and
     //  Student_Courses.courseid and Courses.id would have the same label.
     //  ie: Label(Students.id) = Label(Student_Courses.studentid) ^ Label(Student_Courses.courseid) = Label(Courses.id)
     //
     // 2. Assign values for each label.  All fields with a particular label have the same value.
     //	In the above query, we would have:
     //		Value(Label(Students.id)) = '$id'
     //		**Note from above that Label(Students.id)=Label(Student_Courses.studentid) so their values are also equal.
     //
     // 3. For labels without a value find out if one of the fields assuming that label is an auto-increment field. If so
     // 	  we assign the special value '__Tablename__auto_increment__' where "Tablename" is the name of the table  whose
     // 	  field is to be auto incremented.
     //
     // 4. Collect the the values in a structure so that we can lookup the values of any particular field in any particular
     //    table easily.  Return this structure.
     $relationship =& $this->_schema;
     if ($sql !== null) {
         // An SQL query was specified as a parameter, we parse this and use the resulting data structure
         // for the rest of the computations.
         if (is_string($sql)) {
             $parser = new SQL_Parser(null, 'MySQL');
             $sql = $parser->parse($sql);
         }
         $select =& $sql;
     } else {
         // We use the 'parsed_sql' entry in the relationship as the basis for our dissection.
         $select =& $relationship['parsed_sql'];
     }
     // Build equivalence classes for column names.
     $labels = array();
     $vals = array();
     $this->_makeEquivalenceLabels($labels, $vals, $select);
     // Fill in some default values
     if (is_array($values)) {
         foreach ($values as $field_name => $field_value) {
             if (!$field_value) {
                 continue;
             }
             // we don't want empty and null values to act as defaults because they
             //  tend to screw things up when we are adding related records.
             if (isset($labels[$field_name])) {
                 $label = $labels[$field_name];
             } else {
                 $label = $field_name;
                 $labels[$field_name] = $label;
             }
             $vals[$label] = $field_value;
         }
     }
     // next we need to find 'circular links'.  Ie: There may be columns that are only specified to be equal to each other.  Most of the
     // time this means that one of the fields is an auto increment field that will be automatically filled in.  We need to insert
     // a special value (in this case), so that we know this is the case.
     foreach ($labels as $field_name => $label) {
         if (!isset($vals[$label])) {
             $field =& Dataface_Table::getTableField($field_name);
             $table_auto_increment = null;
             foreach ($labels as $auto_field_name => $auto_label) {
                 if ($auto_label == $label) {
                     $auto_field =& Dataface_Table::getTableField($auto_field_name);
                     if ($auto_field['Extra'] == 'auto_increment') {
                         list($table_auto_increment) = explode('.', $auto_field_name);
                         unset($auto_field);
                         break;
                     }
                     unset($auto_field);
                 }
             }
             if (isset($table_auto_increment)) {
                 //list($table) = explode('.', $field_name);
                 $vals[$label] = "__" . $table_auto_increment . "__auto_increment__";
             } else {
                 $vals[$label] = new Dataface_Relationship_ForeignKey($this, $labels, $label);
             }
             unset($field);
         }
     }
     $table_cols = array();
     foreach ($labels as $field_name => $label) {
         $fieldArr =& Dataface_Table::getTableField($field_name);
         list($table, $field) = explode('.', $field_name);
         if (!$table) {
             continue;
         }
         if (!isset($table_cols[$table])) {
             $table_cols[$table] = array();
         }
         $table_cols[$table][$field] = (is_scalar(@$vals[$label]) and $record !== null and !preg_match('/(blob|binary)/', strtolower($fieldArr['Type']))) ? $record->parseString(@$vals[$label]) : @$vals[$label];
         unset($fieldArr);
     }
     // make sure that each table at least sets all of the mandatory fields.
     foreach ($table_cols as $table => $cols) {
         $tableObject =& Dataface_Table::loadTable($table);
         foreach (array_keys($tableObject->mandatoryFields()) as $key) {
             if (!isset($cols[$key])) {
                 $this->errors[] = PEAR::raiseError(DATAFACE_TABLE_RELATED_RECORD_REQUIRED_FIELD_MISSING_ERROR, null, null, null, "Could not generate SQL to add new record to relationship '" . $this->_name . "' because not all of the required fields have values.  In particular, the field '{$key}' of table '{$table}' is missing but is a key of the table.");
             }
         }
         unset($tableObject);
     }
     if (!isset($values) and !isset($sql) and !isset($record)) {
         $this->_cache[__FUNCTION__] = $table_cols;
     }
     if (!isset($values) and !isset($sql) and is_object($record)) {
         $this->_cache[__FUNCTION__ . $record_id] = $table_cols;
     }
     return $table_cols;
 }
Example #3
0
 function &buildWidget(&$record, &$field, &$form, $formFieldName, $new = false)
 {
     /*
      *
      * This field uses a table widget.
      *
      */
     //$field['display'] = 'block';
     $table =& $record->_table;
     $formTool =& Dataface_FormTool::getInstance();
     $factory =& Dataface_FormTool::factory();
     $widget =& $field['widget'];
     $el =& $factory->addElement('grid', $formFieldName, $widget['label']);
     $el->setProperties($widget);
     $rperms = $record->getPermissions(array('relationship' => $field['relationship']));
     if (!$record->checkPermission('add new related record', array('relationship' => $field['relationship']))) {
         //echo "No add new ".$record->_table->tablename;
         $el->addNew = false;
     }
     if (!$record->checkPermission('add existing related record', array('relationship' => $field['relationship']))) {
         //echo "No add new ".$record->_table->tablename;
         $el->addExisting = false;
     }
     if (isset($field['relationship'])) {
         $relationship =& $table->getRelationship($field['relationship']);
         if (!$record->checkPermission('remove related record', array('relationship' => $field['relationship']))) {
             $el->delete = false;
         } else {
             if ($relationship->isOneToMany() and isset($rperms['delete related record']) and !@$rperms['delete related record']) {
                 $el->delete = false;
             }
         }
         if (!$relationship->supportsRemove()) {
             $el->delete = false;
         }
         if (!$relationship->supportsAddNew()) {
             $el->addNew = false;
         }
         if (!$relationship->supportsAddExisting()) {
             $el->addExisting = false;
         } else {
             $el->addExistingFilters = $relationship->getAddExistingFilters();
         }
         $el->table = $relationship->getDomainTable();
         if (isset($widget['columns'])) {
             $columns = array_map('trim', explode(',', $widget['columns']));
         } else {
             $columns = $relationship->_schema['short_columns'];
         }
         $count = 0;
         $subfactory = new HTML_QuickForm();
         $dummyRelatedRecord = new Dataface_RelatedRecord($record, $relationship->getName());
         //print_r($dummyRelatedRecord->getPermissions());
         $orderCol = $relationship->getOrderColumn();
         if (!$orderCol or PEAR::isError($orderCol)) {
             $el->reorder = false;
         }
         foreach ($columns as $column) {
             $colTable =& $relationship->getTable($column);
             if (!$colTable) {
                 echo "Could not find table for column {$column}";
             }
             $colPerms = $dummyRelatedRecord->getPermissions(array('field' => $column));
             if (!@$colPerms['view']) {
                 unset($colTable);
                 unset($dummyRecord);
                 continue;
             }
             // We need to be a bit more refined on this one.  We need to take
             // into account the context being that we are in a relationship.
             $dummyRecord = new Dataface_Record($colTable->tablename, $record->vals());
             /*
             if ( !$dummyRecord->checkPermission('view', 
             	array('field'=>$column, 'recordmask'=>array('view'=>1))) ) {
             	unset($colTable);
             	unset($dummyRecord);
             	continue;
             }
             */
             $colFieldDef =& $colTable->getField($column);
             $columnElement =& $formTool->buildWidget($dummyRecord, $colFieldDef, $subfactory, $column, false);
             $defaultValue = $colTable->getDefaultValue($column);
             $columnElement->setValue($defaultValue);
             $el->defaults[$column] = $defaultValue;
             $el->addField($colFieldDef, $columnElement, $colPerms);
             unset($columnElement);
             unset($colFieldDef);
             unset($dummyRecord);
             unset($colTable);
             unset($elementFilter);
         }
     } else {
         if (isset($widget['fields'])) {
             $widget_fields =& $widget['fields'];
             foreach ($widget_fields as $widget_field) {
                 $widget_field =& Dataface_Table::getTableField($widget_field, $this->db);
                 if (PEAR::isError($widget_field)) {
                     return $widget_field;
                 }
                 $widget_widget = $formTool->buildWidget($record, $widget_field, $factory, $widget_field['name']);
                 $defaultValue = $table->getDefaultValue($widget_field['name']);
                 $widget_widget->setValue($defaultValue);
                 $el->addField($widget_widget);
                 $el->defaults[$widget_field['name']] = $defaultValue;
             }
         } else {
             if (isset($field['fields'])) {
                 foreach (array_keys($field['fields']) as $field_key) {
                     $widget_widget = $formTool->buildWidget($record, $field['fields'][$field_key], $factory, $field['fields'][$field_key]['name']);
                     $defaultValue = $table->getDefaultValue($widget_field['name']);
                     $widget_widget->setValue($defaultValue);
                     $el->defaults[$widget_field['name']] = $defaultValue;
                     $el->addField($widget_widget);
                     unset($widget_widget);
                 }
             }
         }
     }
     return $el;
 }