filtr Mime type pro PDF haze chybu (application/pdf)

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
worsik
Člen | 40
+
0
-

Zdravím,

mám takový menší problém.
Pro webovou aplikaci jsem nucen vytvořit formulář, který mimo jiné provede upload souboru ⇒ dokumentu PDF nebo obrazku.

<?php

$form->addFile('protocol_tss','Technická specifikace služby')
   ->setHtmlId('protocol')
   ->addCondition('FormTools::uploadTest', $maxFileSize)
       ->addRule(Form::MIME_TYPE, 'Protokolem musí být dokument PDF nebo obrázek formátu .jpg, .gif nebo .png.', 'application/pdf,application/x-pdf,image/jpeg,image/gif,image/png')
       ->addRule(Form::MAX_FILE_SIZE, 'Velikost protokolu může být nanejvýš ' . TemplateHelpers::bytes($maxFileSize) . '.', $maxFileSize);

?>

Problém je, že když nahraju jako dokument PDF, filtr Mime Type vyhodí chybu, že o PDF nejde.
Nechápu jak to řešit.
BTW z kódu je vidět, že jsem použil „FormTools“, které jsem nalezl tady na fóru.

Nejde vůbec o to, že bych měl problém někam soubor uložit. Ve zpracování formu je zatím jen

<?php

dump($this['form']->values);
die();

?>

ale k die() se to ani nedostane.
Má problém PDF, prohlížeč a nebo PHP?

Edit: nebo mám špatně MIME type? Předpokládám, že upload PDF souborů jste již někdo řešili a vyřešili.

Díky za odpovědi

Worsík

Editoval worsik (7. 4. 2010 14:54)

iguana007
Člen | 970
+
0
-

Zkusil bych ještě další mimetypes, které se u PDF uvádějí, možná je zádrhel v tom:

application/pdf, application/x-pdf, application/acrobat, applications/vnd.pdf, text/pdf, text/x-pdf
worsik
Člen | 40
+
0
-
<?php
$form->addFile('protocol_tss','Technická specifikace služby')
   ->setHtmlId('protocol')
   ->addCondition('FormTools::uploadTest', $maxFileSize)
      ->addRule(Form::MIME_TYPE, 'Protokolem musí být dokument PDF nebo obrázek formátu .jpg, .gif nebo .png.',
             'application/pdf, application/x-pdf, application/acrobat, applications/vnd.pdf, text/pdf, text/x-pdf, image/jpeg,image/gif,image/png')
      ->addRule(Form::MAX_FILE_SIZE, 'Velikost protokolu může být nanejvýš ' . TemplateHelpers::bytes($maxFileSize) . '.', $maxFileSize);
?>

Nefunguje, porad mi vypise

Opravte chyby:

    * Protokolem musí být dokument PDF nebo obrázek formátu .jpg, .gif nebo .png.

Nějaký jiný nápad? :o)

worsik
Člen | 40
+
0
-

Sakryš, to vypadá bledě, asi nebudu moci spoléhat na filtr a budu si muset typ souborů pořešit až po uploadu :'(

Docela by se nápad hodil O:-)

worsik
Člen | 40
+
0
-

Vystupy

<?php
dump($_FILES,$this['jmenoFormulare']->values);
?>
array(1) {
   "protocol_tss" => array(5) {
      "name" => string(9) "czech.pdf"
      "type" => string(15) "application/pdf"
      "tmp_name" => string(30) "D:\Programy\wamp\tmp\php93.tmp"
      "error" => int(0)
      "size" => int(347193)
   }
}

array(7) {
   "description" => string(1) "2"
   "note" => string(1) "2"
   "bussinesscontact" => string(1) "6"
   "technicalcontact" => string(1) "6"
   "protocol_tss" => object(HttpUploadedFile) (5) {
      "name" private => string(9) "czech.pdf"
      "type" private => NULL
      "size" private => int(347193)
      "tmpName" private => string(30) "D:\Programy\wamp\tmp\php93.tmp"
      "error" private => int(0)
   }
   "idrealizationstatus" => string(1) "1"
   "idcustomer" => string(1) "1"
}

proč Nette nevidí typ a pole FILES ano?
Je možné, že jde o bug Nette?

Ondřej Mirtes
Člen | 1536
+
0
-

Atribut type se naplňuje až na požádání, při zavolání metody getContentType(). Je to asi kvůli zabezpečení, hodnotě, co přijde od prohlížeče, nelze věřit.

BTW: Zrušil bych v tom výčtu MIME typů mezery okolo čárek. MIME typ se kontroluje tady, tak si tam můžeš umístit nějaké debugovací výpisy.

Editoval Ondřej Mirtes (8. 4. 2010 0:03)

worsik
Člen | 40
+
0
-

Na obrázky ale filtr funguje správně :o)

Edit:
dal jsem si debug výstup do funkce

<?php
static function validateMimeType(FileUpload$control,$mimeType)
{
  $file=$control->getValue();
  if($file instanceof HttpUploadedFile)
  {
	$type=$file->getContentType();
	dump($mimeType,$type);
	die();
	$type=strtolower(preg_replace('#\s*;.*$#','',$type));
	if(!$type){
		return FALSE;
	}
	$mimeTypes=is_array($mimeType)?$mimeType:explode(',',$mimeType);
	if(in_array($type,$mimeTypes,TRUE))
	{
		return TRUE;
	}
	if(in_array(preg_replace('#/.*#','/*',$type),$mimeTypes,TRUE))
	{
		return TRUE;
	}
}return FALSE;
}
?>

Pro PDF mi to ale napíše

string(125) "application/pdf,application/x-pdf,application/acrobat,applications/vnd.pdf,text/pdf,text/x-pdf,image/jpeg,image/gif,image/png"

string(24) "application/octet-stream"

což neodpovídá PDF a filtr mě nepustí dál. Přičemž pro PNG funguje dobře

Mám povolit ve filtru i application/octet-stream ?
Potřebuji jen PDF a obrázky.

Editoval worsik (8. 4. 2010 8:33)

worsik
Člen | 40
+
0
-

Tak se postupně nořím do Nette/loader.php v minified verzi a snažím se najít v čem je problém.

<?php

getContentType()
{
	if($this->isOk()&&$this->type===NULL)
	{
		$info=getimagesize($this->tmpName);
		dump($info);
		die();
		if(isset($info['mime']))
		{
			$this->type=$info['mime'];
		}
		elseif(extension_loaded('fileinfo'))
		{
			$this->type=finfo_file(finfo_open(FILEINFO_MIME),$this->tmpName);
		}
		elseif(function_exists('mime_content_type'))
		{
			$this->type=mime_content_type($this->tmpName);
		}
		if(!$this->type)
		{
			$this->type='application/octet-stream';
		}
	}
	return$this->type;
}

?>

hádám, že pokud nemám žádnou extension loaded, tak musím spoléhat na to, že fce getimagesize() existuje i pro PDF, coz neni pravda.
Pri zadani PDF dokumentu mi dump vyhodí

bool(FALSE)

Při obrázku je vše v pořádku a vypíší se informace o obrázku.

Kde vemu funkce mime_content_type(), popř extension fileinfo?

worsik
Člen | 40
+
0
-

Našel jsem si extension php_fileinfo.dll.

Kód mi při provádění sice skočí do bloku, kde se vykonává fileinfo, ale to mi stejně vrátí bool (FALSE).
Nechápu proč.

worsik
Člen | 40
+
0
-

Tak jsem vyzkoušel PHP extension php_fileinfo.dll, které jsem na PHP 5.2.11 nemohl rozchodit (vcetne extension mime_magic s nastavenou cestou k souboru magic)
Na PHP 5.3.0 ale fileinfo nepotrebuje mime_magic ⇒ muj problem je vyresen a filtr funguje

⇒ akorat to znamena, ze cely kod musi byt v PHP 5.3.0

Honza Kuchař
Člen | 1662
+
0
-

Na PHP 5.3 můžeš používat Nette pro verzi PHP 5.2. (můj případ) :)