uploadedfile subir multiple kartik imagenes files example archivos php file-upload yii2

php - subir - yii2-Entrada de archivo Kartik-actualización



yii2 upload file ajax (4)

Después de una tarde horrible y una noche más productiva, encontré una solución que funcionó para mí ...

El principal problema era que la entrada del archivo no enviaba su valor (nombre del archivo almacenado en la base de datos) al actualizar. Solo envía la información de la imagen si se busca y se selecciona a través de la entrada de archivo.

Entonces, mi solución fue crear otro campo "virtual" para administrar la carga de archivos, llamado "upload_image". Para lograr esto, simplemente agregué una propiedad pública con este nombre a mi clase de modelo: public $upload_image;

También agregué la siguiente validación al método de reglas en la clase Modelo:

public function rules() { return [ [[''upload_image''], ''file'', ''extensions'' => ''png, jpg'', ''skipOnEmpty'' => true], [[''image''], ''required''], ]; }

Aquí, ''upload_image'' es mi columna virtual. Agregué la validación de ''archivo'' con ''skipOnEmpty'' = true, y ''image'' es el campo en mi base de datos, que debe ser requerido en mi caso.

Luego, en mi opinión, configuré el widget ''upload_image'' de la siguiente manera:

echo FileInput::widget([ ''model'' => $model, ''attribute'' => ''upload_image'', ''pluginOptions'' => [ ''initialPreview''=>[ Html::img("/uploads/" . $model->image) ], ''overwriteInitial''=>true ] ]);

En la opción ''initialPreview'', señalo mi nombre de imagen, almacenado en la propiedad ''$ model-> image'' devuelta desde la base de datos.

Finalmente, mi controlador luce como sigue:

public function actionUpdate($id) { $model = $this->findModel($id); $model->load(Yii::$app->request->post()); if(Yii::$app->request->isPost){ //Try to get file info $upload_image = /yii/web/UploadedFile::getInstance($model, ''upload_image''); //If received, then I get the file name and asign it to $model->image in order to store it in db if(!empty($upload_image)){ $image_name = $upload_image->name; $model->image = $image_name; } //I proceed to validate model. Notice that will validate that ''image'' is required and also ''image_upload'' as file, but this last is optional if ($model->validate() && $model->save()) { //If all went OK, then I proceed to save the image in filesystem if(!empty($upload_image)){ $upload_image->saveAs(''uploads/'' . $image_name); } return $this->redirect([''view'', ''id'' => $model->id]); } } return $this->render(''update'', [ ''model'' => $model, ]); }

Esta es la situación: soy nuevo en Yii2 y quería usar algún widget de carga de archivos dentro de ActiveForm ... hasta ahora he encontrado este excelente: / kartik / widget / FileInput

Con este widget puedo administrar la carga de archivos y luego, al ingresar en el modo de edición, mostrar la imagen cargada anterior con la oportunidad de reemplazarla.

El problema es que si presiono el botón "Actualizar" del formulario sin modificar la imagen yii dice que la imagen "no puede estar vacía" porque he establecido la regla ''requerida'' en mi modelo.


Intente precargar el campo de entrada del archivo con el contenido de ese campo. De esta manera, no perderá datos después de enviar su formulario.

Miré a través del widget de entrada de archivos kartik (nice find, btw) y encontré una forma de hacerlo

// Display an initial preview of files with caption // (useful in UPDATE scenarios). Set overwrite `initialPreview` // to `false` to append uploaded images to the initial preview. echo FileInput::widget([ ''name'' => ''attachment_49[]'', ''options'' => [ ''multiple'' => true ], ''pluginOptions'' => [ ''initialPreview'' => [ Html::img("/images/moon.jpg", [''class''=>''file-preview-image'', ''alt''=>''The Moon'', ''title''=>''The Moon'']), Html::img("/images/earth.jpg", [''class''=>''file-preview-image'', ''alt''=>''The Earth'', ''title''=>''The Earth'']), ], ''initialCaption''=>"The Moon and the Earth", ''overwriteInitial''=>false ] ]);

También es posible que desee relajar la regla required en su modelo para ese campo, para que no se queje en la validación. Puede optar por solicitar al usuario a través de medios más sutiles.


He encontrado otra solución al crear escenarios. En tu caso, modificaría las reglas de esta manera:

public funtion rules() { [[''image''], ''file''], [[''image''], ''required'', ''on''=> ''create''] }

Por lo tanto, el campo de carga de archivos se requerirá solo en crear acción. En acción de actualización, tengo este código:

public function actionUpdate($id) { $model = $this->findModel($id); if ($model->load(Yii::$app->request->post())) { $newCover = UploadedFile::getInstance($model, ''image''); if (!empty($newCover)) { $newCoverName = Yii::$app->security->generateRandomString(); unlink($model->cover); $model->cover = ''uploads/covers/'' . $newCoverName . ''.'' . $newCover->extension; $newCover->saveAs(''uploads/covers/'' . $newCoverName . ''.'' . $newCover->extension); } if ($model->validate() && $model->save()) { return $this->redirect([''view'', ''id'' => $model->post_id]); } else { // error saving model } } else { return $this->render(''update'', [ ''model'' => $model, ]); } }

En el escenario de actualización, la imagen archivada no es necesaria, pero el código verifica si no se subió nada y no cambia el valor anterior.

Mi archivo de formulario:

<?= $form->field($model, ''image'')->widget(FileInput::classname(), [ ''options'' => [''accept''=>''image/*''], ''pluginOptions''=>[ ''allowedFileExtensions''=>[''jpg'', ''gif'', ''png'', ''bmp''], ''showUpload'' => true, ''initialPreview'' => [ $model->cover ? Html::img($model->cover) : null, // checks the models to display the preview ], ''overwriteInitial'' => false, ], ]); ?>

Creo que es un poco más fácil que un campo virtual. ¡Espero eso ayude!


De Krajee:

http://webtips.krajee.com/advanced-upload-using-yii2-fileinput-widget

Crear, eliminar, actualizar: realmente fácil, no busques más.

(1) También he establecido la regla ''requerida'' en mi modelo.

(2) Para trabajar en Wampserver:

Yii::$app->params[''uploadPath''] = Yii::$app->basePath . ''/web/uploads/''; Yii::$app->params[''uploadUrl''] = Yii::$app->urlManager->baseUrl . ''/uploads/'';