Připojení ke druhé databázi

před 7 lety

thunderbuff
Člen | 165
+
0
-

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/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)

před 7 lety

Filip Procházka
Moderator | 4693
+
0
-

Žá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)

před 7 lety

thunderbuff
Člen | 165
+
0
-

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í.

před 7 lety

thunderbuff
Člen | 165
+
0
-

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)

před 6 lety

MKI-Miro
Člen | 144
+
0
-

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

před 6 lety

MKI-Miro
Člen | 144
+
0
-

Uz som aj nasiel riesenie, ak by niekto potrevoal treba opravit

jos_vm_productRepository: Shop\jos_vm_productRepository(@nette.database.shop)

na

jos_vm_productRepository: Shop\jos_vm_productRepository(Nette\Database\Context(@nette.database.shop))