Only this pageAll pages
Powered by GitBook
1 of 28

Liman Eklenti Geliştirme

Loading...

Başlangıç

Loading...

Loading...

Genel Bilgiler

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Geliştirme

Loading...

Loading...

Loading...

Loading...

Arayüz Elemanları

Loading...

Loading...

Loading...

Loading...

İleri Seviye

Loading...

Loading...

Loading...

Loading...

Yeni Eklenti Oluşturma

Bu başlık altında yeni eklenti oluşturma yollarından ve eklenti şablonlarından bahsedilecektir.

Eklenti Oluşturmak

Liman MYS üzerinde eklenti oluşturmak için izlenmesi gereken adımlar şu şekildedir.

Gerekli Ayarların Gerçekleştirilmesi

  • Sol alttaki sistem ayarları ikonuna tıklanarak ayarlar sayfası açılır.

  • Ayarlar sayfasındaki sekmelerden "İnce Ayarlar" sekmesi seçilir.

  • Gelişmiş sekmesi seçilir.

  • Eklenti geliştirici modu "Aktif" hale getirilir.

Eklenti Sayfası ve Yeni Eklenti Oluşturmak

  • Bu işlemlerin ardından Eklentiler sekmesine girilir.

  • Yeni düğmesine tıklanır

  • Eklentimizin ismini gireriz. İsim sadece harflerden oluşmalıdır ve boşluk içermemelidir. Eklenti isminde Türkçe karakter de kullanılamaz fakat eklenti oluşturulduktan sonra eklentinin görünen adı istenildiği gibi değiştirilebilir. Bu kısımdan da bahsedeceğiz.

  • Eklentinin şablonu seçilir. Şablonlarımızdan daha detaylı bahsedeceğiz.

  • Seçilmesi gereken şablon "PHP 7.3 + OOP Training" seçeneğidir, eğer bu konuda bilgiliyseniz diğer seçenekleri de seçebilirsiniz.

Yeni Eklenti Ayarları

Eklentiyi oluşturduktan sonra eklenti ayarları sayfasına otomatik yönlendirilir.

Bu kısımda gelin alanları birlikte inceleyelim.

  • Anahtarı Zorunlu Kıl: Bu alan lisanslı eklentileriniz için gereklidir.

  • Destek Email'i: Eklentinin içerisindeki destek düğmesinin gideceği e-posta adresini göstermektedir.

  • Logo (Font awesome): Sol menüde eklentinin gözükeceği ikonu ifade eder. (ör. fas fa-bolt)

  • Paket bağımlılıkları: Eklentinin çalışması için gereken paketleri bu kısımda belirtiriz. (ör. dnsutils php7.3-ldap php-smbclient)

  • Versiyon: Eklentinin versiyon kodudur.

  • Ayar Doğrulama Fonksiyonu/Betiği: Çalıştırılacak doğrulama fonksiyonu belirtilir.

  • Gerekli Minimum Liman Sürüm Kodu: Eklentinin çalışacağı Liman sürümünü belirleriz.

  • Servis Adı ya da Kontrol Portu: Eklentinin çalışması için açık olması gereken port veya servisi bu kısımda belirtiriz.

  • SSL Sertifikası Eklenecek Portlar: Portlardan Liman'a SSL sertifikası eklenerek bağlantı işlemi sağlanmaktadır. (ör. LDAP 636 portu ve sertifikası)

  • Eklenti Görünen Adı: Eklentinin arayüzde (sunucuya eklenti eklerken vs.) görünecek adıdır. Bu kısımda eklenti adında bulunan karakter kısıtlamaları geçerli değildir. Türkçe karakter, boşluk veya özel karakter kullanılabilir. Yukarıdaki resimde görüldüğü gibi tüm Türkçe alfabeyi ve bazı özel karakterlerle boşluğu içeren bir isim verilebilmiştir.

Aşağıdaki örnekte görüldüğü üzere; bir sunucuya eklenti ekleme kısmında, eklentiyi oluştururken verilen Eklenti Adı değil de sonrasında eklenti ayarlarında ayarlanılan Eklenti Görünen Adı belirmektedir.

Eklenti Şablonları

PHP 7.3

Bu seçenek ile geliştirilen eklentilerde nesne yönelimli yapı bulunmamaktadır. Kod okunulabilirliği ve bakımı açısından zordur ancak geliştirmeyi en kolay bu şablon ile yapabilirsiniz.

PHP 7.3 + OOP

Sizler için temel şablonların oluşturulmadığı, komponent örneklerinin bulunmadığı saf eklenti yapısıdır.

PHP 7.3 + OOP Training

Bu eklenti yapısı Liman'ı yeni öğrenecekler için tasarlanmıştır. Tüm komponentlerin örneklerinin bulunduğu, dosyalamanın kod bakımı ve okunulabilirliği açısından en iyi formudur. Bu eklentileri geliştirirken JavaScript ve nesne yönelimli PHP bilgisine ihtiyaç duyulmaktadır.

Eklenti Geliştirici Modu
Eklentiler sayfası
Yeni Oluşturulmuş Eklenti

Hoşgeldiniz!

BT süreçlerinizde bulunan bütün bileşenleri uzaktan, kararlı, güvenli ve genişletilebilir yöntemler ile merkezi olarak yönetmenizi sağlar.

Liman MYS nedir?

Liman MYS'nin kurulumundan yapılandırılmasına ve açık kaynak ve kurumsal çeşitli eklentilerin kullanımı ile ilgili hazırlanan rehberdir.

Liman Merkezi Yönetim Sistemi BT süreçlerinizde bulunan bütün bileşenleri uzaktan, kararlı, güvenli ve genişletilebilir yöntemler ile merkezi olarak yönetmenizi sağlar.

Açık kaynak göç projelerinde Linux çekirdeğine sahip işletim sistemlerini ve diğer platformları Liman MYS ile yönetebilirsiniz.

Liman MYS

Kontrolcüler

Eklentiler üzerinde kontrolcülerin kullanımından ve nasıl çalıştıklarından bahsedilecektir.

Kontrolcü Nedir?

Controller, MVC’de projenin iç süreçlerini kontrol eden bölümdür. Bu bölümde View ile Model arasındaki bağlantı kurulur. Kullanıcılardan gelen istekler (request) Controller’larda değerlendirilir, isteğin detayına göre hangi işlemlerin yapılacağı ve kullanıcıya hangi View’ın döneceği veya JSON response belirtilir.

Eklentilerde Kontrolcüler

Kontrolcüler, MVC yapısındaki ingilizce ismiyle Controller yapısıdır. MVC yapısına aşina olanlar bilecektir ki arka yüz işlemlerini kontrolcüler ile gerçekleştiriyoruz. Gelin birlikte temel bir kontrolcüyü inceleyelim.

<?php
namespace App\Controllers;

class HomeController
{
	public function index()
	{
		return view('index');
	}
}

Gördüğümüz üzere kontrolcü aslında bir PHP nesnesidir. Bu nesne içinde fonksiyon/fonksiyonlar saklamaktadır. Bu fonksiyonları daha sonra rotalar ile birlikte işlerimiz için kullanacağız.

Kontrolcümüzün fonksiyonları içerisinde çalıştırılması gereken arka yüz işlemlerini yapabiliriz. Daha spesifik bir örnek vermemiz gerekirse Liman ile sisteme bir kullanıcı ekleme işlemini şu şekilde gerçekleştirebiliriz.

<?php
namespace App\Controllers;

use Liman\Toolkit\Shell\Command;

class UserController
{
	public function add()
	{
		 $command = Command::runSudo("useradd -p $(echo @{:password} | openssl passwd -1 -stdin) -s /bin/bash -g users @{:username}", [
         "username" => request("username"),
         "password" => request("password")
     ]);

     Command::runSudo("mkhomedir_helper @{:username}", [
         "username" => request("username")
     ]);

     return respond(__("Başarıyla eklendi"), 200);
	}
}

Yukarıdaki kod bloğunda görebileceğimiz üzere UserController nesnemizin içerisinde add() fonksiyonu bulunmaktadır. Bu fonksiyon daha sonra bahsedeceğimiz Liman Toolkitini kullanarak sistem üzerinde bir komut çalıştırmaktadır. Çalıştırdığı komutların ardından işlemin başarılı olduğuna dair bir yanıt döndürmektedir.

Liman eklentilerinde kontrolcüler genelde POST requestlerine yanıt vermek için kullanılır. Nadir durumlarda view döndürülmektedir.

Kontrolcülerde tanımladığımız fonksiyonları daha sonra rotalar ile çağırarak yardımcı fonksiyonlar sekmesinde göreceğimiz request() fonksiyonumuz ile kullanacak, işlemlerin çalıştırılmasını sağlayacağız.

Kontrolcülerin yaşam döngüsü Liman üzerinde aşağıdaki şekilde kullanmayı tercih ediyoruz. İsterseniz View/Controller ve sayfalı yapı da oluşturabilirsiniz ancak biz daha çok REST API olarak kullanmayı tercih ettik.

Daha önceden index kontrolcüsü tarafından render edilmiş interaktif öğeleri kullanarak bir request gönderimi yaparız. Ardından kontrolcümüz bu requestleri alarak yönetilen sistemde veya başka bir işlem için kullanarak değişiklikler yapar. Ardından kontrolcü işlemin durumuna göre başarılı veya başarısız diye bir yanıt gönderir. Yanıt, arayüz tarafından alındıktan sonra kontrolcünün yaşam döngüsü tamamlanmıştır.

Liman Eklenti Kontrolcüsü Yaşam Döngüsü

Veritabanı Mantığı

Geliştirdiğiniz eklentilerde kullanıcıdan veri alıp, bu veriyi nasıl kullanacağımızı öğreneceğiz.

Liman sisteminde eklenti geliştirirken, kullanıcı adı ve şifre gibi bazı bilgileri kullanıcıdan almanız gerekebilir. Bu durumda eklenti veritabanı yapısını kullanabilirsiniz.

Alan Tanımlama

  • Sol menüdeki Sistem Ayarları ikonuna tıklayalım.

  • Eklentiler sekmesinden eklentinize tıklayıp detay sayfasına girelim.

  • Eklenti Veritabanı sekmesine geçelim.

  • Mevcut tanımlanmış alanları bu ekrandan görüp düzenleyebilir veya silebilirsiniz.

  • Yeni bir alan eklemek için Veri Ekle butonuna basalım.

Alan

Tip

Açıklama

Değerler

Adı

string

Kullanıcıya gösterilecek isim.

-

Türü

string

Oluşturulacak input'un tipi.

text password certificate extension server

Variable Adı

string

Kaydedilen veriye yazılımsal olarak erişebilmek için gerekli anahtar adı.

-

Zorun Alan

checkbox

Bu alan işaretlendiğinde kullanıcı bu alanı boş bırakamaz.

-

  • Formdaki gerekli alanları doldurduktan sonra Veri Ekle butonuna basarak kaydedebilirsiniz.

  • İlk veritabanı ayarını eklediğinizde eklentiye girdiğinizde Liman sistemi sizi eklenti ayarları sayfasına yönlendirecek ve sizin belirlediğiniz alanları doldurmanızı isteyecektir.

Alanın Değerine Erişmek

Geliştirdiğiniz eklentide kullanıcıdan aldığınız verilere erişmek için extensionDb helper fonksiyonunu kullanabilirsiniz. Bir önceki aşamada alanı tanımlarken girdiğiniz Variable Adı bu aşamada kullanılmaktadır.

echo extensionDb('username');
Eklenti Veritabanı Sekmesi
Yeni Veri Ekleme Ekranı
Örnek Eklenti Ayarları Sayfası

Dosya ve Dizin Yapısı

Liman eklentilerinin dizin yapısından ve klasörlerin ne işe yaradığını öğreneceğiz.

liman@pardus:/liman/extensions/ornekeklentim$ tree
├── routes.php
├── composer.json
├── db.json
├── app
│   ├── Controllers
│   ├── Helpers
│   └── Tasks
├── lang
├── public
│   ├── css
│   └── js
├── scripts
├── vendor
└── views
    ├── hostname
    ├── layouts
    ├── runscript
    ├── sandbox
    ├── systeminfo
    ├── taskview
    ├── index.blade.php
    └── scripts.blade.php
  • routes.php Controller rotalarımızı tanımladığımız dosya.

  • composer.json Composer ile paket yükleyebilmek için bulunması gereken dosya.

  • db.json Eklentinizin veritabanı kullanması için gereken konfigürasyon dosyası.

  • app Eklentimizin arka yüzünü bulunduran klasör.

    • Controllers Kontrolcülerimizi bulunduran klasör. Arka yüzde çalışan işlemlerin hepsi bu klasör içerisindeki dosyalarda yazılır.

    • Helpers/Helper.php Yardımcı fonksiyonlarınızı bu kısıma yazarsınız. Örneğin bir portun açık olup olmadığını kontrol eden fonksiyon.

    • Tasks Görevleri oluşturduğumuz ve çalıştıracağı komutları belirlediğimiz klasör.

  • lang Yerelleştirme dosyalarını bulunduran bir klasör.

  • public Eklentinin içinde kullanılacak, tüm eklenti genelinde yüklenmesini istediğimiz JavaScript ve CSS dosyalarını ekleyebileceğimiz klasör. Örnek kullanım eklenti şablonunda mevcuttur.

  • scripts Bu klasöre runScript ile sistem üzerinde çalıştırmak istediğimiz betikleri koyarız. Örneğin sambaOlustur.py ve enableWinrm.ps1 gibi.

  • vendor Composer dosyalarını ve class autoloader içeren klasör. Bu klasörde düzenleme yapmayacağız.

  • views Bu klasörde açılan alt klasörler sekmeli eklenti yapısının her bir sekmesi içindir. Bu klasörler de içerisinde main.blade.php ve scripts.blade.php içermektedir. Scriptlerin Javascript yerine blade ile eklenmesinin sebebi yerelleştirme, dinamik rotalar ve PHP ile çıktı alınması gereken bazı kısımların varlığındandır.

    • index.blade.php & scripts.blade.php index dosyamız içerisinde sekmelerimizi oluştururuz ve sekmelerin alt viewlarını include ederiz. Scripts dosyamızda ise tüm tablar geneli çalışmasını istediğimiz PHP bağımlı Javascript kodlarımızı yazabiliriz.

Rotalar

Eklentilerde rotaların görevi tam olarak nedir, ne yapar?

Rota Nedir?

Routing, request işlemlerinde kullanılabilecek, karmaşık kuralları kolaylıkla yönetebilme özelliği (GET, POST gibi HTTP methods, middleware gibi) ile öne çıkar. Routing işleminde işlemler route’lar (path) üzerinden yürütülür. Bu sayede URL eşleştirme işlemleri farklı amaçlarla gerçekleştirilebilmektedir. Bu işlem farklı bir şekilde ele alınsa da (client request) kullanıcılar/ziyaretçiler ve arama motorları URL’lerdeki gibi web sitesinde ve/veya uygulamasında anlamlı sonuçlara (endpoint) ulaşabilirler. Örneğin, /inbox/1/msg/2 gibi bir URL’de ilk path /inbox sonrası ise bu path’in iç yapıları olarak (routing tree) nitelendirilebilirler.

Biz Liman içerisinde rota işlemlerine bu kadar karmaşık yaklaşmıyoruz. Gelin nasıl incelediğimize bakalım.

Eklentilerde Rotalar

Biz eklentilerde rotalara daha çok REST mantığıyla baktığımızdan ve kod karmaşıklığını düşürmek istediğimizden Laravel'deki gibi kodu uzatmamaktayız.

Liman eklentilerinde rotalar sadece iki argüman alır.

  • Endpoint

  • Kontrolcü ismi @ Çağırılacak fonksiyon

Gelin örnek bir rota dosyasını inceleyelim.

routes.php
return [
    "index" => "HomeController@index",
    
    // Hostname Settings
    "get_hostname" => "HostnameController@get",
    "set_hostname" => "HostnameController@set",

    // Systeminfo
    "get_system_info" => "SystemInfoController@get",
    "install_lshw" => "SystemInfoController@install",
];

Görüleceği üzere eklenti rotalarımız POST, GET, PUT, DELETE... gibi argümanlar almamaktadır. Eklentilerde kontrolcüleri API mantığı ile kullandığımız için ihtiyaç duymadık.

Bir rota tanımlamak için aşağıdaki gibi bir tanımlama yapmanız gerekmektedir.

    "<ROTA_ISMI>" => "<CONTROLLER_ISMI>@<CAGIRILACAK_FONKSIYON>"

Yukarıdaki tarzda tanımlama yaptığınızda bunu Javascript yardımcı fonksiyonlarımızdan request ile API("<ROTA_ISMI>") şeklinde çağırabilir. Bu çağrıdan sonra sorunsuz şekilde response alacaksınız ve bunu Javascript ile kullanarak ister bir içeriği manipüle edebilir, ister başka bir içerik oluşturabilirsiniz.

PHP Yardımcı Fonksiyonları

Paket Bağımlılığı Eklemek

Geliştirdiğiniz eklentiyi çalıştırmak için Liman sunucusuna paket kurmanız gerekiyorsa, bu paketleri Liman'a nasıl otomatik kurdurabileceğinizi öğreneceğiz.

Bazı durumlarda eklentinizin bağımlılıkları olabilir, örneğin postgresql eklentisi geliştiriyorsanız php7.3-pgsql paketine ihtiyacınız olabilir. Liman eklentilerinde bu bağımlılıklarınızı db.json dosyanızdan veya Liman eklenti geliştirici arayüzünden tanımlayabilirsiniz.

  • Sol menüden Sistem Ayarları ikonuna tıklanır.

  • Eklentiler sekmesine geçilir ve eklentiye tıklanır.

  • Paket bağımlılıkları alanına paket isimleri araya boşluk bırakılarak yazılır.

  • Kaydet butonuna basılır.

Eklenti ilk defa Liman sistemine eklendiğinde paketler otomatik olarak kurulacaktır.

Eklenti Geliştirici Arayüzü

JS Yardımcı Fonksiyonları

Arayüzde işlemler yaparken kullanabileceğiniz genel Javascript yardımcı fonksiyonlarından bahsedeceğiz.

showSwal

showSwal fonksiyonu Sweetalert2 için kullandığımız yardımcı fonksiyondur. Hızlı ve basit bir şekilde Swal ateşlemenizi sağlar. Örnek kullanımı aşağıdaki gibidir.

showSwal("Yükleniyor...", "info", 2500);

Argüman

Açıklama

Veri Tipi

message

Göstermek istediğiniz mesaj.

String

type

Gösterilen Swal'ın türü. (info, danger, error...)

String

time

Ne kadar süre gösterilecek (ms bazında)

Integer

API

Bu fonksiyon hem Javascript, hem de PHP tarafımızda bulunmaktadır. Bu fonksiyona Rotalar sayfasında girdiğimiz isim değişkenini verdikten sonra bize request atacağımız url'yi döndürmektedir. Örnek kullanım aşağıdaki gibidir.

API("get_files")

Request

Request fonksiyonu Liman eklentilerinde kullandığımız en önemli fonksiyonlardan biridir. Controllerlar veya dış kaynak bir API üzerinden veri almamızı sağlar. Gelin örnek bir request fonksiyonunu inceleyelim.

let data = new FormData()
request("url", data, function(response) {
    console.log(response);
}, function(error) {
    console.log(error);
});

Bu fonksiyon belirlediğimiz url'ye bir POST requesti göndermektedir. Bu requestin sonucunda dönen veriye response, hata alırsak dönen veriye de error denmektedir. Gelin argüman listesi ve detaylarına bakalım.

Argüman

Açıklama

Veri Tipi

url

İstek gönderilmesini istediğimiz endpoint.

String

data

POST requestte göndereceğimiz ek veriler.

FormData

response

Yanıt geldiğinde yapılacak işlemlerin fonksiyonu

Function

error

Hata oluştuğunda yapılacak işlemlerin fonksiyonu

Function

showSwal("{{__('Yükleniyor...')}}", 'info');
let data = new FormData();
request("{{API('list_files')}}", data, function(response){
    $("#filesTable").html(response).find("table").dataTable(dataTablePresets("normal"));
    Swal.close();
}, function(response){
    response = JSON.parse(response);
    showSwal(response.message, 'error');
});

jQuery Fonksiyonları

Liman üzerinde jQuery kullanıldığı için istediğiniz tüm jQuery işlemlerinden faydalanabilirsiniz.

Bileşen Mantığı

Geliştirdiğiniz eklentiye Liman anasayfasına eklenebilen bir bileşen entegre etmeyi öğreneceğiz.

Liman sisteminin anasayfası eklentiler tarafından özelleştirilebilen bir yapıya sahiptir. Eklentinizi entegre ettiğinizde Bileşenler sayfasından anasayfaya eklenip çıkarılabilen bileşenler elde edebilirsiniz.

Bileşen Tanımlama

  • Sol menüdeki Ayarlar menüsüne tıklanır.

  • Eklentiler sekmesine geçilir ve eklentiye tıklanır.

  • Bileşenler sekmesine geçilir.

  • Yeni bir bileşen eklemek için Widget Ekle butonuna basılır.

Alan

Tip

Açıklama

Değerler

Widget Adı

string

Bileşenler sayfasında gösterilecek isim.

-

İkon

string

Bileşen render edildiğinde gösterilecek ikon.

Türü

selectbox

Bileşenin tipi.

Sayı Grafik

Çalışacak Fonksiyon

string

Eklenti içerisinde tanımlanmış ve bileşen verisini geriye döndüren fonksiyonun adı.

-

Fonksiyon Tanımlama

Bileşeninizin verilerini sağlayan fonksiyonu tanımlamak için WidgetController adında bir Kontrolcü oluşturup bu kontrolcü sınıfının içerisinde bir fonksiyon oluşturabilirsiniz.

<?php

namespace App\Controllers;

class WidgetController
{
    public function exampleWidget()
    {
        return respond(5);
    }
}

Ardından routes.php dosyasından bir önceki aşamada Çalışacak Fonksiyon alanına yazdığımız isimde bir Rota oluşturmalıyız.

<?php

return [
    "index" => "HomeController@index",
    "verify" => "HomeController@verify",
    "load" => "HomeController@load",

    "example_widget" => "WidgetController@exampleWidget"
];

Artık Bileşeniniz kullanıma hazır.

Bileşeni Liman'a Eklemek

  • Üst bardaki Bileşenler ikonuna tıklayın.

  • Bileşen Ekle butonuna tıklayın.

  • Sunucu ve Eklenti seçimi yaptıktan sonra yeni eklediğiniz Bileşeni seçebilirsiniz.

  • Bileşen Ekle butonuna bastığınızda Liman anasayfasında bileşeniniz görünecektir.

Bileşenler Ekranı

Bileşenler Ekranı
Bileşen Ekleme Ekranı
Örnek Bileşen Görüntüsü
https://fontawesome.com/v5.15/icons?d=gallery&m=free

Geliştirme Ortamı Kurulumu

Liman üzerinde eklenti geliştirme ortamının kurulumundan bahsedilecektir.

Liman Kurulumu

Linux Ayarları

Kullanıcıya Şifre Eklemek

Liman'ın işletim sisteminde kendine ait bir kullanıcısı olduğundan izin problemleri yaşamamak için sistem üzerindeki "liman" kullanıcısını kullanılabilir hale getirmeliyiz.

sudo passwd liman

Varsayılan Shell Değiştirmek

Bu işlemin ardından liman kullanıcısını kullanabilmemiz için varsayılan shell ayarını bash olarak seçmeliyiz. Bu işlemi aşağıdaki komut ile gerçekleştirebiliriz

sudo usermod --shell /bin/bash liman

Visual Studio Code Kurulumu

Bu tercihimizin altında yatan sebep Remote SSH eklentisi bulunması sebebiyle direkt sunucu üzerinde geliştirme yapabilmemiz.

Resimdeki gibi eklentinin kurulumunu sağladıktan sonra ekranın sol alt köşesinde bağlantı butonumuz çıkacaktır. Ona tıklayarak SSH bağlantı menüsünü açıyoruz.

İkona tıklayıp menüyü açtıktan sonra aşağıdaki gibi bir görüntü bizi bekleyecek. Buradan "Connect to Host..." seçeneğini seçmemiz gerekmektedir.

Connect to Host seçeneğini çıktıktan sonra bizi bu tarz bir ekran karşılayacaktır. Bu ekranda "+ Add New SSH Host..." seçeneğini seçiyoruz.

Bu kısımda en önemli şey SSH bağlantı cümleciğimizi doğru şekilde girmemiz. Format olarak alttaki formatta cümleciği yazmaktayız.

ssh liman@<SUNUCU_IP_ADRESINIZ>

Ardından gelen listede herhangi bir ayarı seçebilirsiniz. Bağlantı başarıyla eklendikten sonra tekrar "Connect to Host..." seçeneğini seçince eklediğimiz sunucu IP adresi ile görünecektir. Tıkladığımızda sunucu şifremizi soracaktır, girdikten sonra bağlantı başarılı olunca artık klasörümüzü açabiliriz.

Klasör açma adımları yukarıdaki resimde gösterilmiştir. Open Folder düğmesine tıklandıktan sonra kutucuğa /liman/extensions/ yazılır, ardından OK tıklandığında eklentilerin düzenlenebilmesi sağlanmaktadır.

Bu adımdan sonra Yeni Eklenti Oluşturma işlemlerini takip edebilirsiniz.

Eklenti geliştirebilmek için öncelikle Liman sunucusuna ihtiyacımız var 😁 Kurulum dokümantasyonuna adresinden ulaşabilir, adımları takip edebilirsiniz.

adresine giderek kurulumu gerçekleştiriyoruz. Kurulum işleminin ardından Remote SSH eklentisini kurmamız gerekmektedir.

Remote SSH Eklentisi
SSH Bağlantı İkonu
Connect to Host...
SSH Kullanıcıları
SSH Bağlantı Cümleciği
Klasör Açma Adımları
https://docs.liman.dev/kullanim-kilavuzu/liman-kurulumu/kurulum
https://code.visualstudio.com/
Yeni Eklenti Oluşturma

PHP Yardımcı Fonksiyonları

Liman üzerinde eklentilerle kullanabileceğiniz PHP yardımcı fonksiyonların listesi.

checkPort

checkPort fonksiyonu bizim için bir portun açık olup olmadığını kontrol etmekte buna göre bir boolean yanıtı döndürmektedir. Fonksiyonu kullanabilmek için iki adet argüman sağlamanız gerekmektedir.

Argüman

Açıklama

Veri Tipi

$ip

IP adresi yazmanız gerekmektedir.

String

$port

Port numarası belirtmeniz gerekmektedir.

Integer

(Return)

Fonksiyonun geri döndürdüğü değer

Boolean

Request

PHP tarafındaki request fonksiyonu bizim kontrolcümüze POST ile gönderilmiş değişkenleri yakalamamızı sağlar. Örneğin bir inputtan clientHostname isimli bir veri gönderdiysek bunu PHP tarafında request("clientHostname") olarak kolayca yakalayabiliriz.

Argüman

Açıklama

Veri Tipi

$name

Attığınız requestteki key ismi

String

server, user, extension

Bu helperlar Laravel tarafındaki server, user, extension modellerini getirmektedir. server()->name örnek bir kullanımdır. Detaylarını anlayabilmek için eklenti kodlarınızda dump(server()) tarzı bir kullanım yaparsanız içeriğini görüntüleyebilirsiniz.

Respond

Yanıt döndürme fonksiyonudur. İki argüman almaktadır. JSON olarak karşıya veri getirir, dönen verinin örnek tipi aşağıdaki gibidir.

{"message": "pardus", "status": 200}

Anlaşılacağı üzere fonksiyon da iki adet argümanı mesaj ve durum kodu olarak almaktadır. Yukarıdaki yanıtı alabilmek için fonksiyonu aşağıdaki gibi çalıştırırız.

return respond("pardus", 200);

Argüman

Açıklama

Veri Tipi

$message

Mesajınızı veya döndürmek istediğiniz PHP, HTML herhangi bir veriyi gönderirsiniz.

Auto

$status

HTTP durum kodlarından birini istediğiniz şekilde gönderiniz. 200 başarılı anlamına gelmektedir.

Integer

View

View fonksiyonu controlleriniz üzerinden bir view dosyasını renderlamanızı sağlamaktadır. Örnek olarak aşağıdaki gibi görebiliriz.

return view("table", [
    "value" => $files,
    "title" => ["İsim", "İzinler", "Sahip", "Grup", "Dosya Boyutu", "Son Değiştirilme"],
    "display" => ["name", "permissions", "user", "group", "size", "date"]
]);

Validate

Kullanım şekli olarak Laravel ile birebir uyuşmasa da kuralların yazıldığı kısım birebir uyuşmaktadır. Gelin bir örnek kullanıma bakalım.

validate([
    'username' => 'required|string',
    'password' => 'required|string'
]);

validate fonksiyonu bir kontrolcü fonksiyonunun başında çağırılır. Aldığı tek argüman kurallar listesidir. Kuralların kullanımında örnek kullanım yukarıdaki gibidir. Örnek olarak listenin ilk elemanından bahsedelim. Bize form data ile gönderilmiş olan username verisi request("username") ile eşleşmektedir. Bu eşleşme uyduğunda doğrulayıcı fonksiyonumuz value olarak verdiğimiz required|string kurallarına göre request("username") verisini doğrulayacaktır. Eğer doğrulanamazsa da kontrolcü fonksiyonunun çalışması durdurulup, mesaj olarak doğrulanamadığına dair hata mesajı dönecektir.

Argüman

Açıklama

Veri Tipi

$rules

Kuralların olduğu liste.

Array

Laravel Helpers

Liman eklenti sandboxu üzerinde Laravel Helpers paketi çalışmaktadır. Bu paket ile Array ve Object manipülasyonları, dosya yolu yardımı, string manipülasyonları, fluent string manipülasyonları, URL işlemleri ve çeşitli ek fonksiyonlar (dump, abort, retry, response, bcrypt, view...) yer almaktadır. Bu paketin yer alması neredeyse Laravel üzerinde çalışan çoğu fonksiyonu eklentilerinizde de kullanabileceğiniz anlamına gelmektedir.

Kendi Helperlarınızı Geliştirin

Validate fonksiyonu Laravel üzerindeki gibi çalışmaktadır. Genel kurallarına ve örnek kullanıma kısmından ulaşabilirsiniz.

sayfasından validation fonksiyonunun detaylı dokümanına ulaşabilirsiniz.

adresinden detaylı dokümana ulaşabilirsiniz.

Kendi özel helperlarınızı geliştirmek için eklenti klasörünüz içerisinde app/Helper/Helpers.php içerisinde daha önce tanımladığımız checkPort fonksiyonuna bakarak tanımlama yapabilirsiniz, daha önceden topluluk tarafından geliştirilmiş Helper dosyalarını incelemek için Liman Market'ten indirdiğiniz açık kaynaklı eklenti kodlarına da göz atabilirsiniz. örnek eklentisinde sistemdeki sertifika kontrolleri için ve LDAP bağlantı kontrolü için de yardımcı fonksiyonlar geliştirilmiştir.

Validation - Laravel Docs
Validation - Laravel Docs
https://laravel.com/docs/8.x/helpers
zekiahmetbayar/liman-sambahvl

Sunucuda Komut Çalıştırmak

Eklentinizi eklediğiniz sunucu üzerinde nasıl komut çalıştırır ve çıktılarını nasıl alırsınız detaylıca bahsedeceğiz.

Standart Komut Çalıştırmak ve Çıktı Almak

Toolkiti çağırmak

use Liman\Toolkit\Shell\Command;

Controller dosyamızı açtığımızda namespace satırının hemen altına bu komutu ekliyoruz. Bu sayede dosyamızda Liman Toolkitin Command classını kullanabilir hale geleceğiz.

Komut çağırmak

$command = Command::run("hostname");

Sudo olarak komut çağırmak

Aslında yukarıdaki kullanımın benzerini gerçekleştireceğiz. Sadece run komutu yerine runSudo şeklinde değiştirdiğimizde yetkili kullanıcı kullanılarak çalıştırılacaktır.

$command = Command::runSudo("cat /etc/network/interfaces");

Dış requestler ve escaping kullanımı

Command classı üzerinde güvenlik için dış inputlara escaping kullanımı mevcuttur. Aynı zamanda validation yardımcı fonksiyonu da bulunduğundan dış komutlarda ister regexp, ister tür, isterseniz de uzunluk kontrolü yapabilirsiniz. Birlikte dış requestlerin kullanıldığı bir senaryoyu inceleyelim.

Command::runSudo("touch /home/liman/@{:filename}", [
    "filename" => request("filename")
]);

Escaping kullanımı

Yukarıdaki runSudo fonksiyonunun ilk argümanında göreceğimiz üzere @{:filename} tarzı bir kullanım mevcuttur. Bu kullanım escaping işlemi gerçekleştirmektedir. Escaping işleminin önem sebebi güvenliktir. Dışarıdan düşük yetkili bir kullanıcı sistemi yönetirken bu boşluğa ; rm -rf * şeklinde bir girdi gönderirse tüm klasör içeriği silinecektir. Burada escaping işlemi ile gönderim sağlarsak ; işareti işlevini kaybedecektir ve sistemimiz daha güvenli bir şekilde kullanıcı girdilerine açık hale gelecektir.

run ve runSudo fonksiyonları normalde tek argümana ihtiyaç duymaktadır ancak escaping yapıldığında ikinci argüman olarak bir array gönderimi de yapmalıyız.

Escaping yapabilmek için @{:degiskenAdi} şeklinde bir kullanım yapmalıyız. Burada degiskenAdi kısmı göndereceğiniz parametrelerin ismine göre değişmeli, ikinci argüman olan arrayinizde bu isimleri key olarak kullanmalısınız.

Dış requestler

Dış requestlerden girdi alabilmemiz için ilk önce escaping yapmamız gerekiyordu. Bu adımı gerçekleştirdikten sonra ikinci argüman olarak kullanılan arrayimizde gönderdiğimiz verinin ismini request() PHP yardımcı fonksiyonu ile alabiliriz. Aldıktan sonra yukarıdaki kod bloğunda görülebileceği üzere key olarak escape edilen değişken adını, değerine ise request fonksiyonumuzdan aldığımız değeri göndermekteyiz.

Fonksiyon Kullanım Parametreleri

Parametre

Açıklama

Veri Tipi

$command

Karşı sunucuda çalıştırılması gereken komut.

String

$variables

Eğer $command parametresi escape edilen kısımlar barındırıyorsa gönderilmesi gereken liste. (Opsiyonel)

Array

Dosya Yükleme, İndirme

Eklentinin eklendiği sunucuya dosya yüklemeyi veya sunucudan dosya indirmeyi öğreneceğiz.

Eklentinin eklendiği sunucudan Liman sunucusuna dosya indirmenin veya Liman sunucusundan karşı sunucuya dosya yüklemenin gerekli olduğu durumlarda kullanılabilecek iki fonksiyon Liman sisteminde tanımlanmıştır.

putFile

Bu fonksiyon Liman sunucusundan karşı sunucuya dosya yükler.

getFile

Bu fonksiyon ise karşı sunucudan Liman sunucusuna dosya indirir.

Sunucuda Betik Çalıştırmak

Sunucu üzerinde Python, Bash ve Powershell betiklerini çalıştırma yöntemleri.

runScript fonksiyonu

Sunucumuzda betik çalıştırmak için runScript yardımcı fonksiyonumuzu kullanmaktayız. Bu fonksiyon eklentinin eklendiği sistem üzerinde Python, Bash ve Powershell betiklerini çalıştırmamızı sağlamaktadır.

Gerekli Ortamı Hazırlama

runScript fonksiyonunun çalışabilmesi için eklenti dizininiz altında bir scripts klasörü oluşturmamız ve betikleri bu klasörün içerisine yüklememiz gerekmektedir.

Kullanım Örneği

runScript fonksiyonunu kullanabilmek için bir controller oluşturmamız gerekmektedir. Bu controlleri doğru şekilde oluşturup rota tanımlamasını doğru şekilde yaptığımızı varsayalım.

Örnek Python Kullanımı

Controllerda tanımlamalarımızı yapıp ardından JavaScript tarafında request yardımcı fonksiyonumuz ile çağrımızı yaptığımızda betik çıktımızı alabiliriz.

Bu Python betiğini yukarıdaki şekilde controller kısmında çağırıp önyüz çağrısı sonucu şu tarz bir çıktı almaktayız.

Bu örneği PHP 7.3 + OOP Training eklenti şablonunda bulabilirsiniz.

Sistem üzerinde komut çalıştırabilmek için içerisinden Command classını kullanmaktayız. Limanda en çok kullanılan şey olduğu için ayrı bir başlıkta anlatma gereği duyduk. Gelin şimdi nasıl çalıştırırız bakalım.

Yukarıdaki kodu çalıştırdığımızda bize sistem üzerinde hostnamekomutunu çalıştıracaktır. $command değişkenini respond yardımcı fonksiyonumuz ile kullanarak döndürdüğümüzde hostname bilgisini problemsiz şekilde elde edebiliriz. kısmındaki eklenti şablonunda bu kullanımların örneği mevcuttur.

Bu değerleri gönderebilmek için ise sayfamızda bulunan fonksiyonunun detaylarını inceleyip, siz de kendi sayfanızdan request gönderimi yapabilirsiniz.

Liman Toolkit
PHP Yardımcı Fonksiyonları
JS Yardımcı Fonksiyonları
Eklenti şablonları
OOP Training
JS Yardımcı Fonksiyonları
request

Argüman

Açıklama

Veri Tipi

$localPath

Liman sunucusundaki dosyanın konumu.

string

$remotePath

Karşı sunucuda dosyanın yükleneceği yol.

string

Argüman

Açıklama

Veri Tipi

$localPath

Liman sunucusunda indirilecek dosyanın yolu.

string

$remotePath

Dosyanın karşı sunucudaki konumu.

string

public function run()
{
    // runScript function
    // 1st parameter: filename under scripts folder STRING
    // 2nd parameter: parameters STRING
    // 3nd parameter: run as sudo BOOL
    $script = runScript("example.py", "", false);
    return respond($script, 200);
}

Parametre

Açıklama

Veri Tipi

Birinci Parametre

scripts klasörü altındaki dosya adını alır

String

İkinci Parametre

scripte göndereceğimiz argümanlar

String

Üçüncü Parametre

sudo olarak mı çalıştırılmalıdır?

Boolean

#!/usr/bin/python3
print("Hello world!")

Tablo

Liman eklentileri üzerinde kolay bir biçimde tablo oluşturma yolu.

Tablo componenti nedir?

Tablo componenti, PHP ile gönderdiğiniz verilerin kolayca DataTables olarak oluşturulmasını sağlar. Ayrıca içerisinde birden çok özellik bulundurmaktadır.

  • Satıra tıklayınca bir işlem yapılması

  • Satıra sağ tıklayınca sağ klik menüsünün açılması

  • Sayfalama fonksiyonu

  • Arama fonksiyonu

  • Sütunlar içerisinde sıralama işlemi yaptırtmak

Nasıl kullanılır?

@include("table", [
    "value" => $exampleTableData,
    "display" => ["name", "surname", "email", "phone", "id:id"],
    "title" => ["İsim", "Soyisim", "Eposta", "Telefon", "*hidden*"],
    "onclick" => "rowOnClickEvent",
    "menu" => [
        "Example Right Click" => [
            "target" => "exampleRightClickEvent",
            "icon" => "fa-file-export"
        ],
    ]
])

Liman içerisinde Blade Render Engine kullanıldığından viewları yukarıdaki şekilde sayfamıza dahil edebiliriz. Formatı anladıysak gelin birlikte değişkenlere bakalım.

Veri

Açıklama

Veri Tipi

value

Tablonun içeriğini oluşturur

Array

title

value verisinden alınan girdilerin viewda gösterilen halidir

Array

display

value verisinden gösterilmesini istediğimiz keyler

Array

onclick

Satır üzerine tıklandığında çağırılacak JS fonksiyonu

String

menu

Satıra sağ tıklandığında çıkacak içerik menüsü

Array

menu/target

Sağ tık menüsünde tıklama yapıldığında çağırılacak fonksiyon

String

Value

$exampleTableData = [
    [
        "id"      => "1",
        "name"    => "Havelsan",
        "surname" => "Aciklab",
        "email"   => "aciklab.org",
        "phone"   => "00000000"
    ],
    [
        "id"      => "2",
        "name"    => "Havelsan",
        "surname" => "Pardus",
        "email"   => "pardus.org",
        "phone"   => "00000000"
    ]
];

Value değişkeni yukarıdaki kod bloğunun yapısında olmalı, diğer veriler de sonradan bu hale getirilerek gönderilmelidir.

Yapı olarak kendisi bir Array veri tipindedir. Liste içerisinde listelerden oluşmaktadır. Liste içerisindeki her bir liste bir satırı temsil etmektedir. Yukarıdaki örnek veri tipinde iki adet satırımız vardır ve çıktısı aşağıdaki gibi olacaktır.

Eklenen her veride zorunlu olarak key değerleri aynı olmalıdır. Aksi halde tablo componenti başarılı şekilde renderlanamayacaktır.

Display

"display" => ["name", "surname", "email", "phone", "id:id"]

Display değişkeninde value arrayinde aldığımız listeden gösterilmesini istediğimiz keyleri yazmaktayız. Burada dikkat edilmesi gereken tek özel kullanım id:id kullanımıdır. Bu kullanımın sebebi ise gizli şekilde göstermek istediğimiz verilerdir. Title kısmında da bu özel kullanımın diğer adımını göreceğiz.

Verileri gizli göstermek istememizin sebebi JavaScript ile yakalama imkanı oluşturmaktır. Örneğin sağ klik işlemine sil isimli bir fonksiyon tanımladığımızı düşünelim. Eğer ID değişkenini JavaScript tarafına gönderebilirsek kolayca request atarak silme işlemini tamamlayabiliriz.

Title

"title" => ["İsim", "Soyisim", "Eposta", "Telefon", "*hidden*"]

Title değişkeni display değişkeninde aldığımız keyleri görüntüsü güzel bir hale getirir. name yerine İsim yazmanızı sağlar. Burada dikkat edilmesi gereken en önemli kısım ise *hidden* kısmının display kısmındaki gizlemek istediğimiz key ile eşleşmesi, orada da keyin id:id formatında kullanılması gerekliliğidir.

Onclick

Tablodaki satıra tıklandığında çalıştırılacak JavaScript fonksiyonunu tanımlarız. Nasıl kullanıldığını anlamak için gelin beraber bir örnek inceleyelim.

function lineOnClickEvent(node) {
    // node satır için bize gönderilen JavaScript seçicisidir(selector)
    console.log(node)

    // satırımızdaki gizli olan id sütununun içeriğini almak
    console.log($(node).children("#id").html())
    
    // bu id ile örnek bir işlem gerçekleştirmek
    Swal.fire(`${$(node).children("#id").html()} idli elemente tıkladınız!`)
}

Yukarıda göreceğimiz üzere node argümanı bizim için o satırın JavaScript selectorunu döndürmektedir. Bu selectoru kullanarak ister ES6, ister jQuery ile kolayca işlerimizi halledebiliriz. Liman altyapısında jQuery bulunduğu için örnekte ben jQuery kullanmayı tercih ettim.

Menu

Sağ klik menüsü açabilmemiz için gereken veri türüdür. Bu veri türünü oluşturmak için isim, JavaScript fonksiyonu ve bir font awesome ikonuna ihtiyacımız var. Gelin örnek bir menü tanımlayalım.

"menu" => [
    "Kopyala" => [
        "target" => "copyEvent",
        "icon" => "fa-copy"
    ],
    "Kes" => [
        "target" => "cutEvent",
        "icon" => "fa-cut"
    ],
    "Yapıştır" => [
        "target" => "pasteEvent",
        "icon" => "fa-paste"
    ],
]

Yukarıdaki biçimi kullanarak örnek bir menü tanımlaması gerçekleştirebiliriz. En dikkat edilmesi gereken detay ise target kısmında bulunan eventlerin JavaScript ile tanımlanmasıdır. Bu tanımlamaları yapmazsak düzgün çalışmayacaktır. Gelin kullanıcı silmek için örnek bir tanımlama yapalım.

function deleteUser(node) {
    showSwal("{{__('Yükleniyor...')}}", 'info');
    let data = new FormData();
    data.append("username", $(node).find("#user").html());
    request("{{API('delete_user')}}", data, function(response){
        Swal.close();
        response = JSON.parse(response);
        showSwal(response.messsage, "success", 2500);
        getUsers();
    }, function(response){
        response = JSON.parse(response);
        showSwal(response.message, "error");
    });
}

Tanımladığımız fonksiyon aynı onclick fonksiyonundaki gibi bir argüman almaktadır. Node isimli selector ile kullanıcı adını yakalayarak Liman üzerinde hazır tanımlanmış Request fonksiyonuna veriyi ekliyor ve bu fonksiyon aracılığı ile POST olarak gönderimi yapıyorum. Dönen cevabı ise showSwal yardımcı fonksiyonum ile ekranda gösteriyorum.

Requestten tablo çekmek

public function list()
{
    $command = Command::runSudo("ls -lah /home/liman");
    $files = explode("\n", $command);
    array_splice($files, 0, 1);
    
    foreach ($files as &$file) {
        $file = preg_replace('/\s+/', ' ', $file);
        $file = explode(" ", $file);
        $file = [
            "permissions" => $file[0],
            "user" => $file[2],
            "group" => $file[3],
            "size" => $file[4],
            "date" => $file[5] . " " . $file[6] . " " . $file[7],
            "name" => $file[8]
        ];
    }
    
    return view("table", [
        "value" => $files,
        "title" => ["İsim", "İzinler", "Sahip", "Grup", "Dosya Boyutu", "Son Değiştirilme"],
        "display" => ["name", "permissions", "user", "group", "size", "date"]
    ]);
}

Yukarıda göreceğimiz kod bloğunda bir dizin üzerinden dosya listesini çekip, parse işlemi yaptıktan sonra response olarak bir tablo viewi gönderdim. Bu tablo viewini de Javascript kullanarak bir HTML elemanının içeriğine yazdırmalıyım ki tablom görünsün. Gelin o işlemi de nasıl yapabileceğimizi inceleyelim.

function listFiles() {
    showSwal("{{__('Yükleniyor...')}}", 'info');
    let data = new FormData();
    request("{{API('list_files')}}", data, function(response){
        $("#filesTable").html(response).find("table").dataTable(dataTablePresets("normal"));
        Swal.close();
    }, function(response){
        response = JSON.parse(response);
        showSwal(response.message, 'error');
    });
}

Bu fonksiyona çağrı atacağınız yeri sizin seçmeniz gerekmektedir, aynı zamanda tablonun çıkmasını istediğiniz yerde filesTable id değerine sahip bir de div oluşturmalısınız.

Tabloyu dataTable yapmak

Requestten aldığımız tablo HTML kodunu koyduğumuzda tabloda arama, sayfalama işlemleri yapılamamaktadır. Bunu çözmek JS yardımcı fonksiyonumuz olan dataTablePresets fonksiyonunu aşağıdaki gibi kullanabiliriz.

$("#exTable").html(response).find("table").dataTable(dataTablePresets("normal"));

Protokol Bağlantıları (LDAP, SMB)

Liman eklentilerinizde belirli protokole nasıl bağlanabileceğinizi öğreneceğiz.

Liman sisteminde eklenti geliştirirken belirli protokollerle çalışmanız gerekebilir. Böyle bir durumda ek bir kütüphane veya destekliyorsa doğrudan php'nin fonksiyonlarını kullanabilirsiniz.

Örnek LDAP Bağlantısı

LDAP protokolünü PHP diliyle kütüphaneye gerek olmadan kullanabilirsiniz. Fakat eklentinize php7.3-ldap debian paketini bağımlılık olarak eklemelisiniz.

LDAP protokolüyle bind olabilmek için kullanıcıdan kullanıcı adı ve şifre gibi bilgileri istemeniz gerekebilir. Eklenti veritabanı ile bu bilgileri kullanıcıdan isteyebilirsiniz.

Sonrasında ise bağlantı açıp istenilen veriler alınmaya başlanabilir.

$connection = ldap_connect('ldaps://' . server()->ip_address); //eklentinin eklendiği sunucunun ip adresi ile LDAPS protokolünü kullanarak bağlantı açıyoruz.
ldap_bind($connection, extensionDb('clientUsername'), extensionDb('clientPassword')); //eklenti veritabanına yazdığımız keylere göre kullanıcının LDAP kullanıcı adı ve şifresiyle bind oluyoruz.
$result = ldap_search($connection, "DC=baran,DC=lab", "(cn=*)"); //base dn'e göre arama yapıyoruz.
$data = ldap_get_entries($connection, $result); //arama sonuçlarını alıyoruz.
dd($data); //dönen sonuçları debug etmek için dd helperını kullanıyoruz. 

Örnek SMB Bağlantısı

SMB bağlantısı için icewind/smb kütüphanesini kullanabilirsiniz. Bu kütüphaneyi kullanmak için de bazı php debian modüllerini kurmanız gerekebilir. php-smbclient ve smbclient debian paketlerini eklentinizin bağımlılıklarına ekleyebilirsiniz.

  • Paket kurulumu için aşağıdaki komutu eklenti dizininizde çalıştırabilirsiniz.

composer require icewind/smb
  • Paketi kurduktan sonra kütüphaneyi kullanmaya başlayabilirsiniz.

$options = new Options();
$options->setTimeOut(5);
$serverFactory = new ServerFactory($options);
$auth = new BasicAuth(extensionDb('clientUsername'), 'workgroup', extensionDb('clientPassword'));
$server = $serverFactory->createServer(server()->ip_address, $auth);
$share = $server->getShare('SYSVOL');
dd($smb->read('ORNEK_PATH'));

Dosya Yükleme

Liman eklentileri üzerinde dosya yükleme formu oluşturmanın anlatımı.

Nasıl kullanılır?

Detaylı kullanımı için aşağıdaki linke bakabilirsiniz.

Görev (Task)

Paket yükleme&kaldırma ve benzeri tüm uzun süren işlemleri arkaplanda çalıştırıp arayüzde çıktıları göstermeyi kolaylaştıran Task(Görev) componentini öğreneceğiz.

Eklentinizde bazı durumlarda uzun süren işlemler yaptırmanız gerekebilir. Bu gibi durumlarda Task componentini kullanabilirsiniz.

Task Soyut Sınıfından Türeyen Bir Sınıf Oluşturmak

  • OOP eklenti klasör yapısında öncelikle app klasöründe Tasks isminde bir klasör oluşturuyoruz ve InstallPackage.php dosyası oluşturuyoruz.

  • Task soyut sınıfındaki değişkenleri yaptıracağımız işe göre override ediyoruz.

Görevleri Çalıştırmak

  • Controller içerisinde bir fonksiyon tanımlıyoruz ve routes.php içerisinde gerekli tanımlamaları yapıyoruz.

  • Bu fonksiyon geriye task componentini çalıştırmanız için gerekli HTML verisini döndürür.

  • Birden fazla task tasks dizisi içerisinde tanımlanabilir böyle bir durumda görevler kuyruklanır ve sırayla çalıştırılır.

Blade İçerisinde Task Componentinin Kullanımı

  • Tercihe bağlı olarak Görev componenti bir Modal içerisinde gösterilebilir.

  • Bu şekilde bir modal tanımlanabilir.

  • Görevi başlatmak için de bu şekilde javascript ile ajax çağrısı yapılır ve Task modal'ının içerisine eklenir.

Toolkit Kullanımı

Toolkit, Liman eklentilerinin geliştirilmesini kolaylaştırmak için çeşitli yardımcılar ve sınıflar sağlayan bir kütüphanedir.

Örnekler

Distro

Command

Formatter

Validation

Modal

Liman eklentileri üzerinde kolay bir biçimde modal (açılır pencere) oluşturmanın yolları.

Modal componenti nedir?

Modal componenti, karmaşık akışları kolaylaştırmak ve sayfa içinde görünmesini istemediğimiz yapılar için kullanılabilecek bir bileşendir.

  • Kullanıcıdan girdi alınması

  • Kullanıcıya veri detayı gösterilmesi

Nasıl kullanılır?

Modal açmak

Modal düğmesi

Modal düğmesi componentini kullanarak oluşturduğunuz modalları açabilirsiniz. Aşağıdaki şekilde kullanılabilmektedir.

Javascript ile modal açmak

Modallar düğme ile açılabildiği gibi sizin belirlediğiniz özel Javascript eventleri, fonksiyonları ile de açılabilmektedir.

Modal oluşturmak

Örnek bir modal oluşturmak için aşağıdaki yapıyı kullanabilirsiniz. @component ve @endcomponent tagları içerisinde kalan kısma checkbox, radio button, input, selectbox ve diğer tüm HTML elementlerini istediğiniz gibi yerleştirerek modal içeriğini oluşturabilirsiniz.

Modaldan değer almak

Yukarıdaki örnekte iki adet input tanımlamıştık. Bir tanesinde kullanıcı adı, diğerinde ise şifre isteniyordu. Bunları kullanıcı tarafından alarak üzerinde nasıl işlem yaparız gelin bakalım.

Betiklerin Bulunduğu Klasör
Betik Çıktısı
Tablo Componenti
Örnek Value Değişkeni

Detaylı bilgi için:

Daha fazla bilgi için:

JS Yardımcı Fonksiyonları
Paket Bağımlılığı Eklemek
Veritabanı Mantığı
https://www.php.net/manual/tr/ref.ldap.php
Composer
https://github.com/icewind1991/SMB
@include("file-input", [
    "title" => "Örnek File Input",
    "id" => "example-file",
    "callback" => "fileUploadEvent"            
])

Parametre

Açıklama

title

Dosya yükleme formunun başlığı.

id

Request yönetimi yapılacak id değeri

callback

Yükleme işlemi yapıldığında yapılacak işlemlerin Javascript fonksiyonu (argüman olarak 1 argüman alır, veri o argümanda yakalanır)

<?php
namespace App\Tasks;

use Liman\Toolkit\Formatter;
use Liman\Toolkit\RemoteTask\Task;

class InstallPackage extends Task
{
    protected $command = "DEBIAN_FRONTEND=noninteractive apt install @{:package} -qqy";
    protected $sudoRequired = true;
    protected $control = "apt\|dpkg";

    public function __construct(array $attributes = []){
        if(!isset($attributes["package"])){
            throw new \Exception("Package name is required");
        }
        $this->attributes = $attributes;
        $this->logFile = Formatter::run(
            "/tmp/install-package-{:package}.txt", 
            ["package" => $attributes["package"]]
        );
        $this->checkCommand = Formatter::run(
            "apt list --installed | grep {:package}", 
            ["package" => $attributes["package"]]
        );
    }
}

Değişken

Tip

Açıklama

$command

string

Çalıştırılacak komut metni.

$logFile

string

Komutun çıktılarının saklanacağı konum.

$sudoRequired

boolean

Sudo gerekli ise true olmalıdır. (opsiyonel)

$control

string

İşlemin bitip bitmediğini anlamak için gerekli grep kontrol deseni.

$attributes

array

Komut metninde değişken kullandıysanız değişkenlerin değerlerinin tanımlanması gereken dizi. (opsiyonel)

$checkCommand

string

İşlemin başarıyla bitip bitmediğinin kontrolünü sağlayan komut. (opsiyonel)

	public function installPackage()
	{
		validate([
			'package_name' => 'required|string',
		]);
		return respond(
			view('task', [
				'tasks' => [
					0 => [
						'name' => 'InstallPackage',
						'attributes' => [
							'package' => request('package')
						]
					]
				]
			]),
			200
		);
	}
@component('modal-component',[
    "id" => "taskModal",
    "title" => "Görev İşleniyor",
])
@endcomponent
    function installPackage(package_name){
        showSwal('{{__("Yükleniyor...")}}', 'info');
        let formData = new FormData();
        formData.append("package_name", package_name);
        request("{{API('install_package')}}", formData, function(response){
            $('#taskModal').find('.modal-body').html(JSON.parse(response).message);
            $('#taskModal').modal("show"); 
            Swal.close();
        }, function(response){
            let error = JSON.parse(response);
            showSwal(error.message, 'error', 2000);
        });
    }
use Liman\Toolkit\OS\Distro;
Distro::debian('apt install nano -y')
    ->centos('yum install nano -y')
    ->runSudo();
Distro::debian("echo 'debian'")
    ->centos("echo 'centos'")
    ->centos6("echo 'centos6'")
    ->centos7("echo 'centos7'")
    ->pardus19("echo 'pardus19'")
    ->pardus192("echo 'pardus19.2'")
    ->pardus193("echo 'pardus19.3'")
    ->ubuntu("echo 'ubuntu'")
    ->ubuntu1804("echo 'ubuntu18.04'")
    ->ubuntu2004("echo 'ubuntu20.04'")
    ->ubuntu2010("echo 'ubuntu20.10'")
    ->default("echo 'Hiçbiri değil'")
    ->run();
use Liman\Toolkit\Shell\Command;
echo Command::run('hostname');
Command::runSudo('hostnamectl set-hostname @{:hostname}', [
    'hostname' => request('hostname')
]);
use Liman\Toolkit\Shell\SSHEngine;
SSHEngine::init(
    request('ipAddress'),
    request('username'),
    request('password')
);
Command::bindEngine(SSHEngine::class);
echo Command::run('hostname');
use Liman\Toolkit\Formatter;
echo Formatter::run('hostnamectl set-hostname @{:hostname}', [
    'hostname' => request('hostname')
]);

//output: hostnamectl set-hostname pardus
validate([
    'hostname' => 'required|string'
]);
@include("modal-button", [
    "text" => "Örnek Modal Aç",
    "class" => "btn-primary",
    "target_id" => "exampleModalWindow"
])

Parametre

Açıklama

text

Modal açma düğmesinin üzerinde yazacak yazı

class

Düğmeye ait olan class parametresi

target_id

Açılması istenilen modalın id değeri

// Modal göster
$("#<MODAL_IDSI>").modal("show");

// Modal gizle
$("#<MODAL_IDSI>").modal("hide");
@component("modal-component", [
    "id" => "exampleModalWindow",
    "title" => "Örnek Modal",
    "notSized" => true,
    "modalDialogClasses" => "classExample",
    "footer" => [
        "class" => "btn-danger",
        "onclick" => "modalDialogEvent()",
        "text" => "What to do"
    ]
])    
    <input type="text" name="username" id="username_field" class="form-control">
    <small>Eklemek istediğiniz kullanıcı adını giriniz</small>

    <div class="mb-3"></div>
    
    <input type="password" name="password" id="password_field" class="form-control">
    <small>Kullanıcı şifresini giriniz</small>
@endcomponent

Parametre

Açıklama

Veri Tipi

id

Modala ait olan id değeri. Benzersiz şekilde belirlenmelidir.

title

Modalda görünecek başlık değeri.

notSized

Boyut geniş mi dar mı olacak belirlediğimiz değer.

modalDialogClasses

Modal üzerine eklenmek istenen class değerleri.

footer

Modal içerisindeki düğmelerin bulunduğu alt kısım.

footer->class

Düğmeye ait class değeri. (Renkler için kullanıyoruz)

footer->onclick

Tıklandığında gerçekleştirilecek işlem.

footer->text

Butonda görünecek yazı.

function modalDialogEvent() {
    showSwal("{{__('Yükleniyor...')}}", 'info');
    let data = new FormData();
    // exampleModalWindow modalının içerisinden username_field idsine sahip
    // inputtan değeri alıyor ve gönderdiğimiz requestin içerisine ekliyoruz.
    data.append("username", $("#exampleModalWindow").find("#username_field").val());
    // benzer bir işlemi şifre için de yapıyoruz
    // bu gönderdiğimiz değişkenlere controller tarafında 
    // request() yardımcı fonksiyonu ile erişeceğiz.
    // örnek: request("password");
    data.append("password", $("#exampleModalWindow").find("#password_field").val());

    request("{{API('add_user')}}", data, function(response){
        // işlem yapıldıktan sonra modal penceresini gizle.
        $("#exampleModalWindow").modal("hide");
        // Yükleniyor mesajını işlem bittiği için kapatıyoruz.
        Swal.close();
        // modal içerisindeki input değerlerini eski haline getiriyoruz.
        $("#exampleModalWindow").find("input").val("");
        response = JSON.parse(response);
        // Başarılı olduğuna dair 2.5 saniyelik bir mesaj gösteriyoruz.
        showSwal(response.message, 'success', 2500);
    }, function(error){
        error = JSON.parse(error);
        showSwal(error.message, 'error');
    });
}
Dosya Yükleme, İndirme
Dökümantasyon

Composer

Eklentilere Composer yardımı ile kütüphane kurup kullanmayı öğreneceğiz.

OOP şablonu ile ile geliştirdiğiniz eklentilerde Composer ile paket kurup kullanabilirsiniz.

Paket Kurulumu

Eklentinizin bulunduğu klasörde terminal açtıktan sonra composer require PAKET_ISMI komutuyla istediğiniz PHP paketini kurup kullanmaya başlayabilirsiniz.

DB Kütüphanesi

Veritabanı işlemleri için kullanabileceğiniz illuminate/database kütüphanesinin entegrasyonunu öğreneceğiz.

Eklentinizde bir veritabanına bağlanıp işlem yaptırmanız gerekiyor ise illuminate/database kütüphanesini entegre edebilirsiniz. Bu kütüphane gelişmiş sql builder'ı ile okunaklı ve güvenli sql komutları çalıştırmanızı sağlar.

Gerekli Paketlerin Kurulumu

Gerekli paketleri kurduktan sonra app/Helpers klasöründe DB.php adında bir dosya oluşturuyoruz. Dosyanın içeriği aşağıdaki gibi olabilir.

Sınıfımızı tanımladıktan sonra veritabanı işlemi yapacağımız kontrolcülerde şu şekilde kullanabiliriz:

  • Öncelikle use anahtar sözcüğü ile sınıfımızı import etmeliyiz.

Sonrasında kontrolcü sınıfımızın herhangi bir yerinde DB sınıfını çağırıp işlemlerimizi yaptırabiliriz.

DB::database('') ifadesi bizim sınıfımıza özel dinamik olarak farklı veritabanlarına bağlanmayı sağlayan bir fonksiyondur. DB sınıfımız illuminate/database kütüphanesindeki Capsule sınıfından türetilmiştir. Dolayısıyla Laravel database dökümanındaki tüm özellikleri DB sınıfıyla kullanabilirsiniz.

Dosya Yükleme
Modal Componenti

Paket listesine ulaşmak için:

Detaylı bilgi için:

https://packagist.org/
composer require illuminate/database
composer require illuminate/events
composer require doctrine/dbal
<?php
namespace App\Helpers;

use Illuminate\Container\Container;
use Illuminate\Database\Events\StatementPrepared;
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Events\Dispatcher;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
use PDO;

class DB extends Capsule
{
	private static $customContainer;
	private static $capsule;
	private static $initialized = false;

	public static function init()
	{
		self::$customContainer = new Container();
		self::$capsule = new self(self::$customContainer);
		self::$capsule->addConnection([
			'driver' => 'pgsql',
			'port' => extensionDb('postgrePort'),
			'host' => extensionDb('postgreHost'),
			'username' => extensionDb('postgreUsername'),
			'password' => extensionDb('postgrePassword'),
			'charset' => 'utf8',
			'collation' => 'utf8_unicode_ci',
			'prefix' => ''
		]);
		self::$capsule->setEventDispatcher($dispatcher = new Dispatcher());
		$dispatcher->listen(StatementPrepared::class, function ($event) {
			$event->statement->setFetchMode(PDO::FETCH_ASSOC);
		});
		self::$capsule->setAsGlobal();
		self::$initialized = true;
	}

	public static function database(string $dbName)
	{
		if (!self::$initialized) {
			self::init();
		}
		$connections = self::$customContainer['config']['database.connections'];
		$connections['default']['database'] = $dbName;
		self::$customContainer['config']['database.connections'] = $connections;
		return self::$capsule;
	}

	public function __call($method, $parameters)
	{
		return self::$capsule::connection()->$method(...$parameters);
	}

	public static function __callStatic($method, $parameters)
	{
		return self::$capsule::connection()->$method(...$parameters);
	}
}
use App\Helpers\DB;
$users = DB::database('example_application')->table('users')->get();
dd($users);
https://laravel.com/docs/8.x/queries#select-statements

Yerelleştirme

Liman eklenti paketlerinizde farklı dil desteği sağlamak için yapmanız gereken işlemler.

Yerelleştirme nedir?

Yerelleştirme, yazılım geliştirme sürecinde, içeriklerin (kitaplar, filmler, Ağ Sayfaları), süreçlerin, ürünlerin ve özellikle bilgisayar yazılımlarının (Software) belirli bir coğrafyaya ya da etnik topluluğa özgü pazar ya da coğrafi bölgede (ülke, bölge ya da etnik gruplar) geçerli yerel dilsel ve kültürel özelliklere uyarlanmasıdır.

Bu sözcüğün İngilizcesi olan localization (Amerikan İngilizcesi) ya da localisation (İngiltere) yazılım geliştiriciler tarafından L10N şeklinde kısaltılmıştır. 10 rakamı L ile N harfleri arasında kalan harflerin sayısını gösterir. Yerelleştirmenin karşıt anlamına gelen I18N ise internationalization için kullanılır.)

Nasıl yapılır?

Liman üzerinde yerelleştirme yapabilmek için sağladığımız yardımcı fonksiyonlar mevcuttur. Bu yardımcı fonksiyon diğer PHP projelerinizden de hakim olabileceğiniz üzerine double underscore fonksiyonudur. __() şeklinde tanımlanır.

Blade içerisinde yerelleştirme

main.blade.php
{{ __("Türkçe string") }}

Blade viewları üzerinde yerelleştirme yaparken yukarıdaki görüntüyü kullanırız. Çifte süslü parantez kullanımının içerisinde yerelleştirme fonksiyonunu çağırabiliriz.

Javascript üzerinde yerelleştirme

Liman eklentileri üzerinde yerelleştirmeyi sağlayabilmek ve PHP'den gelen veriye göre değişken script gösterimi yapabilmek için yine Blade kullanıyoruz. Örnek eklentimizde görebileceğiniz üzere her tab için ayrı bir scripts.blade.php dosyası tanımlanmaktadır. Yine de bizim temel olarak "Yükleniyor..." yazısında kullandığımız örneği görelim.

scripts.blade.php
showSwal("{{__('Yükleniyor...')}}", 'info', 2000);

Çevirileri oluşturma

Çeviriler için eklenti klasörünüzdeki lang klasörünü kullanmaktayız. Türkçe girdiğimiz stringler için en.json dosyası üzerinde key olarak Türkçe stringin kendisini, diğer tarafa da İngilizce çevirisini eklemeliyiz. Örnek olarak kendi eklentiniz içerisindeki en.json dosyasını inceleyebilirsiniz.

en.json
{
    "Sandbox Elemanları": "Sandbox Components",
    "Kullanıcı Ayarları": "Kullanıcı Ayarları",
    "Grup Ayarları": "Grup Ayarları",
    "Merhaba Dünya!": "Hello World!",
    "Hostname Değiştir": "Change Hostname",
    "Durdur": "Stop",
    "Task çalıştırılıyor...": "Running task...",
    "Görev İşleniyor": "Executing Task"
}