diff --git a/application/controllers/TableController.php b/application/controllers/TableController.php index b6c10df..d27553a 100644 --- a/application/controllers/TableController.php +++ b/application/controllers/TableController.php @@ -520,13 +520,16 @@ public function addAction() // Determine fields being added. Remove null fields. $addValues = $this->_fillInitValues($setTable, $form->getFieldValues()); - $meaningfulData = $this->_getFilledFields($addValues); - $meaningfulData = $setTable->removeImports($meaningfulData); + if ( $addValues != null ) + { + $meaningfulData = $this->_getFilledFields($addValues); + $meaningfulData = $setTable->removeImports($meaningfulData); - // Update the database and redisplay the record. - $setTable->addTableEntry($meaningfulData); - $this->_executeSearch($setTable, $meaningfulData, null, - self::DISPLAY_ALL); + // Update the database and redisplay the record. + $setTable->addTableEntry($meaningfulData); + $this->_executeSearch($setTable, $meaningfulData, null, + self::DISPLAY_ALL); + } } else { @@ -1128,9 +1131,6 @@ protected function _isUnaryComparator($field, $comparators) /** * Fill in initial values based on information in setting. - * TODO: Is there any need to consider cases where the - * "external table" is this table, so one field is being - * initialized from another that is not in the database yet? * * @param Application_Model_SetTable table: setting & db info * @param array $data Column-value pairs representing provided data @@ -1138,40 +1138,33 @@ protected function _isUnaryComparator($field, $comparators) protected function _fillInitValues($setTable, array $data) { $storedSourceRecs = array(); - $searchData = $data; $initializedData = $data; // Loop through fields in this table to see if any should be // initialized from values in another table. - $inputFieldNames = array_keys($data); - $relevantFields = $this->view->tableInfo->getExternallyInitFields(); - // Why wasn't this written as the simpler: ? - // $relevantFields = $setTable->getExternallyInitFields(); + $relevantFields = $setTable->getExternallyInitFields(); foreach ( $relevantFields as $newFieldName => $newField ) { - // Initialize from another table if data not already provided. - if ( $data[$newFieldName] == null ) + // Get table reference used by this field. + $sourceTblName = $newField->getInitTableName(); + + // Has the relevant record been read from that table? + if ( ! isset($storedSourceRecs[$sourceTblName]) ) { - // Determine initializing table; see if source record - // has already been retrieved. - $sourceTblName = $newField->getInitTableName(); - if ( ! isset($storedSourceRecs[$sourceTblName]) ) + // Use viewing sequence to search for appropriate record. + $sourceRecord = $this->_getSourceRecord($setTable, + $sourceTblName, $data); + if ( $sourceRecord == null ) { - $sourceRecord = - $this->_getSourceRecord($setTable, $sourceTblName, - $data); - if ( $sourceRecord == null ) - { - continue; - } - else - { - $storedSourceRecs[$sourceTblName] = $sourceRecord; - } + return null; + } + else + { + $storedSourceRecs[$sourceTblName] = $sourceRecord; } - $sourceRecord = $storedSourceRecs[$sourceTblName]; - $initializedData[$newFieldName] = $sourceRecord[$newFieldName]; } + $sourceRecord = $storedSourceRecs[$sourceTblName]; + $initializedData[$newFieldName] = $sourceRecord[$newFieldName]; } return $initializedData; @@ -1189,6 +1182,13 @@ protected function _getSourceRecord($setTable, $sourceTblName, $userData) // Need to retrieve initializing record; check that // user provided enough information to find it. $initRef = $setTable->getInitRefInfo($sourceTblName); + if ( $initRef == null ) + { + $this->view->errMsgs[] = + "Cannot initialize fields from $sourceTblName -- " . + "no 'initTableRef` information provided."; + return null; + } $sourceTbl = $initRef->getViewingSeq()->getSetTableForAdding(); $searchKeys = $initRef->xlFieldValuePairs($userData); $matches = $sourceTbl->getTableEntries($searchKeys); @@ -1197,9 +1197,9 @@ protected function _getSourceRecord($setTable, $sourceTblName, $userData) // Cannot initialize with info provided; proceed // directly to next field. $this->view->errMsgs[] = - "Cannot initialize $newFieldName from " . - "$sourceTblName -- insufficient primary " . - "key information to find source record."; + "Cannot initialize fields from $sourceTblName -- " . + "insufficient primary key information to find unique " . + "source record."; return null; } else @@ -1208,6 +1208,52 @@ protected function _getSourceRecord($setTable, $sourceTblName, $userData) } } + /** + * Fill in initial values based on information in setting. + * + * @param Application_Model_SetTable table: setting & db info + * @param array $data Column-value pairs representing provided data + protected function _fillInitValues($setTable, array $data) + { + $storedSourceRecs = array(); + $searchData = $data; + $initializedData = $data; + + // Loop through fields in this table to see if any should be + // initialized from values in another table. + $relevantFields = $setTable->getExternallyInitFields(); + foreach ( $relevantFields as $newFieldName => $newField ) + { + // Initialize from another table if data not already provided. + if ( $data[$newFieldName] == null ) + { + // Determine initializing table; see if source record + // has already been retrieved. + $sourceTblName = $newField->getInitTableName(); + if ( ! isset($storedSourceRecs[$sourceTblName]) ) + { +throw new Exception("Wanting to initialize fields from " . print_r($sourceTblName, true) . " using set table " . $setTable->getSettingName() . " and data " . print_r($data, true)); + $sourceRecord = + $this->_getSourceRecord($setTable, $sourceTblName, + $data); + if ( $sourceRecord == null ) + { + continue; + } + else + { + $storedSourceRecs[$sourceTblName] = $sourceRecord; + } + } + $sourceRecord = $storedSourceRecs[$sourceTblName]; + $initializedData[$newFieldName] = $sourceRecord[$newFieldName]; + } + } + + return $initializedData; + } + */ + /** * Acquires the lock for the given record in the specified table. * diff --git a/application/devSettings/Smart/Curriculum/ModuleOfferingAdd.ini b/application/devSettings/Smart/Curriculum/ModuleOfferingAdd.ini index dc68728..8949373 100644 --- a/application/devSettings/Smart/Curriculum/ModuleOfferingAdd.ini +++ b/application/devSettings/Smart/Curriculum/ModuleOfferingAdd.ini @@ -9,16 +9,24 @@ initTableRef.Modules.viewingSequence = Smart/Curriculum/Modules initTableRef.Modules.match1.localField = "moduleID" initTableRef.Modules.match1.externalField = "moduleID" +initTableRef.Terms.viewingSequence = Smart/Term/Terms +initTableRef.Terms.match1.localField = "term" +initTableRef.Terms.match1.externalField = "term" + field.term.label = "Term" field.term.selectFrom = "Terms.term" + field.moduleID.label = "Module ID" field.moduleID.selectUsing = "Smart/Curriculum/Modules" -field.section.label = "Section Number" + field.modCode.label = "Code" field.modCode.initFrom = "Modules" field.modNumber.label = "Number" field.modNumber.initFrom = "Modules" + +field.section.label = "Section Number" + field.shortTitle.label = "Short Title" field.shortTitle.initFrom = "Modules" field.longTitle.label = "Long Title" @@ -31,6 +39,7 @@ field.capacity.label = "Capacity" field.capacity.initFrom = "Modules" field.type.label = "Module Type" field.type.initFrom = "Modules" + field.startDate.label = "Start Date" field.startDate.initFrom = "Terms" field.endDate.label = "End Date" diff --git a/application/devSettings/Smart/Curriculum/ModuleOfferings.ini b/application/devSettings/Smart/Curriculum/ModuleOfferings.ini index 5eb2929..cf90cc0 100644 --- a/application/devSettings/Smart/Curriculum/ModuleOfferings.ini +++ b/application/devSettings/Smart/Curriculum/ModuleOfferings.ini @@ -14,7 +14,6 @@ sequence.searchResultsSetting = Smart/Curriculum/ModuleOfferingSelection [ View ] tableName = "ModuleOfferings" -tableConnection.Modules = "ModuleOfferings.moduleID = Modules.moduleID" tableTitle = "Module Offerings" tableDescription = "Details about Specific Module Offerings/Sections" diff --git a/application/models/SetTable.php b/application/models/SetTable.php index 9a0acc4..7cd4d37 100644 --- a/application/models/SetTable.php +++ b/application/models/SetTable.php @@ -1379,6 +1379,7 @@ public function getErrorMsgs() */ public function summarizeSyntaxChecking() { + $this->_recordErrors = true; $present = " "; $absent = " "; @@ -1440,47 +1441,56 @@ public function summarizeSyntaxChecking() // Check table connections, importedFrom clauses. if ( ! empty($this->_joinExpressions) ) - foreach ( $this->_joinExpressions as $tableName => $expression ) - { - $this->_error_msgs[] = "==> Checking table connections and " . - "imported fields for $tableName..."; - $prevNumErrorMsgs = count($this->_error_msgs); - $cols = null; - $prevErrMsgCount = count($this->_error_msgs); - - // Get table's real name (not alias). - $realName = isset($expression[self::ALIAS]) - ? $expression[self::ALIAS] : $tableName; - if ( $realName != $tableName ) + { + foreach ( $this->_joinExpressions as $tableName => $expression ) { - $this->_error_msgs[] = "$tableName is an alias for $realName."; - } + $this->_error_msgs[] = "==> Checking table connections " . + "for $tableName..."; + $prevNumErrorMsgs = count($this->_error_msgs); + $cols = null; + $prevErrMsgCount = count($this->_error_msgs); + + // Get table's real name (not alias). + $realName = isset($expression[self::ALIAS]) + ? $expression[self::ALIAS] : $tableName; + if ( $realName != $tableName ) + { + $this->_error_msgs[] = + "$tableName is an alias for $realName."; + } - // Test if it is a valid table in the database. - $cols = $this->_testTable($realName, true); + // Test if it is a valid table in the database. + $cols = $this->_testTable($realName, true); + if ( $prevNumErrorMsgs == count($this->_error_msgs) ) + { + $this->_error_msgs[] = "    $present"; + } - if ( empty($this->_importAliases[$tableName]) ) - { - $this->_error_msgs[] = "Table connection for $tableName " . - "has no imported fields."; - } - else - { - // Test if field imports are valid. - $fieldAliases = $this->_importAliases[$tableName]; - $aliasLocalNames = array_keys($fieldAliases); - $localFieldNames = array_keys($this->_visibleFields); - $this->_testFields($aliasLocalNames, $localFieldNames, - $this->_settingName . " setting", - "Importing"); - $this->_testFields($fieldAliases, $cols, - $realName, "Importing"); - } - if ( $prevNumErrorMsgs == count($this->_error_msgs) ) - { - $this->_error_msgs[] = "    $present"; + $this->_error_msgs[] = "==> Checking importFrom references... "; + $prevNumErrorMsgs = count($this->_error_msgs); + if ( empty($this->_importAliases[$tableName]) ) + { + $this->_error_msgs[] = "Table connection for $tableName " . + "has no imported fields."; + } + else + { + // Test if field imports are valid. + $fieldAliases = $this->_importAliases[$tableName]; + $aliasLocalNames = array_keys($fieldAliases); + $localFieldNames = array_keys($this->_visibleFields); + $this->_testFields($aliasLocalNames, $localFieldNames, + $this->_settingName . " setting", + "Importing"); + $this->_testFields($fieldAliases, $cols, + $realName, "Importing"); + } + if ( $prevNumErrorMsgs == count($this->_error_msgs) ) + { + $this->_error_msgs[] = "    $present"; + } } - } + } // Check initialize-from information. $this->_error_msgs[] = @@ -1488,7 +1498,20 @@ public function summarizeSyntaxChecking() $prevNumErrorMsgs = count($this->_error_msgs); if ( ! empty($this->_initTblRefs) ) { - $this->_testExternalRefs($this->_initTblRefs, "initTableRef"); + $locFields = $this->_testExternalRefs($this->_initTblRefs, + "initTableRef"); + // Are the fields used for the init reference search required? + foreach ( $locFields as $searchField ) + { + $field = $this->getFieldObject($searchField); + if ( ! $field->valueNecessaryForAdd() ) + { + $this->_error_msgs[] = "$searchField is required for " . + "initialization of other fields but has not been " . + "marked 'required'. (OK if this setting not used " . + "for ADD)."; + } + } } if ( $prevNumErrorMsgs == count($this->_error_msgs) ) { @@ -1504,6 +1527,14 @@ public function summarizeSyntaxChecking() $cols = $this->_testTable($sourceTblName, true); $this->_testFields(array($sourceFieldName), $cols, $sourceTblName, "Initialization"); + // Is there a relevant initTableReference property for the field? + $initRef = $this->getInitRefInfo($sourceTblName); + if ( $initRef == null ) + { + $this->_error_msgs[] = + "There is no 'initTableRef` information provided " . + "for $sourceFieldName" . ".initFrom = $sourceTblName"; + } } if ( $prevNumErrorMsgs == count($this->_error_msgs) ) { @@ -1549,9 +1580,9 @@ public function summarizeSyntaxChecking() /** * Tests that the given table name represents an actual table in the - * database. Returns the columns for that table if so. Adds an - * error message to the _error_msgs instance variable and returns an - * empty array if the table was invalid. + * database. Returns the columns for that table if so. Throws an + * exception or adds an error message to the _error_msgs instance + * variable and returns an empty array if the table was invalid. */ protected function _testTable($tableName, $recordErrors = false) { @@ -1563,6 +1594,8 @@ protected function _testTable($tableName, $recordErrors = false) } catch (Exception $e) { + // Could be used by getTableEntries in future, so allow the + // possibility of throwing an exception. if ( $recordErrors ) { $tableName = $tableName ? : "[no name]"; @@ -1599,6 +1632,7 @@ protected function _testFields($fieldNames, $tableCols, */ protected function _testExternalRefs($references, $type) { + $allLocalConnFields = array(); foreach ( $references as $keyword => $refInfo ) { try @@ -1608,25 +1642,23 @@ protected function _testExternalRefs($references, $type) } catch (Exception $e) { - if ( $this->_recordErrors ) - { - $seqName = $refInfo->getViewingSeqName(); - $this->_error_msgs[] = "Error: $seqName is not a valid " . - "table setting/sequence file."; - return; - } - else - { throw new Exception($e->getMessage()); } + $seqName = $refInfo->getViewingSeqName(); + $this->_error_msgs[] = "Error: $seqName is not a valid " . + "table setting/sequence file."; + return; } $tableName = $setting->getDbTableName(); $cols = $this->_testTable($tableName, true); $connections = $refInfo->getConnectionExpressions(); - $localFields = array_keys($connections); - $localFieldNames = array_keys($this->_visibleFields); - $this->_testFields($localFields, $localFieldNames, + $localConnectionFields = array_keys($connections); + $allLocalConnFields = array_merge($allLocalConnFields, + $localConnectionFields); + $allLocalFieldNames = array_keys($this->_visibleFields); + $this->_testFields($localConnectionFields, $allLocalFieldNames, $this->_settingName . " setting", $type); $this->_testFields($connections, $cols, $tableName, $type); } + return $allLocalConnFields; } protected function _checkExtraneousSettings() diff --git a/public/css/rampColorScheme.css b/public/css/rampColorScheme.css index f3be2d9..0f3e3c3 100644 --- a/public/css/rampColorScheme.css +++ b/public/css/rampColorScheme.css @@ -249,9 +249,11 @@ input.statusCode { background-color: #FAFFFA; /* was #efe; Could be F6FFF6 */ } -#record-block.edit input.readonly { +#record-block.edit input.readonly, +#record-block.add input.readonly +{ background-color: #FAFFFA; /* was #efe; Could be #F6FFF6 */ - color: #999; + color: #aaa; } diff --git a/public/css/smartColorScheme.css b/public/css/smartColorScheme.css index a981a46..3237c91 100644 --- a/public/css/smartColorScheme.css +++ b/public/css/smartColorScheme.css @@ -257,9 +257,11 @@ input.statusCode { background-color: #FAFFFA; /* was #efe; Could be F6FFF6 */ } -#record-block.edit input.readonly { +#record-block.edit input.readonly, +#record-block.add input.readonly +{ background-color: #FAFFFA; /* was #efe; Could be #F6FFF6 */ - color: #999; + color: #aaa; } /* Did not work great... (Green too small, needs box around icon). diff --git a/public/css/smartTestColorScheme.css b/public/css/smartTestColorScheme.css index b27e362..45c137d 100644 --- a/public/css/smartTestColorScheme.css +++ b/public/css/smartTestColorScheme.css @@ -247,9 +247,11 @@ input.statusCode { background-color: #FAFFFA; /* was #efe; Could be F6FFF6 */ } -#record-block.edit input.readonly { +#record-block.edit input.readonly, +#record-block.add input.readonly +{ background-color: #FAFFFA; /* was #efe; Could be #F6FFF6 */ - color: #999; + color: #aaa; }