Problem sending images to the creation of a page (front end)

The code works pretty well but after the creation of the page the site is buged and then displays an error saying that it takes too much time …

I published my code on github, there is just to add the folder ‘thumbs,’ kirby ‘,’ panel '.
My code also works with my “membership” plugin.

I have reduced the code to make it easier to understand:

Template:

<?php if(isset($success)): ?>
<div class="alert success">
	<?php echo $success; ?>
</div>
<?php endif ?>

<?php if(isset($error)): ?>
<div class="alert error">
	<?php echo $error; ?>
</div>
<?php endif ?>

<?php if($alert): ?>
<div class="alert error">
	<p>Make sure you have entered all the information correctly, including the category.</p>
</div>
<?php endif ?>

<?php if(!isset($success)): ?>
<form enctype="multipart/form-data" action="<?= $page->url() ?>" method="post">

	<label for="title">Theme Name: <abbr title="required">*</abbr></label>
	<input type="text" id="title" name="title" placeholder="Theme name" value="<?= isset($data['title']) ? $data['title'] : '' ?>"/>

	<label for="file">Choose a file&hellip;</label>
	<input type="file" name="file[]" id="file" class="inputfile inputfile-2" data-multiple-caption="{count} files selected" multiple />

	<label for="text">Short description of your theme: <abbr title="required">*</abbr></label>
	<textarea name="text" id="text" placeholder="Short description of your theme"><?= isset($data['text']) ? $data['text'] : '' ?></textarea>

	<label for="subject">If you are a human, leave this field empty</label>
	<input type="subject" name="subject" id="subject" placeholder="Subject" value="<?= isset($data['subject']) ? $data['subject'] : '' ?>"/>

	<button type="submit" name="submit" value="Submit">Submit</button>

</form>
<?php endif ?>

Controller:

<?php

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

	// Seuls les utilisateurs connectés sont autorisés!
	$user = $site->user();
	if(!$user) go('login');

	$alert    = null;
	$messages = null;

	if(r::is('post') && get('submit')) {
		if(!empty(get('subject'))) {
			// lets tell the bot that everything is ok
			go($page->url());
			exit;
		}
		$data = array(
			'title'     => esc(get('title')),
			'text'      => esc(get('text')),
			'author'    => $user->username()
		);

		$rules = array(
			'title'     => array('required'),
			'text'      => array('required'),
		);
		$messages = array(
			'title'     => 'Please enter a valid theme name',
			'text'      => 'Please enter a short theme description',
		);

		// some of the data is invalid
		if($invalid = invalid($data, $rules, $messages)) {
			$alert = $invalid;
		} else {

			$p = $pages->find('themes')->children()->create(str::slug($data['title'] . '-' . $user->username()) , 'theme', $data);

			// everything is ok, let's try to create a new registration
			try {

				$newRegistration = $p;

				$success = 'Adding your theme has been successful.';
				$data = array();

				// Upload the images
				$missingFile = false;
				$index = 0;
				do {
					try {
						$upload = new Upload($p->root() . DS . '{safeFilename}', array(
							'input'     => 'file',
							'overwrite' => true,
							'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.';
				}


			} catch(Exception $e) {
				$error = 'Adding your theme failed: ' . $e->getMessage();
			}
		}
	}

	return compact('alert', 'data', 'messages', 'success', 'error');
};

I would like the registered user to send at least 6 images (+ the creation of the page).

Repo GitHub:

I followed the helpers here:
https://getkirby.com/docs/developer-guide/toolkit/upload

As far as I can see, the problem is that the index is incremented ad infinitum, it seems that the code doesn’t get out of the loop until it runs into a script execution timeout. But haven’t found out why yet. (Bastian is currently on vacation).

I saw that the documentation was not finished so I asked for help on the forum.
Thank you very much for responding.
I will wait then.


For those who would like to try on a Starterkit:

It doesn’t get out of the loop, I think, because - if everything goes right (and everything does work, the page is actually created and the files are uploaded) the error is never thrown.

If you add this in your code:

$count = count($_FILES['file']['name']);

and then change the condition in the while loop

while($index > $count-1)

it should work.

So my code should look like this? :

// Upload the images
$count = count($_FILES['file']['name']);
$missingFile = false;
$index = 0;
do {
	try {
		$upload = new Upload($newPage->root() . DS . '{safeFilename}', array(
			'input'     => 'file',
			'overwrite' => true,
			'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($index > $count-1);

// Check if an image has been uploaded at all
if($index === 0) {
	$error = 'No file uploaded.';
}

It works but the problem is that it only upload 1 image…

Sorry, there’s a typo in my code above, should be:

while($index < $count)

It works thanks!
It’s wonderful, I would also like to know how to only allow images?
And also allow to send only 6 images and not more?

Is there any chance that the “Upload class Toolkit” documentation will be updated soon ?

You can set the accept attribute in the input element as a first hint for the browser itself:

<input type="file" name="myImage" accept="image/x-png,image/gif,image/jpeg" />

But you need to evaluate the input on the server as well, in the same way you check other input field. In the case of files, you can evaluate the file type.

The options array also has an accept parameter:

$defaults = array(
      'input'     => 'file',
      'index'     => 0,
      'to'        => $to,
      'overwrite' => true,
      'maxSize'   => false,
      'accept'    => null,
    );

which expects a callback function. You can see this in place in the Panel Uploader class:

I am a little lost I must say… In the meantime, this can help.
This is not an urgent project, I will wait until the documentation arrives.
Thank you again for your help!