0

I have a application using Yii2 basic framework, and I'm using Kartik InputFile for upload file. The file successfully uploaded to the system, and the page also successfully redirect to next page, but a few second before the page redirect to next page, it display an error in progress bar like this enter image description here

Why this widget show notification "upload failed" although the file successfully uploaded?

This is my code in _form.php:

<?php $form = ActiveForm::begin(); ?>
<?php
echo FileInput::widget([
    'name' => 'file_uploads',
    'language' => 'id',
    'options' => [
        'accept' => 'doc/*', 'file/*',
        'multiple' => true,
        'enableLabel' => true,
    ],
    'pluginOptions' => [
        'allowedFileExtensions' => ['xls', 'xlsx'],
        'uploadUrl' => Url::to(['/pib/pib-data/create']),
        'maxFileSize' => 1024,
        'maxFileCount' => 1,
        'showCaption' => false,
        'showMessage'=>false,
        'purifyHtml'=>false
    ]
]);
?>
<?php ActiveForm::end(); ?>

and this the code that I've used in controller:

<?php
public function actionCreate() {
    $model = new PibData();
    $connection = \Yii::$app->db;
    $userId = Yii::$app->user->id;
    if (Yii::$app->user->isGuest) {
        return $this->redirect(['/site/login']);
    }

    $sqlHeader = "UPDATE pib_data SET is_exported = '1' WHERE user_id = '$userId'";
    $exeQuery = Yii::$app->db->createCommand($sqlHeader)->execute();
    $date = new DateTime('now', new \DateTimeZone('Asia/Jakarta'));
    $created_at = $date->format('Y:m:d H:i:s');
    $dirTrash = Yii::getAlias('@webroot/trash');
    $dirSubTrash = Yii::getAlias('@webroot/trash/trash_pib');

    if (!is_dir($dirTrash)) {
        mkdir(Yii::getAlias('@webroot/trash'));
        if (!is_dir($dirSubTrash)) {
            mkdir(Yii::getAlias('@webroot/trash/trash_pib'));
        }
    } else {
        if (!is_dir($dirSubTrash)) {
            mkdir(Yii::getAlias('@webroot/trash/trash_pib'));
        }
    }

    if (Yii::$app->request->post()) {
        $file = UploadedFile::getInstancesByName('file_uploads');
        $middleName = substr(md5(microtime() * 100000), rand(0, 9), 5);
        if ($file !== null) {
            $name = $userId . '_' . $middleName . '_' . date('Y-m-d') . '_' . $file[0]->getBaseName() . "." . $file[0]->getExtension();
            $pathproduct = Yii::getAlias('@webroot/trash/trash_pib/') . $name;
            $file[0]->saveAs($pathproduct);
        Yii::$app->response->format = Response::FORMAT_JSON;
        return [];
        } else {
            $error[] = "Silahkan pilih terlebih dahulu file" . "<strong>" . " Excel " . "</strong>" . "yang akan di convert.";
            Yii::$app->session->setFlash('error', $error);
            return $this->render('create', ['model' => $model]);
        }

        $modelUser = Users::find()->where(['id' => $userId])->one();
        $parentId = $modelUser->parent_id;

        $objPHPExcel = new \PHPExcel();
        $fileName = Yii::getAlias('@webroot/trash/trash_pib/') . $name;
        $inputFiles = fopen(Yii::getAlias('@webroot/trash/trash_pib/') . $name, "r");
        try {
            $inputFileType = \PHPExcel_IOFactory::identify($fileName);
            $objReader = \PHPExcel_IOFactory::createReader($inputFileType);
            $objPHPExcel = $objReader->load($fileName);
        } catch (Exception $ex) {
            die('Error');
        }

        $sheet = $objPHPExcel->getSheet(0);
        $highestRow = $sheet->getHighestDataRow();
        $highestColumn = $sheet->getHighestDataColumn();
        $colNumber = PHPExcel_Cell::columnIndexFromString($highestColumn);
        $col = $colNumber - 1;
        $arrayData = [];
        
        for ($row = 1; $row <= $highestRow; ++$row) {
            $rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);
            $arrayData[] = array_map(function($values) {
                $tempArray = [];
                foreach ($values as $key => $value) {
                    $newKey = $key + 1;
                    $tempArray[] = $newKey . '_' . $value;
                }
                return $tempArray;
            }, $rowData);
        }

        $arrayHeader = array_shift($arrayData);
        $countArrayData = count($arrayData);
        $countArrayHeader = count($arrayHeader[0]);

        for ($i = 0; $i < $countArrayData; $i++) {
            for ($j = 0; $j < $countArrayHeader; $j++) {
                if ($j < 9) {
                    $finalData[$i][] = substr($arrayData[$i][0][$j], 2);
                } else {
                    $finalData[$i][] = substr($arrayData[$i][0][$j], 3);
                }
            }
        }

        for ($x = 0; $x < $countArrayData; $x++) {
            array_unshift($finalData[$x], "dummy");
        }

        $tempData = mysql_escape_string(json_encode($finalData));
        $tempHeader = json_encode($arrayHeader);
        $header = base64_encode($tempHeader);

        $command_1 = "DELETE FROM pib_json_data WHERE user_id= '$userId'";
        $query_1 = Yii::$app->db->createCommand($command_1)->execute();
        $command_2 = "INSERT INTO pib_json_data(json_data, user_id, created_at) VALUES('$tempData', '$userId', '$created_at')";
        $query_2 = Yii::$app->db->createCommand($command_2)->execute();

        $_SESSION['header'] = $header;
        $_SESSION['validHeader'] = 'validHeader';

        return Yii::$app->response->redirect(['/pib/pib-header/select-header']);
    } else {
        return $this->render('create', [
                    'model' => $model,
        ]);
    }
}
?>

anyhelp will be apreciated.

Thanks

Community
  • 1
  • 1
Blackjack
  • 1,016
  • 1
  • 20
  • 51

1 Answers1

1

Well... according to documentation, in "IMPORTANT" section:

You MUST send a valid JSON response from your server, else the upload process will fail. Even if you do not encounter any error, you must at least send an empty JSON object {} from your server.

So, i believe your code should look like this.

Controller :

<?php
public function actionCreate() {
    $model = new PibData();
    $connection = \Yii::$app->db;
    $userId = Yii::$app->user->id;
    if (Yii::$app->user->isGuest) {
        return $this->redirect(['/site/login']);
    }

    $sqlHeader = "UPDATE pib_data SET is_exported = '1' WHERE user_id = '$userId'";
    $exeQuery = Yii::$app->db->createCommand($sqlHeader)->execute();
    $date = new DateTime('now', new \DateTimeZone('Asia/Jakarta'));
    $created_at = $date->format('Y:m:d H:i:s');
    $dirTrash = Yii::getAlias('@webroot/trash');
    $dirSubTrash = Yii::getAlias('@webroot/trash/trash_pib');

    if (!is_dir($dirTrash)) {
        mkdir(Yii::getAlias('@webroot/trash'));
        if (!is_dir($dirSubTrash)) {
            mkdir(Yii::getAlias('@webroot/trash/trash_pib'));
        }
    } else {
        if (!is_dir($dirSubTrash)) {
            mkdir(Yii::getAlias('@webroot/trash/trash_pib'));
        }
    }

    if (Yii::$app->request->post()) {
        Yii::$app->response->format = Response::FORMAT_JSON;
        $result = [];
        $file = UploadedFile::getInstancesByName('file_uploads');
        $middleName = substr(md5(microtime() * 100000), rand(0, 9), 5);
        if ($file !== null) {
            $name = $userId . '_' . $middleName . '_' . date('Y-m-d') . '_' . $file[0]->getBaseName() . "." . $file[0]->getExtension();
            $pathproduct = Yii::getAlias('@webroot/trash/trash_pib/') . $name;
            $file[0]->saveAs($pathproduct);
        } else {
            $error[] = "Silahkan pilih terlebih dahulu file" . "<strong>" . " Excel " . "</strong>" . "yang akan di convert.";
            //Yii::$app->session->setFlash('error', $error);
            //return $this->render('create', ['model' => $model]);
            $result = [
                'error' => $error
            ]; // change error notification used Kartik FileInput build-in error message 
        }

        $modelUser = Users::find()->where(['id' => $userId])->one();
        $parentId = $modelUser->parent_id;

        $objPHPExcel = new \PHPExcel();
        $fileName = Yii::getAlias('@webroot/trash/trash_pib/') . $name;
        $inputFiles = fopen(Yii::getAlias('@webroot/trash/trash_pib/') . $name, "r");
        try {
            $inputFileType = \PHPExcel_IOFactory::identify($fileName);
            $objReader = \PHPExcel_IOFactory::createReader($inputFileType);
            $objPHPExcel = $objReader->load($fileName);
        } catch (Exception $ex) {
            //die('Error');
            $result = [
                'error' => $ex
            ]; // change error notification used Kartik FileInput build-in error message 
        }

        $sheet = $objPHPExcel->getSheet(0);
        $highestRow = $sheet->getHighestDataRow();
        $highestColumn = $sheet->getHighestDataColumn();
        $colNumber = PHPExcel_Cell::columnIndexFromString($highestColumn);
        $col = $colNumber - 1;
        $arrayData = [];

        for ($row = 1; $row <= $highestRow; ++$row) {
            $rowData = $sheet->rangeToArray('A' . $row . ':' . $highestColumn . $row, NULL, TRUE, FALSE);
            $arrayData[] = array_map(function($values) {
                $tempArray = [];
                foreach ($values as $key => $value) {
                    $newKey = $key + 1;
                    $tempArray[] = $newKey . '_' . $value;
                }
                return $tempArray;
            }, $rowData);
        }

        $arrayHeader = array_shift($arrayData);
        $countArrayData = count($arrayData);
        $countArrayHeader = count($arrayHeader[0]);

        for ($i = 0; $i < $countArrayData; $i++) {
            for ($j = 0; $j < $countArrayHeader; $j++) {
                if ($j < 9) {
                    $finalData[$i][] = substr($arrayData[$i][0][$j], 2);
                } else {
                    $finalData[$i][] = substr($arrayData[$i][0][$j], 3);
                }
            }
        }

        for ($x = 0; $x < $countArrayData; $x++) {
            array_unshift($finalData[$x], "dummy");
        }

        $tempData = mysql_escape_string(json_encode($finalData));
        $tempHeader = json_encode($arrayHeader);
        $header = base64_encode($tempHeader);

        $command_1 = "DELETE FROM pib_json_data WHERE user_id= '$userId'";
        $query_1 = Yii::$app->db->createCommand($command_1)->execute();
        $command_2 = "INSERT INTO pib_json_data(json_data, user_id, created_at) VALUES('$tempData', '$userId', '$created_at')";
        $query_2 = Yii::$app->db->createCommand($command_2)->execute();

        $_SESSION['header'] = $header;
        $_SESSION['validHeader'] = 'validHeader';

        //return Yii::$app->response->redirect(['/pib/pib-header/select-header']);
        $result = [
            'url' => Url::to(['/pib/pib-header/select-header'])
        ]; // return url variable to be used by jquery
        return $result;
    } else {
        return $this->render('create', [
                    'model' => $model,
        ]);
    }
}
?>

View :

<?php

use yii\web\View;
...

<?php $form = ActiveForm::begin(); ?>
<?php
echo FileInput::widget([
    'name' => 'file_uploads',
    'language' => 'id',
    'options' => [
        'accept' => 'doc/*', 'file/*',
        'multiple' => true,
        'enableLabel' => true,
    ],
    'pluginOptions' => [
        'allowedFileExtensions' => ['xls', 'xlsx'],
        'uploadUrl' => Url::to(['/pib/pib-data/create']),
        'maxFileSize' => 1024,
        'maxFileCount' => 1,
        'showCaption' => false,
        'showMessage'=>false,
        'purifyHtml'=>false
    ]
]);
?>
<?php ActiveForm::end(); ?>

<?php
$this->registerJS("
    $('#input-id').on('fileuploaded', function(event, data, previewId, index) { // replace input-id with your file input id
        var response = data.response;
        $(location).attr('href', response.url); // redirect use jquery
    });", View::POS_END);

Hope it's help.

Happy coding. :)

  • Yeah you're right, I missed i :D I've tried your code, and It work, it doesn't give error message, but it doesn't redirect to next page. Actually it should be continue to `//another code`. Wish you can help :) Thanks – Blackjack Mar 15 '17 at 12:18
  • Well... if you could give me insight what's that "another code", maybe i could help. :) – MegaGrindStone Mar 15 '17 at 13:13
  • I've add the full action code :) Check it out. Thanks :) – Blackjack Mar 15 '17 at 14:48
  • I think you should handle redirect in view using javascript (or jquery). Updated my answer. Hope it help. :) – MegaGrindStone Mar 15 '17 at 17:21
  • Halo :D I've tried your code, but the javascript didn't work. It redirect to next page but it didn't give an response so it still show an error, and may I know where's I can find out the id of input file? Thanks :) – Blackjack Mar 16 '17 at 03:40
  • I never set any manual id, so if I not wrong the id should be `input-id` as you've said. – Blackjack Mar 16 '17 at 03:41
  • Hmm... i don't get you there, if javascript didn't work, how come it redirect to next page, as we use javascript to redirect the page. As to id of input file, you could right-click at "Select File" (or "Pilih File", as your "id" language) button, and click Inspect. In my end is "w1" (i don't set it manually), perhaps it's same in your's end too. – MegaGrindStone Mar 16 '17 at 07:43
  • AWESOME! It's work :D thankyou so much. I just chance the id become `w1`, and it's work :D. Are you an Indonesian? – Blackjack Mar 16 '17 at 09:44
  • It's OOT, but i had to say, yeah, i'm Indonesian... Hahaha – MegaGrindStone Mar 16 '17 at 16:25