PHP ÇOKLU DİL
Merhaba arkadaşlar öncelikle belirteyim hayatta pek yazı yazmayı seven geliştimenlerden olamadım ondan mütevellit birazdan oluşcak olan yazıda bir kusrumuz olursa affola..
Yapmış olduğumuz sitelerin hemen hemen hepsinde bu yapıyı kullanıyorum.Kendimce anlatmaya çalışcağım bu yapının bir benzerine WP wpml‘de de rasladım, benzer bir mantık en azından DB kısmı diyelim.Neyse yorumları kesip anlatıma geçelim.
öncelikle DB tablomuzu oluşturmakla başlıyalım.
İzninizle bu tablodaki kolonlardan ve ne amaçla kullanılacağından bahsetmek istiyorum.Öncelikle dil ve çevirleri yönetmek için 2 tablo oluşturacağız.
ilk tabloda sitemizdeki kullanılacak dilleri tutacağız diğer tabloyuda sitemizdeki tüm çoklu dil verisine ihtiyaç duyucağımız alanlar için kullanacağız.
Örneklerimi bir blog sitesi üzerinden vericeğim..
CREATE TABLE `lang` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NULL DEFAULT NULL,
`lang` VARCHAR(10) NULL,
`images` VARCHAR(250) NULL DEFAULT NULL,
`open_default_lang` TINYINT(2) NULL DEFAULT '0',
`direction` VARCHAR(3) NOT NULL DEFAULT 'ltr',
`seq` TINYINT(2) NULL DEFAULT '0',
`visible` TINYINT(2) NULL DEFAULT '0',
PRIMARY KEY (`id`),
INDEX `code` (`lang`));
`name` : Bu alanda sitede ekli olan dilin ismini tutucağız.(örn:Türkçe,English,العربية)
`lang` : Bu alanda sitede ekli olan dilin language kodunu tutacağız.(örn: en,tr,ar..)
`images` : Bu alan sitede ekli olan dil için flag icon tarzında bir resim için kullanıcağız.
`open_default_lang` : Bu alanda sitede ekli olan dilden default olanının belirliyecegimiz veri tutulacak.
`direction` : Bu alanda sitede ekli olan dillerin direction verisini tutacağız (örn: ltr,rtl)
`seq` : Bu alanda sitede ekli olan dillerin sıralanması için kullanılacak
`visible` : Bu alanda sitede ekli olan dillerin front end kısmında son kullanıcı tarafından görüntülenip görüntülenmiyecegi verisi tutulacak.
CREATE TABLE `translate` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`table` VARCHAR(20) NOT NULL,
`table_id` INT(11) NOT NULL,
`lang` VARCHAR(5) NULL DEFAULT NULL,
`obje_key` VARCHAR(20) NULL DEFAULT NULL,
`translate` TEXT NULL COLLATE 'utf8mb4_unicode_ci',
PRIMARY KEY (`id`), UNIQUE INDEX `table_table_id_lang_obje_key` (`table`, `table_id`, `lang`, `obje_key`))
`table` : Bu alan çeviriye ihtiyaç duyduğumuz alanın bulunduğu tablo adını tutucağız.(örn:Blog sitemizdeki yazılarımızın tutulduğu `posts` tablosu gibi)
`table_id` : Bu alan çeviriye ihtiyaç duyduğumuz kayıtın bulunduğu primary_key verisini Kayıt idsini tutucağız.(örn:Blog sitemizdeki yazılarımızın `id` si)
`lang` : Bu alan çevirimizin language kodunu tutacağız.(örn: en,tr,ar..)
`obje_key` : Bu alan çeviriye ihtiyaç duyduğumuz kolon’u işaret edicek.(örn: Name,Details..)
`translate` : Bu alanda çevirimizin kendisini tutacağız.
front end kısmında ben DOM Dizin kullanarak oluşturarak kullanıyorum.Hatta biraz üşengeç olduğum için kütüphaneler üzerinden gidiyorum burda direk bir tanesini nasıl olşturabirizden gidelim.
öncelikle nedir DOM Dizin,DOM Array ??
<input ... name="input_name[]" value="Value 1" /> <input ... name="input_name[]" value="Value 2" />
DOM Dizin,DOM Array Özellikle DOM Form elemanlarında elemizi rahatladan DOM elemanlardan türetme yapmak için kullandığımız bir method Dinamik dillerede kullandımız Dizin mantığının DOM yapısındaki karşılığı yada eşteniği denilebilir.
burda standart kullanımdan farklı olarak name alanının sonuna [] koyuyoruz.Bu ekleme bize bu Form elemanlarından gelen verinin Dizin olarak gönderilnesini saglıyor
print_r($_POST); Array(2) { [0] => "Value 1", [1] => "Value 2" }
Neyse asıl olayımıza dönecek olursak..
<input ... name="translate[name][tr]" />
php yle donatalım 😀
<?php $query = $db->query('SELECT * FROM `lang` ORDER BY seq ASC'); foreach ($query as $rs) { ?> <div class="form-group"> <label class="sr-only"><?php echo $rs->name ?></label> <div class="input-group"> <div class="input-group-addon"><img src="<?php echo $rs->images ?>" alt="" /></div> <input type="text" class="form-control" dir="<?php echo $rs->direction ?>" name="translate[name][<?php echo $rs->lang ?>]"> </div> </div> <?php } ?>
obje_key olarak ‘name’ kullandım ama opsiyoneldir değişebilir/arttırılabilir.
Bootstarp tablarla olayı şekillendirebiliriniz…
backend kısmında nasıl kaydedicegimize gelirsek Az önce bahsettiğimiz örnekteki mantıktan yola çıkarsak bizim oluşturduğumuz inputlardan bize gelen veri şu şekilde olucaktır.
print_r($_POST['translate']); Array() { [name] => Array() { [tr] => "Value 1", [en] => "Value 2" ... } ... }
madem başta dedik çeviri gereken heryerde kullanıcağız ozaman en basitinden bir function yazabiliriz.
function setTranslate($args){ global $db; if (!isset($_POST['translate'])) return false; $db->query('DELETE FROM `translate` WHERE `table`="'.$args['table'].'" and `table_id`="'.$args['table_id'].'"'); $insertSql=''; foreach ($_POST['translate'] as $obje_key => $translates){ foreach ($translates as $lang => $translate) { $insertSql .= 'insert into `translate` (`table`,`table_id`,`lang`,`obje_key`,`translate`) VALUES ("'.$args['table'].'","'.$args['table_id'].'","'.$lang.'","'.$obje_key.'","'.$translate.'");'; } } return $db->query($insertSql); } $args = [ 'table'=>'posts', 'table_id'=>1 ]; setTranslate($args);
Son olarak ta yazıyı tamamlamış olmak adına veriyi çekelim
$query = $db->query('SELECT t1.*,t2.name FROM `posts` AS t1 LEFT JOIN `translate` AS t2 ON t1.id=t2.table_id WHERE (t2.table="posts" and t2.lang="tr" and t2.obje_key='name')'); foreach ($query as $rs): echo $rs->name; endforeach;
bu kısma kadar katlanıp okuduysanız teşekkür ederim dedigim gibi bu yazı yazma olayları pek ilgi alanım degil umarım kullandıgım mantığı bir nebze olsun anlatabilmişimdir.