Searcher adalah pembuat kueri penelusuran tanpa kerangka kerja. Kueri pencarian ditulis menggunakan kriteria dan dapat dijalankan pada MySQL, MongoDB, ElasticSearch, file, atau apa pun yang Anda suka. Versi terbaru hanya mendukung PHP 7 . Sekarang diuji juga dengan Humbug
Pernahkah Anda melihat kode yang bertanggung jawab untuk mencari sesuatu berdasarkan banyak kriteria berbeda? Ini bisa menjadi sangat berantakan! Bayangkan Anda memiliki formulir dengan 20 bidang dan semuanya berdampak pada kondisi pencarian. Bukan ide bagus untuk meneruskan seluruh formulir ke beberapa layanan dan membiarkannya menguraikan semuanya di satu tempat. Berkat perpustakaan ini Anda dapat membagi tanggung jawab pembuatan kriteria kueri ke beberapa kelas yang lebih kecil. Satu kelas per filter. Satu CriteriaBuilder
per Criteria
. Dengan cara ini, di dalam CriteriaBuilder
Anda hanya peduli pada satu Criteria
, yang membuatnya lebih mudah dibaca dan dikelola. Nanti Anda dapat menggunakan Criteria
yang sama persis untuk pencarian yang berbeda, dengan CriteriaBuilder
yang berbeda dan bahkan SearchingContext
yang berbeda yang bahkan dapat menggunakan database yang berbeda. Anda bahkan dapat menggunakan pencari untuk menemukan file di sistem Anda berkat FinderSearchingContext
.
Dokumentasi lengkap dapat ditemukan di http://searcher.rtfd.io/
Anda dapat menginstal perpustakaan melalui komposer dengan mengetikkan terminal:
$ komposer memerlukan krzysztof-gzocha/searcher
Integrasi dengan Symfony dilakukan di SearcherBundle
CriteriaBuilder
- akan membangun kondisi baru untuk Criteria
tunggal,
Criteria
- model yang akan diteruskan ke CriteriaBuilder
. Anda hanya perlu menghidrasinya, agar bermanfaat. Kriteria dapat menampung banyak bidang di dalamnya dan semua (atau beberapa) bidang tersebut mungkin digunakan di dalam CriteriaBuilder
,
SearchingContext
- konteks pencarian tunggal. Layanan ini harus mengetahui cara mengambil hasil dari kueri yang dibuat dan berisi sesuatu yang disebut QueryBuilder
, namun bisa berupa apa pun yang sesuai untuk Anda - layanan apa pun. Ini adalah lapisan abstraksi antara pencarian dan database. Ada konteks berbeda untuk ORM, ODM, Elastica, File Doktrin, dan sebagainya. Jika tidak ada konteks untuk Anda, Anda dapat menerapkannya - itu tidak akan sulit,
Searcher
- menyimpan koleksi CriteriaBuilder
dan akan meneruskan Criteria
ke CriteriaBuilder
yang sesuai.
Katakanlah kita ingin mencari orang-orang yang usianya berada dalam rentang yang difilter. Dalam contoh ini kita akan menggunakan QueryBuilder Doctrine, jadi kita akan menggunakan QueryBuilderSearchingContext
dan akan menentukan dalam CriteriaBuidler
kita bahwa ia harus berinteraksi hanya dengan DoctrineORMQueryBuilder
, tapi ingat bahwa kita tidak harus menggunakan Doctrine saja.
Pertama-tama kita perlu membuat AgeRangeCriteria
- kelas yang akan menyimpan nilai usia minimal dan maksimal. Sudah ada Criteria
default yang diterapkan di sini.
class AgeRangeCriteria mengimplementasikan CriteriaInterface{private $minimalAge;private $maximalAge;/** * Hanya metode yang diperlukan. * Jika akan mengembalikan nilai true, maka akan diteruskan ke beberapa CriteriaBuilder(s) */fungsi publik mustBeApplied(): bool{return null !== $this->minimalAge && null !== $this->maximalAge; }// pengambil, penyetel, apa pun}
Pada langkah kedua kami ingin menentukan kondisi yang harus diterapkan untuk model ini. Itu sebabnya kita perlu membuat AgeRangeCriteriaBuilder
kelas AgeRangeCriteriaBuilder mengimplementasikan CriteriaBuilderInterface{fungsi publik buildCriteria(CriteriaInterface $criteria,SearchingContextInterface $searchingContext) {$searchingContext->getQueryBuilder() ->danDimana('e.umur >= :Usia minimal') ->danDimana('e.umur <= :Usia maksimal') ->setParameter('Umur Minimal', $kriteria->getMinimalUmur()) ->setParameter('Umur Maksimal', $kriteria->getUmur Maksimal()); }fungsi publik memungkinkanKriteria(CriteriaInterface $criteria): bool{return $criteria instanceof AgeRangeCriteria; }/** * Anda dapat melewati metode ini jika Anda ingin memperluas dari AbstrakORMCriteriaBuilder. */fungsi publik mendukungSearchingContext(SearchingContextInterface $searchingContext): bool{return $searchingContext instanceof QueryBuilderSearchingContext; } }
Pada langkah selanjutnya kita perlu membuat koleksi untuk keduanya: Criteria
dan CriteriaBuidler
.
$builders = new CriteriaBuilderCollection();$builders->addCriteriaBuilder(new AgeRangeCriteriaBuilder());$builders->addCriteriaBuilder(/** pembuat lainnya */);
$ageRangeCriteria = new AgeRangeCriteria();// Kita harus mengisi model sebelum mencari$ageRangeCriteria->setMinimalAge(23);$ageRangeCriteria->setMaximalAge(29);$criteria = new CriteriaCollection();$criteria->addCriteria( $ageRangeCriteria);$criteria->addCriteria(/** kriteria lainnya */);
Sekarang kami ingin membuat SearchingContext
dan mengisinya dengan QueryBuilder yang diambil dari Doctrine ORM.
$context = new QueryBuilderSearchingContext($queryBuilder);$searcher = new Searcher($builders, $context);$searcher->search($criteriaCollection); // Hore, kita sudah mendapatkan hasilnya!
Jika ada kemungkinan kecil bahwa QueryBuilder Anda akan mengembalikan null
ketika Anda mengharapkan objek atau array yang dapat dilintasi, maka Anda dapat menggunakan WrappedResultsSearcher
alih-alih kelas Searcher
normal. Ini akan bertindak persis sama dengan Searcher
, tetapi akan mengembalikan ResultCollection
, yang hanya akan bekerja dengan array atau Traversable
dan jika hasilnya hanya null
kode Anda akan tetap berfungsi. Berikut tampilannya:
$searcher = new WrappedResultsSearcher(Searcher baru($builders, $context));$results = $searcher->search($criteriaCollection); // instance dari ResultCollectionforeach ($results as $result) {// akan berfungsi!}foreach ($results->getResults() as $result) {// Karena ResultCollection memiliki metode getResults() ini juga akan berfungsi!}
Untuk mengurutkan hasil, Anda dapat menggunakan Criteria
yang sudah diterapkan. Anda tidak perlu menerapkannya dari awal. Ingatlah bahwa Anda masih perlu mengimplementasikan CriteriaBuilder
untuk itu (fitur ini masih dalam pengembangan). Katakanlah Anda ingin mengurutkan hasil dan Anda memerlukan nilai p.id
di CriteriaBuidler untuk melakukannya, namun Anda ingin menampilkannya sebagai pid
kepada pengguna akhir. Tidak ada yang lebih sederhana! Inilah cara Anda membuat OrderByCriteria:
$mappedFields = ['pid' => 'p.id', 'valueForUser' => 'valueForBuilder'];$kriteria = new MappedOrderByAdapter(new OrderByCriteria('pid'),$mappedFields);// $criteria->getMappedOrderBy () = 'p.id'// $kriteria->getOrderBy() = 'pid'
Tentu saja Anda tidak perlu menggunakan MappedOrderByAdapter
- Anda dapat menggunakan OrderByCriteria
saja, tetapi pengguna akan tahu persis bidang apa yang digunakan untuk mengurutkan.
Criteria
untuk penomoran halaman juga diterapkan dan Anda tidak perlu melakukannya, namun perlu diingat bahwa Anda masih perlu menerapkan CriteriaBuilder
yang akan memanfaatkannya dan melakukan penomoran halaman sebenarnya (fitur ini sedang dalam pengembangan). Katakanlah Anda ingin mengizinkan pengguna akhir untuk mengubah halaman, tetapi bukan jumlah item per halaman. Anda dapat menggunakan kode contoh ini:
$kriteria = ImmutablePaginationAdapter baru( PaginationCriteria baru($halaman = 1, $itemsPerPage = 50) );// $kriteria->setItemsPerPage(250); <- pengguna dapat mencoba mengubahnya// $criteria->getItemsPerPage() = 50 <- tetapi dia tidak dapat melakukannya// $criteria->getPage() = 1
Tentu saja jika Anda ingin mengizinkan pengguna mengubah jumlah item per halaman, Anda juga dapat melewati ImmutablePaginationAdapter
dan hanya menggunakan PaginationCriteria
.
Semua ide dan permintaan tarik disambut dan dihargai :) Jika Anda memiliki masalah dengan penggunaan jangan ragu untuk membuat masalah, kami dapat memecahkan masalah Anda bersama.
Perintah untuk menjalankan tes: composer test
.
Semua pengujian unit diuji dengan perpustakaan padric/omong kosong untuk pengujian mutasi, yang bertujuan untuk menjaga Indikator Skor Mutasi sama atau mendekati 100%.
Untuk menjalankan tes mutasi, Anda perlu menginstal omong kosong dan menjalankan: humbug
di direktori utama. Output harus disimpan di humbuglog.txt
.
Dalam urutan abjad
https://github.com/chkris
https://github.com/pawelhertman
https://github.com/usstrugany
https://github.com/wojciech-olszewski
Lisensi: MIT
Pengarang: Krzysztof Gzocha