Geek tričko zdarma Geek tričko zdarma
Tričko zdarma! Stačí před dobitím bodů použít kód TRIKO15. Více informací zde
Avatar
Lukáš
Redaktor
Avatar
Lukáš:7. července 13:11

Ahoj, mám SignUpForm a v něm :

public function create(callable $onSuccess): Form
{
        $form = $this->factory->create();
        $form->addText('username', 'Username:')
                ->setRequired('Please enter a username.');
        $form->addEmail('email', 'Your e-mail:')
                ->setRequired('Please enter your e-mail.');
        $form->addPassword('password', 'Password:')
                ->setRequired('Please create a password.');
        $form->addSubmit('send', 'Sign up');
        $form->onSuccess[] = function (Form $form, \stdClass $values) use ($onSuccess): void {
                try {
                        $this->userManager->add($values->username, $values->email, $values->password);
                } catch (DuplicateNameException $e) {
                        $form['username']->addError('Username is already taken.');
                        return;
                }
                $onSuccess();
        };
        return $form;
}

a UserManager:

public function add(string $username, string $email, string $password): void
{
        Nette\Utils\Validators::assert($email, 'email');
        try {
                $this->database->table(self::TABLE_NAME)->insert([
                        self::COLUMN_NAME => $username,
                        self::COLUMN_PASSWORD => $this->passwords->hash($password),
                        self::COLUMN_EMAIL => $email,
                ]);
        } catch (Nette\Database\UniqueConstraintViolationException $e) {
                throw new DuplicateNameException;
        }
}

Ale když si do formuláře zadám jméno, které mám již v databázi tak to úplně přeskočí ten catch (DuplicateName­Exception) a zase se zaregistruje stejné jméno.. Kde je chyba? :/

Editováno 7. července 13:12
 
Odpovědět 7. července 13:11
Avatar
Odpovídá na Lukáš
Martin Konečný (pavelco1998):7. července 13:39

Ahoj, patrně máš tu exception v jiném namespace.
Např. pokud UserManager je v namespace App\Model, pak danou výjimku máš patrně také tam, tedy App\Model\DuplicateNameException.

No a továrnu na formulář máš patrně jinde, např. v App\Forms, a pokud v ní zachytáváš

catch (DuplicateNameException)

tak se to bude snažit zachytávat výjimku v daném namespace, tedy App\Forms\DuplicateNameException, kterou to pochopitelně nezachytí, jelikož taková se nevyhazuje.

Osobně výjimky řeším tak, že mám pro ně samotný namespace např. App\Exceptions a v souborech, kde výjimky vyhazuji/zachycuji, mám

use App\Exceptions;

v takovém případě poté všude píšu

throw new Exceptions\DuplicateNameException;

catch (Exceptions\DuplicateNameException)

Nestane se mi tedy, že bych omylem zachytával výjimku ve špatném namespace a zároveň mám v kódu přehled o tom, o jakou třídu jde, jelikož v use nepoužívám celou cestu ke třídě, ale jen k jejímu namespace. Tedy pak píšu např.

Entities\User
Facades\UserManager
Exceptions\DuplicateNameException

// atd.

Edit: Ještě taková drobnost - unikátní index ve výchozím stavu neřeší velká a malá písmena, tedy ti půjde registrovat uživatel "Lukáš" i "lukáš", což možná nechceš (závisí na typu aplikace), tak na to dej pozor :D

Editováno 7. července 13:42
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět 7. července 13:39
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Odpovídá na Lukáš
Martin Konečný (pavelco1998):7. července 13:44

I když jsem asi špatně pochopil problém :D Pokud ti to do databáze vloží řádek se stejným jménem, pak patrně vůbec na tom sloupci s 'username' nemáš unikátní index.

Nahoru Odpovědět 7. července 13:44
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Lukáš
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Lukáš:7. července 13:54

Super, díky.. Neměl jsem v databázi přidanej ten unikátní index. :D
A k tomu předchozímu komentu, takže ty si uděláš soubor např. Exceptions a tam dáš

namespace App\Exceptions

a necháš to prázdný nebo tam i nějak zpracováváš ty výjimky?

 
Nahoru Odpovědět 7. července 13:54
Avatar
Odpovídá na Lukáš
Martin Konečný (pavelco1998):7. července 14:13

V namespace App\Exceptions mám jednotlivé výjimky, tzn. 1 soubor = 1 výjimka, kdy to nejčastěji vypadá

namespace App\Exceptions;

class DuplicateNameException extends \RuntimeException
{
}

Jen výjimečně potřebuji ve třídě výjimky něco mít, takže naprostá většina jich jenom dědí a nic víc.
A potom ve třídách, které výjimky používají, to řeším jednoduše

namespace App\Model\Facades;

use Nette;
use App\Exceptions;

class UserManager
{

        public function addUser($data)
        {
                try {
                        $this->db->insert($data);
                } catch (Nette\Database\UniqueConstraintViolationException $e) {
                        throw new Exceptions\DuplicateNameException();
                }
        }

}

namespace App\Forms;

use Nette;
use App\Exceptions;


class RegistrationFormFactory
{

        public function create()
        {
                $form = new Form();
                // ...

                $form->onSuccess[] = array($this, "submitted");

                return $form;
        }


        public function submitted($form, $values)
        {
                try {
                        $this->userManager->addUser($values);
                } catch (Exceptions\DuplicateNameException $e) {
                        $form->addError("Jméno již existuje");
                }
        }

}

Ten kód je jen ukázkový pro představu.

Editováno 7. července 14:14
Nahoru Odpovědět 7. července 14:13
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Lukáš
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Lukáš:7. července 16:58

Dobrá, díky moc a ještě jestli mohu jeden dotaz :-D Když mám formulář s ->addTextArea
a pak to chci dále zpracovávat, tak mi to napíše: Object of class Nette\Forms\Con­trols\TextArea could not be converted to string. Jak to mohu tedy převést do stringu?

 
Nahoru Odpovědět 7. července 16:58
Avatar
Odpovídá na Lukáš
Martin Konečný (pavelco1998):7. července 17:20

Co přesně s tou textarea chceš dělat?

Nahoru Odpovědět 7. července 17:20
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Lukáš
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Lukáš:7. července 17:21

Do text area někdo vloží text a já ho chci rozkouskovat podle svého pomocí preg_split()

 
Nahoru Odpovědět 7. července 17:21
Avatar
Odpovídá na Lukáš
Martin Konečný (pavelco1998):7. července 17:25

A to nejde jednoduše nějak takhle?

public function create()
{
        $form = new Form();
        $form->addTexarea("content", "Obsah");

        return $form;
}

public function formSubmitted(Form $form, $values)
{
        $content = $values->content;
        preg_split(..., $content);
}
Editováno 7. července 17:25
Nahoru Odpovědět 7. července 17:25
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Lukáš
Redaktor
Avatar
Odpovídá na Martin Konečný (pavelco1998)
Lukáš:7. července 18:55

Jop, to funguje. Díky moc za tvůj čas! ;)
Hezký večer.

 
Nahoru Odpovědět  +1 7. července 18:55
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 10.