Připojení ke druhé databázi
- thunderbuff
- Člen | 164
Ahoj, poradíte, jak v configu správně zaregistrovat službu pro připojení k druhé databázi v nette 2.0.4? Docela s tím zápasím.
Zde je můj současný config:
<?php
#
# SECURITY WARNING: it is CRITICAL that this file & directory are NOT accessible directly via a web browser!
#
# If you don't protect this directory from direct web access, anybody will be able to see your passwords.
# https://nette.org/en/security-warning
#
common:
parameters:
database:
driver: mysql
host: localhost
dbname: prod1.stormspire.cz
user: root
password:
login_database:
driver: mysql
host: localhost
dbname: login.stormspire.cz
user: root
password:
instance_name: 'martin'
default_language: 'cs_CZ'
supported_languages: {'en_GB', 'de_DE', 'cs_CZ', 'sk_SK', 'pl_PL'}
profiler_log_over: 5
default_trial_length: 30
php:
date.timezone: Europe/Prague
# session.save_path: "%tempDir%/sessions"
# zlib.output_compression: yes
nette:
session:
expiration: '+ 14 days'
database:
default:
dsn: '%database.driver%:host=%database.host%;dbname=%database.dbname%'
user: %database.user%
password: %database.password%
login:
dsn: '%login_database.driver%:host=%login_database.host%;dbname=%login_database.dbname%'
user: %login_database.user%
password: %login_database.password%
debugger:
email: martin@martinstrouhal.cz
services:
database: @nette.database.default
loginconnection: @nette.database.login
authenticator: Authenticator( @database::table(ss_users), @database, @userslayer, @user )
auhorizator: ACL( @database )
userslayer: AdminModule\UsersLayer( @database )
roleslayer: AdminModule\RolesLayer( @database )
factories:
production < common:
development < common:
?>
Zde inject metoda v presenteru:
<?php
namespace AdminModule;
// ...
public function injectUsers(UsersLayer $usersLayer, RolesLayer $rolesLayer, Authenticator $authenticator, \Loginconnection $loginConnection) {
$this->_usersLayer = $usersLayer;
$this->_rolesLayer = $rolesLayer;
$this->_authenticator = $authenticator;
$this->_loginConnection = $loginConnection;
}
?>
… a zde chyba. Nevím, zda je chyba v zaregistrování služby, nebo v hintu
<?php
No service of type Loginconnection found. Make sure the type hint in Method AdminModule\UsersPresenter::injectUsers() is written correctly and service of this type is registered. search►
?>
Editoval thunderbuff (26. 8. 2012 13:36)
- Filip Procházka
- Moderator | 4668
Žádná třída LoginConnection
neexistuje, to ti říká ta
chyba. Obě dvě připojení jsou instancí
Nette\Database\Connection
, Nette tedy neumí rozlišit, které
je které.
U jednoho tedy budeš muset určit, že je „méně důležité“
services:
nette.database.login:
autowired: false
Tyhle dva řádky můžeš úplně vyhodit, jsou tam zbytečné
database: @nette.database.default
loginconnection: @nette.database.login
Zbude ti tedy tohle.
services:
authenticator: Authenticator(@database::table(ss_users))
auhorizator: ACL()
userslayer: AdminModule\UsersLayer()
roleslayer: AdminModule\RolesLayer()
Nette ti automaticky bude předávat výchozí databázi (a nejenom tu). Teď
ale vzniká problém – jak dostat @nette.database.login
tam kam
potřebuješ. Presenter nakonfigurovat nemůžeš, takže zbývá jediné –
obalit ho do služby
class LoginService extends Nette\Object
{
public function __construct(Nette\Database\Connection $loginDb)
{
// ...
}
}
a tuto si zaregistruješ
services:
loginService: LoginService(@nette.database.login)
Nyní Nette bude vědět, že tato databáze patří do této třídy a všude jinde bude předávat tu druhou. Zbývá už jen upravit inject metodu.
public function injectUsers(
UsersLayer $usersLayer,
RolesLayer $rolesLayer,
Authenticator $authenticator,
\LoginService $login)
{
$this->usersLayer = $usersLayer;
$this->rolesLayer = $rolesLayer;
$this->authenticator = $authenticator;
$this->login = $login;
// nepoužívej podtržítka, je to škaredé ;)
}
Sice nevím co dělají UsersLayer
a RolesLayer
,
ale možná by nebylo od věci ještě schovat je do LoginService
a
upravit Authenticator
tak, aby tuto LoginService
využíval.
A na tebe zbývá poslední úkol, pojmenovat třídu
LoginService
nějak rozumně, podle toho co doopravdy
bude dělat.
Editoval HosipLan (26. 8. 2012 23:27)
- thunderbuff
- Člen | 164
To je vyčerpávající odpověď, díky! Jen pro úplnost doplním, že UsersLayer a RolesLayer jsou API rozhraní pro správu uživatelských účtů a rolí.
- thunderbuff
- Člen | 164
Ještě jednou toto téma oživím. Lze nějak udělat dvě připojení k databázi, která budou obě autowirovaná? Napadlo mě jen triviální řešení:
<?php
class SharedConnection extends Nette\Database\Connection {}
// a následné zaregistrování v configu
?>
V té třídě nic víc není, šlo mi jen o to, aby nette bylo schopno rozlišit názvy tříd. Bohužel to nepomohlo a nette stále detekuje dvě služby typu Connection. Lze to nějak vyřešit, nebo musím jedno připojení „obalovat do služby“?
Editoval thunderbuff (16. 9. 2012 19:38)
- MKI-Miro
- Člen | 277
Ahojte
Ako pripojim dve databzy ponovom ked uz sa neposiela connection ale context ?
Chyba:
must be an instance of Nette\Database\Context, instance of
Nette\Database\Connection given
Config:
jos_vm_productRepository:
Shop\jos_vm_productRepository(@nette.database.shop)
Metoda:
public function __construct(Nette\Database\Context $db,
Dakujem