praca s databazou v komponente

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

Nette Framework 2.0.1 (revision 94abcaa released on 2012–02–29)
PHP 5.3.9
Netbeans IDE 7.1

Ahoj, vytvoril som si takyto formular a umiestnil som si ho do komponentu. Debugger mi hadze chybu, ze context ako property nie je deklarovana. Rozumiem zhruba o co ide, ale neviem to vyriesit. Messages je model.

Tuto istu chybu mi vyhodilo ked som chcel v komponente pracovat s modelom, ale to som vyriesil tak, ze som ten dotaz poslal do konstruktora ako ActiveRow $dotaz

ale tuto mam aj insert aj select a to uz tato s ActiveRow nejde..

<?php
public function contactMessageFormSubmitted(Form $form)
{
	$hasSentToday = $this->context->createMessages()
		->select('id')
		->where(array('ip_address' => $form->values->ip_address))
		->where('created > DATE_SUB(NOW(), INTERVAL 1 DAY)')
		->fetch();
	if($hasSentToday['id'] == FALSE)
	{
		$this->context->createMessages()->insert(array(
			'mlist_title' => $form->values->mlist_title,
			'created' => new DateTime(),
			'ip_address' => $form->values->ip_address,
			'name' => $form->values->name,
			'email' => $form->values->email,
			'message' => $form->values->message
		));
		$this->flashMessage('Message has been sent', 'success');
		$this->redirect('this');
	}
	else
	{
		$this->flashMessage('You have sent message today', 'alert');
		$this->redirect('this');
	}
}
?>

Dakujem!

whitedeath
Člen | 25
+
0
-

no podarilo sa mi to spojazdnit takto

<?php
protected function createComponentLetmetalk()
{
	return new Letmetalk($this->context->createMessages());
}
?>

ale nejde mi ->flashMessage(), da sa to inac vyriesit ako posunut modul v konstruktore?
a ten flashmessage moze byt nastavenim CSS? ale to sa mi nezda nejako…

Etch
Člen | 403
+
0
-

Pokud je „Messages“ model, tak by si ho asi měl mít definovaný spíš jako službu než jako factory.

config.neon

services:
	messages:
		class: \Models\Messages

factories:
	letmetalk:
		class: \Letmetalk

třída Letmetalk

class Letmetalk extends \Nette\Application\UI\Control{

	private $messages;

	public function __construct(\Models\Messages $messages){
		parent::_construct();
		$this->messages = $messages;
	}

	public function contactMessageFormSubmitted(Form $form){
	        $hasSentToday = $this->messages
        	        ->select('id')
                	->where(array('ip_address' => $form->values->ip_address))
	                ->where('created > DATE_SUB(NOW(), INTERVAL 1 DAY)')
        	        ->fetch();
	        if($hasSentToday['id'] == FALSE){
	                $this->messages->insert(array(
        	                'mlist_title' => $form->values->mlist_title,
                	        'created' => new DateTime(),
                        	'ip_address' => $form->values->ip_address,
	                        'name' => $form->values->name,
        	                'email' => $form->values->email,
                	        'message' => $form->values->message
	                ));
			$this->flashMessage('Message has been sent', 'success');
	                $this->redirect('this');
        	}else{
                	$this->flashMessage('You have sent message today', 'alert');
        	        $this->redirect('this');
	        }
	}
}

V presenteru:

protected function createComponentLetmetalk(){
        return $this->context->createLetmetalk();
}

Psáno z hlavy, takže za naprosto správnou funkčnost neručím.

ad FlashMessages: Ty by měli fungovat normálně, pokud budeš svojí komponentu dědit od \Nette\Application\UI\Control

Editoval Etch (14. 3. 2012 3:26)

whitedeath
Člen | 25
+
0
-

Vdaka, tak ja to skusim.

Mal som ten preto ako factory, lebo sa ucim podla tutorialu co je tu na stranke a robim subezne tutorial a svoj vlastny projekt a takto sa snazim na jednom pochopit a na druhom vyskusat to svoje.

Neviem presne ake ma co vyhody: factory vs. service ale tipoval by som ze service je spustena stale? Hladam v tom nejaku analogiu so service v operacnom systeme, mam to tak chapat?

Etch
Člen | 403
+
0
-

Tak jeden ze zásadních rozdílů je ten, že služba vždy vrací stejnou instanci dané třídy, ale factory vždy vytváří novou.

config.neon

	services:

		foo:
			class: \Foo


	factories:

		fooFactory:
			class: \Foo

třída Foo:

class Foo extends Nette\Object{

	public $data;

}

v presenteru:

	$service = $this->context->foo;
	echo $service->data; // tiskne: null
	$service->data = 'data';
	echo $service->data; // tiskne: 'data'

	$service2 = $this->context->foo;
	echo $service2->data; // tiskne: 'data'
	$service2->data = 'nová data';
	echo $service->data; // tiskne: 'nová data'

	$foo = $this->context->createFooFactory();
	echo $foo->data; // tiskne: null
	$foo->data = 'data';
	echo $foo->data; // tiskne: 'data'

	$bar = $this->context->createFooFactory();
	echo $bar->data; // tiskne: null
	$bar->data = 'další data';
	echo $bar->data; // tiskne: 'další data'
	echo $foo->data; // tiskne: 'data'

U modelů většinou nepotřebujeme novou instanci dané třídy, ale stačí nám již jednou vytvořená instance, a proto se většinou definují jako služba. Factory se používá tam, kde vždy chceme novou instanci dané třídy. Továrnám lze navíc předávat parametry.

Doporučuji prostudovat dokumentaci.

Editoval Etch (14. 3. 2012 17:49)

whitedeath
Člen | 25
+
0
-

takze service vs. factory som pochopil :) ale do hlavy mi este nejdu tie flashmesages.
v Letmetalk.php:

<?php
public function render()
{
	$this->template->setFile(__DIR__ . '/letmetalk.latte');
	$this->template->render();
}
?>

a ked do letmetalk.latte vlozim

<?php
<script>
	$(document).ready(function(){
		setTimeout(function() {
			$('.flash').fadeOut('slow');
		}, 2000);
	});
</script>
<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
?>

tak mi vypise messages, ale predtym som mal tieto riadky v @layout.latte, existuje tam nejaka hierarchia alebo akasi forma dedenia v sablonach? alebo musim vypisovat flashmessages globalne vo vseobecnosti a pre komponenty (ak v nich pouzivam vlastne latte) zvlast?

Dakujem za ochotu pomoct!

Etch
Člen | 403
+
0
-

Flash zprávy se ukládají globálně. Pokud budeš mít v layout.latte

<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>

tak se ti budou zobrazovat zprávy vyhozené jak v presenterech, tak v komponentách.

Doufám, že jsem tvou otázku pochopil dobře. Pokud ne, tak ji popřípadě krapet upřesni(přeformuluj).

whitedeath
Člen | 25
+
0
-

ano presne to som mal v layout.latte a neslo mi to, kym som to neskopiroval aj do letmetalk.latte, ktore je ulozene v app/components/letmetalk.latte teraz mi to uz ide, ale mam to v dvoch sablonach.

whitedeath
Člen | 25
+
0
-

este jedna drobnost:
ak mam Pages ako factory, tak viem robit taketo:

<?php
class HomepagePresenter extends BasePresenter
{

	public function renderDefault()
	{
		// Upper content
		$this->template->uppercontent = $this->context->createPages()
			->where(array('plist_title' => 'uppercontent', 'hidden' => false, 'deleted' => false));
		// Lower content
		$this->template->quickexplantation = $this->context->createPages()
			->where(array('plist_title' => 'lowercontent', 'title' => 'quickexplantation', 'hidden' => false, 'deleted' => false))
			->fetch();
		$this->template->ambitions = $this->context->createPages()
			->where(array('plist_title' => 'lowercontent', 'title' => 'ambitions', 'hidden' => false, 'deleted' => false))
			->fetch();
	}

}
?>

ale ak dam pages ako service, tak pri druhom dotaze mi to vyhodi, ze false, tj, prazdny vysledok volania, ale podla Tvojho prikladu so sluzbami som pochopil, ze by to nemal byt problem. Ale ak je, tak potom mam problem aj s Messages, lebo tie chcem vyuzivat tiez podobnym sposobom. Da sa to vyriesit tak nejako, ze si spravim nejake metody v Modeli? napriklad $this->messages->getContact() a $this->messages->insertContact() a toto aj pre pages a podobne?

whitedeath
Člen | 25
+
0
-

prepac, ze Ta zasypavam tolkymi otazkami, ale nemam dost kym to nepochopim :(

Etch
Člen | 403
+
0
-

No na první pohled minimálně u toho prvního dotazu(Upper content) nemáš fetch(). Pošli, jak vypadá ten tvůj „model“. Já s \Nette\Database nedělám, ale používám Dibi, takže si ten model nedokážu dost dobře představit. :)

whitedeath
Člen | 25
+
0
-

No tak spravil som to cez service a pouzil som metody v service na volanie jednotlivych uloh. Napriklad ked chcem nejaku stranku tak to spravim v sluzbe Pages takto:

<?php
/**
 * Vracia stranku
 * @param	string	$plist_title: Plist
 * @param	string	$title: Name
 * @param	bool	$fetch: To fetch
 * @return	array
 */
public function getPage($plist_title = '', $title = '', $fetch = FALSE)
{
	$where = array('hidden' => FALSE, 'deleted' => FALSE);
	if($plist_title != '')
		$where['plist_title'] = $plist_title;
	if($title != '')
	$where['title'] = $title;
	$sql = $this->connection
		->table($this->class)
		->where($where);
	if($fetch)
		return $sql->fetch();
	else
		return $sql;
}
?>
whitedeath
Člen | 25
+
0
-

Btw. aj mne sa velmi paci dibi, ale som si myslel, ze to uz bude prilis velky chaos, keby som do nette montoval aj dibi. Existuju nejake najmenej bolestne cesty, ako to rozbehat? Nestrati sa tam potom nejaka ta myslienka nette? Napriklad ked robim taketo nieco:

<?php
$row = $this->users->where('username', $username)->fetch();
$salt = $this->salts->select('salt')->where('user_id', $row->id)->fetch();
?>

a cez dibi by som pisal nejake query, to je jedno ake, ale takto mam na to nejaku sluzbu a hentak by som mal query, neviem to je prehladnejsie alebo ci ide len o vlastne zvyky? Rad by som sa totiz naucil pouzivat nette tak, aby to bolo co najefektivnejsie a najrozumnejsie, pochopit principom a tak…

Etch
Člen | 403
+
0
-

Ohledně Dibi vs Nette\Database si přečti toto.

Zrovna ty příkazy, které si napsal, by se daly zapsat pomocí Dibi téměř stejně.

<?php

// Tvůj zápis
$row = $this->users->where('username', $username)->fetch();
// Dibi zápis
$row = $this->users->where('username = %s', $username)->fetch();

// Tvůj zápis
$salt = $this->salts->select('salt')->where('user_id', $row->id)->fetch();
// Dibi zápis
$salt = $this->salts->select('salt')->where('user_id = %i', $row->id)->fetch();
?>

To jestli budeš ve výsledku používat Dibi, \Nette\Database, NotORM, Doctrine nebo třeba Propel už záleží jenom na tobě a na tom, co ti více vyhovuje.