Allow guests to create pages from Panel or frontend

I get this error back:

Warning
: pathinfo() expects parameter 1 to be string, array given in
/mamp/site/kirby/toolkit/lib/f.php
on line
438

That’s the bit of the source code your error refers to:

public static function name($name) {
    return pathinfo($name, PATHINFO_FILENAME);

Looks like you are using the name() method somewhere with an array instead of a string?

What does your full code look like now?

This is the form in my template:

<form action="" method="post" enctype="multipart/form-data">
    <ul>
	    <li>
		    <label for="file">Pictures</label>
		    <input name="file[]" type="file" multiple>
	    </li>
	    <input type="submit" name="submit" value="Send it in!" class="button">
    </ul>
</form>

This is my controller now:

<?php 

return function($site, $pages, $page) {
  $error = null;
  if(r::method() === 'POST') {
    // The form has been sent

    $title = get('brand') . "-" . get('tube-name');

    
    // Build an array of the data you want to allow as fields
    // get() fetches the form field value with that `name`
    $data = array(
      'tube-name' => get('tube-name'),
      'brand' => get('brand'),
      'different_manufacturer' => get('different_manufacturer'),
      'country' => get('country'),
      'code_on_tube' => get('code_on_tube'),
      'factory_code' => get('factory_code'),
      'year' => get('year'),
      'bottle_height' => get('bottle_height'),
      'Tip-Shape' => get('Tip-Shape'),
      'glass_color' => get('glass_color'),
      'Mica' => get('Mica'),
      'getter' => get('getter'),
      'getter_support' => get('getter_support'),
      'plate_look' => get('plate_look'),
      'plate_size' => get('plate_size'),
      'plate_color' => get('plate_color'),
      'pin_color' => get('pin_color'),
      'base' => get('base'),
      'special_use' => get('special_use'),
      'other_marks' => get('other_marks'),
      'notes' => get('notes'),
      'uploader_name' => get('uploader_name'),
      'uploader_email' => get('uploader_email')
      );
    
    // Create a new page as child of the current page
    // You can also use a different page by using `page('whatever')->children()->create()`
    $p = page('uploads')->children()->create($title, 'tube', $data);

    
    // Upload an image
    $files = $_FILES['file'];
    foreach($files as $file)  {
      try {
        $upload = new Upload($p->root() . DS . '{safeFilename}', array('input' => 'file'));
      } catch(Error $e) {
        switch($e->getCode()) {
          case Upload::ERROR_MISSING_FILE:
          // File does not exist
          $error = 'No file uploaded.';
          break;
          // See the Upload class for other error values
        }
      }
    }
  }


  return compact('error');
};
?>

Thanks for the code. I just tested it and found out that the way PHP structures the resulting $_FILES array for multiple files is currently not supported by the Upload class.

I will add this feature as a Pull Request later today and come back to you here.

1 Like

Here’s the new Pull Request I created.

If you want to try it, temporarily replace your kirby/toolkit/lib/upload.php with the file from the PR and use the following controller code (your template is fine):

<?php 

return function($site, $pages, $page) {
  $error = null;
  if(r::method() === 'POST') {
    // The form has been sent
    
    $title = get('brand') . "-" . get('tube-name');
    
    // Build an array of the data you want to allow as fields
    // get() fetches the form field value with that `name`
    $data = array(
      'tube-name' => get('tube-name'),
      'brand' => get('brand'),
      'different_manufacturer' => get('different_manufacturer'),
      'country' => get('country'),
      'code_on_tube' => get('code_on_tube'),
      'factory_code' => get('factory_code'),
      'year' => get('year'),
      'bottle_height' => get('bottle_height'),
      'Tip-Shape' => get('Tip-Shape'),
      'glass_color' => get('glass_color'),
      'Mica' => get('Mica'),
      'getter' => get('getter'),
      'getter_support' => get('getter_support'),
      'plate_look' => get('plate_look'),
      'plate_size' => get('plate_size'),
      'plate_color' => get('plate_color'),
      'pin_color' => get('pin_color'),
      'base' => get('base'),
      'special_use' => get('special_use'),
      'other_marks' => get('other_marks'),
      'notes' => get('notes'),
      'uploader_name' => get('uploader_name'),
      'uploader_email' => get('uploader_email')
    );
    
    // Create a new page as child of the current page
    // You can also use a different page by using `page('whatever')->children()->create()`
    $p = page('uploads')->children()->create($title, 'tube', $data);
    
    // Upload the images
    $missingFile = false;
    $index = 0;
    do {
      try {
        $upload = new Upload($p->root() . DS . '{safeFilename}', array('input' => 'file', 'index' => $index));
        $index++;
      } catch(Error $e) {
        switch($e->getCode()) {
          case Upload::ERROR_MISSING_FILE:
            // No more files have been uploaded
            $missingFile = true;
            break;
          // See the Upload class for other error values
        }
      }
    } while(!$missingFile);
    
    // Check if an image has been uploaded at all
    if($index === 0) {
      $error = 'No file uploaded.';
    }
  }
  
  return compact('error');
};

It works now! Thank you! :smiley_cat:

1 Like

I am getting an error when the page is live on the server.
When instead I run the website locally on mamp, everything works good.

The error says:

Fatal error: Uncaught Error: Call to a member function children() on boolean in /home/user/website/site/controllers/submit-page.php:40 Stack trace: #0 /home/user/website/kirby/kirby.php(525): Kirby->{closure}(Object(Site), Object(Children), Object(Page), Array) #1 /home/user/website/kirby/kirby.php(699): Kirby->controller(Object(Page), Array) #2 /home/user/website/kirby/kirby.php(680): Kirby->template(Object(Page), Array) #3 /home/user/website/kirby/kirby.hp(781): Kirby->render(Object(Page)) #4 /home/user/website/index.php(16): Kirby->launch() #5 {main} thrown in /home/user/website/site/controllers/submit-page.php on line 40

What do you think could be?

What is line 40 of your controller?

This is line 40

$p = page('uploads')->children()->create($title, 'tube', $data);**strong text**

The whole controller.php is the same as you posted 4 replies above.

Do you have a page named uploads on your production server? This error normally means that the page does not exist.

You’re right!

The folder wasn’t there on the server. I’ve created it and now works! :slightly_smiling:

1 Like

Hi! Is it possible to make a tutorial or share the code for the newbies? It would be a great help!

2 Likes

Thanks for the feedback. I have added it to our list for new documentation.

1 Like

That would be great! Is it a long list? :wink:

Wait and see. :slightly_smiling:
We are constantly improving parts of the Kirby site and documentation and at some point, we will document this as well.

Until then, maybe the controller code above helps a bit. If you have any questions, don’t hesitate to ask.

2 Likes

I will just take a good look & just try a little bit. Tnx for the reply and I cant wait. Good work!

Ok first question :wink:

Step1) Create a frontend form
Step 2) Create a controller

Use same names :wink: Well so far so good.

But then…

Create a form using uniform? Or how does that work? I heard about several people that they managed to get this done. Anyone who whats to share the steps & code?

Ditto the above! Was this ever documented?

2 Likes

Hi, can @lukasbestle or @gvocale please upload here the finally template and controller? I have still some problems with file uploads and the official doc (https://getkirby.com/docs/developer-guide/toolkit/upload) is still a bit incomplete. Thank you very much.

2 Likes