2

I wrote a simple script in plain PHP that uses $_FILES['uploadedfile']['tmp_name'] to fetch a freshly uploaded file and process its contents directly without permanently storing it. The idea is to allow the user to upload a file containing several rows of data that will be automatically parsed and added to a database by the PHP script. There is no need to store the file itself or a reference to it in the database as only the file contents are important. I know of Import CSV to MySQL, but I am trying to keep things clean and easy for the user (and for the time being I am developing with phpDesktop + sqlite so that my application will be portable).

I am now trying to recreate this process within Agile Toolkit but I cannot seem to figure out how. I know that the filestore model must access ['tmp_name'] before it moves/renames the file but I cannot figure out how to poach just this functionality. I tried looking in /lib/Form/Field/Upload.php to see if any of the methods there might be of use, but I am quite new to PHP so these docs are baffling to me. getFilePath() looked promising, but it seems that $_FILES remains empty when I do something like:

$form = $page->add('Form');
$upl = $form->addField('Upload', 'file');
$form->addSubmit();

if ($form->isSubmitted()){
    $form->js()->univ()->alert($upl->isUploaded())->execute(); //sends js alert('false')
}

I realize that AJAX cannot be used to post files and I have a feeling this is part of the problem but I am not really sure where to go from here. Any help would sincerely be appreciated.

Thanks.

Community
  • 1
  • 1

2 Answers2

1

Agile Toolkit uploads file as soon as it is selected - moves it immediately into filestore and creates database record, so not really what you need.

Anything you write in a plain PHP can also work with Agile Toolkit. You can disable JavaScript in the form by doing this:

$this->add('Form',array('js_widget'=>false));

Such a form would send you a normal POST request.

romaninsh
  • 10,606
  • 4
  • 50
  • 70
0

Ok, I managed to achieve what I wanted by creating a custom extension of Form_Field_Upload and redefining the loadPOST() method within it.

function loadPOST(){
    Form_Field::loadPOST();

    if($_GET[$this->name.'_upload_action']){
        // This is JavaScript upload. We do not want to trigger form submission event
        $_POST=array();
    }
    if($_GET[$this->name.'_upload_action'] || $this->isUploaded()){
        if($this->model){
            try{
            $model=$this->model;

            /*Function is identical to parent above this line*/

            //process file here and do $model->set('custom_field',$value);
            //I am using $this->getFilePath() to analyze the uploaded file

            /*Function is identical to parent below this line*/

            $model->save();

            }catch(Exception $e){
                $this->api->logger->logCaughtException($e);
                $this->uploadFailed($e->getMessage()); //more user friendly
            }

            $this->uploadComplete($model->get());
        }
    }
    if($_POST[$this->name.'_token']){
        $a=explode(',',$_POST[$this->name.'_token']);$b=array();
        foreach($a as $val)if($val)$b[]=$val;
        $this->set(join(',',filter_var_array($b,FILTER_VALIDATE_INT)));
    }
    else $this->set($this->default_value);
}

I sure this is not the most elegant solution but it worked for my purpose anyway.