Prefix a vlastné preklady
- black1101
- Člen | 21
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 | 661
Prefixy
Máš asi 3 volby:
- Udělat builder na sql dotazy.
- Udělat si nástavbu a analyzovat sql, provést změny a vrátit výslednou sql.
- 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
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
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
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.
- black1101
- Člen | 21
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)
- black1101
- Člen | 21
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.
- black1101
- Člen | 21
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)
- CZechBoY
- Člen | 3608
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
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 :)
- black1101
- Člen | 21
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
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#…