1

所以,我有一个支持从 Excel 文件上传数据到模型的行为。在此行为中,我调用 saveMany,它工作正常。但是,如果数据无效,我不会收到任何错误,只会出现静默失败(在这种情况下我会返回一般错误,但我想要验证失败的详细信息)。

我确信有一种方法可以解决这个问题,我作为一个 CakePHP 新手,不知道。这是行为的主要功能(这里有一堆额外的逻辑可能与问题无关,但我不愿意剔除它以防它被证明是微妙相关的):

public function parseExcelFile(Model &$model, $fileInfo, $lookupKeys, $otherData = null, $referencedFields = null) {
    $allowedTypes = array('application/vnd.ms-excel');
    if ((isset($fileInfo['error']) && $fileInfo['error'] == 0) ||
        (!empty( $fileInfo['tmp_name']) && $fileInfo['tmp_name'] != 'none')) {
        // basic pre-checks are done.  Now ask PHP if it's a good file
        if (is_uploaded_file($fileInfo['tmp_name'])) {
            // it's a good uploaded file.  Now check the type
            if (in_array($fileInfo['type'], $allowedTypes)) {

                $data = new Spreadsheet_Excel_Reader($fileInfo['tmp_name']);

                // Check text of header row to be sure that it hasn't been changed (equal to db field name)
                $numAltered = 0;
                $numAdded = 0;
                $schema = $model->schema();
                $newModelData = array($model->name => array()); // this is a holder for the data to be added to the model
                $fieldlist = array();   // this will be an array of field names found in the Excel file, and which we have data for
                $newData = $this->modifyDataForReferencedFields($model, $data, $referencedFields);  // $newData is now 0-based.
                for ($curCol = 0; $curCol < count($newData[0]); $curCol++) {
                    $curFieldName = $newData[0][$curCol];
                    if (!array_key_exists($curFieldName, $schema)) {
                        return 'Row header "'.$curFieldName.'" is not one of the database fields.'
                                .'  You probably altered the template in an incorrect manner.';
                    } else {
                        // set up the fieldlist and newModelData arrays
                        array_push($fieldlist, $curFieldName);
                        $newModelData[$model->name][$curFieldName] = null;
                    }
                }
                // append $otherData fields to fieldlist
                foreach ($otherData as $key => $value) {
                    array_push($fieldlist, $key);
                }

                // So, the headers seem okay, let's try to enter the data into the Model
                $saveData = array();
                for ($curRow = 1; $curRow < count($newData); $curRow++) {   // row 0 is the headers
                    // put the data into the newModelData
                    for ($curCol = 0; $curCol < count($newData[0]); $curCol++) {
                        $curFieldName = $newData[0][$curCol];
                        $curVal = $newData[$curRow][$curCol];
                        $newModelData[$model->name][$curFieldName] = $curVal;
                    }
                    $existingID = $this->existingID($model, $lookupKeys, $newModelData[$model->name]);
                    if ($existingID) {
                        // we must be updating a model entry, so set the ID
                        $newModelData[$model->name]['id'] = $existingID;
                        $numAltered++;
                    } else {
                        // otherwise, unset
                        unset($newModelData[$model->name]['id']);
                        $numAdded++;
                    }

                    // Add in the fixed fields
                    foreach ($otherData as $key => $value) {
                        $newModelData[$model->name][$key] = $value;
                    }
                    array_push($saveData, $newModelData);
                }
                $options = array('fieldlist' => $fieldlist);
                if ($model->saveMany($saveData, $options)) {
                    return 'From the uploaded file, '.$numAdded.' records were added and '.$numAltered.' records were updated.';
                } else {
                    return 'There was a problem with the uploaded data.';
                }
            } else {
                return "The chosen file was not one of the allowed types.";
            }
        } else {
            return "There was something wrong with the upload process.";
        }
    } else {
        return "No file was chosen for uploading.";
    }
}

这是上传表单提交时调用的控制器操作:

public function processUpload() {
    // now parse the file in the model
    $result = $this->Instructor->parseExcelFile(
        $this->data['Instructor']['bulkData'],
        array(  // field(s) for looking up data in the model to see if we are adding or updating
            'username',
        ),
        array(  // a set of fixed fields to add to all entries, new or updates
            'department_id' => $this->request->data['Instructor']['department_id'],
            'role' => 'instructor',
            'password' => '')
    );
    $this->Session->setFlash($result);                  
    $this->redirect($this->referer(), null, true);
}

提前致谢。-戴夫

4

1 回答 1

1

该模型有一些方法可以调用以检查记录。你应该可以使用 Model->validateMany() 模型类还有一些其他的手动验证方法:

Model->validateAssociated()用于验证单个记录及其所有直接关联的记录,而Model->validates()如果所有字段都通过验证,则返回 true。

检查Cake Book的 DataValidation 部分。Cake 2.2.x 还引入了动态更改验证规则的概念,它可以派上用场。

干杯! :)

于 2012-09-19T06:58:43.030 回答