Controller not allowing multiple uploads

Hi, I’m using this in my controller file but for some reason it is not allowing multiple uploads? What am i missing?

<?php

return function($site, $pages, $page) {

    if(r::is('post') and get('save')) {

        try {
                          
            $data = array(
                'title'          => get('title'),
                'reference'      => get('reference'),
                'quantity'       => get('quantity'),
                'lauritz'        => get('lauritz'),
                'location'       => get('location'),
                'date'           => get('date'),
                'notes'          => get('notes'),
                'categories'     => get('categories'),
                'price'          => get('price'),
                'price-s'        => get('price-s'),
                'price-o'        => get('price-o'),
                'price-d'        => get('price-d'),
                'price-p'        => get('price-p'),
                'designer'       => get('designer'),
                'model'          => get('model'),
                'period'         => get('period'),
                'online'         => get('online'),
                'ready'          => get('ready'),
                'material'       => get('material'),
                'description'    => get('description')
            );
            
            $curr = page('shop')->children();
            $newPage = $curr->create(get('title'), 'product', $data);

            $internal = new Upload($newPage->root() . DS . 'LQ-{safeFilename}', array(
                'input'     => 'internalup',
                'overwrite' => false
            ));
        
        $success = true;
            
        } catch(Exception $e) {
            
            $error = true;
            
        }     

  return array('error' => $error, 'success' => $success);
    
 };

Cheers :slight_smile:

Your code uses the internalup field and uploads that single file.

The Kirby 2.3 beta includes a feature to upload multiple files. There’s an example in this topic.

Thanks Lukas,

I’ve changed my controller to the following, I changed it around to look more like the example on the other topic. This is what I currently have and it is working in that it is creating the page and uploading multiple files now. However the page on the front end shows this error.

Fatal error: Maximum execution time of 30 seconds exceeded.

Any idea as to what can be causing this.

This is my controller file -

 <?php

return function($site, $pages, $page) {

    if(r::is('post') and get('save')) {

        $data = array(
            'title'          => get('title'),
            'reference'      => get('reference'),
            'quantity'       => get('quantity'),
            'categories'     => get('categories'),
            'description'    => get('description')
        );

        $curr = page('shop')->children();
        $newPage = $curr->create(get('title'), 'product', $data);
        
        $missingFile = false;
        $index = 0;
        
        do {
            
            try {
                
                $upload = new Upload($newPage->root() . DS . 'LQ-{safeFilename}', array(
                    'input' => 'internalup',
                    'index' => $index
                ));
                
                $index++;
                
                $success = true;
                
            } catch(Exception $e) {
                                
                switch($e->getCode()) {
                case Upload::ERROR_MISSING_FILE:
                    $missingFile = true;
                    break;
                }
            
        }
        
    } while(!$missingFile);

        if($index === 0) {
            $error = true;
        } else {
            $error = false;
        }

    }

return array('error' => $error, 'success' => $success);
};

Also I’m needing to have two upload forms on this one page, would it be as simple as just adding in this between the try statements?

                $upload = new Upload($newPage->root() . DS . 'LQ-{safeFilename}', array(
                    'input' => 'externalup',
                    'index' => $index
                ));

many many thanks if anyone can point me in the right direction…

I’ve tried to strip the code down and remove all error warnings from this apart from the page created successfully or unsuccessfully but its still not working? If this is the case surely i could remove the do/while part of the code and just use the try function?

That’s a matter of your PHP configuration. The upload takes too long and PHP then kills its own process. You can change that time with the max_execution_time option.

No, because there can be a different number of files for the two fields. The whole thing is wrapped with the do while which runs until there are no more files. You need to use a second of these loops for the other field.

Maybe we should implement a helper method so that all this “multiple files” handling wouldn’t be in the controller.

Then you would again only have one file.

The upload itself is going at a normal rate. Its only when the files are uploaded that this happens, could this be because the code is maybe poorly written or is there something wrong with it? Surely a 30 sec limit shouldn’t be reached?

What kind of file are you uploading and how large is it? I have often seen situations where 30 seconds to upload a file are not enough.

If the file is small, please verify again that you are using Kirby 2.3 and not 2.2.3. Kirby 2.2.3 will try to upload the same file again and again because it doesn’t know about the index option.

If you are sure that you are using Kirby 2.3, please post the HTML code of your upload form.

Just in case anyone has the same problem as mentioned above. The problem is …

while(!$missingFile);

If all files are uploaded without errors $missingFile will have its initial value false which means …

while(!false);

I think this leads to an infinite loop. My solution was to first count the files to upload.

$count_files = 0;
if (!empty($_FILES['internalup']['name'])) {
  $count_files = count($_FILES['internalup']['name']);
}

do {
  ...
} while ($index < $count_files && !$missingFile);