I have a script that allows me to upload a CSV file, each line of the CSV is read and if valid (e.g it validates) will insert a new row to a ‘users’ database table using a model.
On some occasions it is possible for duplicates to be found within a CSV, obviously these should not be inserted into the table for data integrity, therefore I am using transactions to basically do a ‘rollback’ if a duplicate is found. This works so far however I’d like to improve this further by being able to highlight each of the problem lines in the CSV by adding this to the $model->getErrors() so it can be used within the flash message for example.
Currently what I have works, however it only provides the csv line of the very first ‘error’ and not any others - is there any way to achieve this to return more than just than first error to the errors array.
Currently at the bottom of the script, the following line is what displays the errors, I can only seem to get errors to return one item (even though it is in a foreach) it only ever contains a single item, but want this to contain multiple items (if multiple duplicates exist)
Yii::app()->user->setFlash(‘importerrors’, $errors);
I am not sure if this is possible in the current structure as I am throwing an Exception…
Any advice would be appreciated
P.S For clarity I have not included the entire function… just the element that is relevant to my question.
<?php
$transaction = Yii::app()->db->beginTransaction();
$errors = array();
try
{
if (($handle = fopen($path, "r")) !== false) {
while (($data = fgetcsv($handle)) !== FALSE) {
if ($currentRow == 1) {
$header = $this->import_fields(array_map('strtolower', $data));
$currentRow++;
continue;
} else {
$data = array_combine($header, $data);
$csv_import_model = null;
if (!empty($data['username'])) {
$csv_import_model = StudentImportForm::model()->findByAttributes(array(
'username' => $data['username'],
'organisation_id' => user()->data->organisation->getViewOrgId()
));
}
if (is_null($csv_import_model)) {
$csv_import_model = new StudentImportForm();
$isNew = true;
} else {
$isNew = false;
}
$csv_import_model->scenario = 'import';
$csv_import_model->setAttributes($data);
$csv_import_model->unsetAttributes(array('password'));
if ($csv_import_model->validate()) {
if (in_array($csv_import_model->username, $processedUsername)) {
$errors[$currentRow] = sprintf('Duplicate username (%1$s) found in csv file. which may already exists on row number %2$s.', $csv_import_model->username, (array_search($csv_import_model->username, $processedUsername) + 1));
throw new Exception('Problem with your CSV - No Student data saved.');
} else {
if ($csv_import_model->save()) {
if ($isNew) {
$this->csv_results['inserted'] = $this->csv_results['inserted']+1;
} else {
$this->csv_results['updated'] = $this->csv_results['updated']+1;
}
} else {
$this->csv_results['error'][$currentRow] = $csv_import_model->getErrors();
throw new Exception('Problem with your CSV - No Student data saved.');
}
}
} else {
$csv_import_model->csv_index = $currentRow;
$this->csv_results['error'][$currentRow] = $csv_import_model->getErrors();
throw new Exception('Problem with your CSV - No Student data saved.');
}
$processedUsername[] = $csv_import_model->username;
$currentRow++;
Yii::getLogger()->flush(false);
}
}
fclose($handle);
}
$transaction->commit();
}
catch(Exception $e)
{
$transaction->rollback();
$this->csv_results = array('inserted' => 0, 'updated' => 0);
Yii::app()->user->setFlash('importerrors', $errors);
Yii::app()->user->setFlash('error', "{$e->getMessage()}");
}