2

I have an activeform using Ajax POST and the form fields are being sent, however it seems the file data is not. Here is the logically relevant code snippets from my files, underneath them is commentary on the test using a JS alert and the result

ActiveForm:

<?= $form->field($model, 'userphoto')->fileInput() ?>

Ajax Submit:

$script = <<< JS

$('form#{$model->formName()}').on('beforeSubmit', function(event)
{

    event.preventDefault();


    var form = $(this);

        formdata = new FormData(form[0]);

            $.ajax({
            url    : form.attr('action'),
            data        : formdata,
            cache       : false,
            contentType : false,
            processData : false,
            type        : 'POST',

            success: function (response) 
            {   
                alert(JSON.stringify(response.status);
                $.pjax.reload({container:'#usergrid'});
                $(form).trigger('reset'); 


            },
            });
            return false;
         });


JS;
$this->registerJs($script);

?>

Model:

use yii\web\UploadedFile;

class Usermanager extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
        return 'user';
    }

    public $userphoto;

    public function rules()
    {
        return [

        [['userphoto'], 'file', 'extensions' => 'jpg, png, gif', 
'skipOnEmpty' => true],

Controller:

namespace app\controllers;

use Yii;
use app\models\Usermanager;
use yii\web\Controller;
use yii\web\Response;
use yii\web\UploadedFile;

class UsermanagerController extends Controller
{

 public function actionCreate()
 {
  $model = new Usermanager();


  if(Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()) && Yii::$app->request->enableCsrfValidation)
  {
    Yii::$app->response->format = 'json';

    $userphoto = UploadedFile::getInstance($model, 'userphoto');
    /* return ['status' => $userphoto];  */
    $model->photo = "web/". $model->username. "." .$userphoto->extension;


        if($model->password !==''){
            $model->password = Yii::$app->security->generatePasswordHash($model->password);
        }

    if($model->validate())
    {   

        $model->save();

    }
    else
    {
    return ActiveForm::validate($model);  
        }
    }

   return $this->renderAjax('create', [
      'model' => $model
    ]);

  }

Here is the JS alert test result:

The test - (controller receives POST)

$userphoto = UploadedFile::getInstance($model, 'userphoto');
return ['status' => $userphoto];

The test result -> alert(JSON.stringify(response.status)):

{"name":"kde.jpg","tempName":"/tmp/phpjp3i4d",
"type":"image/jpeg","size":51253,"error":0}

As you can see the alert details the file attributes as if the file was received. However if an attempt is made to source the file extension thus:

$model->photo = "web/". $model->username. "." .$userphoto->extension;

The extension cannot be found. Further I have also tried to save with $userphoto->saveAs, however the console.log reports could not save null().

So does anyone have a successfully integrated AJAX Submit with file upload using YII2 that is maybe not using a Kartik widget ?

MichaelMcD
  • 31
  • 5
  • 1
    there are several answers posted [here](https://stackoverflow.com/questions/53355009/action-not-found-after-ajax-request/53362159#53362159) , [here](https://stackoverflow.com/questions/51905619/yii2-unable-to-upload-image/51940290#51940290) and [here](https://stackoverflow.com/questions/51905619/yii2-unable-to-upload-image/51940290#51940290) – Muhammad Omer Aslam Mar 14 '19 at 08:34
  • I took a look and can mostly refactor the JS on those solutions to process as mine does and can't see a noticeable difference. I have tried many solutions such as those however what I have arrived at thus is simple and responds to callbacks and fire alerts and gets it as far as appearing the filedata is getting posted but might not be getting processed by Yii2. – MichaelMcD Mar 14 '19 at 09:29
  • you havent added the code properly and i cant be sure what could be the reason can you add the complete code for the `actionCreate` – Muhammad Omer Aslam Mar 14 '19 at 10:49
  • Edited and added thanks. – MichaelMcD Mar 14 '19 at 11:09
  • your code works for me correctly and shows the extension what version are you using for `Yii2`, also verify if calling `return $userphoto->extension` instead of `$model->photo = "web/". $model->username. "." .$userphoto->extension;` and check if you are passing the `username` also – Muhammad Omer Aslam Mar 14 '19 at 12:32
  • when testing the above mentioned change the `alert(JSON.stringify(response.status);` to `alert(response);` and update what it shows you – Muhammad Omer Aslam Mar 14 '19 at 14:16
  • $model->username is passing ok. $userphoto->extension NULL Yii2 version 2.0.16.1 Basic template PHP 7.3.1 alert(response) = [object Object] Tried Chrome, Firefox & Brave – MichaelMcD Mar 14 '19 at 21:48
  • hmm , can you verify by running `php requirements.php` on your project root via terminal and see if the result shows you `fileinfo` extension installed it should show you output like this https://pastebin.com/BjDvsyeX – Muhammad Omer Aslam Mar 14 '19 at 23:11
  • # php phprequirements.php = Fileinfo extension: OK. FYI -Developer Tools Msg:jquery.js:9488 [Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help. ALSO -> Jquery v 3.3.1 – MichaelMcD Mar 14 '19 at 23:37
  • I will do some native php file extension testing and report back. – MichaelMcD Mar 15 '19 at 01:43
  • I have downloaded another composer instance of basic template and have copied my files in - Still not working. Further investigation of PHP performance continues. – MichaelMcD Mar 17 '19 at 22:26
  • I moved the entirety of the project onto an alternate webserver, and still no success in saving the file extension. I am able to alert the extension itself, however it appears to be dropping before saving. So I will trace the creation and processing of the temporary file and report the results. – MichaelMcD Mar 29 '19 at 20:20
  • i hardly think that could be the case because it would have affected the `$_FILES` functionality too, which isn't the case, but it is weird – Muhammad Omer Aslam Mar 30 '19 at 13:02
  • When I moved to the new webserver, I downloaded a new Yii Basic template just to be sure and copied in my components, controllers, models and views and everything else stayed untouched so it's hardly likely to be a Yii issue. I will attempt saving file as BLOB and load from db and see it that works. – MichaelMcD Mar 30 '19 at 21:08
  • I only just noticed that as per the JSON.stringify(alert)... that while the original filename displays the extension, the tempName does not. Unfortunately I cannot get into the /tmp/ of the webserver to ascertain if the tempName is being appended with the extension type and my knowledge of interpreting the JSON return Object...well I have to do some more research.... – MichaelMcD Mar 30 '19 at 21:29
  • Hosting allowed me to override php.ini with a local copy. A change to the upload_tmp_dir to become a path local to the project and the JSON.stringify(alert(... returned the new path but still no file in the folder. More work to be done.... – MichaelMcD Apr 01 '19 at 21:32
  • I am unable to resolve this. I have modified the yii2 basic template not using 'form', instead creating a route from the index.php directly to the create.php which is opening in a bootstrap modal from which the upload occurs, and which I did not think to mention earlier, though I cannot see how this would impact. – MichaelMcD Apr 23 '19 at 01:13
  • So a newbie this forum I am and ho hum due to something about reputation I cannot post a COMPLETE laravel AJAX post to send email working solution. Ri-di-culous. – MichaelMcD Jun 20 '19 at 02:22
  • i dont get what you are unable to do? are you saying that the code is too long and the post is restricting you to add the code? if so you can add a link to the pastebin – Muhammad Omer Aslam Jun 20 '19 at 18:42
  • I tried replying to someone else's comment and was prohibited due to my 'reputation'. – MichaelMcD Jun 21 '19 at 01:25

0 Answers0