nette/http

Validation rule Form::PATTERN for Nette\Http\FileUpload

h4kuna opened this issue · 5 comments

  • bug report? yes
  • feature request? no
  • version: 2.4

Description

Hi,
i have use case

$form->addUpload('csv')
    ->addRule($form::MIME_TYPE, 'Foo', 'text/*')
    // next line does not work
    ->addRule($form::PATTERN, 'Message', '*.csv');

I found in Validator::validatePattern where first parameter is (IControl)->getValue(). It's ok. If i look at (FileUploadControl)->getValue() you get FileUpload and method __toString return tmpName. Where is problem? I don't need run validation on temporary name, but on original name.

For first validation check extension of file. Please you don't write, this valid is not relevant. I can't use PATTERN validation for this moment.

Or throw exception, this rule is not relevant for FileUpload. Because here is wtf behavior.

I understant if you change return value in method __toString(), it can be BC break or anything worse.

dg commented

Feel free to make addUpload() and PATTERN work together. But for consistency you should write .*\.csv instead of *.csv, which can be very confusing.

I am sorry if my issue written aggressively.

Still does not work.

require __DIR__ . '/vendor/autoload.php';

$form = new \Nette\Forms\Form();
$form->addUpload('csv')
	->setRequired(false)
	// next line does not work
	->addRule($form::PATTERN, 'File is not csv.', '.*\.csv');

$form->addSubmit('foo');

$form->onSuccess[] = function ($form, $values) {
	dump($values);die();
};

echo $form;

save this like foo.csv and try upload

a,b,c
e,f,g

In content of Validator::validatePattern() is Strings::match($control->getValue(), "\x01^(?:$pattern)\\z\x01u"); Where $control->getValue() return FileUpload and this class has magic method __toString where return $this->tmpName instance of $this->name. Regular expression check this /tmp/phprSHBNS instance of foo.csv. In class String is strlen where is called __toString too.

If you change pattern for match tmp path, than upload is correct

->addRule($form::PATTERN, 'File is not csv.', '.tmp.*');
dg commented

I understand that it doesn't work, as I said, feel free to fix it. But consider, that PATTERN is used for regular expressions, so it may be confusing to use it for wildcards.

Ok.
If i change return value for FileUpload::__toString(). Is this bad way, isn't it?

Second way, I can add condition to Validator::validatePattern, where check instance of FileUpload and call $control->getValue()->getName().