formulář v kódování iso-8859–2

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

Dobrý den,

rád bych použil nette formulář na webu s kódováním iso-8859–2, ale nedaří se mi to zprovoznit.
Když použiju

$form->encoding = 'ISO-8859-2';

tak se je špatná diakritika u formuláře, ale odeslaná data mohu převést přes iconv do požadovaného kódování.
Když kódování formuláře nepoužiju, tak je jeho diakritika v pořádku, ale už nejsou v pořádku odeslaná data.
Existuje nějaký způsob, jak mít současně v pořádku formulář a odeslaná data?

Diakritiku hlášek u validace klidně oželím.

David Grudl
Nette Core | 8082
+
0
-
$form->encoding = 'ISO-8859-2';

Tohle určuje, v jakém kódování je stránka, ve které je formulář umístěn. Nicméně interně formulář stále běží pod UTF-8, takže metody setDefaults(), getValues() a vůbec všechny metody používají UTF-8.

bartojan
Člen | 4
+
0
-

Pořešil jsem to tedy tak, že jsem formuláři dal informaci o kódování iso a jeho popisky + validační hlášky konvertuju do utf.
Přijatá data si pak konvertuju opět přes iconv z utf na iso.

$form = new Form;
$form->encoding = 'ISO-8859-2';
$form->addText('ulice', iconv("ISO-8859-2","UTF-8",'Ulice'))
      ->addRule(Form::FILLED, iconv("ISO-8859-2","UTF-8",('Vyplňte ulici'));
...
$hodnoty = $form->getValues();
foreach ($hodnoty as $klic=>$co) $hodnoty[$klic]=iconv("UTF-8","ISO-8859-2",$co);

Pořád míň práce, než ošetřovat celý formulář ručně. Kódování stránek nezměním.

kravčo
Člen | 721
+
0
-

Možno by si to mohol ešte viac zjednodušiť a zautomatizovať:

class Latin2Form extends Form
{

    public function __construct($name = NULL, $parent = NULL)
    {
        parent::__construct();
        parent::setEncoding('ISO-8859-2');
        parent::setTranslator(new IconvTranslator('ISO-8859-2', 'UTF-8'));
    }

    public function setTranslator(ITranslator $translator = NULL)
    {
        $this->getTranslator()->setNext($translator);
    }

    public function getValues()
    {
        $values = parent::getValues();
        $translator = new IconvTranslator('UTF-8', 'ISO-8859-2');
        foreach ($values as & $value) {
            $value = $translator->translate($value);
        }
        return $values;
    }
}

class IconvTranslator extends Object implements ITranslator
{
    private $fromEncoding;
    private $toEncoding;

    private $next;

    public function __construct($fromEncoding, $toEncoding)
    {
        $this->fromEncoding = $fromEncoding;
        $this->toEncoding = $toEncoding .'//TRANSLIT';
    }

    public function setNext(ITranslator $next)
    {
        $this->next = $next;
    }

    public function translate($s, $count = NULL)
    {
        $s = iconv($this->fromEncoding, $this->toEncoding, $s);
        if ($this->next) {
            $s = $this->next->translate($s, $count);
        }
        return $s;
    }
}

Editoval kravčo (19. 8. 2009 13:12)

David Grudl
Nette Core | 8082
+
0
-

Na konvertování hlášek a popisek by se dal využít translator. S tím převáděním získaných hodnot to bude chtít iconv("UTF-8","ISO-8859-2//TRANSLIT",$co); nebo iconv("UTF-8","ISO-8859-2//IGNORE",$co);, co když někdo vloží znak, který není v ISO-8859–2?

David Grudl
Nette Core | 8082
+
0
-

byls rychlejší ;)

bartojan
Člen | 4
+
0
-

Díky, to je řešení, které jsem hledal a nikde nenašel :-)
Jelikož se v objektovém programování a Nette neorientuju, bych bych rád, kdybyste mi někdo ještě mohl poradit s chybou, kterou mi háže výše zmínený kód.
Chybová hláška je: Call to a member function setNext() on a non-object
v kódu:

<?php
public function setTranslator(ITranslator $translator = NULL)
{
	    $this->translator->setNext($translator);
}
?>

Formulář řeším snad správně:

<?php
require_once 'nette/latin2form.php';
$form = new Latin2Form;
$form->addText('ulice', 'Ulice')
      ->addRule(Form::FILLED, 'Vyplňte ulici');
?>
kravčo
Člen | 721
+
0
-

Kód som písal len na načrtnutie toho, ako by sa to dalo spraviť a netestoval som ho. Je fakt, že som sa trochu nechal uniesť…

Bolo tam pár drobných bugov, opravil som ich priamo v predchádzajúcom príspevku.

bartojan
Člen | 4
+
0
-

Moc děkuju za funkční řešení :-)