Prefix a vlastné preklady

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

Dobrý deň, prosím Vás mal by som dve otázky pričom prvá je ohľadne používania Dibi a či je možné nejakým spôsobom do config neon-u pridať prefix tabuliek aby som následne nemusel používať všade ten istý prefix.

Napríklad:

$this->db->query("SELECT * FROM abcd_langs WHERE lang_country = %s", $country);

som bol zvyknutý zapísať jednoducho ako:

$this->db->query("SELECT * FROM ::langs WHERE lang_country = %s", $country);

Čítal som tu na fóre, že to možné nie je a že si mám normálne pomenovať tabuľky, ale tá odpoveď je stará, nepohlo sa náhodou niečo od vtedy?

Pokiaľ nie, tak akým najlepším spôsobom a hlavne kde v aplikácií definovať prefix ako konštantu, ktorú by som následne v celej aplikácií poprepisoval.

Chystám sa totiž celú appku preklopiť do nette a rád by som spravil takéto veci poriadne. Vopred ďakujem veľmi pekne.

Tá druhá otázka sa týka ohľadom vlastných prekladov. Mám tabuľku abcd_langs kde mám tri stĺpce a to:
1-konstanta 2-preklad 3-jazyk

Následne som si v hlavnom controlleri (v starej aplikácií) vybral všetko z tabulky abcd_langs → uložil do globálnej premennej language a všade kde som chcel (controlleri, modely, knižnice) zavolal túto glob. premennú a bolo hotovo.

Prosím Vás viete mi poradiť, ako najlepšie a kde spraviť takýto výber a potom môcť používať všade na webe? Zatiaľ to mám v base_repository asi takýmto štýlom:

namespace App\Model;

use Nette;

class BaseRepository extends Nette\Object {


    /** @var \DibiConnection */
    private $db;

    /** @var Nette\Http\SessionSection */
    private $langSession;

    public function __construct(\DibiConnection $connection, Nette\Http\Session $session) {
        $this->db = $connection;

        $this->langSession = $session->getSection('lang');

        //$this->langSession->lang = 'franta';
        //unset($this->langSession->lang);
    }

    public function getLanguage() {

      $country = ($this->langSession->lang ? $this->langSession->lang : 'sk');

      $q = $this->db->query("SELECT * FROM abcd_langs WHERE lang_country = %s", $country);

      $pack = array();

      if (count($q)) {
        foreach ($q->fetchAssoc("lang_constant") as $key => $value) {
          $pack[$value["lang_constant"]] = $value["lang_trans"];
        }
      }

      return $pack;
    }
a následne v presenteri zavolám:

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    /** @var Model\BaseRepository @inject */
    public $baseRep;

    public $language;

    public function startup() {

        parent::startup();

        /*Načitanie prekladov*/
        $this->language = $this->baseRep->getLanguage();

Akurát neviem potom, ako budem používať preklady povedzme v inom repository. Presenteri dedia od môjho basepresenteru, takže tam problém nie je.

Ďakujem vopred za akúkoľvek pomoc a ochotu.

Pekný deň.

Martk
Člen | 652
+
0
-

Prefixy
Máš asi 3 volby:

  1. Udělat builder na sql dotazy.
  2. Udělat si nástavbu a analyzovat sql, provést změny a vrátit výslednou sql.
  3. Přes konstanty:
class FooRepository extends BaseRepository {

	const TABLE = self::PREFIX . 'table';

	public function selectAll() {
		return $this->db->query('SELECT * FROM ' . self::TABLE);
	}

}

Překlady
Uděláš si novou třídu, která bude spravovat překlady:

class LanguageManager {

	private $language;

	public function __construct(BaseRepository $repository) {
		$this->language = $this->repository->getLanguage();
	}

	public function getLanguage() {
		return $this->language;
	}

}

zaregistruješ jako službu a injektuješ do presenterů a komponent.

Editoval Antik (25. 8. 2016 17:11)

black1101
Člen | 21
+
0
-

Antik: ďakujem za odpoveď, bol som mimo teraz tak až teraz som sa k tomu vrátil.

Čo sa týka tých konštant, to nie je asi veľmi dobré riešenie, nakoľko ja som to myslel tak, že napríklad tabulku nieco_users môžem využívať vo viacerých modeloch alebo presenteroch a preto by som rád mal niekde definovaný ten prefix, aby som nemusel všade písať nieco_ ale iba napr ::users kde :: mi nahradí môj prefix.

A k tým prekladom. Momentálne mám urobený komponent typu:

public function __construct(\DibiConnection $connection/*, Nette\Http\Session $session*/) {
        $this->db = $connection;
    }

    public function getLanguage($lang = null) {

      $country = ($lang ? $lang : 'sk');

      $qAll = $this->db->query("SELECT * FROM nieco_langs WHERE lang_country = %s", 'sk');


      $packAll = array();

      if (count($qAll)) {
          foreach ($qAll->fetchAssoc("lang_constant") as $key => $value) {
          $packAll[$value["lang_constant"]] = $value["lang_trans"];
        }
      }

      return $packAll;
    }

a následne ju používam takto v Base presenteri, čím môžem automaticky používať preklady vo všetkých presenteroch ktoré dedia od Base presenteri:

abstract class BasePresenter extends Nette\Application\UI\Presenter
{

    /** @persistent */
    public $locale;

    /** @var Model\BaseRepository @inject */
    public $baseRep;

    protected $language;

        /*Načitanie prekladov*/
        $this->language = $this->baseRep->getLanguage($this->locale);

a takto v nejakom inom modeli

class IndexRepository extends Nette\Object {

    /** @var \DibiConnection */
    private $db;

    /** @var Model\BaseRepository @inject */
    private $myLang;

    public function __construct(\DibiConnection $connection, BaseRepository $lang/*, Nette\Http\Session $session*/) {
        $this->db = $connection;
        $this->myLang = $lang->getLanguage('sk');
    }

je to OK takto?

ešte sa chcem spýtať, či komponent v nette znamená napríklad v mojom prípade vyššie indexrepository, a či zaregistrovanie ako služby máš na mysli vloženie do config.neon napr:

services:
	- App\Model\IndexRepository

prepáč za blbé otázky ale zoznamujem sa s nette a rád by som mal ucelené takéto základné veci.

Ďakujem vopred za odpoveď a prajem pekný deň.

ps: ešte jedna otázka: nevadí, že napríklad getLanguage volám a injectujem na viacerých miestach naraz? Napr ako som aj písal v basepresenteri a potom v indexrepository, ktorý následne využívam v niektorom presenteri a taktiež tam môžem využívať povedzme usersRepository, v ktorom tiež injectujem indexRepository aby som mohol získať language. Díki moc.

Editoval black1101 (13. 9. 2016 19:40)

CZechBoY
Člen | 3608
+
+2
-

Vůbec se mi to nelíbí :-) odkud jako každá třída zjistí co je aktuálně nastaveno za jazyk? Nemůžeš takhle dost jednoduše přijít o konzistenci jazyka napříč aplikací? tzn. jedna třída si dá češtinu, presenter si dá slovenštinu atd.
Pokud se ti to nechce moc řešit tak použij Kdyby\Translation a ten balík vyřeší vše za tebe. Potom si už jen injectuješ/předáváš Nette\Localization\ITranslator a voláš $translator->translate($message, $count = null);

Editoval CZechBoY (13. 9. 2016 20:42)

black1101
Člen | 21
+
0
-

Czechboy: dakujem za reakciu ale takto: preklady uz mam riešené v db takýmto štýlom takze neviem využívať nieco iné. Na tvoju otázku to teraz funguje tak: ze v base presenteri si predám aktuálny parameter locale z URL a na základe toho si nastavím aktuálny jazyk, pripadne to bude uložené v session.

CZechBoY
Člen | 3608
+
0
-

Takže v modelu potom ten jazyk vybíráš ze session nebo odkud vezmeš jaký jazyk je právě nastavený?

black1101
Člen | 21
+
0
-

Áno, v tom modeli kde je metoda getLanguage si vyberiem jazyk zo session, prípadne ho do tej metody getLanguage posielam ako parameter → ktorý môžem nastaviť pri volaní metódy.

CZechBoY
Člen | 3608
+
0
-

A není trochu složitý v každým modelu hrabat do session a zjišťovat kam to někdo uložil místo nastavit jazyk překladači, kterej si jen předáš?
Nebo k čemu tě vede mít možnost nastavit jazyk pro konkrétní instanci třídy na nějakou ručně definovanou/kdo ví odkud vytaženou?

black1101
Člen | 21
+
0
-

Hej máš pravdu, prosím ťa keď momentálne mám v basePresenteri

   /** @persistent */
   public $locale;

	a následne v
startup(){
	$this->language = $this->baseRep->getLanguage($this->locale);
	.....
	}

Akým štýlom si v baseRepository kde mám getLanguage predám tú persistant premennú locale?

Len by som si ju tu predal do tej metódy getLanguage a nemala by žiaden parameter.
Dík za radu.

Editoval black1101 (17. 9. 2016 14:54)

CZechBoY
Člen | 3608
+
0
-

Já nastavuju jazyk přímo překladači – takže nějaký tvojí třídě s jazykem bych nastavil jazyk ve startup.

black1101
Člen | 21
+
0
-

Skúšam to prerobiť tak ako píšeš, ale nerozumiem dobre celkovo k tomu pristupovaniu a nastavovaniu (ospravedlňujem sa, ale čítal som aj dokumentáciu a neviem si pomôcť.)

Teraz mám model Languages.php:

<?php

namespace App\Common;

use Nette;

class Languages extends Nette\Object
{
    /** @var \DibiConnection */
    private $db;

    public $locale = 'sk';

    public function __construct(\DibiConnection $connection) {
        $this->db = $connection;
    }

    public function getLanguage() {

      $qAll = $this->db->query("SELECT lang_constant, lang_trans FROM langs WHERE lang_country = $this->locale);

      if (count($qAll)) {
          foreach ($qAll->fetchAssoc("constant") as $key => $value) {
          $packAll[$value["constant"]] = $value["trans"];
        }
      }

      return $packAll;
    }

}

a Následne v BasePresenteri, kde vyťahujem preklady pre template a ostatné presenteri, urobím toto:

/** @persistent */
public $locale;
/** @var Common\Languages @inject */
public $languagesManager;

public function startup() {

    parent::startup();

    $this->languagesManager->locale = $this->locale;
    $this->language = $this->languagesManager->getLanguage();

A všetko funguje super, keď mám link Administracia/cz/
tak to ťahá české, keď sk, tak slovenské.

Problém ale spočíva v tom, že keď si chcem preklady použiť v nejakom inom modeli, respektíve povedzme v IndexRepository, ktorý vyzerá takto:

/** @var \DibiConnection */
private $db;

/** @var Common\Languages @inject */
private $myLang;

public function __construct(\DibiConnection $connection, Common\Languages $lang) {
    $this->db = $connection;
    $this->myLang = $lang->getLanguage();
}

tak tam sa mi stále sťahujú len defaultné SK preklady. Asi je ti to jasné, ale vieš mi to prosím ťa objasniť a vysvetliť, ako to mám nastaviť? Ďakujem vopred.

CZechBoY
Člen | 3608
+
0
-

Připadá mi to ok. Ty repozitáře máš normálně registrovaný jako služby?

black1101
Člen | 21
+
0
-

Hej hej presne tak, takže vôbec nerozumiem, prečo mi to hodí za každým v tom indexrepository po slovensky, aj keď je aktivovaná čeština.

//edit

pokiaľ v Indexrepository v __construct…

doplním pred $lang->getLanguage();
toto: $lang->locale = ‚cz‘;

tak následne je čeština aj tam

Editoval black1101 (17. 9. 2016 18:07)

black1101
Člen | 21
+
0
-

Zistil som, že IndexRepository sa akoby zavolá pred BasePresenter s metodou startup… ako je to možné? ten indexRepository injectujem v IndexPresenteri, ktorý rozširuje base presenter.

CZechBoY
Člen | 3608
+
0
-

jj, nemůžeš tenhle kod přesunout někam na pozdějc?

$this->myLang = $lang->getLanguage();

Stále teda moje otázka „Proč nepoužíváš ITranslator?“ je nezodpovězena :-) V modelu bys potom při překládání použil jen

$this->translator->translate('abc');

namísto nějakého prohledávání slovníku (což je práce překladače).

black1101
Člen | 21
+
0
-

czechboy: takže služby sa volajú vlastne ešte pred startUp takže preto mi to tam nevedel priradiť, vyriešil som to tak, že v triede s jazykom si parsnem jednoducho urlku, z ktorej si vytiahnem aktuálny jazyk a na základe toho vrátim výsledky, následne si raz zavolám načítanie jazyku v basepresenteri, keď to predám aj všetkým ostatným presenterom, ktoré dedia a pokiaľ potrebujem jazyk v niektorom ďalšom modeli, tak to tam injektknem ako som písal aj vyššie a funguje to tak ako chcem, takže zrjeme je po probléme.

K tvojej otázke prečo nepoužívam ITranslator, tak ja ho poznám ale na tomto projekte sa musia preklady poriešiť takýmto štýlom z jednoduchého dôvodu, takého, že je to v tomto okamihu lepšie riešenie.

ps: čo sa týka tých prefixov databázy, tak neviem si nejakým spôsobom podobný tomuto:

		require_once TOOLS."dibi.min.php";

		$dbconfig = array(
	    'driver'   => 'mysql',
	    'host'     => DBHOST,
	    'username' => DBUSER,
	    'password' => DBPASS,
	    'database' => DBDB,
	    'charset'  => 'utf8',
	    'prefix' => 'nasPrefix_',
		/*'profiler' => array(
	        'run' => TRUE,
	        'file' => 'log.sql',
	    ),*/
		);

	    dibi::connect($dbconfig);
		dibi::getSubstitutes()->{''} = $dbconfig['prefix'];

nastaviť prefix a potom ho používať tak ako som sa pýtal? Nechcem zbytočné konštanty, to veľa nepomôže a používa sa dibi a aj bude.
Navyše aj ja osobne som zvyknutý na zápis cez dve bodky, pokiaľ používame nejaký prefix v tabulkách:

$this->db->query("SELECT * FROM ::langs WHERE lang_country = %s", $country);

Díki moc už teraz :)

CZechBoY
Člen | 3608
+
0
-

A to dibi teda nemůžeš použít?
Btw. v čem je složitý nainstalovat Kdyby\Translation z composeru a za 10 minut ho používat? :-)

Editoval CZechBoY (19. 9. 2016 15:43)

black1101
Člen | 21
+
0
-

ja dibi používam, akurát, že neviem nastaviť ten prefix.

Dibi som inštaloval cez composer a v bootrstrap volám toto:

$configurator->onCompile[] = function ($configurator, $compiler) {
    $compiler->addExtension('dibi', new Dibi\Bridges\Nette\DibiExtension22);
};

$container = $configurator->createContainer();

Neviem ako mám zapracovať tú časť s nastavením prefixu, ktorú som posielal vyššie.

Dik.

CZechBoY
Člen | 3608
+
0
-

dibi si přidej jako extension v konfiguráku rovnou :-)

extensions:
	dibi: Dibi\Bridges\Nette\DibiExtension22

Podle návodu se substituce dělá trochu jinak
https://dibiphp.com/cs/quick-start#…

black1101
Člen | 21
+
0
-

Jasné dík za tip, už som to konečne spojazdnil, nižšie dávam kód:

$this->db->getSubstitutes()->{''} = 'test_';

Dá sa tento kód dostať nejakým spôsobom do configu? (tam som zmätený)

ps: tá metóda addSubst je zastaralá

Editoval black1101 (19. 9. 2016 20:54)