Yazma, okuma, güncelleme ve silme operasyonları için işleyici sınıflarından tetiklenen Model sınıfları kullanılır. Bir model sınıfı birden fazla fonksiyon içerebilir. Bir modelin çalışabilmesi önce aşağıdaki gibi App/ConfigProvider.php dosyasına tanımlanması gerekir.
public function getDependencies() : array
{
return [
'factories' => [
// Models
//
Model\CompanyModel::class => function ($container) {
$dbAdapter = $container->get(AdapterInterface::class);
$companies = new TableGateway('companies', $dbAdapter, null, new ResultSet(ResultSet::TYPE_ARRAY));
$columnFilters = $container->get(ColumnFilters::class);
return new Model\CompanyModel($companies, $columnFilters);
},
]
];
}
Eğer http başlığından aşağıdaki gibi dizi türünde bir veri geliyorsa;
src/App/Schema/Employees/EmployeeSave.php
/**
* @var array
* @OA\Property(
* type="array",
* @OA\Items(
* @OA\Property(
* property="childId",
* type="string",
* ),
* @OA\Property(
* property="childName",
* type="string",
* ),
* @OA\Property(
* property="childBirthdate",
* type="string",
* ),
* ),
* );
*/
public $employeeChildren;
{
"employeeId": "string",
"name": "string",
"surname": "string",
"employeeChildren": [
{
"childId" : "string",
"childNameSurname" : "string"
}
]
}
[
"employeeId" => "string",
"name" => "string",
"surname" => "string",
"employeeChildren" => [
[
"childId" => "string",
"childNameSurname" => "string",
]
],
]
employeeChildren dizisinden elde edilen veri takip eden örnekte oluduğu gibi kayıt edilir.
Aşağıdaki örnekte dizi türündeki employeeChildren verisi create metodu içerisinde foreach ifadesi ile kayıt ediliyor.
src/App/Model/EmployeeModel.php
public function create(array $data)
{
$employeeId = $data['id'];
try {
$this->conn->beginTransaction();
$data['employees']['employeeId'] = $employeeId;
$data['employees']['createdAt'] = date('Y-m-d H:i:s');
$this->employees->insert($data['employees']);
// children
if (! empty($data['employeeChildren'])) {
foreach ($data['employeeChildren'] as $val) {
$val['employeeId'] = $employeeId;
$this->employeeChildren->insert($val);
}
}
$this->conn->commit();
} catch (Exception $e) {
$this->conn->rollback();
throw $e;
}
}
Takip eden örnekte dizi türündeki employeeChildren verisi update metodu içerisinde foreach ifadesi ile kayıt ediliyor.
src/App/Model/EmployeeModel.php
public function update(array $data)
{
$employeeId = $data['id'];
try {
$this->conn->beginTransaction();
$this->employees->update($data['employees'], ['employeeId' => $employeeId]);
// delete children
//
$this->employeeChildren->delete(['employeeId' => $employeeId]);
if (! empty($data['employeeChildren'])) {
foreach ($data['employeeChildren'] as $val) {
$val['employeeId'] = $employeeId;
$this->employeeChildren->insert($val);
}
}
$this->conn->commit();
} catch (Exception $e) {
$this->conn->rollback();
throw $e;
}
}
Olobase\Mezzio\ColumnFiltersInterface, sütun filtresi sınıfı önyüzden api a gönderilen url adresini çözümleyerek veritabanında çalıştırılmak üzere SQL sorguları oluşturur.
Yukarıdaki resimde görülen filtreleme tarayıcınızda ve arka uç API'nizde aşağıdaki gibi görünecektir:
http://127.0.0.1:3000/employees?page=1&perPage=10&filter={"jobTitleId":[{"id":"137b00c8-0e36-ce3a-25f2-ce4b7b1cf97c","name":"Web+Designer"},{"id":"28fd1a31-becf-2329-6bcf-0c80bcc64e2d","name":"Computer+Programmer"}],"companyId":[{"id":"ebf6b935-5bd8-46c1-877b-9c758073f278","name":"Demo+Company","companyShortName":"Demo"}]}
http://demo.local/api/employees/findAllByPaging?jobTitleId[][id]=137b00c8-0e36-ce3a-25f2-ce4b7b1cf97c&jobTitleId[][name]=Web Designer&jobTitleId[][id]=28fd1a31-becf-2329-6bcf-0c80bcc64e2d&jobTitleId[][name]=Computer Programmer&companyId[][id]=ebf6b935-5bd8-46c1-877b-9c758073f278&companyId[][name]=Demo Company&companyId[][companyShortName]=Demo&_perPage=10&_page=1
Arka uca gönderilen değerler aşağıdaki gibi elde edilir.
$get = $request->getQueryParams();
var_dump($get);
/*
array (
'jobTitleId' =>
array (
0 => array ('id' => '137b00c8-0e36-ce3a-25f2-ce4b7b1cf97c'),
1 => array ('name' => 'Web Designer'),
2 => array ('id' => '28fd1a31-becf-2329-6bcf-0c80bcc64e2d',),
3 => array ('name' => 'Computer Programmer',),
),
'companyId' =>
array (
0 => array ('id' => 'ebf6b935-5bd8-46c1-877b-9c758073f278'),
1 => array ('name' => 'Demo Company'),
2 => array ('companyShortName' => 'Demo'),
),
'_perPage' => '10',
'_page' => '1',
)
*/
Sütun filtreleme sınıfına mevcut sütunlarınızı tanımlamak için columnFilters->setColumns() metodu kullanılır.
$this->columnFilters->setColumns([
'companyId',
'employeeNumber',
'name',
'surname',
'companyId',
'jobTitleId',
'gradeId'
]);
Eğer sütun adı yerine bir başka tablo adı kullanılmak isteniyorsa columnFilters->setAlias() metodu kullanılır.
$this->columnFilters->setAlias('companyId', 'c.companyId');
Tanımladığınız sütunlar içerisinde bir like aramasının gerçekleşmesini istiyorsanız columnFilters->setLikeColumns() metodunu kullanmalısınız.
$this->columnFilters->setLikeColumns(
[
'employeeNumber',
'name',
'surname',
]
);
Tanımladığınız sütunlar içerisinde bir where aramasının gerçekleşmesini istiyorsanız columnFilters->setWhereColumns() metodunu kullanmalısınız.
$this->columnFilters->setWhereColumns(
[
'companyId',
'jobTitleId',
'gradeId',
'departmentId',
]
);
Takip eden örnekte EmployeeModel sınıfı findAllByPaging() metodu ile bir sütun filtreleme örneği gösteriliyor;
src/App/Model/EmployeeModel.php
<?php
declare(strict_types=1);
namespace App\Model;
use Olobase\Mezzio\ColumnFiltersInterface;
class EmployeeModel
{
public function __construct(
TableGatewayInterface $employees,
TableGatewayInterface $employeeChildren,
TableGatewayInterface $employeeFiles,
TableGatewayInterface $files,
ColumnFiltersInterface $columnFilters
) {
$this->adapter = $employees->getAdapter();
$this->employees = $employees;
$this->employeeChildren = $employeeChildren;
$this->employeeFiles = $employeeFiles;
$this->files = $files;
$this->conn = $this->adapter->getDriver()->getConnection();
$this->columnFilters = $columnFilters;
}
/*
...
.
*/
public function findAllByPaging(array $get)
{
$select = $this->findAll();
$this->columnFilters->clear();
$this->columnFilters->setAlias('companyId', 'c.companyId');
$this->columnFilters->setAlias('jobTitleId', 'j.jobTitleId');
$this->columnFilters->setAlias('gradeId', 'g.gradeId');
$this->columnFilters->setColumns([
'companyId',
'employeeNumber',
'name',
'surname',
'companyId',
'jobTitleId',
'gradeId'
]);
$this->columnFilters->setLikeColumns(
[
'employeeNumber',
'name',
'surname',
]
);
$this->columnFilters->setWhereColumns(
[
'companyId',
'jobTitleId',
'gradeId',
'departmentId',
]
);
$this->columnFilters->setData($get);
$this->columnFilters->setSelect($select);
if ($this->columnFilters->searchDataIsNotEmpty()) {
$nest = $select->where->nest();
foreach ($this->columnFilters->getSearchData() as $col => $words) {
$nest = $nest->or->nest();
foreach ($words as $str) {
$nest->or->like(new Expression($col), '%'.$str.'%');
}
$nest = $nest->unnest();
}
$nest->unnest();
}
if ($this->columnFilters->likeDataIsNotEmpty()) {
foreach ($this->columnFilters->getLikeData() as $column => $value) {
if (is_array($value)) {
$nest = $select->where->nest();
foreach ($value as $val) {
$nest->or->like(new Expression($column), '%'.$val.'%');
}
$nest->unnest();
} else {
$select->where->like(new Expression($column), '%'.$value.'%');
}
}
}
if ($this->columnFilters->whereDataIsNotEmpty()) {
foreach ($this->columnFilters->getWhereData() as $column => $value) {
if (is_array($value)) {
$nest = $select->where->nest();
foreach ($value as $val) {
$nest->or->equalTo(new Expression($column), $val);
}
$nest->unnest();
} else {
$select->where->equalTo(new Expression($column), $value);
}
}
}
if ($this->columnFilters->orderDataIsNotEmpty()) {
$select->order($this->columnFilters->getOrderData());
}
// echo $select->getSqlString($this->adapter->getPlatform());
// die;
$paginatorAdapter = new DbSelect(
$select,
$this->adapter
);
$paginator = new Paginator($paginatorAdapter);
return $paginator;
}
/*
...
.
*/
}
Eğer insert,update,delete operasyonlarından bir sql çıktısı elde etmeyi amaçlıyorsanız aşağıdaki örnekten faydalanabilirsiniz.
$sql = new Sql($this->adapter);
$insert = $sql->insert();
$insert->into("example");
$insert->columns(
[
'companyId',
'workplaceId',
'yearId',
'monthId',
'creationDate',
]
);
$insert->values(
[
$companyId,
$workplaceId,
$yearId,
$monthId,
date('Y-m-d H:i:s')
]
);
$string = $sql->buildSqlString($insert);
echo $string.PHP_EOL; // sql output of insert operation
$statement = $sql->prepareStatementForSqlObject($insert);
$statement->execute();
Takip eden örnekte olduğu gibi herhangi bir model sınıfında ve $select nesnesinin varolduğu bir metot içerisinde iken $select->getSqlString() metodu yardımı ile sql kodunu string türünde elde edebilirsiniz.
$sql = new Sql($this->adapter);
$select = $sql->select();
$select->columns([
'permId',
'route',
'method',
'action',
]);
$select->join(
['rp' => 'rolePermissions'],
'permissions.permId = rp.permId', [], $select::JOIN_INNER);
$select->join(
['r' => 'roles'],
'r.roleId = rp.roleId', ['roleKey','roleLevel'], $select::JOIN_LEFT);
echo $select->getSqlString($adapter->getPlatform());
die;
/*
SELECT `permissions`.`permId` AS `permId`, `permissions`.`route` AS `route`, `permissions`.`method` AS `method`,
`r`.`roleKey` AS `roleKey`, `r`.`roleLevel` AS `roleLevel` FROM `permissions` INNER JOIN `rolePermissions` AS `rp` ON
`permissions`.`permId` = `rp`.`permId` LEFT JOIN `roles` AS `r` ON `r`.`roleId` = `rp`.`roleId`
*/
ColumnFilters sınıfına ait değişkenlerin değerini sıfırlar.
Eğer iki tarih arasında bir filtreleme gerçekleştiriliyorsa $select nesnesi columnFilters sınıfına gönderilmelidir. Aksi durumda filtreleme gerçekleşmez.
$this->columnFilters->setSelect($this->select);
$this->columnFilters->setDateFilter('creationDate');
Hangi sütunların sorgulanması gerektiğini belirler.
$this->columnFilters->setColumns(
[
'customerId',
'customerShortName',
]
);
Sorgulanması gereken sütunları siler.
Sorgulanan sütun isimlerine geri döner.
$this->columnFilters->setAlias('purchaserName', $this->concatFunction);
You can also use Laminas\Db\Sql\Expression object as value.
$this->columnFilters->setAlias('orderItems', new Expression($this->orderItemFunction, [LANG_ID]));
Tanımladığınız sütunlar içerisinde bir like aramasının gerçekleşmesini sağlar.
$this->columnFilters->setLikeColumns(
[
'employeeNumber',
'name',
'surname',
]
);
Tanımladığınız sütunlar içerisinde bir where aramasının gerçekleşmesini sağlar.
$this->columnFilters->setWhereColumns(
[
'companyId',
'jobTitleId',
'gradeId',
'departmentId',
]
);
Bu fonksiyona genelde birden fazla boolean türünde olan ve dağınık görünen filtreleri bir çoklu seçim girdisine dönüştürdüğüzde ihtiyacınız olacak.
Yukarıdaki örneği göz önüne alırsak; ssl, verified ve resourceAccess adlı 3 adet sütuna sahip olduğunuzu ve bu sütunları tablonuzda var olmayan bir isim altında gruplamak istediğimizi varsayalım.
$this->columnFilters->setGroupedColumns(
'resources', // group name
[
'ssl', // column names that you want to group
'verified',
'resourceAccess',
]
);
Sql çıktı:
SELECT
`d`.`domainId` AS `id`,
`d`.`name` AS `name`,
`d`.`url` AS `url`,
`d`.`ssl` AS `ssl`,
`d`.`verified` AS `verified`,
`d`.`resourceAccess` AS `resourceAccess`,
FROM
`domains` AS `d`
WHERE `ssl` = '1'
AND `verified` = '1'
AND `resourceAccess` = '1'
Eğer 3. parametreden bir closure fonksiyonu göndermeyi seçseydik bu durumda sonuç aşağıdaki gibi olacaktı.
$this->columnFilters->setGroupedColumns(
'resources', // group name
[
'ssl', // column names that you want to group
'verified',
'resourceAccess',
],
function ($val) {
return (string)$val;
}
);
Sql çıktı:
SELECT
`d`.`domainId` AS `id`,
`d`.`name` AS `name`,
`d`.`url` AS `url`,
`d`.`ssl` AS `ssl`,
`d`.`verified` AS `verified`,
`d`.`resourceAccess` AS `resourceAccess`,
FROM
`domains` AS `d`
WHERE `ssl` = 'ssl'
AND `verified` = 'verified'
AND `resourceAccess` = 'resourceAccess'
Sütun filtresi tarafından işlenmemiş sütun verilerine geri döner.
Dizi formatında gelen http verisini sütun filtresi sınıfına gönderir.
$this->columnFilters->setData($get);
Dizi formatında gelen http verisine geri döner.
Tarih filtrelerini girilen değerlere göre otomatik oluşturur.
Aşağıdaki örnek gözönüne alındığında, eğer endDate değeri boş gönderilirse,
$this->columnFilters->setSelect($this->select);
$this->columnFilters->setDateFilter('creationDate');
bu kodu aşağıdaki gibi bir sql sorgusu üretir.
/*
$nest = $this->select->where->nest();
$nest->and->between($dateColumn, $data[$columnStart], $data[$columnEnd]);
$nest->unnest();
*/
Eğer sadece belirli iki veritabanı sütunu arasında sorgu gerekiyorsa, 2. parametre sorgunun iki tarih arasında gerçekleşmesini sağlar ve,
$this->columnFilters->setSelect($this->select);
$this->columnFilters->setDateFilter('startDate', 'endDate');
yukarıdaki kod aşağıdaki gibi bir sql sorgusu üretir.
/*
$nest = $this->select->where->nest();
$nest->and->lessThanOrEqualTo($columnStart, $data[$endKey])
->and->greaterThanOrEqualTo($columnEnd, $data[$startKey]);
$nest->unnest();
*/
Eğer fixedDate değeri girilirse,
$this->columnFilters->setSelect($this->select);
$this->columnFilters->setDateFilter('startDate', 'endDate', 'startDate');
bu kod aşağıdaki gibi bir sql sorgusu üretir.
/*
$nest = $this->select->where->nest();
$nest->and->lessThanOrEqualTo($columnStart, $data[$fixedDate])
->and->greaterThanOrEqualTo($columnEnd, $data[$fixedDate]);
$nest->unnest();
*/
Eğer sütunlara göre bir arama isteği gönderilmiş ise sorgulanan sütun isimleri ve değerlerine geri döner.
print_r($this->columnFilters->getLikeData());
die;
/*
Array
(
[`firstname`] => demo
)
*/
Eğer sütunlara göre bir arama isteği gönderilmiş ise sorgulanan sütun isimleri ve değerlerine geri döner.
print_r($this->columnFilters->getWhereData());
die;
/*
Array
(
[c.companyId] => Array
(
[0] => ebf6b935-5bd8-46c1-877b-9c758073f278
)
[j.jobTitleId] => Array
(
[0] => 137b00c8-0e36-ce3a-25f2-ce4b7b1cf97c
)
[g.gradeId] => Array
(
[0] => 8e9204c4-0133-4a51-82ca-4265b1656b1d
[1] => 07ef35ed-5f96-4776-a57a-998d5f09a891
)
)
*/
Sıralanmış sütun isimleri ve değerlerine geri döner.
print_r($this->columnFilters->getOrderData());
die;
/*
Array
(
[0] => j.jobTitleId ASC
[1] => name ASC
)
*/
Eğer evrensel arama girdisinden arama değerleri gönderildi ise text araması yapılan sütun isimleri ve değerlerine geri döner.
print_r($this->columnFilters->getSearchData());
die;
/*
Array
(
[c.companyId] => Array
(
[0] => Brown
)
[`employeeNumber`] => Array
(
[0] => Brown
)
[`name`] => Array
(
[0] => Brown
)
[`surname`] => Array
(
[0] => Brown
)
[j.jobTitleId] => Array
(
[0] => Brown
)
[g.gradeId] => Array
(
[0] => Brown
)
)
*/
Eğer evrensel arama verisi boş değilse true aksi durumda false değerine geri döner.
Eğer evrensel arama verisi boş ise true aksi durumda false değerine geri döner.
Eğer like arama verisi boş değilse true aksi durumda false değerine geri döner.
Eğer like arama verisi boş ise true aksi durumda false değerine geri döner.
Eğer where arama verisi boş değilse true aksi durumda false değerine geri döner.
Eğer where arama verisi boş ise true aksi durumda false değerine geri döner.
Eğer sıralama verileri boş değilse true aksi durumda false değerine geri döner.
Eğer sıralama verileri boş ise true aksi durumda false değerine geri döner.