Hace un par de días que me estoy haciendo un modulo que actualice la información que tengo en un sistema desarrollado en Yii2, por lo que decidí importar la información con un CSV que rescato de otra base de datos. Este post es sobre como arreglar un problema que existe al subir los archivos CSV al momento de ser validados.
A grandes rasgos subir archivos con Yii2 es bastante sencillo, se crea un modelo que se encarga de realizar las validaciones, se crea el controlador que pasa la información y la vista que en este caso mostrará el formulario para subir el archivo.
Al realizarlo con un archivo CSV esto no me funcionó, mientras que con todo el resto si, por lo que decidí publicar el proceso completo de como subir un archivo CSV a mi servidor usando Yii2.
Después de debugear bastante y escribir la pregunta en el foro de Yii sin respuesta encontré un bug report sobre el mismo proceso. Adjunto ambos links por si a alguien les sirve:
Siguiendo los mismos pasos de la guía para subir archivos de Yii2, lo primero que haremos es crear el modelo.
namespace app\models;
use yii\base\Model;
use yii\web\UploadedFile;
class UploadCSVForm extends Model
{
/**
* @var UploadedFile
*/
public $File;
public function rules()
{
return [
[
['File'], 'file', 'skipOnEmpty' => false,
'extensions' => 'png, jpg, csv, pdf',
'checkExtensionByMimeType' => false,
],
];
}
public function upload()
{
if ($this->validate()) {
$this->imageFile->saveAs('uploads/' . $this->imageFile->baseName . '.' . $this->imageFile->extension);
return true;
} else {
return false;
}
}
}
Lo único que hemos cambiado es la opción de configuración checkExtensionByMimeType para evitar el problema que detecte de manera errada el CSV como PlainText y no permita que se suba de manera adecuada.
Ahora creamos la vista en la que subiremos el archivo. Ojo, el modelo que ocupamos lo especificamos en el controlador y no en la vista.
<?php
use yii\widgets\ActiveForm;
?>
<?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?>
<?= $form->field($model, 'File')->fileInput() ?>
<button>Submit</button>
<?php ActiveForm::end() ?>
Ahora el controlador que junta nuestro modelo con la vista.
namespace app\controllers;
use Yii;
use yii\web\Controller;
use app\models\UploadForm;
use yii\web\UploadedFile;
class SiteController extends Controller
{
public function actionUploadCSV()
{
$model = new UploadCSVForm();
if (Yii::$app->request->isPost) {
$model->File = UploadedFile::getInstance($model, 'File');
if ($model->upload()) {
// file is uploaded successfully
return;
}
}
return $this->render('upload', ['model' => $model]);
}
}
Esto que fue tan sencillo, me costó un par de días darme cuenta cual fue la razón de no poder subir el CSV. Revisé Apache, los permisos, las carpetas, etc.
Espero que a nadie más le pase !
Origen: Uploading Files – Getting Data from Users – The Definitive Guide to Yii 2.0