From 6a15e77e014c3776be0bcafadb8e8a3b9e97c230 Mon Sep 17 00:00:00 2001 From: miladev-ent <98118400+milwad-dev@users.noreply.github.com> Date: Tue, 1 Aug 2023 01:49:23 +0330 Subject: [PATCH 001/224] Create WindowTest.php --- tests/Windows/WindowTest.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 tests/Windows/WindowTest.php diff --git a/tests/Windows/WindowTest.php b/tests/Windows/WindowTest.php new file mode 100644 index 0000000..19b90f1 --- /dev/null +++ b/tests/Windows/WindowTest.php @@ -0,0 +1,16 @@ +id('main') + ->title('milwad') + ->titleBarStyle('milwad') + ->hideMenu(); + + $windowArray = $window->toArray(); + + expect($windowArray['id'])->toBe('main'); + expect($windowArray['title'])->toBe('milwad'); + expect($windowArray['titleBarStyle'])->toBe('milwad'); + expect($windowArray['autoHideMenuBar'])->toBeTrue(); +}); From f3c727d4bdd43f60e585acce3b6216a5b1042b8d Mon Sep 17 00:00:00 2001 From: miladev-ent <98118400+milwad-dev@users.noreply.github.com> Date: Tue, 1 Aug 2023 01:54:54 +0330 Subject: [PATCH 002/224] wip --- tests/Windows/WindowTest.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/Windows/WindowTest.php b/tests/Windows/WindowTest.php index 19b90f1..736f2ec 100644 --- a/tests/Windows/WindowTest.php +++ b/tests/Windows/WindowTest.php @@ -5,6 +5,19 @@ ->id('main') ->title('milwad') ->titleBarStyle('milwad') + ->rememberState() + ->frameless() + ->focusable() + ->hasShadow() + ->alwaysOnTop() + ->showDevTools() + ->resizable() + ->movable() + ->minimizable() + ->maximizable() + ->closable() + ->fullscreen() + ->kiosk() ->hideMenu(); $windowArray = $window->toArray(); @@ -12,5 +25,18 @@ expect($windowArray['id'])->toBe('main'); expect($windowArray['title'])->toBe('milwad'); expect($windowArray['titleBarStyle'])->toBe('milwad'); + expect($windowArray['rememberState'])->toBeTrue(); + expect($windowArray['frame'])->toBeFalse(); + expect($windowArray['focusable'])->toBeTrue(); + expect($windowArray['hasShadow'])->toBeTrue(); + expect($windowArray['alwaysOnTop'])->toBeTrue(); + expect($windowArray['showDevTools'])->toBeTrue(); + expect($windowArray['resizable'])->toBeTrue(); + expect($windowArray['movable'])->toBeTrue(); + expect($windowArray['minimizable'])->toBeTrue(); + expect($windowArray['maximizable'])->toBeTrue(); + expect($windowArray['closable'])->toBeTrue(); + expect($windowArray['fullscreen'])->toBeFalse(); + expect($windowArray['kiosk'])->toBeFalse(); expect($windowArray['autoHideMenuBar'])->toBeTrue(); }); From d3fe140866e87841194b88c5dcd28d040973c752 Mon Sep 17 00:00:00 2001 From: miladev-ent <98118400+milwad-dev@users.noreply.github.com> Date: Tue, 1 Aug 2023 02:01:43 +0330 Subject: [PATCH 003/224] add tests for title bar --- tests/Windows/WindowTest.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/Windows/WindowTest.php b/tests/Windows/WindowTest.php index 736f2ec..64c79af 100644 --- a/tests/Windows/WindowTest.php +++ b/tests/Windows/WindowTest.php @@ -1,7 +1,9 @@ id('main') ->title('milwad') ->titleBarStyle('milwad') @@ -40,3 +42,18 @@ expect($windowArray['kiosk'])->toBeFalse(); expect($windowArray['autoHideMenuBar'])->toBeTrue(); }); + +it('test title bar for window', function () { + $window = Window::open() + ->titleBarHidden(); + + expect($window->toArray()['titleBarStyle'])->toBe('hidden'); + + $window->titleBarHiddenInset(); + + expect($window->toArray()['titleBarStyle'])->toBe('hiddenInset'); + + $window->titleBarButtonsOnHover(); + + expect($window->toArray()['titleBarStyle'])->toBe('customButtonsOnHover'); +}); From f1e2452d8a5aa47c2cb2129e3ea340dae96aa9c5 Mon Sep 17 00:00:00 2001 From: miladev-ent <98118400+milwad-dev@users.noreply.github.com> Date: Tue, 1 Aug 2023 02:04:11 +0330 Subject: [PATCH 004/224] add `test for invisibleFrameless in window` --- tests/Windows/WindowTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/Windows/WindowTest.php b/tests/Windows/WindowTest.php index 64c79af..1aa7107 100644 --- a/tests/Windows/WindowTest.php +++ b/tests/Windows/WindowTest.php @@ -57,3 +57,13 @@ expect($window->toArray()['titleBarStyle'])->toBe('customButtonsOnHover'); }); + +it('test for invisibleFrameless in window', function () { + $window = Window::open()->invisibleFrameless(); + $windowArray = $window->toArray(); + + expect($windowArray['frame'])->toBeTrue(); + expect($windowArray['transparent'])->toBeTrue(); + expect($windowArray['focusable'])->toBeFalse(); + expect($windowArray['hasShadow'])->toBeFalse(); +}); From a42e092fc11683c6fc7ab6c90d6a046bb745a420 Mon Sep 17 00:00:00 2001 From: Bastiaan Date: Tue, 1 Aug 2023 14:08:13 +0200 Subject: [PATCH 005/224] Add printToPDF function --- src/System.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/System.php b/src/System.php index 03b879b..d918d52 100644 --- a/src/System.php +++ b/src/System.php @@ -49,4 +49,12 @@ public function print(string $html, Printer $printer = null): void 'printer' => $printer->name ?? '', ]); } + + public function printToPDF(string $html, $path = null): void + { + $this->client->post('system/print-to-pdf', [ + 'html' => $html, + 'path' => $path ?? '', + ]); + } } From b144aa6b7cdf1280a8446e5d9e10b637d8c2b3f2 Mon Sep 17 00:00:00 2001 From: Bastiaan Date: Wed, 2 Aug 2023 11:08:52 +0200 Subject: [PATCH 006/224] PDF-file is returned as base64 string --- src/System.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/System.php b/src/System.php index d918d52..faaed14 100644 --- a/src/System.php +++ b/src/System.php @@ -50,11 +50,10 @@ public function print(string $html, Printer $printer = null): void ]); } - public function printToPDF(string $html, $path = null): void + public function printToPDF(string $html): string { $this->client->post('system/print-to-pdf', [ 'html' => $html, - 'path' => $path ?? '', ]); } } From 8235273d660d8a804d64dac6fac623c8e79383b0 Mon Sep 17 00:00:00 2001 From: Bert Bredewold Date: Wed, 2 Aug 2023 11:10:11 +0200 Subject: [PATCH 007/224] Add method to update an existing context-menu of the menu bar --- src/Facades/MenuBar.php | 2 ++ src/MenuBar/MenuBarManager.php | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/Facades/MenuBar.php b/src/Facades/MenuBar.php index e5c6984..97abad9 100644 --- a/src/Facades/MenuBar.php +++ b/src/Facades/MenuBar.php @@ -3,12 +3,14 @@ namespace Native\Laravel\Facades; use Illuminate\Support\Facades\Facade; +use Native\Laravel\Menu\Menu; /** * @method static \Native\Laravel\MenuBar\PendingCreateMenuBar create() * @method static void show() * @method static void hide() * @method static void label(string $label) + * @method static void contextMenu(Menu $contextMenu) */ class MenuBar extends Facade { diff --git a/src/MenuBar/MenuBarManager.php b/src/MenuBar/MenuBarManager.php index b4b0941..a7877ae 100644 --- a/src/MenuBar/MenuBarManager.php +++ b/src/MenuBar/MenuBarManager.php @@ -3,6 +3,7 @@ namespace Native\Laravel\MenuBar; use Native\Laravel\Client\Client; +use Native\Laravel\Menu\Menu; class MenuBarManager { @@ -32,4 +33,11 @@ public function label(string $label) 'label' => $label, ]); } + + public function contextMenu(Menu $contextMenu) + { + $this->client->post('menu-bar/context-menu', [ + 'contextMenu' => $contextMenu->toArray()['submenu'], + ]); + } } From ae1266e2daad7834d47931b0d9ad0064c3d340a8 Mon Sep 17 00:00:00 2001 From: Hossain Mohammad Shahidullah Jaber Date: Thu, 3 Aug 2023 00:48:38 +0600 Subject: [PATCH 008/224] import VerifyCsrfToken --- routes/api.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/routes/api.php b/routes/api.php index c7a5d5a..59f0837 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,14 +1,15 @@ PreventRegularBrowserAccess::class], function () { Route::post('_native/api/booted', NativeAppBootedController::class); Route::post('_native/api/events', DispatchEventFromAppController::class); -})->withoutMiddleware(\App\Http\Middleware\VerifyCsrfToken::class); +})->withoutMiddleware(VerifyCsrfToken::class); Route::get('_native/api/cookie', CreateSecurityCookieController::class); From aff2080c57d945729a1ce4cffa1f6d649bd9d0f0 Mon Sep 17 00:00:00 2001 From: Hossain Mohammad Shahidullah Jaber Date: Thu, 3 Aug 2023 01:12:49 +0600 Subject: [PATCH 009/224] refector --- src/Dialog.php | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Dialog.php b/src/Dialog.php index 0913a69..fb7f89c 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -121,18 +121,23 @@ public function asSheet(string $windowId = null): self return $this; } - public function open() + public function dataArray(): array { - $result = $this->client->post('dialog/open', [ + return [ 'title' => $this->title, 'windowReference' => $this->windowReference, 'defaultPath' => $this->defaultPath, 'filters' => $this->filters, 'buttonLabel' => $this->buttonLabel, 'properties' => array_unique($this->properties), - ])->json('result'); + ]; + } + + public function open() + { + $result = $this->client->post('dialog/open', $this->dataArray())->json('result'); - if (! in_array('multiSelections', $this->properties)) { + if (!in_array('multiSelections', $this->properties)) { return $result[0] ?? null; } @@ -141,13 +146,6 @@ public function open() public function save() { - return $this->client->post('dialog/save', [ - 'title' => $this->title, - 'windowReference' => $this->windowReference, - 'defaultPath' => $this->defaultPath, - 'filters' => $this->filters, - 'buttonLabel' => $this->buttonLabel, - 'properties' => array_unique($this->properties), - ])->json('result'); + return $this->client->post('dialog/save', $this->dataArray())->json('result'); } } From eab88ebe0b3c056c1aad7343473ee6f83c5e5cef Mon Sep 17 00:00:00 2001 From: Raj Shekhar Dev Date: Thu, 3 Aug 2023 01:44:24 +0530 Subject: [PATCH 010/224] modified return type of clipboard image method --- src/Clipboard.php | 2 +- src/Facades/Clipboard.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Clipboard.php b/src/Clipboard.php index a91400a..1f01c2c 100644 --- a/src/Clipboard.php +++ b/src/Clipboard.php @@ -41,7 +41,7 @@ public function html($html = null): string return $html; } - public function image($image = null): string + public function image($image = null): string|null { if (is_null($image)) { return $this->client->get('clipboard/image')->json('image'); diff --git a/src/Facades/Clipboard.php b/src/Facades/Clipboard.php index 0de117b..c10fd5d 100644 --- a/src/Facades/Clipboard.php +++ b/src/Facades/Clipboard.php @@ -8,7 +8,7 @@ * @method static void clear() * @method static string text($text = null) * @method static string html($html = null) - * @method static string image($image = null) + * @method static string|null image($image = null) */ class Clipboard extends Facade { From 263bca393722fac347d872ba7454ae008e23626d Mon Sep 17 00:00:00 2001 From: Daniel Hudson Date: Wed, 2 Aug 2023 22:52:15 +0100 Subject: [PATCH 011/224] add windowPosition --- src/Concerns/HasPositioner.php | 90 ++++++++++++++++++++++++++++++++++ src/MenuBar/MenuBar.php | 3 ++ tests/MenuBar/MenuBarTest.php | 1 + 3 files changed, 94 insertions(+) create mode 100644 src/Concerns/HasPositioner.php diff --git a/src/Concerns/HasPositioner.php b/src/Concerns/HasPositioner.php new file mode 100644 index 0000000..6f61b8a --- /dev/null +++ b/src/Concerns/HasPositioner.php @@ -0,0 +1,90 @@ +windowPosition = $position; + + return $this; + } + + public function trayLeft(): self + { + return $this->windowPosition('trayLeft'); + } + + public function trayBottomLeft(): self + { + return $this->windowPosition('trayBottomLeft'); + } + + public function trayRight(): self + { + return $this->windowPosition('trayRight'); + } + + public function trayBottomRight(): self + { + return $this->windowPosition('trayBottomRight'); + } + + public function trayCenter(): self + { + return $this->windowPosition('trayCenter'); + } + + public function trayBottomCenter(): self + { + return $this->windowPosition('trayBottomCenter'); + } + + public function topLeft(): self + { + return $this->windowPosition('topLeft'); + } + + public function topRight(): self + { + return $this->windowPosition('topRight'); + } + + public function bottomLeft(): self + { + return $this->windowPosition('bottomLeft'); + } + + public function bottomRight(): self + { + return $this->windowPosition('bottomRight'); + } + + public function topCenter(): self + { + return $this->windowPosition('topCenter'); + } + + public function bottomCenter(): self + { + return $this->windowPosition('bottomCenter'); + } + + public function leftCenter(): self + { + return $this->windowPosition('leftCenter'); + } + + public function rightCenter(): self + { + return $this->windowPosition('rightCenter'); + } + + public function center(): self + { + return $this->windowPosition('center'); + } +} diff --git a/src/MenuBar/MenuBar.php b/src/MenuBar/MenuBar.php index 30b9876..b91f19d 100644 --- a/src/MenuBar/MenuBar.php +++ b/src/MenuBar/MenuBar.php @@ -4,6 +4,7 @@ use Native\Laravel\Client\Client; use Native\Laravel\Concerns\HasDimensions; +use Native\Laravel\Concerns\HasPositioner; use Native\Laravel\Concerns\HasUrl; use Native\Laravel\Concerns\HasVibrancy; use Native\Laravel\Menu\Menu; @@ -12,6 +13,7 @@ class MenuBar { use HasVibrancy; use HasDimensions; + use HasPositioner; use HasUrl; protected string $icon = ''; @@ -94,6 +96,7 @@ public function toArray(): array return [ 'url' => $this->url, 'icon' => $this->icon, + 'windowPosition' => $this->windowPosition, 'x' => $this->x, 'y' => $this->y, 'label' => $this->label, diff --git a/tests/MenuBar/MenuBarTest.php b/tests/MenuBar/MenuBarTest.php index ec19c7b..ec1c022 100644 --- a/tests/MenuBar/MenuBarTest.php +++ b/tests/MenuBar/MenuBarTest.php @@ -22,5 +22,6 @@ $this->assertEquals('milwad', $menuBarArray['label']); $this->assertEquals('https://github.com/milwad-dev', $menuBarArray['url']); $this->assertEquals('nativephp.png', $menuBarArray['icon']); + $this->assertEquals('trayCenter', $menuBarArray['windowPosition']); $this->assertIsArray($menuBarArray['contextMenu']); }); From 3fab8d83f32f712995a641ed77321a460b45f9c0 Mon Sep 17 00:00:00 2001 From: Aron Rotteveel Date: Thu, 3 Aug 2023 00:27:51 +0200 Subject: [PATCH 012/224] Implement MenuBarDroppedFiles event --- src/Events/MenuBar/MenuBarDroppedFiles.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/Events/MenuBar/MenuBarDroppedFiles.php diff --git a/src/Events/MenuBar/MenuBarDroppedFiles.php b/src/Events/MenuBar/MenuBarDroppedFiles.php new file mode 100644 index 0000000..89fce9a --- /dev/null +++ b/src/Events/MenuBar/MenuBarDroppedFiles.php @@ -0,0 +1,21 @@ + Date: Thu, 3 Aug 2023 00:41:25 +0200 Subject: [PATCH 013/224] Add files to the event --- src/Events/MenuBar/MenuBarDroppedFiles.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Events/MenuBar/MenuBarDroppedFiles.php b/src/Events/MenuBar/MenuBarDroppedFiles.php index 89fce9a..e9937c4 100644 --- a/src/Events/MenuBar/MenuBarDroppedFiles.php +++ b/src/Events/MenuBar/MenuBarDroppedFiles.php @@ -12,6 +12,10 @@ class MenuBarDroppedFiles implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; + public function __construct(public array $files = []) + { + } + public function broadcastOn() { return [ From 08cad00884d10872610e19a0662ad479ed2663da Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 3 Aug 2023 13:58:48 +0100 Subject: [PATCH 014/224] Update issue config --- .github/ISSUE_TEMPLATE/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 90b5184..b66f18f 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,11 @@ blank_issues_enabled: true contact_links: - name: Ask a question - url: https://github.com/nativephp/nativephp-laravel/discussions/new?category=q-a + url: https://github.com/nativephp/laravel/discussions/new?category=q-a about: Ask the community for help - name: Request a feature - url: https://github.com/nativephp/nativephp-laravel/discussions/new?category=ideas + url: https://github.com/nativephp/laravel/discussions/new?category=ideas about: Share ideas for new features - name: Report a security issue - url: https://github.com/nativephp/nativephp-laravel/security/policy + url: https://github.com/nativephp/laravel/security/policy about: Learn how to notify us for sensitive bugs From ef82ca3865b83703fe763dc1c90b07665cc9479d Mon Sep 17 00:00:00 2001 From: Ethan Brace Date: Thu, 3 Aug 2023 11:31:31 -0400 Subject: [PATCH 015/224] add hide method + event --- src/Events/Windows/WindowHidden.php | 26 ++++++++++++++++++++++++++ src/Windows/WindowManager.php | 7 +++++++ 2 files changed, 33 insertions(+) create mode 100644 src/Events/Windows/WindowHidden.php diff --git a/src/Events/Windows/WindowHidden.php b/src/Events/Windows/WindowHidden.php new file mode 100644 index 0000000..fd03348 --- /dev/null +++ b/src/Events/Windows/WindowHidden.php @@ -0,0 +1,26 @@ +client->post('window/hide', [ + 'id' => $id ?? $this->detectId(), + ]); + } + public function current() { return (object) $this->client->get('window/current')->json(); From cd2320034effc320c6c422abcb7b0da5dd7bef28 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Fri, 4 Aug 2023 00:43:40 +0200 Subject: [PATCH 016/224] Add dev dependency --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index be7f4a1..6efaf14 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ "symfony/finder": "^6.2" }, "require-dev": { + "guzzlehttp/guzzle": "^7.0", "laravel/pint": "^1.0", "nunomaduro/collision": "^7.9", "nunomaduro/larastan": "^2.0.1", From ac3decf1069b562837844a50f1d9567d0f251e7e Mon Sep 17 00:00:00 2001 From: mpociot Date: Thu, 3 Aug 2023 22:46:59 +0000 Subject: [PATCH 017/224] Fix styling --- routes/api.php | 6 +++--- src/Dialog.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/routes/api.php b/routes/api.php index 59f0837..18df0ab 100644 --- a/routes/api.php +++ b/routes/api.php @@ -1,11 +1,11 @@ PreventRegularBrowserAccess::class], function () { Route::post('_native/api/booted', NativeAppBootedController::class); diff --git a/src/Dialog.php b/src/Dialog.php index fb7f89c..346173e 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -137,7 +137,7 @@ public function open() { $result = $this->client->post('dialog/open', $this->dataArray())->json('result'); - if (!in_array('multiSelections', $this->properties)) { + if (! in_array('multiSelections', $this->properties)) { return $result[0] ?? null; } From 8d0ca9d38ce8ac684595c09fc354fdde7ce474f6 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Fri, 4 Aug 2023 00:47:16 +0200 Subject: [PATCH 018/224] rename method --- src/Dialog.php | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Dialog.php b/src/Dialog.php index fb7f89c..cc5c046 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -121,21 +121,9 @@ public function asSheet(string $windowId = null): self return $this; } - public function dataArray(): array - { - return [ - 'title' => $this->title, - 'windowReference' => $this->windowReference, - 'defaultPath' => $this->defaultPath, - 'filters' => $this->filters, - 'buttonLabel' => $this->buttonLabel, - 'properties' => array_unique($this->properties), - ]; - } - public function open() { - $result = $this->client->post('dialog/open', $this->dataArray())->json('result'); + $result = $this->client->post('dialog/open', $this->dialogData())->json('result'); if (!in_array('multiSelections', $this->properties)) { return $result[0] ?? null; @@ -146,6 +134,18 @@ public function open() public function save() { - return $this->client->post('dialog/save', $this->dataArray())->json('result'); + return $this->client->post('dialog/save', $this->dialogData())->json('result'); + } + + public function dialogData(): array + { + return [ + 'title' => $this->title, + 'windowReference' => $this->windowReference, + 'defaultPath' => $this->defaultPath, + 'filters' => $this->filters, + 'buttonLabel' => $this->buttonLabel, + 'properties' => array_unique($this->properties), + ]; } } From 9c7e7aa99c53e272c26fa23c103df6e9248c1d52 Mon Sep 17 00:00:00 2001 From: mpociot Date: Thu, 3 Aug 2023 22:48:33 +0000 Subject: [PATCH 019/224] Fix styling --- src/Clipboard.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Clipboard.php b/src/Clipboard.php index 1f01c2c..a6d7326 100644 --- a/src/Clipboard.php +++ b/src/Clipboard.php @@ -41,7 +41,7 @@ public function html($html = null): string return $html; } - public function image($image = null): string|null + public function image($image = null): ?string { if (is_null($image)) { return $this->client->get('clipboard/image')->json('image'); From fd258f3b9e28b25f5f2fd785240007eab7eaa486 Mon Sep 17 00:00:00 2001 From: Bastiaan Date: Fri, 4 Aug 2023 08:06:59 +0200 Subject: [PATCH 020/224] Return base64 string from json-response --- src/System.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.php b/src/System.php index faaed14..e1f61cd 100644 --- a/src/System.php +++ b/src/System.php @@ -52,8 +52,8 @@ public function print(string $html, Printer $printer = null): void public function printToPDF(string $html): string { - $this->client->post('system/print-to-pdf', [ + return $this->client->post('system/print-to-pdf', [ 'html' => $html, - ]); + ])->json('result'); } } From 6a4357518a93f73bc8a80fb0a69996b8a9e6470b Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Mon, 7 Aug 2023 21:55:53 +0200 Subject: [PATCH 021/224] Only register internal artisan commands when NativePHP is running --- src/NativeServiceProvider.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index f332bcc..fe5ff60 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -2,6 +2,7 @@ namespace Native\Laravel; +use Illuminate\Console\Application as Artisan; use Illuminate\Support\Arr; use Native\Laravel\Commands\LoadPHPConfigurationCommand; use Native\Laravel\Commands\LoadStartupConfigurationCommand; @@ -19,9 +20,6 @@ public function configurePackage(Package $package): void ->name('nativephp') ->hasCommands([ MigrateCommand::class, - MinifyApplicationCommand::class, - LoadStartupConfigurationCommand::class, - LoadPHPConfigurationCommand::class, ]) ->hasConfigFile() ->hasRoute('api') @@ -37,6 +35,14 @@ public function packageRegistered() }); if (config('nativephp-internal.running')) { + Artisan::starting(function ($artisan) { + $artisan->resolveCommands([ + MinifyApplicationCommand::class, + LoadStartupConfigurationCommand::class, + LoadPHPConfigurationCommand::class, + ]); + }); + $this->configureApp(); } } From 15814d8f6347be45ec6cfbdda118959d612bdc93 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Mon, 7 Aug 2023 21:56:22 +0200 Subject: [PATCH 022/224] Add the ability to remove custom .env keys when bundling the application --- config/nativephp.php | 6 +++++ src/Commands/MinifyApplicationCommand.php | 29 ++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/config/nativephp.php b/config/nativephp.php index 8d951f0..378a2e7 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -38,6 +38,12 @@ */ 'provider' => \App\Providers\NativeAppServiceProvider::class, + /** + * A list of environment keys that should be removed from the + * .env file when the application is bundled for production. + */ + 'cleanup_env_keys' => [], + /** * The NativePHP updater configuration. */ diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index 8526089..d8d4030 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -3,6 +3,8 @@ namespace Native\Laravel\Commands; use Illuminate\Console\Command; +use Illuminate\Support\Str; +use Native\Laravel\Compactor\Php; use Symfony\Component\Finder\Finder; class MinifyApplicationCommand extends Command @@ -21,7 +23,9 @@ public function handle() $this->info('Minifying application…'); - $compactor = new \Native\Laravel\Compactor\Php(); + $this->cleanUpEnvFile($appPath); + + $compactor = new Php(); $phpFiles = Finder::create() ->files() @@ -33,4 +37,27 @@ public function handle() file_put_contents($phpFile->getRealPath(), $minifiedContent); } } + + protected function cleanUpEnvFile(string $appPath): void + { + $envFile = $appPath.'/.env'; + + if (! file_exists($envFile)) { + return; + } + + $this->info('Cleaning up .env file…'); + + $cleanUpKeys = config('nativephp.cleanup_env_keys', []); + + $envContent = file_get_contents($envFile); + $envValues = collect(explode("\n", $envContent)) + ->filter(function (string $line) use ($cleanUpKeys) { + $key = Str::before($line, '='); + return ! in_array($key, $cleanUpKeys); + }) + ->join("\n"); + + file_put_contents($envFile, $envValues); + } } From d3fa38dddf577a2fb3951561da691ed9baa59041 Mon Sep 17 00:00:00 2001 From: mpociot Date: Mon, 7 Aug 2023 19:56:54 +0000 Subject: [PATCH 023/224] Fix styling --- src/Commands/MinifyApplicationCommand.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index d8d4030..5984c56 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -54,6 +54,7 @@ protected function cleanUpEnvFile(string $appPath): void $envValues = collect(explode("\n", $envContent)) ->filter(function (string $line) use ($cleanUpKeys) { $key = Str::before($line, '='); + return ! in_array($key, $cleanUpKeys); }) ->join("\n"); From 8d405f45b1c0858cbe11b94fa9ef3326b8c5c458 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Wed, 9 Aug 2023 22:44:37 +0200 Subject: [PATCH 024/224] Add default keys to remove --- config/nativephp.php | 11 ++++++++++- src/Commands/MinifyApplicationCommand.php | 2 +- src/NativeServiceProvider.php | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/config/nativephp.php b/config/nativephp.php index 378a2e7..23ac9a4 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -41,8 +41,17 @@ /** * A list of environment keys that should be removed from the * .env file when the application is bundled for production. + * You may use wildcards to match multiple keys. */ - 'cleanup_env_keys' => [], + 'cleanup_env_keys' => [ + 'AWS_*', + 'DO_SPACES_*', + '*_SECRET', + 'NATIVEPHP_UPDATER_PATH', + 'NATIVEPHP_APPLE_ID', + 'NATIVEPHP_APPLE_ID_PASS', + 'NATIVEPHP_APPLE_TEAM_ID', + ], /** * The NativePHP updater configuration. diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index 5984c56..639098c 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -55,7 +55,7 @@ protected function cleanUpEnvFile(string $appPath): void ->filter(function (string $line) use ($cleanUpKeys) { $key = Str::before($line, '='); - return ! in_array($key, $cleanUpKeys); + return ! Str::is($cleanUpKeys, $key); }) ->join("\n"); diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index fe5ff60..fc0b41a 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -20,6 +20,7 @@ public function configurePackage(Package $package): void ->name('nativephp') ->hasCommands([ MigrateCommand::class, + MinifyApplicationCommand::class, ]) ->hasConfigFile() ->hasRoute('api') @@ -37,7 +38,6 @@ public function packageRegistered() if (config('nativephp-internal.running')) { Artisan::starting(function ($artisan) { $artisan->resolveCommands([ - MinifyApplicationCommand::class, LoadStartupConfigurationCommand::class, LoadPHPConfigurationCommand::class, ]); From 03ce978aed7cf39e551e304716fa68bd6ad802ed Mon Sep 17 00:00:00 2001 From: mpociot Date: Wed, 9 Aug 2023 21:03:03 +0000 Subject: [PATCH 025/224] Update CHANGELOG --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1c437c..b8f74ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.4.0 - 2023-08-09 + +### What's Changed + +- Added the ability to remove custom .env keys when bundling the application +- Allow custom php.ini settings by @mpociot in https://github.com/NativePHP/laravel/pull/98 +- Add method to configure disks by @mpociot in https://github.com/NativePHP/laravel/pull/99 +- Printer support by @mpociot in https://github.com/NativePHP/laravel/pull/103 +- Adds 'php artisan native:migrate fresh' command by @shanerbaner82 in https://github.com/NativePHP/laravel/pull/81 +- Add Tests For `Windows` by @milwad-dev in https://github.com/NativePHP/laravel/pull/100 +- import VerifyCsrfToken and refactor by @JaberWiki in https://github.com/NativePHP/laravel/pull/110 +- Modified return type of clipboard image method by @blankRSD in https://github.com/NativePHP/laravel/pull/111 +- add windowPosition by @DanielHudson in https://github.com/NativePHP/laravel/pull/112 +- Implement MenuBarDroppedFiles event by @ArondeParon in https://github.com/NativePHP/laravel/pull/113 + +### New Contributors + +- @mpociot made their first contribution in https://github.com/NativePHP/laravel/pull/98 +- @shanerbaner82 made their first contribution in https://github.com/NativePHP/laravel/pull/81 +- @JaberWiki made their first contribution in https://github.com/NativePHP/laravel/pull/110 +- @blankRSD made their first contribution in https://github.com/NativePHP/laravel/pull/111 +- @DanielHudson made their first contribution in https://github.com/NativePHP/laravel/pull/112 +- @ArondeParon made their first contribution in https://github.com/NativePHP/laravel/pull/113 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.3.0...0.4.0 + ## 0.3.0 - 2023-07-31 ### What's Changed From a089c975feac170eff42257e699dede14c752ba5 Mon Sep 17 00:00:00 2001 From: JT Smith Date: Wed, 9 Aug 2023 17:07:17 -0600 Subject: [PATCH 026/224] Allow for adding files and folders to exclusion list --- config/nativephp.php | 11 +++ src/Commands/MinifyApplicationCommand.php | 47 +++++++++++ tests/Command/IgnoreFilesAndFoldersTest.php | 88 +++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 tests/Command/IgnoreFilesAndFoldersTest.php diff --git a/config/nativephp.php b/config/nativephp.php index 23ac9a4..d0ebdab 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -53,6 +53,17 @@ 'NATIVEPHP_APPLE_TEAM_ID', ], + /** + * A list of files and folders that should be removed from the + * final app before it is bundled for production. + * You may use glob / wildcard patterns here. + */ + 'cleanup_exclude_files' => [ + 'content', + 'storage/app/framework/{sessions,testing,cache}', + 'storage/logs/laravel.log', + ], + /** * The NativePHP updater configuration. */ diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index 639098c..c3426ee 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -24,6 +24,7 @@ public function handle() $this->info('Minifying application…'); $this->cleanUpEnvFile($appPath); + $this->removeIgnoredFilesAndFolders($appPath); $compactor = new Php(); @@ -61,4 +62,50 @@ protected function cleanUpEnvFile(string $appPath): void file_put_contents($envFile, $envValues); } + + protected function removeIgnoredFilesAndFolders(string $appPath): void + { + $this->info('Cleaning up ignored files and folders…'); + + $itemsToRemove = config('nativephp.cleanup_exclude_files', []); + + foreach ($itemsToRemove as $item) { + $fullPath = $appPath.'/'.$item; + + if (file_exists($fullPath)) { + if (is_dir($fullPath)) { + $this->delete_directory($fullPath); + } else { + array_map('unlink', glob($fullPath)); + } + } else { + foreach (glob($item) as $pathFound) { + unlink($pathFound); + } + } + } + } + + private function delete_directory($dir) + { + if (! file_exists($dir)) { + return true; + } + + if (! is_dir($dir)) { + return unlink($dir); + } + + foreach (scandir($dir) as $item) { + if ($item == '.' || $item == '..') { + continue; + } + + if (! $this->delete_directory($dir.'/'.$item)) { + return false; + } + } + + return rmdir($dir); + } } diff --git a/tests/Command/IgnoreFilesAndFoldersTest.php b/tests/Command/IgnoreFilesAndFoldersTest.php new file mode 100644 index 0000000..e805cc0 --- /dev/null +++ b/tests/Command/IgnoreFilesAndFoldersTest.php @@ -0,0 +1,88 @@ +artisan('native:minify resources/app'); + $this->assertFalse(file_exists($laravelLog)); + + // Clean up after ourselves + if (file_exists($laravelLog)) { + unlink($laravelLog); + } + if (file_exists('resources/app/storage/logs')) { + rmdir('resources/app/storage/logs'); + } + if (file_exists('resources/app/storage')) { + rmdir('resources/app/storage'); + } + removeAppFolder(); +}); + +it('will remove the content folder by default before building', function () { + $contentPath = 'resources/app/content'; + + // Create a dummy copy of the folder + if (! file_exists($contentPath)) { + mkdir($contentPath, 0755, true); + } + + // Run the test + $this->artisan('native:minify resources/app'); + $this->assertFalse(file_exists($contentPath)); + + // Clean up after ourselves + if (file_exists($contentPath)) { + unlink($contentPath); + } + removeAppFolder(); +}); + +it('will remove only files that match a globbed path', function () { + $wildcardPath = 'resources/app/wildcardPath'; + $yes1DeletePath = $wildcardPath.'/YES1.txt'; + $yes2DeletePath = $wildcardPath.'/YES2.txt'; + $noDeletePath = $wildcardPath.'/NO.txt'; + + config()->set('nativephp.cleanup_exclude_files', [$wildcardPath.'/YES*']); + + // Create some dummy files + if (! file_exists($wildcardPath)) { + mkdir($wildcardPath, 0755, true); + } + file_put_contents($yes1DeletePath, 'PLEASE DELETE ME'); + file_put_contents($yes2DeletePath, 'PLEASE DELETE ME TOO'); + file_put_contents($noDeletePath, 'DO NOT DELETE ME'); + + // Run the test + $this->artisan('native:minify resources/app'); + $this->assertFalse(file_exists($yes1DeletePath)); + $this->assertFalse(file_exists($yes2DeletePath)); + $this->assertTrue(file_exists($noDeletePath)); + + // Clean up after ourselves + foreach ([$yes1DeletePath, $yes2DeletePath, $noDeletePath] as $remove) { + if (file_exists($remove)) { + unlink($remove); + } + } + if (file_exists($wildcardPath)) { + rmdir($wildcardPath); + } + removeAppFolder(); +}); + +function removeAppFolder() +{ + if (file_exists('resources/app')) { + rmdir('resources/app'); + } +} From 1bd5d552b136a73836b0c635c88a479fb380c8ea Mon Sep 17 00:00:00 2001 From: JT Smith Date: Wed, 9 Aug 2023 17:08:23 -0600 Subject: [PATCH 027/224] Renamed delete_directory_recursive function to be more explicit --- src/Commands/MinifyApplicationCommand.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index c3426ee..f132ef9 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -74,7 +74,7 @@ protected function removeIgnoredFilesAndFolders(string $appPath): void if (file_exists($fullPath)) { if (is_dir($fullPath)) { - $this->delete_directory($fullPath); + $this->delete_directory_recursive($fullPath); } else { array_map('unlink', glob($fullPath)); } @@ -86,7 +86,7 @@ protected function removeIgnoredFilesAndFolders(string $appPath): void } } - private function delete_directory($dir) + private function delete_directory_recursive($dir) { if (! file_exists($dir)) { return true; @@ -101,7 +101,7 @@ private function delete_directory($dir) continue; } - if (! $this->delete_directory($dir.'/'.$item)) { + if (! $this->delete_directory_recursive($dir.'/'.$item)) { return false; } } From 60295d9382647672e5eb5160911d35000223a4e6 Mon Sep 17 00:00:00 2001 From: JT Smith Date: Thu, 17 Aug 2023 10:41:32 -0600 Subject: [PATCH 028/224] camelCase update --- src/Commands/MinifyApplicationCommand.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index f132ef9..589b26b 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -74,7 +74,7 @@ protected function removeIgnoredFilesAndFolders(string $appPath): void if (file_exists($fullPath)) { if (is_dir($fullPath)) { - $this->delete_directory_recursive($fullPath); + $this->deleteDirectoryRecursive($fullPath); } else { array_map('unlink', glob($fullPath)); } @@ -86,7 +86,7 @@ protected function removeIgnoredFilesAndFolders(string $appPath): void } } - private function delete_directory_recursive($dir) + private function deleteDirectoryRecursive($dir) { if (! file_exists($dir)) { return true; @@ -101,7 +101,7 @@ private function delete_directory_recursive($dir) continue; } - if (! $this->delete_directory_recursive($dir.'/'.$item)) { + if (! $this->deleteDirectoryRecursive($dir.'/'.$item)) { return false; } } From 9a6733d3a16e2f40b767221101cad498d3c29bde Mon Sep 17 00:00:00 2001 From: JT Smith Date: Thu, 17 Aug 2023 10:42:38 -0600 Subject: [PATCH 029/224] Typed param --- src/Commands/MinifyApplicationCommand.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index 589b26b..67bc50c 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -86,26 +86,26 @@ protected function removeIgnoredFilesAndFolders(string $appPath): void } } - private function deleteDirectoryRecursive($dir) + private function deleteDirectoryRecursive(string $directory) { - if (! file_exists($dir)) { + if (! file_exists($directory)) { return true; } - if (! is_dir($dir)) { - return unlink($dir); + if (! is_dir($directory)) { + return unlink($directory); } - foreach (scandir($dir) as $item) { + foreach (scandir($directory) as $item) { if ($item == '.' || $item == '..') { continue; } - if (! $this->deleteDirectoryRecursive($dir.'/'.$item)) { + if (! $this->deleteDirectoryRecursive($directory.'/'.$item)) { return false; } } - return rmdir($dir); + return rmdir($directory); } } From afb6e75696f00fad780f41e68993484d585fcc85 Mon Sep 17 00:00:00 2001 From: JT Smith Date: Thu, 17 Aug 2023 10:50:25 -0600 Subject: [PATCH 030/224] Added return type --- src/Commands/MinifyApplicationCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index 67bc50c..6bd0f85 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -86,7 +86,7 @@ protected function removeIgnoredFilesAndFolders(string $appPath): void } } - private function deleteDirectoryRecursive(string $directory) + private function deleteDirectoryRecursive(string $directory): void { if (! file_exists($directory)) { return true; @@ -106,6 +106,6 @@ private function deleteDirectoryRecursive(string $directory) } } - return rmdir($directory); + rmdir($directory); } } From 99386bf583057fd22e483d1173fcf5e14e4c2c35 Mon Sep 17 00:00:00 2001 From: Dan Johnson Date: Tue, 22 Aug 2023 21:19:45 +0100 Subject: [PATCH 031/224] feat: adds the required config for using GitHub as an updater provider --- config/nativephp.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/config/nativephp.php b/config/nativephp.php index 23ac9a4..dde80e0 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -66,11 +66,22 @@ /** * The updater provider to use. - * Supported: "s3", "spaces" + * Supported: "github", "s3", "spaces" */ 'default' => env('NATIVEPHP_UPDATER_PROVIDER', 'spaces'), 'providers' => [ + 'github' => [ + 'driver' => 'github', + 'repo' => env('GITHUB_REPO'), + 'owner' => env('GITHUB_OWNER'), + 'token' => env('GITHUB_TOKEN'), + 'vPrefixedTagName' => env('GITHUB_V_PREFIXED_TAG_NAME', true), + 'private' => env('GITHUB_PRIVATE', false), + 'channel' => env('GITHUB_CHANNEL', 'latest'), + 'releaseType' => env('GITHUB_RELEASE_TYPE', 'draft'), + ], + 's3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), From 2fec19ab42ebd66f3923ed4ffb7f72ca576a4491 Mon Sep 17 00:00:00 2001 From: Ahmed shamim Date: Tue, 29 Aug 2023 02:56:56 +0600 Subject: [PATCH 032/224] fix: #175 'native:migrate fresh' command does not work --- src/Commands/FreshCommand.php | 13 ++++++++----- src/NativeServiceProvider.php | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/Commands/FreshCommand.php b/src/Commands/FreshCommand.php index 843822c..0fd5059 100644 --- a/src/Commands/FreshCommand.php +++ b/src/Commands/FreshCommand.php @@ -3,19 +3,22 @@ namespace Native\Laravel\Commands; use Illuminate\Console\Command; +use Illuminate\Database\Console\Migrations\FreshCommand as BaseFreshCommand; use Native\Laravel\NativeServiceProvider; -class FreshCommand extends Command +class FreshCommand extends BaseFreshCommand { - protected $description = 'Run the database migrations in the NativePHP development environment'; + protected $description = 'Drop all tables and re-run all migrations in the NativePHP development environment'; - protected $signature = 'native:migrate fresh'; + protected $signature = 'native:migrate:fresh'; public function handle() { - unlink(config('nativephp-internal.database_path')); + $nativeServiceProvider = new NativeServiceProvider($this->laravel); - (new NativeServiceProvider($this->laravel))->rewriteDatabase(); + $nativeServiceProvider->removeDatabase(); + + $nativeServiceProvider->rewriteDatabase(); $this->call('native:migrate'); } diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index fc0b41a..67f3b74 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -4,6 +4,7 @@ use Illuminate\Console\Application as Artisan; use Illuminate\Support\Arr; +use Native\Laravel\Commands\FreshCommand; use Native\Laravel\Commands\LoadPHPConfigurationCommand; use Native\Laravel\Commands\LoadStartupConfigurationCommand; use Native\Laravel\Commands\MigrateCommand; @@ -20,6 +21,7 @@ public function configurePackage(Package $package): void ->name('nativephp') ->hasCommands([ MigrateCommand::class, + FreshCommand::class, MinifyApplicationCommand::class, ]) ->hasConfigFile() @@ -107,6 +109,21 @@ public function rewriteDatabase() config(['database.default' => 'nativephp']); } + public function removeDatabase() + { + $databasePath = config('nativephp-internal.database_path'); + + if (config('app.debug')) { + $databasePath = database_path('nativephp.sqlite'); + + if (! file_exists($databasePath)) { + return; + } + } + + unlink($databasePath); + } + protected function configureDisks(): void { $disks = [ From 836c7a51ec3afbc665eb9973443bec2827fd147b Mon Sep 17 00:00:00 2001 From: Ahmed shamim Date: Tue, 29 Aug 2023 03:18:29 +0600 Subject: [PATCH 033/224] fix: 'native:db:seed' command not working --- src/NativeServiceProvider.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index fc0b41a..9ff9ed4 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -8,6 +8,7 @@ use Native\Laravel\Commands\LoadStartupConfigurationCommand; use Native\Laravel\Commands\MigrateCommand; use Native\Laravel\Commands\MinifyApplicationCommand; +use Native\Laravel\Commands\SeedDatabaseCommand; use Native\Laravel\Logging\LogWatcher; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -20,6 +21,7 @@ public function configurePackage(Package $package): void ->name('nativephp') ->hasCommands([ MigrateCommand::class, + SeedDatabaseCommand::class, MinifyApplicationCommand::class, ]) ->hasConfigFile() From dd5dd96369b2b6d93e1436bde3fbd0727f2ec5ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Sep 2023 01:16:04 +0000 Subject: [PATCH 034/224] Bump actions/checkout from 3 to 4 Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/fix-php-code-style-issues.yml | 2 +- .github/workflows/phpstan.yml | 2 +- .github/workflows/run-tests.yml | 2 +- .github/workflows/update-changelog.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 7520a18..a5b1b60 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -14,7 +14,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ github.head_ref }} diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 9d41c0c..ccfa9d9 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -11,7 +11,7 @@ jobs: name: phpstan runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 57152e1..180659f 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index 8c12ba9..a817f81 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -13,7 +13,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: main From 31c91104970a0af67c73f05e8b704bf7e1854c12 Mon Sep 17 00:00:00 2001 From: mpociot Date: Thu, 21 Sep 2023 12:47:55 +0000 Subject: [PATCH 035/224] Fix styling --- src/Compactor/Php.php | 16 ++++++++-------- src/MenuBar/MenuBar.php | 2 +- src/Windows/Window.php | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Compactor/Php.php b/src/Compactor/Php.php index 8f93b75..f4838bf 100644 --- a/src/Compactor/Php.php +++ b/src/Compactor/Php.php @@ -36,7 +36,7 @@ protected function compactContent(string $contents): string // Note: $tokens may be updated by reference as well! $retokenized = $this->retokenizeAttribute($tokens, $index); - if (null !== $retokenized) { + if ($retokenized !== null) { array_splice($tokens, $index, 1, $retokenized); $tokenCount = count($tokens); } @@ -65,7 +65,7 @@ protected function compactContent(string $contents): string // Handle whitespace potentially being split into two tokens after attribute retokenization. $nextToken = $tokens[$index + 1] ?? null; - if (null !== $nextToken + if ($nextToken !== null && $nextToken->is(T_WHITESPACE) ) { $whitespace .= $nextToken->text; @@ -119,16 +119,16 @@ private static function findAttributeCloser(array $tokens, int $opener): ?int $tokenText = $tokens[$i]->text; // Allow for short arrays within attributes. - if ('[' === $tokenText) { + if ($tokenText === '[') { $brackets[] = $i; continue; } - if (']' === $tokenText) { + if ($tokenText === ']') { array_pop($brackets); - if (0 === count($brackets)) { + if (count($brackets) === 0) { $closer = $i; break; } @@ -157,7 +157,7 @@ private function retokenizeAttribute(array &$tokens, int $opener): ?array // Multi-line attribute or attribute containing something which looks like a PHP close tag. // Retokenize the rest of the file after the attribute opener. - if (null === $closer) { + if ($closer === null) { foreach (array_slice($tokens, $opener + 1) as $token) { $attributeBody .= $token->text; } @@ -167,7 +167,7 @@ private function retokenizeAttribute(array &$tokens, int $opener): ?array $closer = self::findAttributeCloser($subTokens, 0); - if (null !== $closer) { + if ($closer !== null) { array_splice( $tokens, $opener + 1, @@ -179,7 +179,7 @@ private function retokenizeAttribute(array &$tokens, int $opener): ?array } } - if (null === $closer) { + if ($closer === null) { return null; } diff --git a/src/MenuBar/MenuBar.php b/src/MenuBar/MenuBar.php index b91f19d..9885233 100644 --- a/src/MenuBar/MenuBar.php +++ b/src/MenuBar/MenuBar.php @@ -11,10 +11,10 @@ class MenuBar { - use HasVibrancy; use HasDimensions; use HasPositioner; use HasUrl; + use HasVibrancy; protected string $icon = ''; diff --git a/src/Windows/Window.php b/src/Windows/Window.php index fc57058..b8f5926 100644 --- a/src/Windows/Window.php +++ b/src/Windows/Window.php @@ -9,9 +9,9 @@ class Window { - use HasVibrancy; use HasDimensions; use HasUrl; + use HasVibrancy; protected bool $autoHideMenuBar = false; From 8a959c9097c0b4642ab4e7285f88d6f857244633 Mon Sep 17 00:00:00 2001 From: Dan Johnson Date: Thu, 21 Sep 2023 16:23:19 +0100 Subject: [PATCH 036/224] feat: mark GITHUB_* keys to be cleaned up --- config/nativephp.php | 1 + 1 file changed, 1 insertion(+) diff --git a/config/nativephp.php b/config/nativephp.php index dde80e0..729a685 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -45,6 +45,7 @@ */ 'cleanup_env_keys' => [ 'AWS_*', + 'GITHUB_*', 'DO_SPACES_*', '*_SECRET', 'NATIVEPHP_UPDATER_PATH', From 02106ecf742af6d81548153378a367a1e94194fe Mon Sep 17 00:00:00 2001 From: Curtis Blackwell Date: Fri, 29 Sep 2023 08:42:29 -0500 Subject: [PATCH 037/224] Fix the issue that prevented setting the position on open windows --- src/Windows/WindowManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/WindowManager.php b/src/Windows/WindowManager.php index c7209c2..325b800 100644 --- a/src/Windows/WindowManager.php +++ b/src/Windows/WindowManager.php @@ -42,7 +42,7 @@ public function resize($width, $height, $id = null) public function position($x, $y, $animated = false, $id = null) { - $this->client->post('window/resize', [ + $this->client->post('window/position', [ 'id' => $id ?? $this->detectId(), 'x' => $x, 'y' => $y, From 6675be16b2c9398255a01a3d4d4521ee2bee6d73 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 9 Oct 2023 00:52:03 +0000 Subject: [PATCH 038/224] Bump stefanzweifel/git-auto-commit-action from 4 to 5 Bumps [stefanzweifel/git-auto-commit-action](https://github.com/stefanzweifel/git-auto-commit-action) from 4 to 5. - [Release notes](https://github.com/stefanzweifel/git-auto-commit-action/releases) - [Changelog](https://github.com/stefanzweifel/git-auto-commit-action/blob/master/CHANGELOG.md) - [Commits](https://github.com/stefanzweifel/git-auto-commit-action/compare/v4...v5) --- updated-dependencies: - dependency-name: stefanzweifel/git-auto-commit-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/fix-php-code-style-issues.yml | 2 +- .github/workflows/update-changelog.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index a5b1b60..28816d3 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -22,6 +22,6 @@ jobs: uses: aglipanci/laravel-pint-action@2.3.0 - name: Commit changes - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Fix styling diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index a817f81..ec40921 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -24,7 +24,7 @@ jobs: release-notes: ${{ github.event.release.body }} - name: Commit updated CHANGELOG - uses: stefanzweifel/git-auto-commit-action@v4 + uses: stefanzweifel/git-auto-commit-action@v5 with: branch: main commit_message: Update CHANGELOG From 56af6e7f9ae9c2da75c0273303c49be6685559e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jan 2024 00:45:53 +0000 Subject: [PATCH 039/224] Bump aglipanci/laravel-pint-action from 2.3.0 to 2.3.1 Bumps [aglipanci/laravel-pint-action](https://github.com/aglipanci/laravel-pint-action) from 2.3.0 to 2.3.1. - [Release notes](https://github.com/aglipanci/laravel-pint-action/releases) - [Commits](https://github.com/aglipanci/laravel-pint-action/compare/2.3.0...2.3.1) --- updated-dependencies: - dependency-name: aglipanci/laravel-pint-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/fix-php-code-style-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 28816d3..ab1a6d2 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -19,7 +19,7 @@ jobs: ref: ${{ github.head_ref }} - name: Fix PHP code style issues - uses: aglipanci/laravel-pint-action@2.3.0 + uses: aglipanci/laravel-pint-action@2.3.1 - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v5 From c699310de0b52653789dd8198d598072dfa53f58 Mon Sep 17 00:00:00 2001 From: LunashaGit Date: Tue, 6 Feb 2024 18:39:56 +0100 Subject: [PATCH 040/224] Fix PHP Fatal Error deleteDirectoryRecursive function in MinifyApplicationCommand --- src/Commands/MinifyApplicationCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index 6bd0f85..5b7373c 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -86,7 +86,7 @@ protected function removeIgnoredFilesAndFolders(string $appPath): void } } - private function deleteDirectoryRecursive(string $directory): void + private function deleteDirectoryRecursive(string $directory): bool { if (! file_exists($directory)) { return true; @@ -106,6 +106,6 @@ private function deleteDirectoryRecursive(string $directory): void } } - rmdir($directory); + return rmdir($directory); } } From e9a75323b089869b1dbc96a3e4b07a3200080b60 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Wed, 7 Feb 2024 16:45:12 +0000 Subject: [PATCH 041/224] Fix styling --- src/Dialog.php | 2 +- src/Menu/Menu.php | 6 +++--- src/System.php | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Dialog.php b/src/Dialog.php index f31261b..153976f 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -110,7 +110,7 @@ public function properties(array $properties): self return $this; } - public function asSheet(string $windowId = null): self + public function asSheet(?string $windowId = null): self { if (is_null($windowId)) { $this->windowReference = Window::current()->id; diff --git a/src/Menu/Menu.php b/src/Menu/Menu.php index d27dee0..7709a41 100644 --- a/src/Menu/Menu.php +++ b/src/Menu/Menu.php @@ -66,17 +66,17 @@ public function label(string $label): self return $this->add(new Label($label)); } - public function checkbox(string $label, bool $checked = false, string $hotkey = null): self + public function checkbox(string $label, bool $checked = false, ?string $hotkey = null): self { return $this->add(new Checkbox($label, $checked, $hotkey)); } - public function event(string $event, string $text, string $hotkey = null): self + public function event(string $event, string $text, ?string $hotkey = null): self { return $this->add(new Event($event, $text, $hotkey)); } - public function link(string $url, string $text, string $hotkey = null): self + public function link(string $url, string $text, ?string $hotkey = null): self { return $this->add(new Link($url, $text, $hotkey)); } diff --git a/src/System.php b/src/System.php index e1f61cd..65a2c0c 100644 --- a/src/System.php +++ b/src/System.php @@ -42,7 +42,7 @@ public function printers(): array })->toArray(); } - public function print(string $html, Printer $printer = null): void + public function print(string $html, ?Printer $printer = null): void { $this->client->post('system/print', [ 'html' => $html, From 45b7ccfcb86ebf35be35c1eb7fbb9f05a224448f Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Mon, 24 Jul 2023 16:00:12 -0600 Subject: [PATCH 042/224] Allow for string events String events are especially useful for passing custom data to the listener. Consider the following: ```php use Native\Laravel\Client\Client; use Native\Laravel\Notification; // Send a notification with a custom event $client = new Client(); $notification = new Notification($client); $articleId = 1; $notification->title('EXTRA EXTRA READ ALL ABOUT IT') ->message('You should totally click this) ->event('notification.clicked.newArticle' . $articleId) ->show(); // Listen to the notification Event::listen('notification.clicked.newArticle.*', function ($event) { $event = explode('.', $event) $articleId = array_last($event); // do stuff... }); ``` --- src/Http/Controllers/DispatchEventFromAppController.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Http/Controllers/DispatchEventFromAppController.php b/src/Http/Controllers/DispatchEventFromAppController.php index 2ae7bb9..0f467f1 100644 --- a/src/Http/Controllers/DispatchEventFromAppController.php +++ b/src/Http/Controllers/DispatchEventFromAppController.php @@ -9,10 +9,13 @@ class DispatchEventFromAppController public function __invoke(Request $request) { $event = $request->get('event'); - if (class_exists($event)) { - $event = new $event(...$request->get('payload', [])); + $payload = $request->get('payload', []); + if (class_exists($event)) { + $event = new $event(...$payload); event($event); + } else { + event($event, $payload); } return response()->json([ From 3b0871fac88e644a43a5fb3e1bfe58248928bb12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 01:14:57 +0000 Subject: [PATCH 043/224] Bump ramsey/composer-install from 2 to 3 Bumps [ramsey/composer-install](https://github.com/ramsey/composer-install) from 2 to 3. - [Release notes](https://github.com/ramsey/composer-install/releases) - [Commits](https://github.com/ramsey/composer-install/compare/v2...v3) --- updated-dependencies: - dependency-name: ramsey/composer-install dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/phpstan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index ccfa9d9..3855a08 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -20,7 +20,7 @@ jobs: coverage: none - name: Install composer dependencies - uses: ramsey/composer-install@v2 + uses: ramsey/composer-install@v3 - name: Run PHPStan run: ./vendor/bin/phpstan --error-format=github From 03796c5ab1a1fc6844dbb6dfc9029e38871ceb29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 00:41:42 +0000 Subject: [PATCH 044/224] Bump dependabot/fetch-metadata from 1.6.0 to 2.0.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.6.0 to 2.0.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.6.0...v2.0.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index ca2197d..67e66c6 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.6.0 + uses: dependabot/fetch-metadata@v2.0.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From 44cc93d1f4c5ec24262128ff0eaedebd8dba383a Mon Sep 17 00:00:00 2001 From: mel Date: Tue, 26 Mar 2024 06:16:09 +0000 Subject: [PATCH 045/224] Fix for laravel 11 upgrade --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 6efaf14..a1c089c 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,9 @@ ], "require": { "php": "^8.1", - "illuminate/contracts": "^10.0", + "illuminate/contracts": "^11.0", "spatie/laravel-package-tools": "^1.14.0", - "symfony/finder": "^6.2" + "symfony/finder": "^7.0" }, "require-dev": { "guzzlehttp/guzzle": "^7.0", From e71760284180281e8bc04a629dd2f199766b8fb7 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Mon, 1 Apr 2024 16:16:17 +0100 Subject: [PATCH 046/224] Fix for L10 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index a1c089c..1c71f69 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,9 @@ ], "require": { "php": "^8.1", - "illuminate/contracts": "^11.0", + "illuminate/contracts": "^10.0|^11.0", "spatie/laravel-package-tools": "^1.14.0", - "symfony/finder": "^7.0" + "symfony/finder": "^6.2|^7.0" }, "require-dev": { "guzzlehttp/guzzle": "^7.0", From 9336d1262fe73cf1334319e48692dad19023c129 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Mon, 1 Apr 2024 16:42:33 +0000 Subject: [PATCH 047/224] Update CHANGELOG --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8f74ff..2d05dbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,36 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.5.0 - 2024-04-01 + +### What's Changed + +* Add Laravel 11 support by @meliani in https://github.com/NativePHP/laravel/pull/262 +* Add printToPDF function by @basst85 in https://github.com/NativePHP/laravel/pull/104 +* Add method to update an existing context-menu of the menu bar by @bbredewold in https://github.com/NativePHP/laravel/pull/108 +* Add required config for using GitHub as an updater provider by @danjohnson95 in https://github.com/NativePHP/laravel/pull/189 +* Add ability to exclude files and entire folders from built application by @nexxai in https://github.com/NativePHP/laravel/pull/165 +* Add ability to use string events by @LukeTowers in https://github.com/NativePHP/laravel/pull/67 +* Fix 'native:db:seed' command not working by @me-shaon in https://github.com/NativePHP/laravel/pull/199 +* Fix an issue that prevented setting the position on open windows by @curtisblackwell in https://github.com/NativePHP/laravel/pull/215 +* Fix PHP Fatal Error deleteDirectoryRecursive function in MinifyApplicationCommand by @LunashaGit in https://github.com/NativePHP/laravel/pull/249 +* Bump actions/checkout from 3 to 4 by @dependabot in https://github.com/NativePHP/laravel/pull/208 +* Bump stefanzweifel/git-auto-commit-action from 4 to 5 by @dependabot in https://github.com/NativePHP/laravel/pull/217 +* Bump aglipanci/laravel-pint-action from 2.3.0 to 2.3.1 by @dependabot in https://github.com/NativePHP/laravel/pull/240 + +### New Contributors + +* @me-shaon made their first contribution in https://github.com/NativePHP/laravel/pull/199 +* @bbredewold made their first contribution in https://github.com/NativePHP/laravel/pull/108 +* @danjohnson95 made their first contribution in https://github.com/NativePHP/laravel/pull/189 +* @curtisblackwell made their first contribution in https://github.com/NativePHP/laravel/pull/215 +* @nexxai made their first contribution in https://github.com/NativePHP/laravel/pull/165 +* @LunashaGit made their first contribution in https://github.com/NativePHP/laravel/pull/249 +* @LukeTowers made their first contribution in https://github.com/NativePHP/laravel/pull/67 +* @meliani made their first contribution in https://github.com/NativePHP/laravel/pull/262 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.4.0...0.5.0 + ## 0.4.0 - 2023-08-09 ### What's Changed From 33a840858a50e35221e0fd4fd095141dd16d88c6 Mon Sep 17 00:00:00 2001 From: Milwad Date: Tue, 2 Apr 2024 14:05:12 +0330 Subject: [PATCH 048/224] Update run-tests.yml --- .github/workflows/run-tests.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 180659f..a87dd7a 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,10 +13,14 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest, windows-latest] - php: [8.2, 8.1] - laravel: [10.*] + php: [8.3, 8.2, 8.1] + laravel: [11.*, 10.*] stability: [prefer-lowest, prefer-stable] include: + - laravel: 11.* + testbench: 9.* + carbon: ^3.2 + - laravel: 10.* testbench: 8.* carbon: ^2.63 From 7e60bd5d37f220338fedc019f3e739db7b082d92 Mon Sep 17 00:00:00 2001 From: Milwad Date: Tue, 2 Apr 2024 14:08:49 +0330 Subject: [PATCH 049/224] Update run-tests.yml --- .github/workflows/run-tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index a87dd7a..2ceb3c7 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -25,6 +25,10 @@ jobs: testbench: 8.* carbon: ^2.63 + exclude: + - laravel: 11.* + php: 8.1 + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} steps: From 04c99b5f27e88df384a27112588804fc0286b71e Mon Sep 17 00:00:00 2001 From: Milwad Date: Tue, 2 Apr 2024 14:25:39 +0330 Subject: [PATCH 050/224] wip --- .github/workflows/run-tests.yml | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 2ceb3c7..9924344 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -28,7 +28,7 @@ jobs: exclude: - laravel: 11.* php: 8.1 - + name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} steps: diff --git a/composer.json b/composer.json index 1c71f69..e2cc82b 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require": { "php": "^8.1", "illuminate/contracts": "^10.0|^11.0", - "spatie/laravel-package-tools": "^1.14.0", + "spatie/laravel-package-tools": "^1.16.4", "symfony/finder": "^6.2|^7.0" }, "require-dev": { From 9dec31d1b3f5981d26537ddfb40c23c4ccfe66e7 Mon Sep 17 00:00:00 2001 From: Milwad Date: Tue, 2 Apr 2024 14:34:39 +0330 Subject: [PATCH 051/224] Update run-tests.yml --- .github/workflows/run-tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 9924344..2d67173 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -20,10 +20,12 @@ jobs: - laravel: 11.* testbench: 9.* carbon: ^3.2 + laravel-package-tools: ^11.0 - laravel: 10.* testbench: 8.* carbon: ^2.63 + laravel-package-tools: ^10.0 exclude: - laravel: 11.* @@ -49,7 +51,7 @@ jobs: - name: Install dependencies run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" --no-interaction --no-update + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" "spatie/laravel-package-tools:${{ matrix.laravel-package-tools }}" --no-interaction --no-update composer update --${{ matrix.stability }} --prefer-dist --no-interaction - name: List Installed Dependencies From c7959063bd2a399fc7e13f4ece74371941941d4f Mon Sep 17 00:00:00 2001 From: Milwad Date: Tue, 2 Apr 2024 14:36:31 +0330 Subject: [PATCH 052/224] Update run-tests.yml --- .github/workflows/run-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 2d67173..834642b 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -20,12 +20,12 @@ jobs: - laravel: 11.* testbench: 9.* carbon: ^3.2 - laravel-package-tools: ^11.0 + laravel-package-tools: ^1.16.4 - laravel: 10.* testbench: 8.* carbon: ^2.63 - laravel-package-tools: ^10.0 + laravel-package-tools: ^1.16.4 exclude: - laravel: 11.* From 9d367a873d2f902fbd5dad63712c102ccc7acbc1 Mon Sep 17 00:00:00 2001 From: Milwad Date: Tue, 2 Apr 2024 14:56:10 +0330 Subject: [PATCH 053/224] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e2cc82b..8ca6d30 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": "^8.1", - "illuminate/contracts": "^10.0|^11.0", + "laravel/framework": "^10.0|^11.0", "spatie/laravel-package-tools": "^1.16.4", "symfony/finder": "^6.2|^7.0" }, From cc5dd34e4d8b4f6f77af5e6c5cbbed27d75bc473 Mon Sep 17 00:00:00 2001 From: Milwad Date: Tue, 2 Apr 2024 15:00:45 +0330 Subject: [PATCH 054/224] Update run-tests.yml --- .github/workflows/run-tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 834642b..0e42097 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -21,11 +21,13 @@ jobs: testbench: 9.* carbon: ^3.2 laravel-package-tools: ^1.16.4 + collision: ^8.1.1 - laravel: 10.* testbench: 8.* carbon: ^2.63 laravel-package-tools: ^1.16.4 + collision: ^7.* exclude: - laravel: 11.* @@ -51,7 +53,7 @@ jobs: - name: Install dependencies run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" "spatie/laravel-package-tools:${{ matrix.laravel-package-tools }}" --no-interaction --no-update + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" "spatie/laravel-package-tools:${{ matrix.laravel-package-tools }}" "nunomaduro/collision:${{ matrix.collision }}" --no-interaction --no-update composer update --${{ matrix.stability }} --prefer-dist --no-interaction - name: List Installed Dependencies From 29d88db64f5a317351bfb3b8ea5f3101b956106b Mon Sep 17 00:00:00 2001 From: Milwad Date: Tue, 2 Apr 2024 15:01:44 +0330 Subject: [PATCH 055/224] Update run-tests.yml --- .github/workflows/run-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 0e42097..107761b 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -27,7 +27,7 @@ jobs: testbench: 8.* carbon: ^2.63 laravel-package-tools: ^1.16.4 - collision: ^7.* + collision: 7.* exclude: - laravel: 11.* From 94a3122b6820feca05898b3baa494724b2f0d1c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 01:07:10 +0000 Subject: [PATCH 056/224] Bump aglipanci/laravel-pint-action from 2.3.1 to 2.4 Bumps [aglipanci/laravel-pint-action](https://github.com/aglipanci/laravel-pint-action) from 2.3.1 to 2.4. - [Release notes](https://github.com/aglipanci/laravel-pint-action/releases) - [Commits](https://github.com/aglipanci/laravel-pint-action/compare/2.3.1...2.4) --- updated-dependencies: - dependency-name: aglipanci/laravel-pint-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/fix-php-code-style-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index ab1a6d2..255506b 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -19,7 +19,7 @@ jobs: ref: ${{ github.head_ref }} - name: Fix PHP code style issues - uses: aglipanci/laravel-pint-action@2.3.1 + uses: aglipanci/laravel-pint-action@2.4 - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v5 From 81a8911b8d663c162349459813bbe9a5fbaefcb3 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Sun, 28 Apr 2024 17:47:45 +0000 Subject: [PATCH 057/224] Fix styling --- src/Commands/FreshCommand.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Commands/FreshCommand.php b/src/Commands/FreshCommand.php index 0fd5059..add5c32 100644 --- a/src/Commands/FreshCommand.php +++ b/src/Commands/FreshCommand.php @@ -2,7 +2,6 @@ namespace Native\Laravel\Commands; -use Illuminate\Console\Command; use Illuminate\Database\Console\Migrations\FreshCommand as BaseFreshCommand; use Native\Laravel\NativeServiceProvider; From dd4974d81c178f018decc68b0e68db8dd15bd545 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 28 Apr 2024 18:50:35 +0100 Subject: [PATCH 058/224] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8ca6d30..e2cc82b 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": "^8.1", - "laravel/framework": "^10.0|^11.0", + "illuminate/contracts": "^10.0|^11.0", "spatie/laravel-package-tools": "^1.16.4", "symfony/finder": "^6.2|^7.0" }, From 56da96981652909a508d7ed1886716963316f8d2 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 28 Apr 2024 19:05:25 +0100 Subject: [PATCH 059/224] Add author --- composer.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/composer.json b/composer.json index e2cc82b..dac3289 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,11 @@ "name": "Marcel Pociot", "email": "marcel@beyondco.de", "role": "Developer" + }, + { + "name": "Simon Hamp", + "email": "simon.hamp@me.com", + "role": "Developer" } ], "require": { From 9d4b16f2aec635a85ded93cbff72a57d3c15b5d0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 00:49:18 +0000 Subject: [PATCH 060/224] Bump dependabot/fetch-metadata from 2.0.0 to 2.1.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.0.0 to 2.1.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.0.0...v2.1.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 67e66c6..611344a 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.0.0 + uses: dependabot/fetch-metadata@v2.1.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From 57cb209df6bab7c98b6bc137b2a64313c4f6c1b3 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 1 May 2024 17:52:57 +0100 Subject: [PATCH 061/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index aedbe99..6a58160 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,12 +1,20 @@ name: Bug Report -description: Report an Issue or Bug with the Package +description: Report an Issue or Bug in NativePHP title: "[Bug]: " labels: ["bug"] body: - type: markdown attributes: value: | - We're sorry to hear you have a problem. Can you help us solve it by providing the following details. + We're sorry to hear you have a problem. Please help us solve it by providing the following details. + - type: textarea + id: what-doing + attributes: + label: What were you trying to do? + description: Some context about what you were trying to achieve + placeholder: Trying to build my app for production + validations: + required: true - type: textarea id: what-happened attributes: @@ -26,9 +34,8 @@ body: - type: input id: package-version attributes: - label: Package Version - description: What version of our Package are you running? Please be as specific as possible - placeholder: 2.0.0 + label: Package Versions + description: What versions of the NativePHP packages are you running? Output of `composer show nativephp/* --format=json` validations: required: true - type: input @@ -58,13 +65,21 @@ body: - type: dropdown id: operating-systems attributes: - label: Which operating systems does with happen with? + label: Which operating systems have you seen this occur on? description: You may select more than one. multiple: true options: - macOS - Windows - Linux + - type: input + id: os-version + attributes: + label: OS version + description: Which version of these OSes are you using? + placeholder: 'win11 (23H2), macos14.1 (23B74)' + validations: + required: true - type: textarea id: notes attributes: From 5b1b5ee4f48a0b3b3ebedc0957c7fbbdbd28d6d3 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 1 May 2024 17:54:32 +0100 Subject: [PATCH 062/224] Update config.yml --- .github/ISSUE_TEMPLATE/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index b66f18f..113e1ea 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,10 +1,10 @@ blank_issues_enabled: true contact_links: - name: Ask a question - url: https://github.com/nativephp/laravel/discussions/new?category=q-a + url: https://github.com/orgs/nativephp/discussions/new?category=q-a about: Ask the community for help - name: Request a feature - url: https://github.com/nativephp/laravel/discussions/new?category=ideas + url: https://github.com/orgs/nativephp/discussions/new?category=ideas about: Share ideas for new features - name: Report a security issue url: https://github.com/nativephp/laravel/security/policy From 72a1c92a3aaac9b315279ac0f4d36e2837a7c6a0 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 1 May 2024 20:23:07 +0100 Subject: [PATCH 063/224] Add default app ID --- config/nativephp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nativephp.php b/config/nativephp.php index 8e4e4ed..b24afec 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -13,7 +13,7 @@ * usually in the form of a reverse domain name. * For example: com.nativephp.app */ - 'app_id' => env('NATIVEPHP_APP_ID'), + 'app_id' => env('NATIVEPHP_APP_ID', 'com.nativephp.app'), /** * If your application allows deep linking, you can specify the scheme From 4181ef97ddcfab1348426f983a180202e992e664 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Thu, 2 May 2024 10:56:23 +0000 Subject: [PATCH 064/224] Update CHANGELOG --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d05dbb..ca8daa0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,25 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.5.1 - 2024-05-02 + +### What's Changed + +* Add a default `NATIVEPHP_APP_ID` to fix #284 +* Fix for #175 `native:migrate:fresh` command @me-shaon in https://github.com/NativePHP/laravel/pull/198 +* Add hide window functionality by @braceyourself in https://github.com/NativePHP/laravel/pull/144 +* Update Tests workflow by @milwad-dev in https://github.com/NativePHP/laravel/pull/265 +* Bump ramsey/composer-install from 2 to 3 by @dependabot in https://github.com/NativePHP/laravel/pull/255 +* Bump dependabot/fetch-metadata from 1.6.0 to 2.0.0 by @dependabot in https://github.com/NativePHP/laravel/pull/260 +* Bump aglipanci/laravel-pint-action from 2.3.1 to 2.4 by @dependabot in https://github.com/NativePHP/laravel/pull/268 +* Bump dependabot/fetch-metadata from 2.0.0 to 2.1.0 by @dependabot in https://github.com/NativePHP/laravel/pull/275 + +### New Contributors + +* @braceyourself made their first contribution in https://github.com/NativePHP/laravel/pull/144 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.5.0...0.6.0 + ## 0.5.0 - 2024-04-01 ### What's Changed From 485835c3dd00396cb76bccc941663822c5341ef3 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 2 May 2024 16:45:00 +0100 Subject: [PATCH 065/224] Fix package auto-discovery --- src/NativeServiceProvider.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 396478a..609cf42 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -35,6 +35,10 @@ public function packageRegistered() { $this->mergeConfigFrom($this->package->basePath('/../config/nativephp-internal.php'), 'nativephp-internal'); + $this->app->singleton(FreshCommand::class, function ($app) { + return new FreshCommand($app['migrator']); + }); + $this->app->singleton(MigrateCommand::class, function ($app) { return new MigrateCommand($app['migrator'], $app['events']); }); From 806dcd97c88a9a4e31efbe1fac687e9e5e1dc84a Mon Sep 17 00:00:00 2001 From: simonhamp Date: Thu, 2 May 2024 15:45:56 +0000 Subject: [PATCH 066/224] Update CHANGELOG --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca8daa0..4eb8f57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.5.2 - 2024-05-02 + +### What's Changed + +* Fixes a regression introduced in 0.5.1 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.5.1...0.5.2 + ## 0.5.1 - 2024-05-02 ### What's Changed From 420133a52606d3fdbb0f52907f9b0476517be846 Mon Sep 17 00:00:00 2001 From: Shomisha Date: Sun, 5 May 2024 01:17:48 +0200 Subject: [PATCH 067/224] Implement the reload() method on the WindowManager (#294) --- src/Facades/Window.php | 1 + src/Windows/WindowManager.php | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/Facades/Window.php b/src/Facades/Window.php index 35cf900..439d25f 100644 --- a/src/Facades/Window.php +++ b/src/Facades/Window.php @@ -11,6 +11,7 @@ * @method static void resize($width, $height, $id = null) * @method static void position($x, $y, $animated = false, $id = null) * @method static void alwaysOnTop($alwaysOnTop = true, $id = null) + * @method static void reload($id = null) */ class Window extends Facade { diff --git a/src/Windows/WindowManager.php b/src/Windows/WindowManager.php index 6216f74..4a622b7 100644 --- a/src/Windows/WindowManager.php +++ b/src/Windows/WindowManager.php @@ -71,4 +71,11 @@ public function maximize($id = null): void 'id' => $id ?? $this->detectId(), ]); } + + public function reload($id = null): void + { + $this->client->post('window/reload', [ + 'id' => $id ?? $this->detectId(), + ]); + } } From 9dc657b828183e35155d37dc65590c1a0bad1b79 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 8 May 2024 10:01:04 +0100 Subject: [PATCH 068/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 6a58160..d0bd3f4 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,6 +1,5 @@ name: Bug Report description: Report an Issue or Bug in NativePHP -title: "[Bug]: " labels: ["bug"] body: - type: markdown From 4143a585613615b40935facc7f0b4900357c75bd Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 14 May 2024 09:05:17 +0100 Subject: [PATCH 069/224] Update config.yml --- .github/ISSUE_TEMPLATE/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 113e1ea..534c2ac 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,4 +1,4 @@ -blank_issues_enabled: true +blank_issues_enabled: false contact_links: - name: Ask a question url: https://github.com/orgs/nativephp/discussions/new?category=q-a From f5179ba8c6d7c0d053a49a4c389653dcc13e8730 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 14 May 2024 09:07:31 +0100 Subject: [PATCH 070/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index d0bd3f4..24b400a 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,5 +1,5 @@ name: Bug Report -description: Report an Issue or Bug in NativePHP +description: Report an issue or bug in NativePHP. **Before submitting your report, please make sure you've been through the [debugging steps](https://nativephp.com/docs/getting-started/debugging)!** labels: ["bug"] body: - type: markdown From 53a9a77829cb5db87920bc9b9082e435990cc95c Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 14 May 2024 09:07:56 +0100 Subject: [PATCH 071/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 24b400a..51d4177 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,5 +1,5 @@ name: Bug Report -description: Report an issue or bug in NativePHP. **Before submitting your report, please make sure you've been through the [debugging steps](https://nativephp.com/docs/getting-started/debugging)!** +description: Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the debugging steps: https://nativephp.com/docs/getting-started/debugging labels: ["bug"] body: - type: markdown From d99a5bb0a3e6728b1b54234d09c482cb139cb1c8 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 14 May 2024 09:08:18 +0100 Subject: [PATCH 072/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 51d4177..5062711 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,5 +1,5 @@ name: Bug Report -description: Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the debugging steps: https://nativephp.com/docs/getting-started/debugging +description: "Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the debugging steps: https://nativephp.com/docs/getting-started/debugging" labels: ["bug"] body: - type: markdown From bf0c70c474deb03c46865d4801aad90953ec1c4d Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 14 May 2024 14:03:58 +0100 Subject: [PATCH 073/224] Create funding.yml --- .github/funding.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/funding.yml diff --git a/.github/funding.yml b/.github/funding.yml new file mode 100644 index 0000000..28c3a03 --- /dev/null +++ b/.github/funding.yml @@ -0,0 +1 @@ +github: simonhamp From 91adb889edf65fcd6f40e9f773a9b9984f9d378e Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 14 May 2024 14:16:59 +0100 Subject: [PATCH 074/224] Update composer.json --- composer.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/composer.json b/composer.json index dac3289..768a863 100644 --- a/composer.json +++ b/composer.json @@ -8,6 +8,12 @@ ], "homepage": "https://github.com/nativephp/laravel", "license": "MIT", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/simonhamp" + } + ], "authors": [ { "name": "Marcel Pociot", From d88fe14aec8e1b68a077d8511ee4ec927004a46f Mon Sep 17 00:00:00 2001 From: Alvin Lau Date: Fri, 24 May 2024 08:37:18 +0800 Subject: [PATCH 075/224] Implement `trafficLightPosition()` method on Window (#310) --- src/Windows/Window.php | 10 ++++++++++ tests/Windows/WindowTest.php | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/Windows/Window.php b/src/Windows/Window.php index b8f5926..2348577 100644 --- a/src/Windows/Window.php +++ b/src/Windows/Window.php @@ -43,6 +43,8 @@ class Window protected string $titleBarStyle = 'default'; + protected array $trafficLightPosition = []; + protected string $title = ''; protected string $id = 'main'; @@ -88,6 +90,13 @@ public function titleBarHiddenInset(): self return $this->titleBarStyle('hiddenInset'); } + public function trafficLightPosition(int $x, int $y): self + { + $this->trafficLightPosition = ['x' => $x, 'y' => $y]; + + return $this; + } + public function rememberState(): self { $this->rememberState = true; @@ -225,6 +234,7 @@ public function toArray() 'hasShadow' => $this->hasShadow, 'frame' => $this->frame, 'titleBarStyle' => $this->titleBarStyle, + 'trafficLightPosition' => $this->trafficLightPosition, 'showDevTools' => $this->showDevTools, 'vibrancy' => $this->vibrancy, 'transparency' => $this->transparent, diff --git a/tests/Windows/WindowTest.php b/tests/Windows/WindowTest.php index 1aa7107..6db8a9a 100644 --- a/tests/Windows/WindowTest.php +++ b/tests/Windows/WindowTest.php @@ -58,6 +58,25 @@ expect($window->toArray()['titleBarStyle'])->toBe('customButtonsOnHover'); }); +it('test for trafficLightPosition in window', function () { + $window = Window::open() + ->trafficLightPosition(10, 10); + + expect($window->toArray()['trafficLightPosition']) + ->toBeArray() + ->toHaveKeys(['x', 'y']) + ->toHaveLength(2) + ->toMatchArray(['x' => 10, 'y' => 10]); + + $window->trafficLightPosition(5, 15); + + expect($window->toArray()['trafficLightPosition']) + ->toBeArray() + ->toHaveKeys(['x', 'y']) + ->toHaveLength(2) + ->toMatchArray(['x' => 5, 'y' => 15]); +}); + it('test for invisibleFrameless in window', function () { $window = Window::open()->invisibleFrameless(); $windowArray = $window->toArray(); From 626fa2351cfb8dc9cacd67b282a5487942677372 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jul 2024 00:40:21 +0000 Subject: [PATCH 076/224] Bump dependabot/fetch-metadata from 2.1.0 to 2.2.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.1.0 to 2.2.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.1.0...v2.2.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 611344a..eb537d8 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.1.0 + uses: dependabot/fetch-metadata@v2.2.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From db818a8bc05bb00556c3970b6f0d0fc642fea50f Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 00:10:37 +0100 Subject: [PATCH 077/224] Add timezone support --- src/Support/Timezones.php | 344 ++++++++++++++++++++++++++++++++++++++ src/System.php | 14 ++ 2 files changed, 358 insertions(+) create mode 100644 src/Support/Timezones.php diff --git a/src/Support/Timezones.php b/src/Support/Timezones.php new file mode 100644 index 0000000..179c77d --- /dev/null +++ b/src/Support/Timezones.php @@ -0,0 +1,344 @@ + 'Etc/GMT+12', + 'UTC-11' => 'Etc/GMT+11', + 'Aleutian Standard Time' => 'America/Adak', + 'Hawaiian Standard Time' => 'Pacific/Honolulu', + 'Marquesas Standard Time' => 'Pacific/Marquesas', + 'Alaskan Standard Time' => 'America/Anchorage', + 'UTC-09' => 'Etc/GMT+9', + 'Pacific Standard Time (Mexico)' => 'America/Tijuana', + 'UTC-08' => 'Etc/GMT+8', + 'Pacific Standard Time' => 'America/Los_Angeles', + 'US Mountain Standard Time' => 'America/Phoenix', + 'Mountain Standard Time (Mexico)' => 'America/Chihuahua', + 'Mountain Standard Time' => 'America/Denver', + 'Yukon Standard Time' => 'America/Whitehorse', + 'Central America Standard Time' => 'America/Guatemala', + 'Central Standard Time' => 'America/Chicago', + 'Easter Island Standard Time' => 'Pacific/Easter', + 'Central Standard Time (Mexico)' => 'America/Mexico_City', + 'Canada Central Standard Time' => 'America/Regina', + 'SA Pacific Standard Time' => 'America/Bogota', + 'Eastern Standard Time (Mexico)' => 'America/Cancun', + 'Eastern Standard Time' => 'America/New_York', + 'Haiti Standard Time' => 'America/Port-au-Prince', + 'Cuba Standard Time' => 'America/Havana', + 'US Eastern Standard Time' => 'America/Indianapolis', + 'Turks And Caicos Standard Time' => 'America/Grand_Turk', + 'Paraguay Standard Time' => 'America/Asuncion', + 'Atlantic Standard Time' => 'America/Halifax', + 'Venezuela Standard Time' => 'America/Caracas', + 'Central Brazilian Standard Time' => 'America/Cuiaba', + 'SA Western Standard Time' => 'America/La_Paz', + 'Pacific SA Standard Time' => 'America/Santiago', + 'Newfoundland Standard Time' => 'America/St_Johns', + 'Tocantins Standard Time' => 'America/Araguaina', + 'E. South America Standard Time' => 'America/Sao_Paulo', + 'Argentina Standard Time' => 'America/Argentina/Buenos_Aires', + 'Greenland Standard Time' => 'America/Godthab', + 'Montevideo Standard Time' => 'America/Montevideo', + 'Magallanes Standard Time' => 'America/Punta_Arenas', + 'Saint Pierre Standard Time' => 'America/Miquelon', + 'Bahia Standard Time' => 'America/Bahia', + 'UTC-02' => 'Etc/GMT+2', + 'Azores Standard Time' => 'Atlantic/Azores', + 'Cape Verde Standard Time' => 'Atlantic/Cape_Verde', + 'UTC' => 'Etc/UTC', + 'GMT Standard Time' => 'Europe/London', + 'Greenwich Standard Time' => 'Atlantic/Reykjavik', + 'Sao Tome Standard Time' => 'Africa/Sao_Tome', + 'Morocco Standard Time' => 'Africa/Casablanca', + 'W. Europe Standard Time' => 'Europe/Berlin', + 'Central Europe Standard Time' => 'Europe/Budapest', + 'Romance Standard Time' => 'Europe/Paris', + 'Central European Standard Time' => 'Europe/Warsaw', + 'W. Central Africa Standard Time' => 'Africa/Lagos', + 'Jordan Standard Time' => 'Asia/Amman', + 'GTB Standard Time' => 'Europe/Bucharest', + 'Middle East Standard Time' => 'Asia/Beirut', + 'Egypt Standard Time' => 'Africa/Cairo', + 'E. Europe Standard Time' => 'Europe/Chisinau', + 'Syria Standard Time' => 'Asia/Damascus', + 'West Bank Standard Time' => 'Asia/Hebron', + 'South Africa Standard Time' => 'Africa/Johannesburg', + 'FLE Standard Time' => 'Europe/Kiev', + 'Israel Standard Time' => 'Asia/Jerusalem', + 'Kaliningrad Standard Time' => 'Europe/Kaliningrad', + 'Sudan Standard Time' => 'Africa/Khartoum', + 'Libya Standard Time' => 'Africa/Tripoli', + 'Namibia Standard Time' => 'Africa/Windhoek', + 'Arabic Standard Time' => 'Asia/Baghdad', + 'Turkey Standard Time' => 'Europe/Istanbul', + 'Arab Standard Time' => 'Asia/Riyadh', + 'Belarus Standard Time' => 'Europe/Minsk', + 'Russian Standard Time' => 'Europe/Moscow', + 'E. Africa Standard Time' => 'Africa/Nairobi', + 'Iran Standard Time' => 'Asia/Tehran', + 'Arabian Standard Time' => 'Asia/Dubai', + 'Astrakhan Standard Time' => 'Europe/Astrakhan', + 'Azerbaijan Standard Time' => 'Asia/Baku', + 'Russia Time Zone 3' => 'Europe/Samara', + 'Mauritius Standard Time' => 'Indian/Mauritius', + 'Saratov Standard Time' => 'Europe/Saratov', + 'Georgian Standard Time' => 'Asia/Tbilisi', + 'Caucasus Standard Time' => 'Asia/Yerevan', + 'Afghanistan Standard Time' => 'Asia/Kabul', + 'West Asia Standard Time' => 'Asia/Tashkent', + 'Ekaterinburg Standard Time' => 'Asia/Yekaterinburg', + 'Pakistan Standard Time' => 'Asia/Karachi', + 'India Standard Time' => 'Asia/Kolkata', + 'Sri Lanka Standard Time' => 'Asia/Colombo', + 'Nepal Standard Time' => 'Asia/Kathmandu', + 'Central Asia Standard Time' => 'Asia/Almaty', + 'Bangladesh Standard Time' => 'Asia/Dhaka', + 'Omsk Standard Time' => 'Asia/Omsk', + 'Myanmar Standard Time' => 'Asia/Yangon', + 'SE Asia Standard Time' => 'Asia/Bangkok', + 'Altai Standard Time' => 'Asia/Barnaul', + 'W. Mongolia Standard Time' => 'Asia/Hovd', + 'North Asia Standard Time' => 'Asia/Krasnoyarsk', + 'N. Central Asia Standard Time' => 'Asia/Novosibirsk', + 'Tomsk Standard Time' => 'Asia/Tomsk', + 'China Standard Time' => 'Asia/Shanghai', + 'North Asia East Standard Time' => 'Asia/Irkutsk', + 'Singapore Standard Time' => 'Asia/Singapore', + 'W. Australia Standard Time' => 'Australia/Perth', + 'Taipei Standard Time' => 'Asia/Taipei', + 'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar', + 'North Korea Standard Time' => 'Asia/Pyongyang', + 'Aus Central W. Standard Time' => 'Australia/Eucla', + 'Transbaikal Standard Time' => 'Asia/Chita', + 'Tokyo Standard Time' => 'Asia/Tokyo', + 'Korea Standard Time' => 'Asia/Seoul', + 'Yakutsk Standard Time' => 'Asia/Yakutsk', + 'Cen. Australia Standard Time' => 'Australia/Adelaide', + 'AUS Central Standard Time' => 'Australia/Darwin', + 'E. Australia Standard Time' => 'Australia/Brisbane', + 'AUS Eastern Standard Time' => 'Australia/Sydney', + 'West Pacific Standard Time' => 'Pacific/Port_Moresby', + 'Tasmania Standard Time' => 'Australia/Hobart', + 'Vladivostok Standard Time' => 'Asia/Vladivostok', + 'Lord Howe Standard Time' => 'Australia/Lord_Howe', + 'Bougainville Standard Time' => 'Pacific/Bougainville', + 'Russia Time Zone 10' => 'Asia/Srednekolymsk', + 'Magadan Standard Time' => 'Asia/Magadan', + 'Norfolk Standard Time' => 'Pacific/Norfolk', + 'Sakhalin Standard Time' => 'Asia/Sakhalin', + 'Central Pacific Standard Time' => 'Pacific/Guadalcanal', + 'Russia Time Zone 11' => 'Asia/Kamchatka', + 'New Zealand Standard Time' => 'Pacific/Auckland', + 'UTC+12' => 'Etc/GMT-12', + 'Fiji Standard Time' => 'Pacific/Fiji', + 'Kamchatka Standard Time' => 'Asia/Kamchatka', + 'Chatham Islands Standard Time' => 'Pacific/Chatham', + 'UTC+13' => 'Etc/GMT-13', + 'Tonga Standard Time' => 'Pacific/Tongatapu', + 'Samoa Standard Time' => 'Pacific/Apia', + 'Line Islands Standard Time' => 'Pacific/Kiritimati', + ]; + + private array $nix = [ + 'ACDT' => 'Australia/Adelaide', + 'ACST' => 'Australia/Darwin', + 'ACT' => 'Australia/Darwin', + 'ACWST' => 'Australia/Eucla', + 'ADT' => 'America/Halifax', + 'AEDT' => 'Australia/Sydney', + 'AEST' => 'Australia/Brisbane', + 'AET' => 'Australia/Sydney', + 'AFT' => 'Asia/Kabul', + 'AKDT' => 'America/Anchorage', + 'AKST' => 'America/Anchorage', + 'ALMT' => 'Asia/Almaty', + 'AMST' => 'America/Campo_Grande', + 'AMT' => 'America/Campo_Grande', + 'ANAST' => 'Asia/Anadyr', + 'ANAT' => 'Asia/Anadyr', + 'AQTT' => 'Asia/Aqtau', + 'ART' => 'America/Argentina/Buenos_Aires', + 'AST' => 'America/Halifax', + 'AWDT' => 'Australia/Perth', + 'AWST' => 'Australia/Perth', + 'AZOST' => 'Atlantic/Azores', + 'AZOT' => 'Atlantic/Azores', + 'AZST' => 'Asia/Baku', + 'AZT' => 'Asia/Baku', + 'BNT' => 'Asia/Brunei', + 'BIOT' => 'Indian/Chagos', + 'BIT' => 'Pacific/Pago_Pago', + 'BOT' => 'America/La_Paz', + 'BRST' => 'America/Sao_Paulo', + 'BRT' => 'America/Sao_Paulo', + 'BST' => 'Europe/London', + 'BTT' => 'Asia/Thimphu', + 'CAT' => 'Africa/Maputo', + 'CCT' => 'Indian/Cocos', + 'CDT' => 'America/Chicago', + 'CEST' => 'Europe/Berlin', + 'CET' => 'Europe/Berlin', + 'CHADT' => 'Pacific/Chatham', + 'CHAST' => 'Pacific/Chatham', + 'CHOT' => 'Asia/Choibalsan', + 'CHOST' => 'Asia/Choibalsan', + 'CHST' => 'Pacific/Guam', + 'CHUT' => 'Pacific/Chuuk', + 'CIST' => 'Pacific/Rarotonga', + 'CIT' => 'Asia/Makassar', + 'CKT' => 'Pacific/Rarotonga', + 'CLST' => 'America/Santiago', + 'CLT' => 'America/Santiago', + 'COST' => 'America/Bogota', + 'COT' => 'America/Bogota', + 'CST' => 'America/Chicago', + 'CT' => 'America/Chicago', + 'CVT' => 'Atlantic/Cape_Verde', + 'CWST' => 'Australia/Eucla', + 'CXT' => 'Indian/Christmas', + 'DAVT' => 'Antarctica/Davis', + 'DDUT' => 'Antarctica/DumontDUrville', + 'DFT' => 'Europe/Paris', + 'EASST' => 'Pacific/Easter', + 'EAST' => 'Pacific/Easter', + 'EAT' => 'Africa/Nairobi', + 'ECT' => 'Europe/Paris', + 'EDT' => 'America/New_York', + 'EEST' => 'Europe/Istanbul', + 'EET' => 'Europe/Istanbul', + 'EGST' => 'Atlantic/Reykjavik', + 'EGT' => 'Atlantic/Reykjavik', + 'EST' => 'America/New_York', + 'ET' => 'America/New_York', + 'FET' => 'Europe/Kaliningrad', + 'FJT' => 'Pacific/Fiji', + 'FKST' => 'Atlantic/Stanley', + 'FKT' => 'Atlantic/Stanley', + 'FNT' => 'America/Noronha', + 'GALT' => 'Pacific/Galapagos', + 'GAMT' => 'Pacific/Gambier', + 'GET' => 'Asia/Tbilisi', + 'GFT' => 'America/Cayenne', + 'GILT' => 'Pacific/Tarawa', + 'GMT' => 'Atlantic/Reykjavik', + 'GST' => 'Asia/Dubai', + 'GYT' => 'America/Guyana', + 'HDT' => 'Pacific/Honolulu', + 'HAEC' => 'Europe/Paris', + 'HST' => 'Pacific/Honolulu', + 'HKT' => 'Asia/Hong_Kong', + 'HMT' => 'Asia/Kolkata', + 'HOVT' => 'Asia/Hovd', + 'ICT' => 'Asia/Bangkok', + 'IDLW' => 'Pacific/Wake', + 'IDT' => 'Asia/Jerusalem', + 'IOT' => 'Indian/Chagos', + 'IRDT' => 'Asia/Tehran', + 'IRKT' => 'Asia/Irkutsk', + 'IRST' => 'Asia/Tehran', + 'IST' => 'Asia/Kolkata', + 'JST' => 'Asia/Tokyo', + 'KALT' => 'Europe/Kaliningrad', + 'KGT' => 'Asia/Bishkek', + 'KOST' => 'Pacific/Kosrae', + 'KRAT' => 'Asia/Krasnoyarsk', + 'KST' => 'Asia/Seoul', + 'LHDT' => 'Australia/Lord_Howe', + 'LINT' => 'Pacific/Kiritimati', + 'MAGT' => 'Asia/Magadan', + 'MART' => 'Pacific/Marquesas', + 'MAWT' => 'Antarctica/Mawson', + 'MDT' => 'America/Denver', + 'MET' => 'Europe/Berlin', + 'MEST' => 'Europe/Berlin', + 'MHT' => 'Pacific/Kwajalein', + 'MIST' => 'Antarctica/Macquarie', + 'MIT' => 'Pacific/Apia', + 'MMT' => 'Asia/Yangon', + 'MSK' => 'Europe/Moscow', + 'MST' => 'America/Denver', + 'MUT' => 'Indian/Mauritius', + 'MVT' => 'Indian/Maldives', + 'MYT' => 'Asia/Kuala_Lumpur', + 'NCT' => 'Pacific/Noumea', + 'NDT' => 'America/St_Johns', + 'NFT' => 'Pacific/Norfolk', + 'NPT' => 'Asia/Kathmandu', + 'NST' => 'America/St_Johns', + 'NT' => 'America/St_Johns', + 'NUT' => 'Pacific/Niue', + 'NZDT' => 'Pacific/Auckland', + 'NZST' => 'Pacific/Auckland', + 'OMST' => 'Asia/Omsk', + 'ORAT' => 'Asia/Oral', + 'PDT' => 'America/Los_Angeles', + 'PETT' => 'Asia/Kamchatka', + 'PHOT' => 'Pacific/Enderbury', + 'PHST' => 'Asia/Manila', + 'PKT' => 'Asia/Karachi', + 'PMDT' => 'America/Miquelon', + 'PMST' => 'America/Miquelon', + 'PONT' => 'Pacific/Pohnpei', + 'PST' => 'America/Los_Angeles', + 'PT' => 'America/Los_Angeles', + 'PYST' => 'America/Asuncion', + 'PYT' => 'America/Asuncion', + 'RET' => 'Indian/Reunion', + 'ROTT' => 'Antarctica/Rothera', + 'SAKT' => 'Asia/Sakhalin', + 'SAMT' => 'Europe/Samara', + 'SAST' => 'Africa/Johannesburg', + 'SBT' => 'Pacific/Guadalcanal', + 'SCT' => 'Indian/Mahe', + 'SGT' => 'Asia/Singapore', + 'SLST' => 'Asia/Colombo', + 'SRET' => 'Asia/Srednekolymsk', + 'SRT' => 'America/Paramaribo', + 'SST' => 'Pacific/Apia', + 'SYOT' => 'Antarctica/Syowa', + 'TAHT' => 'Pacific/Tahiti', + 'THA' => 'Asia/Bangkok', + 'TFT' => 'Indian/Kerguelen', + 'TJT' => 'Asia/Dushanbe', + 'TKT' => 'Pacific/Fakaofo', + 'TLT' => 'Asia/Dili', + 'TMT' => 'Asia/Ashgabat', + 'TOT' => 'Pacific/Tongatapu', + 'TVT' => 'Pacific/Funafuti', + 'ULAST' => 'Asia/Ulaanbaatar', + 'ULAT' => 'Asia/Ulaanbaatar', + 'UYST' => 'America/Montevideo', + 'UYT' => 'America/Montevideo', + 'UZT' => 'Asia/Tashkent', + 'VET' => 'America/Caracas', + 'VLAT' => 'Asia/Vladivostok', + 'VOLT' => 'Europe/Volgograd', + 'VOST' => 'Antarctica/Vostok', + 'VUT' => 'Pacific/Efate', + 'WAKT' => 'Pacific/Wake', + 'WAST' => 'Africa/Windhoek', + 'WAT' => 'Africa/Lagos', + 'WEST' => 'Europe/Lisbon', + 'WET' => 'Europe/Lisbon', + 'WIT' => 'Asia/Jayapura', + 'WGST' => 'America/Godthab', + 'WGT' => 'America/Godthab', + 'WST' => 'Australia/Perth', + 'YAKT' => 'Asia/Yakutsk', + 'YEKT' => 'Asia/Yekaterinburg', + ]; + + public function translateFromWindowsString(string $source): string + { + return $this->windows[$source] ?? 'UTC'; + } + + public function translateFromAbbreviatedString(string $source): string + { + return $this->nix[$source] ?? 'UTC'; + } +} diff --git a/src/System.php b/src/System.php index 65a2c0c..ba0f6ae 100644 --- a/src/System.php +++ b/src/System.php @@ -4,6 +4,7 @@ use Native\Laravel\Client\Client; use Native\Laravel\DataObjects\Printer; +use Native\Laravel\Support\Timezones; class System { @@ -56,4 +57,17 @@ public function printToPDF(string $html): string 'html' => $html, ])->json('result'); } + + public function timezone(): string + { + $timezones = new Timezones(); + + if (PHP_OS_FAMILY === 'Windows') { + $timezone = $timezones->translateFromWindowsString(exec('tzutil /g')); + } else { + $timezone = $timezones->translateFromAbbreviatedString(exec('date +%Z')); + } + + return $timezone; + } } From a65f716f5c87d4ef010e52eac42037649eda6edc Mon Sep 17 00:00:00 2001 From: simonhamp Date: Wed, 17 Jul 2024 23:11:07 +0000 Subject: [PATCH 078/224] Fix styling --- src/App.php | 4 +--- src/Clipboard.php | 4 +--- src/ContextMenu.php | 4 +--- src/DataObjects/Printer.php | 4 +--- src/Dialog.php | 4 +--- src/Dock.php | 4 +--- src/Events/App/ApplicationBooted.php | 5 +---- src/Events/App/OpenFile.php | 5 +---- src/Events/App/OpenedFromURL.php | 5 +---- src/Events/Menu/MenuItemClicked.php | 4 +--- src/Events/MenuBar/MenuBarDroppedFiles.php | 4 +--- src/Events/Settings/SettingChanged.php | 5 +---- src/Events/Windows/WindowClosed.php | 4 +--- src/GlobalShortcut.php | 4 +--- src/Logging/LogWatcher.php | 5 +---- src/Menu/Items/Event.php | 5 +---- src/Menu/Items/Link.php | 5 +---- src/Menu/Items/Role.php | 5 +---- src/Menu/Menu.php | 4 +--- src/MenuBar/MenuBarManager.php | 5 +---- src/Notification.php | 4 +--- src/Process.php | 4 +--- src/ProgressBar.php | 4 +--- src/Screen.php | 4 +--- src/Settings.php | 4 +--- src/Shell.php | 4 +--- src/System.php | 4 +--- src/Windows/WindowManager.php | 5 +---- tests/Http/Controller/DispatchEventFromAppControllerTest.php | 5 +---- tests/Http/Controller/NativeAppBootedControllerTest.php | 5 +---- 30 files changed, 30 insertions(+), 102 deletions(-) diff --git a/src/App.php b/src/App.php index 15fba4e..81f1a26 100644 --- a/src/App.php +++ b/src/App.php @@ -6,9 +6,7 @@ class App { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function focus(): void { diff --git a/src/Clipboard.php b/src/Clipboard.php index a6d7326..22884bc 100644 --- a/src/Clipboard.php +++ b/src/Clipboard.php @@ -6,9 +6,7 @@ class Clipboard { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function clear() { diff --git a/src/ContextMenu.php b/src/ContextMenu.php index e0e8fa7..d56690e 100644 --- a/src/ContextMenu.php +++ b/src/ContextMenu.php @@ -7,9 +7,7 @@ class ContextMenu { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function register(Menu $menu) { diff --git a/src/DataObjects/Printer.php b/src/DataObjects/Printer.php index 30795a8..ba7d054 100644 --- a/src/DataObjects/Printer.php +++ b/src/DataObjects/Printer.php @@ -11,7 +11,5 @@ public function __construct( public int $status, public bool $isDefault, public array $options - ) { - - } + ) {} } diff --git a/src/Dialog.php b/src/Dialog.php index 153976f..a217b56 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -26,9 +26,7 @@ class Dialog protected $windowReference; - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public static function new() { diff --git a/src/Dock.php b/src/Dock.php index 63a7a49..dbd091d 100644 --- a/src/Dock.php +++ b/src/Dock.php @@ -7,9 +7,7 @@ class Dock { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function menu(Menu $menu) { diff --git a/src/Events/App/ApplicationBooted.php b/src/Events/App/ApplicationBooted.php index b87d645..f455a9f 100644 --- a/src/Events/App/ApplicationBooted.php +++ b/src/Events/App/ApplicationBooted.php @@ -10,8 +10,5 @@ class ApplicationBooted { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct() - { - - } + public function __construct() {} } diff --git a/src/Events/App/OpenFile.php b/src/Events/App/OpenFile.php index 9753e73..2f09572 100644 --- a/src/Events/App/OpenFile.php +++ b/src/Events/App/OpenFile.php @@ -12,10 +12,7 @@ class OpenFile implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public $path) - { - - } + public function __construct(public $path) {} public function broadcastOn() { diff --git a/src/Events/App/OpenedFromURL.php b/src/Events/App/OpenedFromURL.php index 596db3f..d89d81f 100644 --- a/src/Events/App/OpenedFromURL.php +++ b/src/Events/App/OpenedFromURL.php @@ -12,10 +12,7 @@ class OpenedFromURL implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public $url) - { - - } + public function __construct(public $url) {} public function broadcastOn() { diff --git a/src/Events/Menu/MenuItemClicked.php b/src/Events/Menu/MenuItemClicked.php index 2a2a456..d9daa74 100644 --- a/src/Events/Menu/MenuItemClicked.php +++ b/src/Events/Menu/MenuItemClicked.php @@ -12,9 +12,7 @@ class MenuItemClicked implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public array $item) - { - } + public function __construct(public array $item) {} public function broadcastOn() { diff --git a/src/Events/MenuBar/MenuBarDroppedFiles.php b/src/Events/MenuBar/MenuBarDroppedFiles.php index e9937c4..d040f9e 100644 --- a/src/Events/MenuBar/MenuBarDroppedFiles.php +++ b/src/Events/MenuBar/MenuBarDroppedFiles.php @@ -12,9 +12,7 @@ class MenuBarDroppedFiles implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public array $files = []) - { - } + public function __construct(public array $files = []) {} public function broadcastOn() { diff --git a/src/Events/Settings/SettingChanged.php b/src/Events/Settings/SettingChanged.php index 47fdfef..a447db4 100644 --- a/src/Events/Settings/SettingChanged.php +++ b/src/Events/Settings/SettingChanged.php @@ -12,10 +12,7 @@ class SettingChanged implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public string $key, public mixed $value) - { - - } + public function __construct(public string $key, public mixed $value) {} public function broadcastOn() { diff --git a/src/Events/Windows/WindowClosed.php b/src/Events/Windows/WindowClosed.php index 48d1b1b..512b4c2 100644 --- a/src/Events/Windows/WindowClosed.php +++ b/src/Events/Windows/WindowClosed.php @@ -12,9 +12,7 @@ class WindowClosed implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public string $id) - { - } + public function __construct(public string $id) {} public function broadcastOn() { diff --git a/src/GlobalShortcut.php b/src/GlobalShortcut.php index 24020cf..991c341 100644 --- a/src/GlobalShortcut.php +++ b/src/GlobalShortcut.php @@ -10,9 +10,7 @@ class GlobalShortcut protected string $event; - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function key(string $key): self { diff --git a/src/Logging/LogWatcher.php b/src/Logging/LogWatcher.php index 650882b..e48eaf4 100644 --- a/src/Logging/LogWatcher.php +++ b/src/Logging/LogWatcher.php @@ -8,10 +8,7 @@ class LogWatcher { - public function __construct(protected Client $client) - { - - } + public function __construct(protected Client $client) {} public function register(): void { diff --git a/src/Menu/Items/Event.php b/src/Menu/Items/Event.php index 178349c..02af55e 100644 --- a/src/Menu/Items/Event.php +++ b/src/Menu/Items/Event.php @@ -4,10 +4,7 @@ class Event extends MenuItem { - public function __construct(protected string $event, protected ?string $label, protected ?string $accelerator = null) - { - - } + public function __construct(protected string $event, protected ?string $label, protected ?string $accelerator = null) {} public function toArray(): array { diff --git a/src/Menu/Items/Link.php b/src/Menu/Items/Link.php index 684cb7e..ec5a1cd 100644 --- a/src/Menu/Items/Link.php +++ b/src/Menu/Items/Link.php @@ -6,10 +6,7 @@ class Link extends MenuItem { protected string $type = 'link'; - public function __construct(protected string $url, protected ?string $label, protected ?string $accelerator = null) - { - - } + public function __construct(protected string $url, protected ?string $label, protected ?string $accelerator = null) {} public function toArray(): array { diff --git a/src/Menu/Items/Role.php b/src/Menu/Items/Role.php index c8a04bd..3fa3b24 100644 --- a/src/Menu/Items/Role.php +++ b/src/Menu/Items/Role.php @@ -8,10 +8,7 @@ class Role extends MenuItem { protected string $type = 'role'; - public function __construct(protected RolesEnum $role, protected ?string $label = '') - { - - } + public function __construct(protected RolesEnum $role, protected ?string $label = '') {} public function toArray(): array { diff --git a/src/Menu/Menu.php b/src/Menu/Menu.php index 7709a41..379b4e2 100644 --- a/src/Menu/Menu.php +++ b/src/Menu/Menu.php @@ -21,9 +21,7 @@ class Menu implements MenuItem protected string $prepend = ''; - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public static function new(): static { diff --git a/src/MenuBar/MenuBarManager.php b/src/MenuBar/MenuBarManager.php index a7877ae..3101f2b 100644 --- a/src/MenuBar/MenuBarManager.php +++ b/src/MenuBar/MenuBarManager.php @@ -7,10 +7,7 @@ class MenuBarManager { - public function __construct(protected Client $client) - { - - } + public function __construct(protected Client $client) {} public function create() { diff --git a/src/Notification.php b/src/Notification.php index fd4d023..18d27af 100644 --- a/src/Notification.php +++ b/src/Notification.php @@ -12,9 +12,7 @@ class Notification protected string $event = ''; - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public static function new() { diff --git a/src/Process.php b/src/Process.php index 7a189f9..a78d983 100644 --- a/src/Process.php +++ b/src/Process.php @@ -6,9 +6,7 @@ class Process { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function arch(): string { diff --git a/src/ProgressBar.php b/src/ProgressBar.php index b4a6760..0f0c29b 100644 --- a/src/ProgressBar.php +++ b/src/ProgressBar.php @@ -16,9 +16,7 @@ class ProgressBar protected float $maxSecondsBetweenRedraws = 1; - public function __construct(protected int $maxSteps, protected Client $client) - { - } + public function __construct(protected int $maxSteps, protected Client $client) {} public static function create(int $maxSteps): static { diff --git a/src/Screen.php b/src/Screen.php index b0f4e7f..dfd98bb 100644 --- a/src/Screen.php +++ b/src/Screen.php @@ -6,9 +6,7 @@ class Screen { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function cursorPosition(): object { diff --git a/src/Settings.php b/src/Settings.php index 0c7b6ee..68e65b5 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -6,9 +6,7 @@ class Settings { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function set($key, $value): void { diff --git a/src/Shell.php b/src/Shell.php index 38dedca..9389321 100644 --- a/src/Shell.php +++ b/src/Shell.php @@ -6,9 +6,7 @@ class Shell { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function showInFolder(string $path): void { diff --git a/src/System.php b/src/System.php index ba0f6ae..c750886 100644 --- a/src/System.php +++ b/src/System.php @@ -8,9 +8,7 @@ class System { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function canPromptTouchID(): bool { diff --git a/src/Windows/WindowManager.php b/src/Windows/WindowManager.php index 4a622b7..ca227e3 100644 --- a/src/Windows/WindowManager.php +++ b/src/Windows/WindowManager.php @@ -9,10 +9,7 @@ class WindowManager { use DetectsWindowId; - public function __construct(protected Client $client) - { - - } + public function __construct(protected Client $client) {} public function open(string $id = 'main') { diff --git a/tests/Http/Controller/DispatchEventFromAppControllerTest.php b/tests/Http/Controller/DispatchEventFromAppControllerTest.php index 278c414..7361a92 100644 --- a/tests/Http/Controller/DispatchEventFromAppControllerTest.php +++ b/tests/Http/Controller/DispatchEventFromAppControllerTest.php @@ -4,10 +4,7 @@ class TestEvent { - public function __construct(public string $test = '') - { - - } + public function __construct(public string $test = '') {} } it('dispatches an event', function () { diff --git a/tests/Http/Controller/NativeAppBootedControllerTest.php b/tests/Http/Controller/NativeAppBootedControllerTest.php index f8e9648..0a9bc7f 100644 --- a/tests/Http/Controller/NativeAppBootedControllerTest.php +++ b/tests/Http/Controller/NativeAppBootedControllerTest.php @@ -5,10 +5,7 @@ class TestProvider { - public function boot() - { - - } + public function boot() {} } it('boots the NativePHP provider', function () { From 11277b5fb648031234efbe20f782590aa5c1ab1d Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 01:36:13 +0100 Subject: [PATCH 079/224] Fix native:migrate:fresh --- src/Commands/FreshCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Commands/FreshCommand.php b/src/Commands/FreshCommand.php index add5c32..875b5ff 100644 --- a/src/Commands/FreshCommand.php +++ b/src/Commands/FreshCommand.php @@ -7,9 +7,9 @@ class FreshCommand extends BaseFreshCommand { - protected $description = 'Drop all tables and re-run all migrations in the NativePHP development environment'; + protected $name = 'native:migrate:fresh'; - protected $signature = 'native:migrate:fresh'; + protected $description = 'Drop all tables and re-run all migrations in the NativePHP development environment'; public function handle() { From a04d13fe69fdda8a934066209a80e2be19628fe7 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 01:41:52 +0100 Subject: [PATCH 080/224] Fully fix native:migrate:fresh --- src/Commands/FreshCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Commands/FreshCommand.php b/src/Commands/FreshCommand.php index 875b5ff..96746c6 100644 --- a/src/Commands/FreshCommand.php +++ b/src/Commands/FreshCommand.php @@ -19,6 +19,6 @@ public function handle() $nativeServiceProvider->rewriteDatabase(); - $this->call('native:migrate'); + return parent::handle(); } } From 39342eeac42eae0b7a05373a907be17417ff3c72 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 02:17:20 +0100 Subject: [PATCH 081/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 5062711..bf906d4 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,5 +1,5 @@ name: Bug Report -description: "Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the debugging steps: https://nativephp.com/docs/getting-started/debugging" +description: "Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the [debugging steps](https://nativephp.com/docs/getting-started/debugging)" labels: ["bug"] body: - type: markdown From 13f991edd7530f91244aa262f90256ef59b5284d Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 02:17:56 +0100 Subject: [PATCH 082/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index bf906d4..4b0f394 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,5 +1,5 @@ name: Bug Report -description: "Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the [debugging steps](https://nativephp.com/docs/getting-started/debugging)" +description: "Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the debugging stepshttps://nativephp.com/docs/getting-started/debugging" labels: ["bug"] body: - type: markdown From 20eaa2dce0bd69f16a98c1adaad861bf10ae0b0e Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 02:18:20 +0100 Subject: [PATCH 083/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 4b0f394..54edf13 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,5 +1,5 @@ name: Bug Report -description: "Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the debugging stepshttps://nativephp.com/docs/getting-started/debugging" +description: "Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the debugging stepshttps://nativephp.com/docs/getting-started/debugging" labels: ["bug"] body: - type: markdown From 2afc115a1cb0f4cf5d3b0c70f8f310fa16e3ca53 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 02:20:36 +0100 Subject: [PATCH 084/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 54edf13..ca5c9fb 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,5 +1,7 @@ name: Bug Report -description: "Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the debugging stepshttps://nativephp.com/docs/getting-started/debugging" +description: | + Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the + section "[Debugging](https://nativephp.com/docs/getting-started/debugging)" on nativephp.com labels: ["bug"] body: - type: markdown From 536e600bbf1f03030fb37a20bbdd6b5b65614a4a Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 02:22:01 +0100 Subject: [PATCH 085/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index ca5c9fb..0796a56 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,7 +1,6 @@ name: Bug Report description: | - Report an issue or bug in NativePHP. Before submitting your report, please make sure you've been through the - section "[Debugging](https://nativephp.com/docs/getting-started/debugging)" on nativephp.com + Found a bug in NativePHP? Before submitting your report, please make sure you've been through the section "[Debugging](https://nativephp.com/docs/getting-started/debugging)" on nativephp.com labels: ["bug"] body: - type: markdown From c43de4923ac8ec521588289ff29bd7af4ca7a2f1 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 02:24:22 +0100 Subject: [PATCH 086/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 0796a56..03980f2 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,6 +1,6 @@ name: Bug Report description: | - Found a bug in NativePHP? Before submitting your report, please make sure you've been through the section "[Debugging](https://nativephp.com/docs/getting-started/debugging)" on nativephp.com + Found a bug in NativePHP? Before submitting your report, please make sure you've been through the section "Debugging" in the docs: https://nativephp.com/docs/getting-started/debugging. labels: ["bug"] body: - type: markdown From 1746e3db7e6d628e2fa74ab1a6237f3b6d8b22c3 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Thu, 18 Jul 2024 03:16:29 +0000 Subject: [PATCH 087/224] Update CHANGELOG --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eb8f57..7e2e090 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.5.3 - 2024-07-18 + +### What's Changed + +* Add the reload() method to the WindowManager by @shomisha in https://github.com/NativePHP/laravel/pull/294 +* Add `trafficLightPosition()` method on Window by @sarukomine in https://github.com/NativePHP/laravel/pull/310 +* Add a new `System::timezone` helper to detect and normalise system time zone data +* Fix `native:migrate:fresh` so that it behaves more like Laravel's `migrate:fresh` (e.g. you can use seeders etc) +* Bump dependabot/fetch-metadata from 2.1.0 to 2.2.0 by @dependabot in https://github.com/NativePHP/laravel/pull/333 + +### New Contributors + +* @shomisha made their first contribution in https://github.com/NativePHP/laravel/pull/294 +* @sarukomine made their first contribution in https://github.com/NativePHP/laravel/pull/310 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.5.2...0.5.3 + ## 0.5.2 - 2024-05-02 ### What's Changed From 047c774013fe3c1fad9b9b04870bb570973467c2 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 18 Jul 2024 05:07:20 +0100 Subject: [PATCH 088/224] docblocks --- src/Facades/System.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Facades/System.php b/src/Facades/System.php index 31ff684..b420368 100644 --- a/src/Facades/System.php +++ b/src/Facades/System.php @@ -7,6 +7,10 @@ /** * @method static bool canPromptTouchID() * @method static bool promptTouchID(string $reason) + * @method static array printers() + * @method static void print(string $html, ?\Native\Laravel\DataObjects\Printer $printer = null) + * @method static string printToPDF(string $reason) + * @method static string timezone() */ class System extends Facade { From 1fdd34b1bba7d496a164885bf1592fb91140796c Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 7 Aug 2024 22:59:30 +0100 Subject: [PATCH 089/224] Add fullscreenable support (#340) * Add fullscreenable support * Fix styling * Change default parameter value --------- Co-authored-by: simonhamp --- src/Commands/MinifyApplicationCommand.php | 2 +- src/Dialog.php | 2 +- src/Http/Controllers/NativeAppBootedController.php | 2 +- src/Menu/Menu.php | 4 ++-- src/MenuBar/MenuBarManager.php | 2 +- src/Notification.php | 2 +- src/ProgressBar.php | 2 +- src/System.php | 2 +- src/Windows/Window.php | 12 +++++++++++- 9 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php index 5b7373c..37d8378 100644 --- a/src/Commands/MinifyApplicationCommand.php +++ b/src/Commands/MinifyApplicationCommand.php @@ -26,7 +26,7 @@ public function handle() $this->cleanUpEnvFile($appPath); $this->removeIgnoredFilesAndFolders($appPath); - $compactor = new Php(); + $compactor = new Php; $phpFiles = Finder::create() ->files() diff --git a/src/Dialog.php b/src/Dialog.php index a217b56..223c853 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -30,7 +30,7 @@ public function __construct(protected Client $client) {} public static function new() { - return new static(new Client()); + return new static(new Client); } public function title(string $title): self diff --git a/src/Http/Controllers/NativeAppBootedController.php b/src/Http/Controllers/NativeAppBootedController.php index 8d56bc5..36ed735 100644 --- a/src/Http/Controllers/NativeAppBootedController.php +++ b/src/Http/Controllers/NativeAppBootedController.php @@ -12,7 +12,7 @@ public function __invoke(Request $request) $provider = app(config('nativephp.provider')); $provider->boot(); - event(new ApplicationBooted()); + event(new ApplicationBooted); return response()->json([ 'success' => true, diff --git a/src/Menu/Menu.php b/src/Menu/Menu.php index 379b4e2..47a81b0 100644 --- a/src/Menu/Menu.php +++ b/src/Menu/Menu.php @@ -25,7 +25,7 @@ public function __construct(protected Client $client) {} public static function new(): static { - return new static(new Client()); + return new static(new Client); } public function register(): void @@ -51,7 +51,7 @@ public function submenu(string $header, Menu $submenu): static public function separator(): static { - return $this->add(new Separator()); + return $this->add(new Separator); } public function quit(): static diff --git a/src/MenuBar/MenuBarManager.php b/src/MenuBar/MenuBarManager.php index 3101f2b..04aedb0 100644 --- a/src/MenuBar/MenuBarManager.php +++ b/src/MenuBar/MenuBarManager.php @@ -11,7 +11,7 @@ public function __construct(protected Client $client) {} public function create() { - return (new PendingCreateMenuBar())->setClient($this->client); + return (new PendingCreateMenuBar)->setClient($this->client); } public function show() diff --git a/src/Notification.php b/src/Notification.php index 18d27af..85c7a73 100644 --- a/src/Notification.php +++ b/src/Notification.php @@ -16,7 +16,7 @@ public function __construct(protected Client $client) {} public static function new() { - return new static(new Client()); + return new static(new Client); } public function title(string $title): self diff --git a/src/ProgressBar.php b/src/ProgressBar.php index 0f0c29b..74ca9d7 100644 --- a/src/ProgressBar.php +++ b/src/ProgressBar.php @@ -20,7 +20,7 @@ public function __construct(protected int $maxSteps, protected Client $client) { public static function create(int $maxSteps): static { - return new static($maxSteps, new Client()); + return new static($maxSteps, new Client); } public function start() diff --git a/src/System.php b/src/System.php index c750886..5535368 100644 --- a/src/System.php +++ b/src/System.php @@ -58,7 +58,7 @@ public function printToPDF(string $html): string public function timezone(): string { - $timezones = new Timezones(); + $timezones = new Timezones; if (PHP_OS_FAMILY === 'Windows') { $timezone = $timezones->translateFromWindowsString(exec('tzutil /g')); diff --git a/src/Windows/Window.php b/src/Windows/Window.php index 2348577..67308af 100644 --- a/src/Windows/Window.php +++ b/src/Windows/Window.php @@ -17,6 +17,8 @@ class Window protected bool $fullscreen = false; + protected bool $fullscreenable = true; + protected bool $kiosk = false; protected $rememberState = false; @@ -202,13 +204,20 @@ public function hideMenu($autoHideMenuBar = true): static return $this; } - public function fullscreen($fullscreen = false): static + public function fullscreen($fullscreen = true): static { $this->fullscreen = $fullscreen; return $this; } + public function fullscreenable($fullscreenable = true): static + { + $this->fullscreenable = $fullscreenable; + + return $this; + } + public function kiosk($kiosk = false): static { $this->kiosk = $kiosk; @@ -247,6 +256,7 @@ public function toArray() 'closable' => $this->closable, 'title' => $this->title, 'fullscreen' => $this->fullscreen, + 'fullscreenable' => $this->fullscreenable, 'kiosk' => $this->kiosk, 'autoHideMenuBar' => $this->autoHideMenuBar, ]; From eff3a78cc38e271468c72f5b5e37e2ff14ef8268 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 8 Aug 2024 08:51:23 +0100 Subject: [PATCH 090/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 03980f2..e84c04c 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -35,7 +35,7 @@ body: id: package-version attributes: label: Package Versions - description: What versions of the NativePHP packages are you running? Output of `composer show nativephp/* --format=json` + description: What versions of the NativePHP packages are you running? Output of `composer show "nativephp/*" --format=json` validations: required: true - type: input From 7397d15e3ddc2d14c84ea096147f6140bc4473ba Mon Sep 17 00:00:00 2001 From: Robert Wesner Date: Sat, 24 Aug 2024 00:38:03 +0200 Subject: [PATCH 091/224] Implemented minimizing (#347) --- src/Facades/Window.php | 2 ++ src/Windows/WindowManager.php | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/Facades/Window.php b/src/Facades/Window.php index 439d25f..75efc45 100644 --- a/src/Facades/Window.php +++ b/src/Facades/Window.php @@ -12,6 +12,8 @@ * @method static void position($x, $y, $animated = false, $id = null) * @method static void alwaysOnTop($alwaysOnTop = true, $id = null) * @method static void reload($id = null) + * @method static void maximize($id = null) + * @method static void minimize($id = null) */ class Window extends Facade { diff --git a/src/Windows/WindowManager.php b/src/Windows/WindowManager.php index ca227e3..9378c5f 100644 --- a/src/Windows/WindowManager.php +++ b/src/Windows/WindowManager.php @@ -69,6 +69,13 @@ public function maximize($id = null): void ]); } + public function minimize($id = null): void + { + $this->client->post('window/minimize', [ + 'id' => $id ?? $this->detectId(), + ]); + } + public function reload($id = null): void { $this->client->post('window/reload', [ From 54461562d53ef7e519ec72cb62eabd0b64450eaf Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sat, 24 Aug 2024 11:20:20 +0100 Subject: [PATCH 092/224] Fluent API for opening windows maximized/minimized (#349) --- src/Windows/PendingOpenWindow.php | 4 ++++ src/Windows/Window.php | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/Windows/PendingOpenWindow.php b/src/Windows/PendingOpenWindow.php index 46175d4..5027953 100644 --- a/src/Windows/PendingOpenWindow.php +++ b/src/Windows/PendingOpenWindow.php @@ -12,5 +12,9 @@ public function __destruct() protected function open(): void { $this->client->post('window/open', $this->toArray()); + + foreach ($this->afterOpenCallbacks as $cb) { + $cb($this); + } } } diff --git a/src/Windows/Window.php b/src/Windows/Window.php index 67308af..a96fd2b 100644 --- a/src/Windows/Window.php +++ b/src/Windows/Window.php @@ -6,6 +6,7 @@ use Native\Laravel\Concerns\HasDimensions; use Native\Laravel\Concerns\HasUrl; use Native\Laravel\Concerns\HasVibrancy; +use Native\Laravel\Facades\Window as WindowFacade; class Window { @@ -53,6 +54,8 @@ class Window protected Client $client; + protected array $afterOpenCallbacks = []; + public function __construct(string $id) { $this->id = $id; @@ -181,6 +184,16 @@ public function maximizable($maximizable = true): static return $this; } + public function minimized(): static + { + $this->afterOpen(fn () => WindowFacade::minimize($this->id)); + } + + public function maximized(): static + { + $this->afterOpen(fn () => WindowFacade::maximize($this->id)); + } + public function closable($closable = true): static { $this->closable = $closable; @@ -261,4 +274,11 @@ public function toArray() 'autoHideMenuBar' => $this->autoHideMenuBar, ]; } + + public function afterOpen(callable $cb): static + { + $this->afterOpenCallbacks[] = $cb; + + return $this; + } } From 1c4d2f8e52b50c8f7f97ba1f5198c9a4749a600c Mon Sep 17 00:00:00 2001 From: simonhamp Date: Sat, 24 Aug 2024 10:21:34 +0000 Subject: [PATCH 093/224] Update CHANGELOG --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e2e090..ea88fcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.5.4 - 2024-08-24 + +### What's Changed + +* Add fullscreenable support by @simonhamp in https://github.com/NativePHP/laravel/pull/340 +* Implemented minimizing by @RobertWesner in https://github.com/NativePHP/laravel/pull/347 +* Fluent API for opening windows maximized/minimized by @simonhamp in https://github.com/NativePHP/laravel/pull/349 + +### New Contributors + +* @RobertWesner made their first contribution in https://github.com/NativePHP/laravel/pull/347 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.5.3...0.5.4 + ## 0.5.3 - 2024-07-18 ### What's Changed From 6d7b038d2e085bcb43d9d98e397926cca7d60e05 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 2 Sep 2024 13:04:44 +0100 Subject: [PATCH 094/224] Battery/AC power, plus more (#355) * feat: create enum for thermal states * feat: create enum for SystemIdleStates * feat: create PowerMonitor class * feat: create facade wrapper * feat: create enum for power states * feat: create events for PowerMonitor * Fix styling --- src/Enums/PowerStatesEnum.php | 9 +++++ src/Enums/SystemIdleStatesEnum.php | 11 ++++++ src/Enums/ThermalStatesEnum.php | 12 ++++++ src/Events/PowerMonitor/PowerStateChanged.php | 29 ++++++++++++++ src/Events/PowerMonitor/SpeedLimitChanged.php | 28 ++++++++++++++ .../PowerMonitor/ThermalStateChanged.php | 29 ++++++++++++++ src/Facades/PowerMonitor.php | 19 ++++++++++ src/PowerMonitor.php | 38 +++++++++++++++++++ 8 files changed, 175 insertions(+) create mode 100644 src/Enums/PowerStatesEnum.php create mode 100644 src/Enums/SystemIdleStatesEnum.php create mode 100644 src/Enums/ThermalStatesEnum.php create mode 100644 src/Events/PowerMonitor/PowerStateChanged.php create mode 100644 src/Events/PowerMonitor/SpeedLimitChanged.php create mode 100644 src/Events/PowerMonitor/ThermalStateChanged.php create mode 100644 src/Facades/PowerMonitor.php create mode 100644 src/PowerMonitor.php diff --git a/src/Enums/PowerStatesEnum.php b/src/Enums/PowerStatesEnum.php new file mode 100644 index 0000000..b1996fb --- /dev/null +++ b/src/Enums/PowerStatesEnum.php @@ -0,0 +1,9 @@ +state = PowerStatesEnum::from($state); + } + + public function broadcastOn() + { + return [ + new Channel('nativephp'), + ]; + } +} diff --git a/src/Events/PowerMonitor/SpeedLimitChanged.php b/src/Events/PowerMonitor/SpeedLimitChanged.php new file mode 100644 index 0000000..9b3e3b0 --- /dev/null +++ b/src/Events/PowerMonitor/SpeedLimitChanged.php @@ -0,0 +1,28 @@ +limit = (int) $limit; + } + + public function broadcastOn() + { + return [ + new Channel('nativephp'), + ]; + } +} diff --git a/src/Events/PowerMonitor/ThermalStateChanged.php b/src/Events/PowerMonitor/ThermalStateChanged.php new file mode 100644 index 0000000..bed0583 --- /dev/null +++ b/src/Events/PowerMonitor/ThermalStateChanged.php @@ -0,0 +1,29 @@ +state = ThermalStatesEnum::from($state); + } + + public function broadcastOn() + { + return [ + new Channel('nativephp'), + ]; + } +} diff --git a/src/Facades/PowerMonitor.php b/src/Facades/PowerMonitor.php new file mode 100644 index 0000000..5233856 --- /dev/null +++ b/src/Facades/PowerMonitor.php @@ -0,0 +1,19 @@ +client->get('power-monitor/get-system-idle-state', [ + 'threshold' => $threshold, + ])->json('result'); + + return SystemIdleStatesEnum::tryFrom($result) ?? SystemIdleStatesEnum::UNKNOWN; + } + + public function getSystemIdleTime(): int + { + return $this->client->get('power-monitor/get-system-idle-time')->json('result'); + } + + public function getCurrentThermalState(): ThermalStatesEnum + { + $result = $this->client->get('power-monitor/get-current-thermal-state')->json('result'); + + return ThermalStatesEnum::tryFrom($result) ?? ThermalStatesEnum::UNKNOWN; + } + + public function isOnBatteryPower(): bool + { + return $this->client->get('power-monitor/is-on-battery-power')->json('result'); + } +} From 5385347d78a748569c9ade7d11ccb2135d0430d4 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Mon, 2 Sep 2024 15:05:50 +0100 Subject: [PATCH 095/224] Safe storage (#357) * Add safe storage methods * fix --- src/Facades/System.php | 3 +++ src/System.php | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/Facades/System.php b/src/Facades/System.php index b420368..088ce1d 100644 --- a/src/Facades/System.php +++ b/src/Facades/System.php @@ -7,6 +7,9 @@ /** * @method static bool canPromptTouchID() * @method static bool promptTouchID(string $reason) + * @method static bool canEncrypt() + * @method static string encrypt(string $string) + * @method static string decrypt(string $string) * @method static array printers() * @method static void print(string $html, ?\Native\Laravel\DataObjects\Printer $printer = null) * @method static string printToPDF(string $reason) diff --git a/src/System.php b/src/System.php index 5535368..b6c7e07 100644 --- a/src/System.php +++ b/src/System.php @@ -22,6 +22,25 @@ public function promptTouchID(string $reason): bool ])->successful(); } + public function canEncrypt(): bool + { + return $this->client->get('system/can-encrypt')->json('result'); + } + + public function encrypt(string $string): ?string + { + return $this->client->post('system/encrypt', [ + 'string' => $string, + ])->json('result'); + } + + public function decrypt(string $string): ?string + { + return $this->client->post('system/decrypt', [ + 'string' => $string, + ])->json('result'); + } + /** * @return array<\Native\Laravel\DataObjects\Printer> */ From 41692119471d84984feeca1e7838022136551b43 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Mon, 2 Sep 2024 14:09:57 +0000 Subject: [PATCH 096/224] Update CHANGELOG --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea88fcf..8f1d584 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.5.5 - 2024-09-02 + +### What's Changed + +* Battery/AC power, plus more by @danjohnson95 in https://github.com/NativePHP/laravel/pull/355 +* Safe storage by @simonhamp in https://github.com/NativePHP/laravel/pull/357 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.5.4...0.5.5 + ## 0.5.4 - 2024-08-24 ### What's Changed From 2d1a4333b4c3a3dd37c910932117994aad230dd9 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 4 Sep 2024 12:40:21 +0100 Subject: [PATCH 097/224] Create SECURITY.md --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..da9c516 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +## Security contact information + +To report a security vulnerability, please use the +[Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. From 9afd7db857f78855051f8507c97707a1cca82076 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 4 Sep 2024 13:19:45 +0100 Subject: [PATCH 098/224] Fix chainable (#360) --- src/Windows/Window.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Windows/Window.php b/src/Windows/Window.php index a96fd2b..fa958bd 100644 --- a/src/Windows/Window.php +++ b/src/Windows/Window.php @@ -186,12 +186,12 @@ public function maximizable($maximizable = true): static public function minimized(): static { - $this->afterOpen(fn () => WindowFacade::minimize($this->id)); + return $this->afterOpen(fn () => WindowFacade::minimize($this->id)); } public function maximized(): static { - $this->afterOpen(fn () => WindowFacade::maximize($this->id)); + return $this->afterOpen(fn () => WindowFacade::maximize($this->id)); } public function closable($closable = true): static From 949a06e73c0e9f7cb49dee78ae6f544f6b2bd380 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 8 Sep 2024 15:34:30 +0100 Subject: [PATCH 099/224] Add docblock to facade Helps with IDE support --- src/Facades/Shell.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Facades/Shell.php b/src/Facades/Shell.php index aa5f7c1..27c8b03 100644 --- a/src/Facades/Shell.php +++ b/src/Facades/Shell.php @@ -4,6 +4,12 @@ use Illuminate\Support\Facades\Facade; +/** + * @method static void showInFolder(string $path) + * @method static string openFile(string $path) + * @method static void trashFile(string $path) + * @method static void openExternal(string $url) + */ class Shell extends Facade { protected static function getFacadeAccessor() From cc11cebb9c291cb7e50abea17278f99299fee8ab Mon Sep 17 00:00:00 2001 From: Robert Wesner Date: Sun, 8 Sep 2024 19:15:38 +0200 Subject: [PATCH 100/224] Fixed Tests (#362) --- src/Windows/Window.php | 1 + .../DispatchEventFromAppControllerTest.php | 7 ++++--- tests/Windows/WindowTest.php | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Windows/Window.php b/src/Windows/Window.php index fa958bd..cc430ca 100644 --- a/src/Windows/Window.php +++ b/src/Windows/Window.php @@ -272,6 +272,7 @@ public function toArray() 'fullscreenable' => $this->fullscreenable, 'kiosk' => $this->kiosk, 'autoHideMenuBar' => $this->autoHideMenuBar, + 'transparent' => $this->transparent, ]; } diff --git a/tests/Http/Controller/DispatchEventFromAppControllerTest.php b/tests/Http/Controller/DispatchEventFromAppControllerTest.php index 7361a92..39b2dcf 100644 --- a/tests/Http/Controller/DispatchEventFromAppControllerTest.php +++ b/tests/Http/Controller/DispatchEventFromAppControllerTest.php @@ -19,15 +19,16 @@ public function __construct(public string $test = '') {} Event::assertDispatched(TestEvent::class); }); -it('dispatches no event in case it does not exist', function () { +// Since 45b7ccfcb86ebf35be35c1eb7fbb9f05a224448f nonexistent classes are handled as string events +it('dispatches a string event', function () { Event::fake(); $this->withoutMiddleware() ->post('_native/api/events', [ - 'event' => InvalidEvent::class, + 'event' => 'some-event-that-is-no-class', ]); - Event::assertNotDispatched(InvalidEvent::class); + Event::assertDispatched('some-event-that-is-no-class'); }); it('passes the payload to the event', function () { diff --git a/tests/Windows/WindowTest.php b/tests/Windows/WindowTest.php index 6db8a9a..25dbafc 100644 --- a/tests/Windows/WindowTest.php +++ b/tests/Windows/WindowTest.php @@ -1,8 +1,12 @@ andReturn(new WindowClass('main')); + $window = Window::open() ->id('main') ->title('milwad') @@ -38,12 +42,15 @@ expect($windowArray['minimizable'])->toBeTrue(); expect($windowArray['maximizable'])->toBeTrue(); expect($windowArray['closable'])->toBeTrue(); - expect($windowArray['fullscreen'])->toBeFalse(); + expect($windowArray['fullscreen'])->toBeTrue(); expect($windowArray['kiosk'])->toBeFalse(); expect($windowArray['autoHideMenuBar'])->toBeTrue(); }); it('test title bar for window', function () { + Window::shouldReceive('open') + ->andReturn(new WindowClass('main')); + $window = Window::open() ->titleBarHidden(); @@ -59,6 +66,9 @@ }); it('test for trafficLightPosition in window', function () { + Window::shouldReceive('open') + ->andReturn(new WindowClass('main')); + $window = Window::open() ->trafficLightPosition(10, 10); @@ -78,10 +88,13 @@ }); it('test for invisibleFrameless in window', function () { + Window::shouldReceive('open') + ->andReturn(new WindowClass('main')); + $window = Window::open()->invisibleFrameless(); $windowArray = $window->toArray(); - expect($windowArray['frame'])->toBeTrue(); + expect($windowArray['frame'])->toBeFalse(); expect($windowArray['transparent'])->toBeTrue(); expect($windowArray['focusable'])->toBeFalse(); expect($windowArray['hasShadow'])->toBeFalse(); From 5168639292445402bcdbbfa1b6ef4417e8173ae5 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Mon, 9 Sep 2024 14:46:24 +0100 Subject: [PATCH 101/224] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 04e464d..b4d636a 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,15 @@ Check out the [Getting Started](https://nativephp.com/docs/1/getting-started/int - [Application Lifecycle](https://nativephp.com/docs/1/the-basics/app-lifecycle) - [Contributing Guide](https://github.com/NativePHP/laravel/blob/main/CONTRIBUTING.md) +## Sponsors + +Thanks to the following sponsors for funding NativePHP development. Please consider [sponsoring](https://github.com/sponsors/simonhamp). + +[BeyondCode](https://beyondco.de/?utm_source=nativephp-docs&utm_medium=logo&utm_campaign=nativephp) - Connecting the best Laravel Developers with the best Laravel Teams. +[Laradir](https://laradir.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. +[RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. +[Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. + ## Changelog Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. From 405691a9bc6e05b3e95e68609ea327dea214dbf3 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Mon, 9 Sep 2024 16:55:11 +0000 Subject: [PATCH 102/224] Update CHANGELOG --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f1d584..1359d18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.5.6 - 2024-09-09 + +### What's Changed + +* Fix chainable by @simonhamp in https://github.com/NativePHP/laravel/pull/360 +* Fixed Tests by @RobertWesner in https://github.com/NativePHP/laravel/pull/362 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.5.5...0.5.6 + ## 0.5.5 - 2024-09-02 ### What's Changed From 91afa37837e752dc828410ebeafe31f5b83da0d0 Mon Sep 17 00:00:00 2001 From: Willem Leuverink Date: Tue, 10 Sep 2024 15:34:28 +0200 Subject: [PATCH 103/224] Feature: Broadcast custom Events on IPC (#367) * Add EventWatcher * Add event name to client request * Filter only custom events & fix event fqcn --- src/Events/EventWatcher.php | 40 +++++++++++++++++++++++++++++++++++ src/NativeServiceProvider.php | 3 +++ 2 files changed, 43 insertions(+) create mode 100644 src/Events/EventWatcher.php diff --git a/src/Events/EventWatcher.php b/src/Events/EventWatcher.php new file mode 100644 index 0000000..edc53de --- /dev/null +++ b/src/Events/EventWatcher.php @@ -0,0 +1,40 @@ +broadcastOn(); + + // Only events dispatched on the nativephp channel + if(! in_array('nativephp', $channels)) { + return; + } + + // Only post custom events to broadcasting endpoint + if(str_starts_with($eventName ,'Native\\Laravel\\Events')) { + return; + } + + $this->client->post('broadcast', [ + 'event' => "\\{$eventName}", + 'payload' => $event + ]); + }); + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 609cf42..2f618ee 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -11,6 +11,7 @@ use Native\Laravel\Commands\MinifyApplicationCommand; use Native\Laravel\Commands\SeedDatabaseCommand; use Native\Laravel\Logging\LogWatcher; +use Native\Laravel\Events\EventWatcher; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -61,6 +62,8 @@ protected function configureApp() app(LogWatcher::class)->register(); } + app(EventWatcher::class)->register(); + $this->rewriteStoragePath(); $this->rewriteDatabase(); From 2ca082ef229541f421fddd3b8331d89b01a994c3 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Tue, 10 Sep 2024 13:35:13 +0000 Subject: [PATCH 104/224] Fix styling --- src/Events/EventWatcher.php | 6 +++--- src/NativeServiceProvider.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Events/EventWatcher.php b/src/Events/EventWatcher.php index edc53de..b7f57c5 100644 --- a/src/Events/EventWatcher.php +++ b/src/Events/EventWatcher.php @@ -22,18 +22,18 @@ public function register(): void $channels = $event->broadcastOn(); // Only events dispatched on the nativephp channel - if(! in_array('nativephp', $channels)) { + if (! in_array('nativephp', $channels)) { return; } // Only post custom events to broadcasting endpoint - if(str_starts_with($eventName ,'Native\\Laravel\\Events')) { + if (str_starts_with($eventName, 'Native\\Laravel\\Events')) { return; } $this->client->post('broadcast', [ 'event' => "\\{$eventName}", - 'payload' => $event + 'payload' => $event, ]); }); } diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 2f618ee..b76186f 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -10,8 +10,8 @@ use Native\Laravel\Commands\MigrateCommand; use Native\Laravel\Commands\MinifyApplicationCommand; use Native\Laravel\Commands\SeedDatabaseCommand; -use Native\Laravel\Logging\LogWatcher; use Native\Laravel\Events\EventWatcher; +use Native\Laravel\Logging\LogWatcher; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; From 9e029cde3333fa47252bc6423ab907fed72fb87a Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 11 Sep 2024 10:38:37 +0100 Subject: [PATCH 105/224] Update sponsors --- README.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b4d636a..9ffe408 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,11 @@ Check out the [Getting Started](https://nativephp.com/docs/1/getting-started/int Thanks to the following sponsors for funding NativePHP development. Please consider [sponsoring](https://github.com/sponsors/simonhamp). -[BeyondCode](https://beyondco.de/?utm_source=nativephp-docs&utm_medium=logo&utm_campaign=nativephp) - Connecting the best Laravel Developers with the best Laravel Teams. -[Laradir](https://laradir.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. -[RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. -[Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. +- [BeyondCode](https://beyondco.de/?utm_source=nativephp-docs&utm_medium=logo&utm_campaign=nativephp) - Connecting the best Laravel Developers with the best Laravel Teams. +- [Laradir](https://laradir.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. +- [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. +- [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. +- [serverauth](https://serverauth.com) - Website Deployment & Server Management, made simple! ## Changelog From eb582b1321267136dc4441bcfbbf0e78d3e387ac Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 11 Sep 2024 10:39:02 +0100 Subject: [PATCH 106/224] style --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9ffe408..0a16c28 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Thanks to the following sponsors for funding NativePHP development. Please consi - [Laradir](https://laradir.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. -- [serverauth](https://serverauth.com) - Website Deployment & Server Management, made simple! +- [ServerAuth](https://serverauth.com) - Website Deployment & Server Management, made simple! ## Changelog From 751a41ad7d882d17be8248968bb60d2719341c37 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 11 Sep 2024 15:38:54 +0100 Subject: [PATCH 107/224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0a16c28..9455185 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ Check out the [Getting Started](https://nativephp.com/docs/1/getting-started/int Thanks to the following sponsors for funding NativePHP development. Please consider [sponsoring](https://github.com/sponsors/simonhamp). -- [BeyondCode](https://beyondco.de/?utm_source=nativephp-docs&utm_medium=logo&utm_campaign=nativephp) - Connecting the best Laravel Developers with the best Laravel Teams. +- [BeyondCode](https://beyondco.de/?utm_source=nativephp-docs&utm_medium=logo&utm_campaign=nativephp) - Essential tools for web developers. - [Laradir](https://laradir.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. From d0e0b123a6a7cb05f02d3f2674d79854dde07529 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 15 Sep 2024 11:26:14 +0100 Subject: [PATCH 108/224] Update funding.yml --- .github/funding.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/funding.yml b/.github/funding.yml index 28c3a03..23b9601 100644 --- a/.github/funding.yml +++ b/.github/funding.yml @@ -1 +1,2 @@ github: simonhamp +open_collective: nativephp From 3b36fe2e8fab18a9d0f2f2fe094c37ea0731a78a Mon Sep 17 00:00:00 2001 From: simonhamp Date: Mon, 16 Sep 2024 13:19:12 +0000 Subject: [PATCH 109/224] Update CHANGELOG --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1359d18..cfea8a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.5.7 - 2024-09-16 + +### What's Changed + +* Feature: Broadcast custom Events on IPC by @gwleuverink in https://github.com/NativePHP/laravel/pull/367 + +### New Contributors + +* @gwleuverink made their first contribution in https://github.com/NativePHP/laravel/pull/367 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.5.6...0.5.7 + ## 0.5.6 - 2024-09-09 ### What's Changed From 2012e43a3af52a5e9a1f6de381415080da7c9b2d Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 17 Sep 2024 11:14:39 +0100 Subject: [PATCH 110/224] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9455185..b0705e7 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Thanks to the following sponsors for funding NativePHP development. Please consi - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. - [ServerAuth](https://serverauth.com) - Website Deployment & Server Management, made simple! +- [KaasHosting](https://kaashosting.com) - Minecraft Server and VPS hosting from The Netherlands. ## Changelog From 5799d3b4a92c61b6c693f45f6d78fcfa86694f5e Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 17 Sep 2024 11:15:21 +0100 Subject: [PATCH 111/224] Update link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0705e7..50256f1 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Check out the [Getting Started](https://nativephp.com/docs/1/getting-started/int ## Sponsors -Thanks to the following sponsors for funding NativePHP development. Please consider [sponsoring](https://github.com/sponsors/simonhamp). +Thanks to the following sponsors for funding NativePHP development. Please consider [sponsoring](https://nativephp.com/docs/getting-started/sponsoring). - [BeyondCode](https://beyondco.de/?utm_source=nativephp-docs&utm_medium=logo&utm_campaign=nativephp) - Essential tools for web developers. - [Laradir](https://laradir.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. From 7d3596aa0dbc0b61e253ce7532efae2aae1bf8c1 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 17 Sep 2024 11:48:19 +0100 Subject: [PATCH 112/224] Update URL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 50256f1..4bea809 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Thanks to the following sponsors for funding NativePHP development. Please consi - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. - [ServerAuth](https://serverauth.com) - Website Deployment & Server Management, made simple! -- [KaasHosting](https://kaashosting.com) - Minecraft Server and VPS hosting from The Netherlands. +- [KaasHosting](https://www.kaashosting.nl/?lang=en) - Minecraft Server and VPS hosting from The Netherlands. ## Changelog From bfb80b60ab5adf9e9f75d5dad91a843d7c6d81c7 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 18 Sep 2024 12:50:05 +0100 Subject: [PATCH 113/224] Update composer.json --- composer.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/composer.json b/composer.json index 768a863..c3950b1 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,10 @@ { "type": "github", "url": "https://github.com/sponsors/simonhamp" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/nativephp" } ], "authors": [ From a7a438b9db591889e73d77f7cf83ded5c181a38c Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 16 Oct 2024 15:37:52 +0100 Subject: [PATCH 114/224] Create funding-manifest-urls --- .well-known/funding-manifest-urls | 1 + 1 file changed, 1 insertion(+) create mode 100644 .well-known/funding-manifest-urls diff --git a/.well-known/funding-manifest-urls b/.well-known/funding-manifest-urls new file mode 100644 index 0000000..90fe782 --- /dev/null +++ b/.well-known/funding-manifest-urls @@ -0,0 +1 @@ +https://nativephp.com/funding.json From 23c78e2fa66007ed5a4303f7784b7319adc39e29 Mon Sep 17 00:00:00 2001 From: "Daniel, Petrica Andrei-Daniel" Date: Fri, 18 Oct 2024 13:04:56 +0200 Subject: [PATCH 115/224] Skip links as supporting library doesn't support that (#378) --- src/NativeServiceProvider.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index b76186f..e2ae30a 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -157,6 +157,7 @@ protected function configureDisks(): void 'driver' => 'local', 'root' => env($env, ''), 'throw' => false, + 'links' => 'skip', ]]); } } From 46662459911624fb5b5a3b8806e53103c9c298c5 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Fri, 18 Oct 2024 11:05:43 +0000 Subject: [PATCH 116/224] Fix styling --- src/NativeServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index e2ae30a..92f88e4 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -157,7 +157,7 @@ protected function configureDisks(): void 'driver' => 'local', 'root' => env($env, ''), 'throw' => false, - 'links' => 'skip', + 'links' => 'skip', ]]); } } From b5982c5c834af508950f5a23a0668e728b8c6f16 Mon Sep 17 00:00:00 2001 From: "Daniel, Petrica Andrei-Daniel" Date: Sun, 20 Oct 2024 18:12:28 +0200 Subject: [PATCH 117/224] added getCenterOfActiveScreen in Screen class (#375) --- src/Facades/Screen.php | 3 +++ src/Screen.php | 32 +++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Facades/Screen.php b/src/Facades/Screen.php index fe917f1..82dfcfa 100644 --- a/src/Facades/Screen.php +++ b/src/Facades/Screen.php @@ -7,6 +7,9 @@ /** * @method static object cursorPosition() * @method static array displays() + * @method static array getCenterOfActiveScreen() + * @method static array active() + * @method static array primary() */ class Screen extends Facade { diff --git a/src/Screen.php b/src/Screen.php index dfd98bb..ab8d61b 100644 --- a/src/Screen.php +++ b/src/Screen.php @@ -6,7 +6,9 @@ class Screen { - public function __construct(protected Client $client) {} + public function __construct(protected Client $client) + { + } public function cursorPosition(): object { @@ -17,4 +19,32 @@ public function displays(): array { return $this->client->get('screen/displays')->json('displays'); } + + public function primary(): object + { + return $this->client->get('screen/primary-display')->json('primaryDisplay'); + } + + public function active(): object + { + return $this->client->get('screen/active')->json(); + } + + /** + * Returns the center of the screen where the mouse pointer is placed. + * + * @return array + */ + public function getCenterOfActiveScreen(): array + { + /* Navigate every screen and check for cursor position against the bounds of the screen. */ + $activeScreen = $this->active(); + + $bounds = $activeScreen['bounds']; + + return [ + 'x' => $bounds['x'] + $bounds['width'] / 2, + 'y' => $bounds['y'] + $bounds['height'] / 2, + ]; + } } From 27cc28b860321e11506d619fbf71a854d419ff00 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Sun, 20 Oct 2024 16:12:49 +0000 Subject: [PATCH 118/224] Fix styling --- src/Screen.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Screen.php b/src/Screen.php index ab8d61b..c15d4e1 100644 --- a/src/Screen.php +++ b/src/Screen.php @@ -6,9 +6,7 @@ class Screen { - public function __construct(protected Client $client) - { - } + public function __construct(protected Client $client) {} public function cursorPosition(): object { From 2c89fbafe994bec2173625a5539783e8eb087ed4 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 30 Oct 2024 14:56:24 +0000 Subject: [PATCH 119/224] Improved window management (#391) * consistency * Use the Window class * Sensible default * Allow setting title and URL * Use setter * Add closable * Add webPreferences support * Dynamic DevTools * Type hint * Use passed ID * Fix dialog loading --- src/Concerns/HasUrl.php | 2 +- src/Dialog.php | 6 +-- src/Windows/Window.php | 92 ++++++++++++++++++++++++++++++++--- src/Windows/WindowManager.php | 19 ++++++-- 4 files changed, 104 insertions(+), 15 deletions(-) diff --git a/src/Concerns/HasUrl.php b/src/Concerns/HasUrl.php index bb98b01..0a642c2 100644 --- a/src/Concerns/HasUrl.php +++ b/src/Concerns/HasUrl.php @@ -15,7 +15,7 @@ public function url(string $url): self public function route(string $route, array $parameters = []): self { - $this->url = route($route, $parameters); + $this->url(route($route, $parameters)); return $this; } diff --git a/src/Dialog.php b/src/Dialog.php index 223c853..6188efa 100644 --- a/src/Dialog.php +++ b/src/Dialog.php @@ -110,11 +110,7 @@ public function properties(array $properties): self public function asSheet(?string $windowId = null): self { - if (is_null($windowId)) { - $this->windowReference = Window::current()->id; - } else { - $this->windowReference = $windowId; - } + $this->windowReference = $windowId ?? Window::current()->getId(); return $this; } diff --git a/src/Windows/Window.php b/src/Windows/Window.php index cc430ca..17b3ecb 100644 --- a/src/Windows/Window.php +++ b/src/Windows/Window.php @@ -11,7 +11,9 @@ class Window { use HasDimensions; - use HasUrl; + use HasUrl { + HasUrl::url as defaultUrl; + } use HasVibrancy; protected bool $autoHideMenuBar = false; @@ -28,6 +30,8 @@ class Window protected bool $showDevTools = false; + protected bool $devToolsOpen = false; + protected bool $resizable = true; protected bool $movable = true; @@ -40,6 +44,8 @@ class Window protected bool $focusable = true; + protected bool $focused = false; + protected bool $hasShadow = true; protected bool $frame = true; @@ -56,6 +62,8 @@ class Window protected array $afterOpenCallbacks = []; + protected array $webPreferences = []; + public function __construct(string $id) { $this->id = $id; @@ -71,10 +79,36 @@ public function id(string $id = 'main'): self return $this; } + public function getId(): string + { + return $this->id; + } + public function title(string $title): self { $this->title = $title; + if (! $this instanceof PendingOpenWindow) { + $this->client->post('window/title', [ + 'id' => $this->id, + 'title' => $title, + ]); + } + + return $this; + } + + public function url(string $url) + { + $this->defaultUrl($url); + + if (! $this instanceof PendingOpenWindow) { + $this->client->post('window/url', [ + 'id' => $this->id, + 'url' => $url, + ]); + } + return $this; } @@ -142,21 +176,43 @@ public function setClient(Client $client): self return $this; } - public function alwaysOnTop($alwaysOnTop = true): self + public function alwaysOnTop(bool $alwaysOnTop = true): self { $this->alwaysOnTop = $alwaysOnTop; return $this; } - public function showDevTools($showDevTools = true): self + public function showDevTools(bool $showDevTools = true): self { $this->showDevTools = $showDevTools; + if (! $this instanceof PendingOpenWindow) { + $this->client->post('window/show-dev-tools', [ + 'id' => $this->id, + ]); + } + + return $this; + } + + public function hideDevTools(): self + { + if (! $this instanceof PendingOpenWindow) { + $this->client->post('window/hide-dev-tools', [ + 'id' => $this->id, + ]); + } + return $this; } - public function resizable($resizable = true): static + public function devToolsOpen(): bool + { + return $this->devToolsOpen; + } + + public function resizable(bool $resizable = true): static { $this->resizable = $resizable; @@ -194,10 +250,17 @@ public function maximized(): static return $this->afterOpen(fn () => WindowFacade::maximize($this->id)); } - public function closable($closable = true): static + public function closable(bool $closable = true): static { $this->closable = $closable; + if (! $this instanceof PendingOpenWindow) { + $this->client->post('window/closable', [ + 'id' => $this->id, + 'closable' => $closable, + ]); + } + return $this; } @@ -231,13 +294,20 @@ public function fullscreenable($fullscreenable = true): static return $this; } - public function kiosk($kiosk = false): static + public function kiosk($kiosk = true): static { $this->kiosk = $kiosk; return $this; } + public function webPreferences(array $preferences): static + { + $this->webPreferences = $preferences; + + return $this; + } + public function toArray() { return [ @@ -273,6 +343,7 @@ public function toArray() 'kiosk' => $this->kiosk, 'autoHideMenuBar' => $this->autoHideMenuBar, 'transparent' => $this->transparent, + 'webPreferences' => $this->webPreferences, ]; } @@ -282,4 +353,13 @@ public function afterOpen(callable $cb): static return $this; } + + public function fromRuntimeWindow(object $window): static + { + foreach ($window as $key => $value) { + $this->{$key} = $value; + } + + return $this; + } } diff --git a/src/Windows/WindowManager.php b/src/Windows/WindowManager.php index 9378c5f..9890708 100644 --- a/src/Windows/WindowManager.php +++ b/src/Windows/WindowManager.php @@ -25,14 +25,27 @@ public function close($id = null) public function hide($id = null) { - return $this->client->post('window/hide', [ + $this->client->post('window/hide', [ 'id' => $id ?? $this->detectId(), ]); } - public function current() + public function current(): Window { - return (object) $this->client->get('window/current')->json(); + $window = (object) $this->client->get('window/current')->json(); + + return (new Window($window->id)) + ->setClient($this->client) + ->fromRuntimeWindow($window); + } + + public function get(string $id): Window + { + $window = (object) $this->client->get("window/get/{$id}")->json(); + + return (new Window($id)) + ->setClient($this->client) + ->fromRuntimeWindow($window); } public function resize($width, $height, $id = null) From fcdcc06958cd8e6b23d1603fe18adf8ca1b2e9e2 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 31 Oct 2024 13:06:31 +0000 Subject: [PATCH 120/224] Child processes (#389) * wip * Fix styling * cleanup * phpstan * Fix event * Fix event watcher * Fix facade * add events * Remove useless stubs * Fix styling * add some sanity tests * wip * add artisan shorthand * allow passing either a string or array * correct return type * flip arguments for consistency * tidy - remove unused class properties * remove unnecessary space escape * add optional arg to make the process persistent * improvements - ChildProcess instances can be used to interact with a process - get, all and restart are piped up * Fix styling * Update src/ChildProcess.php Co-authored-by: Simon Hamp * feedback - tidy cwd default path * stub out php command tests * fix - tests after upstream merge * add php convenience method * wip - refactor * add phpdoc for facade methods * Update src/Facades/ChildProcess.php Co-authored-by: Simon Hamp * remove exploding string commands * fix - return a fresh instance from the facade each time --------- Co-authored-by: simonhamp Co-authored-by: gwleuverink Co-authored-by: Willem Leuverink --- phpstan.neon.dist | 1 - src/ChildProcess.php | 129 ++++++++++++++++++++ src/Commands/MigrateCommand.php | 2 +- src/Events/ChildProcess/ErrorReceived.php | 22 ++++ src/Events/ChildProcess/MessageReceived.php | 22 ++++ src/Events/ChildProcess/ProcessExited.php | 22 ++++ src/Events/ChildProcess/ProcessSpawned.php | 22 ++++ src/Events/EventWatcher.php | 2 +- src/Facades/ChildProcess.php | 26 ++++ tests/ChildProcess/ChildProcessTest.php | 127 +++++++++++++++++++ 10 files changed, 372 insertions(+), 3 deletions(-) create mode 100644 src/ChildProcess.php create mode 100644 src/Events/ChildProcess/ErrorReceived.php create mode 100644 src/Events/ChildProcess/MessageReceived.php create mode 100644 src/Events/ChildProcess/ProcessExited.php create mode 100644 src/Events/ChildProcess/ProcessSpawned.php create mode 100644 src/Facades/ChildProcess.php create mode 100644 tests/ChildProcess/ChildProcessTest.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index a91953b..260b5e1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -10,5 +10,4 @@ parameters: tmpDir: build/phpstan checkOctaneCompatibility: true checkModelProperties: true - checkMissingIterableValueType: false diff --git a/src/ChildProcess.php b/src/ChildProcess.php new file mode 100644 index 0000000..ff80a07 --- /dev/null +++ b/src/ChildProcess.php @@ -0,0 +1,129 @@ +alias; + + $process = $this->client->get("child-process/get/{$alias}")->json(); + + if (! $process) { + return null; + } + + return $this->fromRuntimeProcess($process); + } + + public function all(): array + { + $processes = $this->client->get('child-process/')->json(); + + if (empty($processes)) { + return []; + } + + $hydrated = []; + + foreach ($processes as $alias => $process) { + $hydrated[$alias] = (new static($this->client)) + ->fromRuntimeProcess($process); + } + + return $hydrated; + } + + public function start( + string|array $cmd, + string $alias, + ?string $cwd = null, + ?array $env = null, + bool $persistent = false + ): static { + + $process = $this->client->post('child-process/start', [ + 'alias' => $alias, + 'cmd' => (array) $cmd, + 'cwd' => $cwd ?? base_path(), + 'env' => $env, + 'persistent' => $persistent, + ])->json(); + + return $this->fromRuntimeProcess($process); + } + + public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self + { + $cmd = [PHP_BINARY, ...(array) $cmd]; + + return $this->start($cmd, $alias, env: $env, persistent: $persistent); + } + + public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self + { + $cmd = ['artisan', ...(array) $cmd]; + + return $this->php($cmd, $alias, env: $env, persistent: $persistent); + } + + public function stop(?string $alias = null): void + { + $this->client->post('child-process/stop', [ + 'alias' => $alias ?? $this->alias, + ])->json(); + } + + public function restart(?string $alias = null): ?static + { + $process = $this->client->post('child-process/restart', [ + 'alias' => $alias ?? $this->alias, + ])->json(); + + if (! $process) { + return null; + } + + return $this->fromRuntimeProcess($process); + } + + public function message(string $message, ?string $alias = null): static + { + $this->client->post('child-process/message', [ + 'alias' => $alias ?? $this->alias, + 'message' => $message, + ])->json(); + + return $this; + } + + protected function fromRuntimeProcess($process): static + { + if (isset($process['pid'])) { + $this->pid = $process['pid']; + } + + foreach ($process['settings'] as $key => $value) { + $this->{$key} = $value; + } + + return $this; + } +} diff --git a/src/Commands/MigrateCommand.php b/src/Commands/MigrateCommand.php index ebf8522..9093d67 100644 --- a/src/Commands/MigrateCommand.php +++ b/src/Commands/MigrateCommand.php @@ -22,6 +22,6 @@ public function handle() { (new NativeServiceProvider($this->laravel))->rewriteDatabase(); - parent::handle(); + return parent::handle(); } } diff --git a/src/Events/ChildProcess/ErrorReceived.php b/src/Events/ChildProcess/ErrorReceived.php new file mode 100644 index 0000000..65db9c6 --- /dev/null +++ b/src/Events/ChildProcess/ErrorReceived.php @@ -0,0 +1,22 @@ +makePartial() + ->shouldAllowMockingProtectedMethods(); + + $this->instance(ChildProcessImplement::class, $mock->allows([ + 'fromRuntimeProcess' => $mock, + ])); +}); + +it('can start a child process', function () { + ChildProcess::start('foo bar', 'some-alias', 'path/to/dir', ['baz' => 'zah']); + + Http::assertSent(function (Request $request) { + return $request->url() === 'http://localhost:4000/api/child-process/start' && + $request['alias'] === 'some-alias' && + $request['cmd'] === ['foo bar'] && + $request['cwd'] === 'path/to/dir' && + $request['env'] === ['baz' => 'zah']; + }); +}); + +it('can start a php command', function () { + ChildProcess::php("-r 'sleep(5);'", 'some-alias', ['baz' => 'zah']); + + Http::assertSent(function (Request $request) { + return $request->url() === 'http://localhost:4000/api/child-process/start' && + $request['alias'] === 'some-alias' && + $request['cmd'] === [PHP_BINARY, "-r 'sleep(5);'"] && + $request['cwd'] === base_path() && + $request['env'] === ['baz' => 'zah']; + }); +}); + +it('can start a artisan command', function () { + ChildProcess::artisan('foo:bar --verbose', 'some-alias', ['baz' => 'zah']); + + Http::assertSent(function (Request $request) { + return $request->url() === 'http://localhost:4000/api/child-process/start' && + $request['alias'] === 'some-alias' && + $request['cmd'] === [PHP_BINARY, 'artisan', 'foo:bar --verbose'] && + $request['cwd'] === base_path() && + $request['env'] === ['baz' => 'zah']; + }); +}); + +it('accepts either a string or a array as start command argument', function () { + ChildProcess::start('foo bar', 'some-alias'); + Http::assertSent(fn (Request $request) => $request['cmd'] === ['foo bar']); + + ChildProcess::start(['foo', 'baz'], 'some-alias'); + Http::assertSent(fn (Request $request) => $request['cmd'] === ['foo', 'baz']); +}); + +it('accepts either a string or a array as php command argument', function () { + ChildProcess::php("-r 'sleep(5);'", 'some-alias'); + Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, "-r 'sleep(5);'"]); + + ChildProcess::php(['-r', "'sleep(5);'"], 'some-alias'); + Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, '-r', "'sleep(5);'"]); +}); + +it('accepts either a string or a array as artisan command argument', function () { + ChildProcess::artisan('foo:bar', 'some-alias'); + Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, 'artisan', 'foo:bar']); + + ChildProcess::artisan(['foo:baz'], 'some-alias'); + Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, 'artisan', 'foo:baz']); +}); + +it('sets the cwd to the base path if none was given', function () { + ChildProcess::start(['foo', 'bar'], 'some-alias', cwd: 'path/to/dir'); + Http::assertSent(fn (Request $request) => $request['cwd'] === 'path/to/dir'); + + ChildProcess::start(['foo', 'bar'], 'some-alias'); + Http::assertSent(fn (Request $request) => $request['cwd'] === base_path()); +}); + +it('can stop a child process', function () { + ChildProcess::stop('some-alias'); + + Http::assertSent(function (Request $request) { + return $request->url() === 'http://localhost:4000/api/child-process/stop' && + $request['alias'] === 'some-alias'; + }); +}); + +it('can send messages to a child process', function () { + ChildProcess::message('some-message', 'some-alias'); + + Http::assertSent(function (Request $request) { + return $request->url() === 'http://localhost:4000/api/child-process/message' && + $request['alias'] === 'some-alias' && + $request['message'] === 'some-message'; + }); +}); + +it('can mark a process as persistent', function () { + ChildProcess::start('foo bar', 'some-alias', persistent: true); + Http::assertSent(fn (Request $request) => $request['persistent'] === true); +}); + +it('can mark a php command as persistent', function () { + ChildProcess::php("-r 'sleep(5);'", 'some-alias', persistent: true); + Http::assertSent(fn (Request $request) => $request['persistent'] === true); +}); + +it('can mark a artisan command as persistent', function () { + ChildProcess::artisan('foo:bar', 'some-alias', persistent: true); + Http::assertSent(fn (Request $request) => $request['persistent'] === true); +}); + +it('marks the process as non-persistent by default', function () { + ChildProcess::start('foo bar', 'some-alias'); + Http::assertSent(fn (Request $request) => $request['persistent'] === false); +}); From 5ca804a85697dd622c72e77131c8528a0797796d Mon Sep 17 00:00:00 2001 From: simonhamp Date: Fri, 1 Nov 2024 09:56:01 +0000 Subject: [PATCH 121/224] Update CHANGELOG --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cfea8a7..202c6d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.6.0 - 2024-11-01 + +### What's Changed + +* Skip links as supporting library doesn't support that by @danielpetrica in https://github.com/NativePHP/laravel/pull/378 +* Add `getCenterOfActiveScreen` in Screen class by @danielpetrica in https://github.com/NativePHP/laravel/pull/375 +* Improved window management by @simonhamp in https://github.com/NativePHP/laravel/pull/391 +* Child processes by @simonhamp and @gwleuverink in https://github.com/NativePHP/laravel/pull/389 + +### New Contributors + +* @danielpetrica made their first contribution in https://github.com/NativePHP/laravel/pull/378 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.5.7...0.6.0 + ## 0.5.7 - 2024-09-16 ### What's Changed From 1cb1c56dad7079bceeb2f075f884484578bc50d3 Mon Sep 17 00:00:00 2001 From: Jerke Combee Date: Sat, 2 Nov 2024 15:11:39 +0100 Subject: [PATCH 122/224] Add a function to the window manager in order to list all open windows (#396) --- src/Facades/Window.php | 1 + src/Windows/WindowManager.php | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/Facades/Window.php b/src/Facades/Window.php index 75efc45..5ac1e90 100644 --- a/src/Facades/Window.php +++ b/src/Facades/Window.php @@ -8,6 +8,7 @@ * @method static \Native\Laravel\Windows\PendingOpenWindow open(string $id = 'main') * @method static void close($id = null) * @method static object current() + * @method static array all() * @method static void resize($width, $height, $id = null) * @method static void position($x, $y, $animated = false, $id = null) * @method static void alwaysOnTop($alwaysOnTop = true, $id = null) diff --git a/src/Windows/WindowManager.php b/src/Windows/WindowManager.php index 9890708..49574e6 100644 --- a/src/Windows/WindowManager.php +++ b/src/Windows/WindowManager.php @@ -39,6 +39,18 @@ public function current(): Window ->fromRuntimeWindow($window); } + public function all(): array + { + $windows = (array) $this->client->get('window/all')->json(); + + return array_map( + fn ($window) => (new Window($window['id'])) + ->setClient($this->client) + ->fromRuntimeWindow((object) $window), + $windows + ); + } + public function get(string $id): Window { $window = (object) $this->client->get("window/get/{$id}")->json(); From d8a09b86d7cdd510f7d9c72134acda27398cbe86 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 3 Nov 2024 17:11:30 +0000 Subject: [PATCH 123/224] Add exception handler (#398) * Add exception handler to report exceptions in console * Fix styling --------- Co-authored-by: simonhamp --- src/Exceptions/Handler.php | 15 +++++++++++++++ src/NativeServiceProvider.php | 6 ++++++ 2 files changed, 21 insertions(+) create mode 100644 src/Exceptions/Handler.php diff --git a/src/Exceptions/Handler.php b/src/Exceptions/Handler.php new file mode 100644 index 0000000..d1d3c56 --- /dev/null +++ b/src/Exceptions/Handler.php @@ -0,0 +1,15 @@ +reportable(function (\Throwable $e) { + error_log('[NATIVE_EXCEPTION]: '.$e->getMessage()); + }); + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 92f88e4..f6eb5b3 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -11,6 +11,7 @@ use Native\Laravel\Commands\MinifyApplicationCommand; use Native\Laravel\Commands\SeedDatabaseCommand; use Native\Laravel\Events\EventWatcher; +use Native\Laravel\Exceptions\Handler; use Native\Laravel\Logging\LogWatcher; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -44,6 +45,11 @@ public function packageRegistered() return new MigrateCommand($app['migrator'], $app['events']); }); + $this->app->singleton( + \Illuminate\Contracts\Debug\ExceptionHandler::class, + Handler::class + ); + if (config('nativephp-internal.running')) { Artisan::starting(function ($artisan) { $artisan->resolveCommands([ From 68018b50f3363389441700c32689d37eea6ee01f Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Mon, 4 Nov 2024 11:15:38 +0000 Subject: [PATCH 124/224] Add detail to output --- src/Exceptions/Handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Exceptions/Handler.php b/src/Exceptions/Handler.php index d1d3c56..4fce003 100644 --- a/src/Exceptions/Handler.php +++ b/src/Exceptions/Handler.php @@ -9,7 +9,7 @@ class Handler extends \Illuminate\Foundation\Exceptions\Handler public function register(): void { $this->reportable(function (\Throwable $e) { - error_log('[NATIVE_EXCEPTION]: '.$e->getMessage()); + error_log("[NATIVE_EXCEPTION]: {$e->getMessage()} ({$e->getCode()}) in {$e->getFile()}:{$e->getLine()}"); }); } } From b885affa6e8da230b5953e98cb682d20dc97def6 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Mon, 4 Nov 2024 11:19:46 +0000 Subject: [PATCH 125/224] Update CHANGELOG --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 202c6d5..a59e823 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,19 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.6.1 - 2024-11-04 + +### What's Changed + +* Add a function to the window manager in order to list all open windows by @JCombee in https://github.com/NativePHP/laravel/pull/396 +* Add exception handler by @simonhamp in https://github.com/NativePHP/laravel/pull/398 + +### New Contributors + +* @JCombee made their first contribution in https://github.com/NativePHP/laravel/pull/396 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.6.0...0.6.1 + ## 0.6.0 - 2024-11-01 ### What's Changed From 3b2aa37b52c73e4ba3073105ed44f7e02cf94d06 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 6 Nov 2024 15:58:42 +0000 Subject: [PATCH 126/224] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4bea809..4de29bb 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Check out the [Getting Started](https://nativephp.com/docs/1/getting-started/int Thanks to the following sponsors for funding NativePHP development. Please consider [sponsoring](https://nativephp.com/docs/getting-started/sponsoring). - [BeyondCode](https://beyondco.de/?utm_source=nativephp-docs&utm_medium=logo&utm_campaign=nativephp) - Essential tools for web developers. -- [Laradir](https://laradir.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. +- [Laradevs](https://laradevs.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. - [ServerAuth](https://serverauth.com) - Website Deployment & Server Management, made simple! From fd5860a0c25c9f5a8041ab00211008a69e5d91ba Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 12 Nov 2024 18:27:55 +0000 Subject: [PATCH 127/224] Enable WAL mode in SQLite (#405) --- src/NativeServiceProvider.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index f6eb5b3..f966db7 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -4,6 +4,7 @@ use Illuminate\Console\Application as Artisan; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\DB; use Native\Laravel\Commands\FreshCommand; use Native\Laravel\Commands\LoadPHPConfigurationCommand; use Native\Laravel\Commands\LoadStartupConfigurationCommand; @@ -122,6 +123,9 @@ public function rewriteDatabase() ]]); config(['database.default' => 'nativephp']); + + DB::statement('PRAGMA journal_mode=WAL;'); + DB::statement('PRAGMA busy_timeout=5000;'); } public function removeDatabase() From f86de673df0ba055c588f42a840e86a94695bc7f Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 12 Nov 2024 18:28:49 +0000 Subject: [PATCH 128/224] Migrate the dev DB when created (#406) --- src/NativeServiceProvider.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index f966db7..0831933 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -111,6 +111,8 @@ public function rewriteDatabase() if (! file_exists($databasePath)) { touch($databasePath); + + Artisan::call('native:migrate'); } } From 05d8f4375d8dc55a274081423604e1a45caabeac Mon Sep 17 00:00:00 2001 From: simonhamp Date: Wed, 13 Nov 2024 07:27:42 +0000 Subject: [PATCH 129/224] Update CHANGELOG --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a59e823..c05ef3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.6.2 - 2024-11-13 + +### What's Changed + +* Enable WAL mode in SQLite by @simonhamp in https://github.com/NativePHP/laravel/pull/405 +* Migrate the dev DB when created by @simonhamp in https://github.com/NativePHP/laravel/pull/406 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.6.1...0.6.2 + ## 0.6.1 - 2024-11-04 ### What's Changed From 9330eb7555e566c83a604b99a0167d416af86822 Mon Sep 17 00:00:00 2001 From: Angelos Michalopoulos Date: Thu, 14 Nov 2024 19:55:32 +0200 Subject: [PATCH 130/224] Use Artisan Facade to call native:migrate (#408) --- src/NativeServiceProvider.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 0831933..9f0fd71 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -2,9 +2,10 @@ namespace Native\Laravel; -use Illuminate\Console\Application as Artisan; +use Illuminate\Console\Application; use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Artisan; use Native\Laravel\Commands\FreshCommand; use Native\Laravel\Commands\LoadPHPConfigurationCommand; use Native\Laravel\Commands\LoadStartupConfigurationCommand; @@ -52,8 +53,8 @@ public function packageRegistered() ); if (config('nativephp-internal.running')) { - Artisan::starting(function ($artisan) { - $artisan->resolveCommands([ + Application::starting(function ($app) { + $app->resolveCommands([ LoadStartupConfigurationCommand::class, LoadPHPConfigurationCommand::class, ]); From 9d768bedd1a6f9da65ce064005866d054252d1a5 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Thu, 14 Nov 2024 17:55:58 +0000 Subject: [PATCH 131/224] Fix styling --- src/NativeServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 9f0fd71..a2d5f03 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -4,8 +4,8 @@ use Illuminate\Console\Application; use Illuminate\Support\Arr; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Artisan; +use Illuminate\Support\Facades\DB; use Native\Laravel\Commands\FreshCommand; use Native\Laravel\Commands\LoadPHPConfigurationCommand; use Native\Laravel\Commands\LoadStartupConfigurationCommand; From 6e6cf13698eb218eeed129b03fb9b5957dc3e61c Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 14 Nov 2024 18:10:04 +0000 Subject: [PATCH 132/224] Fix accessing window properties (#410) * Add type hint * Add magic getter * Cleanup --- src/Events/EventWatcher.php | 1 - src/Windows/Window.php | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Events/EventWatcher.php b/src/Events/EventWatcher.php index bab9373..bae9ae7 100644 --- a/src/Events/EventWatcher.php +++ b/src/Events/EventWatcher.php @@ -12,7 +12,6 @@ public function __construct(protected Client $client) {} public function register(): void { Event::listen('*', function (string $eventName, array $data) { - $event = $data[0] ?? (object) null; if (! method_exists($event, 'broadcastOn')) { diff --git a/src/Windows/Window.php b/src/Windows/Window.php index 17b3ecb..7eadd24 100644 --- a/src/Windows/Window.php +++ b/src/Windows/Window.php @@ -24,7 +24,7 @@ class Window protected bool $kiosk = false; - protected $rememberState = false; + protected bool $rememberState = false; protected bool $alwaysOnTop = false; @@ -362,4 +362,9 @@ public function fromRuntimeWindow(object $window): static return $this; } + + public function __get($var) + { + return $this->$var ?? null; + } } From c223e0f3e630260bf3e522002ac987c64c193b1c Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 14 Nov 2024 18:13:17 +0000 Subject: [PATCH 133/224] Feature/menubar improvement (#411) * Refactor variable * Remove override method `url` is already available from the `HasUrl` trait * Add tooltip setting * Add resizable setting * Allow updating of tooltip * Allow updating of icon * Support firing a custom event on click --- src/MenuBar/MenuBar.php | 41 ++++++++++++++++++++++++++-------- src/MenuBar/MenuBarManager.php | 14 ++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/MenuBar/MenuBar.php b/src/MenuBar/MenuBar.php index 9885233..cfc2873 100644 --- a/src/MenuBar/MenuBar.php +++ b/src/MenuBar/MenuBar.php @@ -20,12 +20,18 @@ class MenuBar protected string $label = ''; - protected bool $onlyShowContextWindow = false; + protected string $tooltip = ''; + + protected bool $resizable = true; + + protected bool $onlyShowContextMenu = false; protected ?Menu $contextMenu = null; protected bool $alwaysOnTop = false; + protected ?string $event = null; + protected bool $showDockIcon = false; protected Client $client; @@ -51,28 +57,35 @@ public function icon(string $icon): self public function onlyShowContextMenu(bool $onlyContextMenu = true): self { - $this->onlyShowContextWindow = $onlyContextMenu; + $this->onlyShowContextMenu = $onlyContextMenu; return $this; } - public function url(string $url): self + public function showDockIcon($value = true): self { - $this->url = $url; + $this->showDockIcon = $value; return $this; } - public function showDockIcon($value = true): self + public function label(string $label = ''): self { - $this->showDockIcon = $value; + $this->label = $label; return $this; } - public function label(string $label = ''): self + public function tooltip(string $tooltip = ''): self { - $this->label = $label; + $this->tooltip = $tooltip; + + return $this; + } + + public function resizable(bool $resizable = true): static + { + $this->resizable = $resizable; return $this; } @@ -84,6 +97,13 @@ public function alwaysOnTop($alwaysOnTop = true): self return $this; } + public function event(string $event): self + { + $this->event = $event; + + return $this; + } + public function withContextMenu(Menu $menu): self { $this->contextMenu = $menu; @@ -100,15 +120,18 @@ public function toArray(): array 'x' => $this->x, 'y' => $this->y, 'label' => $this->label, + 'tooltip' => $this->tooltip, + 'resizable' => $this->resizable, 'width' => $this->width, 'height' => $this->height, 'vibrancy' => $this->vibrancy, 'showDockIcon' => $this->showDockIcon, 'transparency' => $this->transparent, 'backgroundColor' => $this->backgroundColor, - 'onlyShowContextWindow' => $this->onlyShowContextWindow, + 'onlyShowContextMenu' => $this->onlyShowContextMenu, 'contextMenu' => ! is_null($this->contextMenu) ? $this->contextMenu->toArray()['submenu'] : null, 'alwaysOnTop' => $this->alwaysOnTop, + 'event' => $this->event, ]; } } diff --git a/src/MenuBar/MenuBarManager.php b/src/MenuBar/MenuBarManager.php index 04aedb0..b10992d 100644 --- a/src/MenuBar/MenuBarManager.php +++ b/src/MenuBar/MenuBarManager.php @@ -31,6 +31,20 @@ public function label(string $label) ]); } + public function tooltip(string $tooltip) + { + $this->client->post('menu-bar/tooltip', [ + 'tooltip' => $tooltip, + ]); + } + + public function icon(string $icon) + { + $this->client->post('menu-bar/icon', [ + 'icon' => $icon, + ]); + } + public function contextMenu(Menu $contextMenu) { $this->client->post('menu-bar/context-menu', [ From cee53d740d6e16851cc8d5d89cb71e2a1e8a601c Mon Sep 17 00:00:00 2001 From: simonhamp Date: Thu, 14 Nov 2024 18:15:53 +0000 Subject: [PATCH 134/224] Update CHANGELOG --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c05ef3a..af3daf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.6.3 - 2024-11-14 + +### What's Changed + +* Fix native:migrate:fresh by @miagg in https://github.com/NativePHP/laravel/pull/408 +* Fix accessing window properties by @simonhamp in https://github.com/NativePHP/laravel/pull/410 +* MenuBar improvements by @simonhamp in https://github.com/NativePHP/laravel/pull/411 + +### New Contributors + +* @miagg made their first contribution in https://github.com/NativePHP/laravel/pull/408 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.6.2...0.6.3 + ## 0.6.2 - 2024-11-13 ### What's Changed From a3bd955f5b5f7d833d076838bd721c301ab6b9f1 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Fri, 15 Nov 2024 11:36:33 +0000 Subject: [PATCH 135/224] Fix some DB stuff (#413) * Resolve native:migrate command so we can call it * Only run exception handler in native context * Only configure DB if we have one * Silently unlink all SQlite files --- src/NativeServiceProvider.php | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index a2d5f03..d9c28a1 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -47,16 +47,17 @@ public function packageRegistered() return new MigrateCommand($app['migrator'], $app['events']); }); - $this->app->singleton( - \Illuminate\Contracts\Debug\ExceptionHandler::class, - Handler::class - ); - if (config('nativephp-internal.running')) { + $this->app->singleton( + \Illuminate\Contracts\Debug\ExceptionHandler::class, + Handler::class + ); + Application::starting(function ($app) { $app->resolveCommands([ LoadStartupConfigurationCommand::class, LoadPHPConfigurationCommand::class, + MigrateCommand::class, ]); }); @@ -127,8 +128,10 @@ public function rewriteDatabase() config(['database.default' => 'nativephp']); - DB::statement('PRAGMA journal_mode=WAL;'); - DB::statement('PRAGMA busy_timeout=5000;'); + if (file_exists($databasePath)) { + DB::statement('PRAGMA journal_mode=WAL;'); + DB::statement('PRAGMA busy_timeout=5000;'); + } } public function removeDatabase() @@ -137,13 +140,11 @@ public function removeDatabase() if (config('app.debug')) { $databasePath = database_path('nativephp.sqlite'); - - if (! file_exists($databasePath)) { - return; - } } - unlink($databasePath); + @unlink($databasePath); + @unlink($databasePath.'-shm'); + @unlink($database.'-wal'); } protected function configureDisks(): void From 63390309094e2b07838d3f790c85220bd9ab1e8c Mon Sep 17 00:00:00 2001 From: Willem Leuverink Date: Sun, 17 Nov 2024 16:02:41 +0100 Subject: [PATCH 136/224] Add dedicated php child process endpoint (#414) * add separate php endpoint * fix window test --- src/ChildProcess.php | 10 ++++++++-- tests/ChildProcess/ChildProcessTest.php | 16 ++++++++-------- tests/Windows/WindowTest.php | 5 ++++- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/ChildProcess.php b/src/ChildProcess.php index ff80a07..171210f 100644 --- a/src/ChildProcess.php +++ b/src/ChildProcess.php @@ -72,9 +72,15 @@ public function start( public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self { - $cmd = [PHP_BINARY, ...(array) $cmd]; + $process = $this->client->post('child-process/start-php', [ + 'alias' => $alias, + 'cmd' => (array) $cmd, + 'cwd' => $cwd ?? base_path(), + 'env' => $env, + 'persistent' => $persistent, + ])->json(); - return $this->start($cmd, $alias, env: $env, persistent: $persistent); + return $this->fromRuntimeProcess($process); } public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self diff --git a/tests/ChildProcess/ChildProcessTest.php b/tests/ChildProcess/ChildProcessTest.php index a2d9259..7bd13b7 100644 --- a/tests/ChildProcess/ChildProcessTest.php +++ b/tests/ChildProcess/ChildProcessTest.php @@ -35,9 +35,9 @@ ChildProcess::php("-r 'sleep(5);'", 'some-alias', ['baz' => 'zah']); Http::assertSent(function (Request $request) { - return $request->url() === 'http://localhost:4000/api/child-process/start' && + return $request->url() === 'http://localhost:4000/api/child-process/start-php' && $request['alias'] === 'some-alias' && - $request['cmd'] === [PHP_BINARY, "-r 'sleep(5);'"] && + $request['cmd'] === ["-r 'sleep(5);'"] && $request['cwd'] === base_path() && $request['env'] === ['baz' => 'zah']; }); @@ -47,9 +47,9 @@ ChildProcess::artisan('foo:bar --verbose', 'some-alias', ['baz' => 'zah']); Http::assertSent(function (Request $request) { - return $request->url() === 'http://localhost:4000/api/child-process/start' && + return $request->url() === 'http://localhost:4000/api/child-process/start-php' && $request['alias'] === 'some-alias' && - $request['cmd'] === [PHP_BINARY, 'artisan', 'foo:bar --verbose'] && + $request['cmd'] === ['artisan', 'foo:bar --verbose'] && $request['cwd'] === base_path() && $request['env'] === ['baz' => 'zah']; }); @@ -65,18 +65,18 @@ it('accepts either a string or a array as php command argument', function () { ChildProcess::php("-r 'sleep(5);'", 'some-alias'); - Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, "-r 'sleep(5);'"]); + Http::assertSent(fn (Request $request) => $request['cmd'] === ["-r 'sleep(5);'"]); ChildProcess::php(['-r', "'sleep(5);'"], 'some-alias'); - Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, '-r', "'sleep(5);'"]); + Http::assertSent(fn (Request $request) => $request['cmd'] === ['-r', "'sleep(5);'"]); }); it('accepts either a string or a array as artisan command argument', function () { ChildProcess::artisan('foo:bar', 'some-alias'); - Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, 'artisan', 'foo:bar']); + Http::assertSent(fn (Request $request) => $request['cmd'] === ['artisan', 'foo:bar']); ChildProcess::artisan(['foo:baz'], 'some-alias'); - Http::assertSent(fn (Request $request) => $request['cmd'] === [PHP_BINARY, 'artisan', 'foo:baz']); + Http::assertSent(fn (Request $request) => $request['cmd'] === ['artisan', 'foo:baz']); }); it('sets the cwd to the base path if none was given', function () { diff --git a/tests/Windows/WindowTest.php b/tests/Windows/WindowTest.php index 25dbafc..8cf21d6 100644 --- a/tests/Windows/WindowTest.php +++ b/tests/Windows/WindowTest.php @@ -1,13 +1,16 @@ andReturn(new WindowClass('main')); $window = Window::open() + ->setClient(new Client) ->id('main') ->title('milwad') ->titleBarStyle('milwad') @@ -43,7 +46,7 @@ expect($windowArray['maximizable'])->toBeTrue(); expect($windowArray['closable'])->toBeTrue(); expect($windowArray['fullscreen'])->toBeTrue(); - expect($windowArray['kiosk'])->toBeFalse(); + expect($windowArray['kiosk'])->toBeTrue(); expect($windowArray['autoHideMenuBar'])->toBeTrue(); }); From 1df3c34b7e24a0f7e57caaf38a46d68bcc9769b6 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Sun, 17 Nov 2024 15:08:11 +0000 Subject: [PATCH 137/224] Update CHANGELOG --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af3daf4..9a866e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.6.4 - 2024-11-17 + +### What's Changed + +* Fix some DB stuff by @simonhamp in https://github.com/NativePHP/laravel/pull/413 +* Add dedicated PHP ChildProcess endpoint by @gwleuverink in https://github.com/NativePHP/laravel/pull/414 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.6.3...0.6.4 + ## 0.6.3 - 2024-11-14 ### What's Changed From c29bd0d63b64ff87ac3f4859f0dea3d720558304 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 19 Nov 2024 16:26:24 +0100 Subject: [PATCH 138/224] Fix Settings facade DocBloc (#419) --- src/Facades/Settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facades/Settings.php b/src/Facades/Settings.php index d1126c5..2fc2fdd 100644 --- a/src/Facades/Settings.php +++ b/src/Facades/Settings.php @@ -6,7 +6,7 @@ /** * @method static void set($key, $value) - * @method static void mixed($key, $default = null) + * @method static mixed get($key, $default = null) */ class Settings extends Facade { From 3e0c562e871a038a4ed4f6699251b6eda060fa67 Mon Sep 17 00:00:00 2001 From: A G Date: Wed, 20 Nov 2024 07:29:21 -0500 Subject: [PATCH 139/224] Fake test double for WindowManager::Class: (#422) - Usage of (relatively lenient) WindowManagerContract::class in Laravel container - Implement WindowManagerFake::class with several testing assertions and helper methods - Laravel-style facade Window::fake() method - Tests --- src/Contracts/WindowManager.php | 23 +++++ src/Facades/Window.php | 11 +- src/Fakes/WindowManagerFake.php | 94 +++++++++++++++++ src/NativeServiceProvider.php | 7 ++ src/Windows/WindowManager.php | 3 +- tests/Fakes/FakeWindowManagerTest.php | 142 ++++++++++++++++++++++++++ 6 files changed, 278 insertions(+), 2 deletions(-) create mode 100644 src/Contracts/WindowManager.php create mode 100644 src/Fakes/WindowManagerFake.php create mode 100644 tests/Fakes/FakeWindowManagerTest.php diff --git a/src/Contracts/WindowManager.php b/src/Contracts/WindowManager.php new file mode 100644 index 0000000..e4bbe63 --- /dev/null +++ b/src/Contracts/WindowManager.php @@ -0,0 +1,23 @@ + + */ + public function all(): array; + + public function get(string $id): Window; +} diff --git a/src/Facades/Window.php b/src/Facades/Window.php index 5ac1e90..e774755 100644 --- a/src/Facades/Window.php +++ b/src/Facades/Window.php @@ -3,6 +3,8 @@ namespace Native\Laravel\Facades; use Illuminate\Support\Facades\Facade; +use Native\Laravel\Contracts\WindowManager as WindowManagerContract; +use Native\Laravel\Fakes\WindowManagerFake; /** * @method static \Native\Laravel\Windows\PendingOpenWindow open(string $id = 'main') @@ -18,8 +20,15 @@ */ class Window extends Facade { + public static function fake() + { + return tap(new WindowManagerFake, function ($fake) { + static::swap($fake); + }); + } + protected static function getFacadeAccessor() { - return \Native\Laravel\Windows\WindowManager::class; + return WindowManagerContract::class; } } diff --git a/src/Fakes/WindowManagerFake.php b/src/Fakes/WindowManagerFake.php new file mode 100644 index 0000000..2f2a1ce --- /dev/null +++ b/src/Fakes/WindowManagerFake.php @@ -0,0 +1,94 @@ + $windows + */ + public function alwaysReturnWindows(array $windows): self + { + $this->forcedWindowReturnValues = $windows; + + return $this; + } + + public function open(string $id = 'main') + { + $this->opened[] = $id; + } + + public function close($id = null) + { + $this->closed[] = $id; + } + + public function hide($id = null) + { + $this->hidden[] = $id; + } + + public function current(): Window + { + $this->ensureForceReturnWindowsProvided(); + + return $this->forcedWindowReturnValues[array_rand($this->forcedWindowReturnValues)]; + } + + /** + * @return array + */ + public function all(): array + { + $this->ensureForceReturnWindowsProvided(); + + return $this->forcedWindowReturnValues; + } + + public function get(string $id): Window + { + $this->ensureForceReturnWindowsProvided(); + + $matchingWindows = array_filter($this->forcedWindowReturnValues, fn (Window $window) => $window->getId() === $id); + + PHPUnit::assertNotEmpty($matchingWindows); + PHPUnit::assertCount(1, $matchingWindows); + + return Arr::first($matchingWindows); + } + + public function assertOpened(string $id): void + { + PHPUnit::assertContains($id, $this->opened); + } + + public function assertClosed(?string $id): void + { + PHPUnit::assertContains($id, $this->closed); + } + + public function assertHidden(?string $id): void + { + PHPUnit::assertContains($id, $this->hidden); + } + + private function ensureForceReturnWindowsProvided(): void + { + PHPUnit::assertNotEmpty($this->forcedWindowReturnValues); + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index d9c28a1..dc2e258 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -3,6 +3,7 @@ namespace Native\Laravel; use Illuminate\Console\Application; +use Illuminate\Foundation\Application as Foundation; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; @@ -12,9 +13,11 @@ use Native\Laravel\Commands\MigrateCommand; use Native\Laravel\Commands\MinifyApplicationCommand; use Native\Laravel\Commands\SeedDatabaseCommand; +use Native\Laravel\Contracts\WindowManager as WindowManagerContract; use Native\Laravel\Events\EventWatcher; use Native\Laravel\Exceptions\Handler; use Native\Laravel\Logging\LogWatcher; +use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -47,6 +50,10 @@ public function packageRegistered() return new MigrateCommand($app['migrator'], $app['events']); }); + $this->app->bind(WindowManagerContract::class, function (Foundation $app) { + return $app->make(WindowManagerImplementation::class); + }); + if (config('nativephp-internal.running')) { $this->app->singleton( \Illuminate\Contracts\Debug\ExceptionHandler::class, diff --git a/src/Windows/WindowManager.php b/src/Windows/WindowManager.php index 49574e6..6404686 100644 --- a/src/Windows/WindowManager.php +++ b/src/Windows/WindowManager.php @@ -4,8 +4,9 @@ use Native\Laravel\Client\Client; use Native\Laravel\Concerns\DetectsWindowId; +use Native\Laravel\Contracts\WindowManager as WindowManagerContract; -class WindowManager +class WindowManager implements WindowManagerContract { use DetectsWindowId; diff --git a/tests/Fakes/FakeWindowManagerTest.php b/tests/Fakes/FakeWindowManagerTest.php new file mode 100644 index 0000000..5f0fbb1 --- /dev/null +++ b/tests/Fakes/FakeWindowManagerTest.php @@ -0,0 +1,142 @@ +toBeInstanceOf(WindowManagerFake::class); +}); + +it('asserts that a window was opened', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + app(WindowManagerContract::class)->open('main'); + app(WindowManagerContract::class)->open('secondary'); + + $fake->assertOpened('main'); + $fake->assertOpened('secondary'); + + try { + $fake->assertOpened('tertiary'); + } catch (AssertionFailedError) { + expect(true)->toBeTrue(); + + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts that a window was closed', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + app(WindowManagerContract::class)->close('main'); + app(WindowManagerContract::class)->close('secondary'); + + $fake->assertClosed('main'); + $fake->assertClosed('secondary'); + + try { + $fake->assertClosed('tertiary'); + } catch (AssertionFailedError) { + expect(true)->toBeTrue(); + + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts that a window was hidden', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + app(WindowManagerContract::class)->hide('main'); + app(WindowManagerContract::class)->hide('secondary'); + + $fake->assertHidden('main'); + $fake->assertHidden('secondary'); + + try { + $fake->assertHidden('tertiary'); + } catch (AssertionFailedError) { + expect(true)->toBeTrue(); + + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('forces the return value of current window', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + $fake->alwaysReturnWindows($windows = [ + new WindowClass('testA'), + new WindowClass('testB'), + ]); + + expect($windows)->toContain(app(WindowManagerContract::class)->current()); +}); + +it('forces the return value of all windows', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + $fake->alwaysReturnWindows($windows = [ + new WindowClass('testA'), + new WindowClass('testB'), + ]); + + expect(app(WindowManagerContract::class)->all())->toBe($windows); +}); + +it('forces the return value of a specific window', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + $fake->alwaysReturnWindows($windows = [ + new WindowClass('testA'), + new WindowClass('testB'), + ]); + + expect(app(WindowManagerContract::class)->get('testA'))->toBe($windows[0]); + expect(app(WindowManagerContract::class)->get('testB'))->toBe($windows[1]); +}); + +test('that the get method throws an exception if multiple matching window ids exist', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + $fake->alwaysReturnWindows($windows = [ + new WindowClass('testA'), + new WindowClass('testA'), + ]); + + app(WindowManagerContract::class)->get('testA'); +})->throws(AssertionFailedError::class); + +test('that the get method throws an exception if no matching window id exists', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + $fake->alwaysReturnWindows($windows = [ + new WindowClass('testA'), + ]); + + app(WindowManagerContract::class)->get('testB'); +})->throws(AssertionFailedError::class); + +test('that the current method throws an exception if no forced window return values are provided', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + app(WindowManagerContract::class)->current(); +})->throws(AssertionFailedError::class); + +test('that the all method throws an exception if no forced window return values are provided', function () { + swap(WindowManagerContract::class, $fake = new WindowManagerFake); + + app(WindowManagerContract::class)->all(); +})->throws(AssertionFailedError::class); From 3b3d8dc8e12a5150b428cc3b2879467d839e7648 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Wed, 20 Nov 2024 12:29:41 +0000 Subject: [PATCH 140/224] Fix styling --- src/Fakes/WindowManagerFake.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Fakes/WindowManagerFake.php b/src/Fakes/WindowManagerFake.php index 2f2a1ce..c3cf791 100644 --- a/src/Fakes/WindowManagerFake.php +++ b/src/Fakes/WindowManagerFake.php @@ -6,7 +6,6 @@ use Native\Laravel\Contracts\WindowManager as WindowManagerContract; use Native\Laravel\Windows\Window; use PHPUnit\Framework\Assert as PHPUnit; -use RuntimeException; class WindowManagerFake implements WindowManagerContract { From ff9283e990cd3a47c5b7433b9f758b3263b5922f Mon Sep 17 00:00:00 2001 From: A G Date: Fri, 22 Nov 2024 06:24:04 -0500 Subject: [PATCH 141/224] Child process test double: (#430) - ChildProcess::class now implements Contracts\ChildProcess::class interface - Facades\ChildProcess::fake() swaps implementations with a test double concrete - Implement new binding in NativeServiceProvider::class - Implement Contracts/ChildProcess::class methods, mimicing that of the implementation - Implement ChildProcessFake::class with assertion helpers - Test that ChildProcessFake::class assertions work --- src/ChildProcess.php | 3 +- src/Contracts/ChildProcess.php | 28 +++ src/Facades/ChildProcess.php | 14 +- src/Fakes/ChildProcessFake.php | 252 +++++++++++++++++++++++++++ src/NativeServiceProvider.php | 6 + tests/Fakes/FakeChildProcessTest.php | 219 +++++++++++++++++++++++ 6 files changed, 518 insertions(+), 4 deletions(-) create mode 100644 src/Contracts/ChildProcess.php create mode 100644 src/Fakes/ChildProcessFake.php create mode 100644 tests/Fakes/FakeChildProcessTest.php diff --git a/src/ChildProcess.php b/src/ChildProcess.php index 171210f..37cff65 100644 --- a/src/ChildProcess.php +++ b/src/ChildProcess.php @@ -3,8 +3,9 @@ namespace Native\Laravel; use Native\Laravel\Client\Client; +use Native\Laravel\Contracts\ChildProcess as ChildProcessContract; -class ChildProcess +class ChildProcess implements ChildProcessContract { public readonly int $pid; diff --git a/src/Contracts/ChildProcess.php b/src/Contracts/ChildProcess.php new file mode 100644 index 0000000..9859e3e --- /dev/null +++ b/src/Contracts/ChildProcess.php @@ -0,0 +1,28 @@ +make(ChildProcessFake::class), function ($fake) { + static::swap($fake); + }); + } + protected static function getFacadeAccessor() { - self::clearResolvedInstance(Implement::class); + self::clearResolvedInstance(ChildProcessContract::class); - return Implement::class; + return ChildProcessContract::class; } } diff --git a/src/Fakes/ChildProcessFake.php b/src/Fakes/ChildProcessFake.php new file mode 100644 index 0000000..4e6add8 --- /dev/null +++ b/src/Fakes/ChildProcessFake.php @@ -0,0 +1,252 @@ + + */ + public array $gets = []; + + /** + * @var array + */ + public array $starts = []; + + /** + * @var array + */ + public array $phps = []; + + /** + * @var array + */ + public array $artisans = []; + + /** + * @var array + */ + public array $stops = []; + + /** + * @var array + */ + public array $restarts = []; + + /** + * @var array + */ + public array $messages = []; + + public function get(?string $alias = null): self + { + $this->gets[] = $alias; + + return $this; + } + + public function all(): array + { + return [$this]; + } + + public function start( + array|string $cmd, + string $alias, + ?string $cwd = null, + ?array $env = null, + bool $persistent = false + ): self { + $this->starts[] = [ + 'cmd' => $cmd, + 'alias' => $alias, + 'cwd' => $cwd, + 'env' => $env, + 'persistent' => $persistent, + ]; + + return $this; + } + + public function php( + array|string $cmd, + string $alias, + ?array $env = null, + ?bool $persistent = false + ): self { + $this->phps[] = [ + 'cmd' => $cmd, + 'alias' => $alias, + 'env' => $env, + 'persistent' => $persistent, + ]; + + return $this; + } + + public function artisan( + array|string $cmd, + string $alias, + ?array $env = null, + ?bool $persistent = false + ): self { + $this->artisans[] = [ + 'cmd' => $cmd, + 'alias' => $alias, + 'env' => $env, + 'persistent' => $persistent, + ]; + + return $this; + } + + public function stop(?string $alias = null): void + { + $this->stops[] = $alias; + } + + public function restart(?string $alias = null): self + { + $this->restarts[] = $alias; + + return $this; + } + + public function message(string $message, ?string $alias = null): self + { + $this->messages[] = [ + 'message' => $message, + 'alias' => $alias, + ]; + + return $this; + } + + /** + * @param string|Closure(string): bool $alias + */ + public function assertGet(string|Closure $alias): void + { + if (is_callable($alias) === false) { + PHPUnit::assertContains($alias, $this->gets); + + return; + } + + $hit = empty( + array_filter( + $this->gets, + fn (mixed $get) => $alias($get) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param Closure(array|string $cmd, string $alias, ?string $cwd, ?array $env, bool $persistent): bool $callback + */ + public function assertStarted(Closure $callback): void + { + $hit = empty( + array_filter( + $this->starts, + fn (array $started) => $callback(...$started) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param Closure(array|string $cmd, string $alias, ?array $env, ?bool $persistent): bool $callback + */ + public function assertPhp(Closure $callback): void + { + $hit = empty( + array_filter( + $this->phps, + fn (array $php) => $callback(...$php) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param Closure(array|string $cmd, string $alias, ?array $env, ?bool $persistent): bool $callback + */ + public function assertArtisan(Closure $callback): void + { + $hit = empty( + array_filter( + $this->artisans, + fn (array $artisan) => $callback(...$artisan) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param string|Closure(string): bool $alias + */ + public function assertStop(string|Closure $alias): void + { + if (is_callable($alias) === false) { + PHPUnit::assertContains($alias, $this->stops); + + return; + } + + $hit = empty( + array_filter( + $this->stops, + fn (mixed $stop) => $alias($stop) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param string|Closure(string): bool $alias + */ + public function assertRestart(string|Closure $alias): void + { + if (is_callable($alias) === false) { + PHPUnit::assertContains($alias, $this->restarts); + + return; + } + + $hit = empty( + array_filter( + $this->restarts, + fn (mixed $restart) => $alias($restart) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param Closure(string $message, string|null $alias): bool $callback + */ + public function assertMessage(Closure $callback): void + { + $hit = empty( + array_filter( + $this->messages, + fn (array $message) => $callback(...$message) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index dc2e258..a17d953 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -7,12 +7,14 @@ use Illuminate\Support\Arr; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; +use Native\Laravel\ChildProcess as ChildProcessImplementation; use Native\Laravel\Commands\FreshCommand; use Native\Laravel\Commands\LoadPHPConfigurationCommand; use Native\Laravel\Commands\LoadStartupConfigurationCommand; use Native\Laravel\Commands\MigrateCommand; use Native\Laravel\Commands\MinifyApplicationCommand; use Native\Laravel\Commands\SeedDatabaseCommand; +use Native\Laravel\Contracts\ChildProcess as ChildProcessContract; use Native\Laravel\Contracts\WindowManager as WindowManagerContract; use Native\Laravel\Events\EventWatcher; use Native\Laravel\Exceptions\Handler; @@ -54,6 +56,10 @@ public function packageRegistered() return $app->make(WindowManagerImplementation::class); }); + $this->app->bind(ChildProcessContract::class, function (Foundation $app) { + return $app->make(ChildProcessImplementation::class); + }); + if (config('nativephp-internal.running')) { $this->app->singleton( \Illuminate\Contracts\Debug\ExceptionHandler::class, diff --git a/tests/Fakes/FakeChildProcessTest.php b/tests/Fakes/FakeChildProcessTest.php new file mode 100644 index 0000000..8fece8a --- /dev/null +++ b/tests/Fakes/FakeChildProcessTest.php @@ -0,0 +1,219 @@ +toBeInstanceOf(ChildProcessFake::class); +}); + +it('asserts get using string', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->get('testA'); + $fake->get('testB'); + + $fake->assertGet('testA'); + $fake->assertGet('testB'); + + try { + $fake->assertGet('testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts get using callable', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->get('testA'); + $fake->get('testB'); + + $fake->assertGet(fn (string $alias) => $alias === 'testA'); + $fake->assertGet(fn (string $alias) => $alias === 'testB'); + + try { + $fake->assertGet(fn (string $alias) => $alias === 'testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts started using callable', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->start('cmdA', 'aliasA', 'cwdA', ['envA'], true); + $fake->start('cmdB', 'aliasB', 'cwdB', ['envB'], false); + + $fake->assertStarted(fn ($cmd, $alias, $cwd, $env, $persistent) => $alias === 'aliasA' && + $cmd === 'cmdA' && + $cwd === 'cwdA' && + $env === ['envA'] && + $persistent === true); + + $fake->assertStarted(fn ($cmd, $alias, $cwd, $env, $persistent) => $alias === 'aliasB' && + $cmd === 'cmdB' && + $cwd === 'cwdB' && + $env === ['envB'] && + $persistent === false); + + try { + $fake->assertStarted(fn ($cmd, $alias, $cwd, $env, $persistent) => $alias === 'aliasC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts php using callable', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->php('cmdA', 'aliasA', ['envA'], true); + $fake->php('cmdB', 'aliasB', ['envB'], false); + + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasA' && + $cmd === 'cmdA' && + $env === ['envA'] && + $persistent === true); + + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasB' && + $cmd === 'cmdB' && + $env === ['envB'] && + $persistent === false); + + try { + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts artisan using callable', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->artisan('cmdA', 'aliasA', ['envA'], true); + $fake->artisan('cmdB', 'aliasB', ['envB'], false); + + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasA' && + $cmd === 'cmdA' && + $env === ['envA'] && + $persistent === true); + + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasB' && + $cmd === 'cmdB' && + $env === ['envB'] && + $persistent === false); + + try { + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts stop using string', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->stop('testA'); + $fake->stop('testB'); + + $fake->assertStop('testA'); + $fake->assertStop('testB'); + + try { + $fake->assertStop('testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts stop using callable', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->stop('testA'); + $fake->stop('testB'); + + $fake->assertStop(fn (string $alias) => $alias === 'testA'); + $fake->assertStop(fn (string $alias) => $alias === 'testB'); + + try { + $fake->assertStop(fn (string $alias) => $alias === 'testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts restart using string', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->restart('testA'); + $fake->restart('testB'); + + $fake->assertRestart('testA'); + $fake->assertRestart('testB'); + + try { + $fake->assertRestart('testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts restart using callable', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->restart('testA'); + $fake->restart('testB'); + + $fake->assertRestart(fn (string $alias) => $alias === 'testA'); + $fake->assertRestart(fn (string $alias) => $alias === 'testB'); + + try { + $fake->assertRestart(fn (string $alias) => $alias === 'testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts message using callable', function () { + swap(ChildProcessContract::class, $fake = app(ChildProcessFake::class)); + + $fake->message('messageA', 'aliasA'); + $fake->message('messageB', 'aliasB'); + + $fake->assertMessage(fn (string $message, string $alias) => $message === 'messageA' && $alias === 'aliasA'); + $fake->assertMessage(fn (string $message, string $alias) => $message === 'messageB' && $alias === 'aliasB'); + + try { + $fake->assertMessage(fn (string $message, string $alias) => $message === 'messageC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + + From 3133d14af3f1f2695dcc3143d07b4824deaf2d4a Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Fri, 22 Nov 2024 12:24:24 +0100 Subject: [PATCH 142/224] fix: Notification facade docbloc (#428) Method returns `static` instead of `object` --- src/Facades/Notification.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Facades/Notification.php b/src/Facades/Notification.php index 4f9f56d..425fea1 100644 --- a/src/Facades/Notification.php +++ b/src/Facades/Notification.php @@ -5,9 +5,9 @@ use Illuminate\Support\Facades\Facade; /** - * @method static object title(string $title) - * @method static object event(string $event) - * @method static object message(string $body) + * @method static static title(string $title) + * @method static static event(string $event) + * @method static static message(string $body) * @method static void show() */ class Notification extends Facade From a6dea1f2bb014ddc74befc44479d24a59a2aca70 Mon Sep 17 00:00:00 2001 From: A G Date: Fri, 22 Nov 2024 06:25:25 -0500 Subject: [PATCH 143/224] Improvements to window test doubles (#426) * Improvements to fake assertions: - Add support for optionally passing closures to methods that perform value assertions - Add count assertions - Enhancements to FakeWindowManagerTest::class * Improvements to window faking: - Resolve test environment error caused FakeWindowManager::open() not returning a Window/PendingOpenWindow object. This now mimics the real WindowManager::open() behavior - Remove usage of PHPUnit assertions in FakeWindowManager::class for internal assertions. Now only used for final assertions. This change fixes issue where PHPUnit was reporting 2 assertions per ::assertX() call on the test double --- src/Facades/Window.php | 2 +- src/Fakes/WindowManagerFake.php | 103 +++++++++++-- tests/Fakes/FakeWindowManagerTest.php | 209 +++++++++++++++++++++++--- 3 files changed, 287 insertions(+), 27 deletions(-) diff --git a/src/Facades/Window.php b/src/Facades/Window.php index e774755..f73e216 100644 --- a/src/Facades/Window.php +++ b/src/Facades/Window.php @@ -22,7 +22,7 @@ class Window extends Facade { public static function fake() { - return tap(new WindowManagerFake, function ($fake) { + return tap(static::getFacadeApplication()->make(WindowManagerFake::class), function ($fake) { static::swap($fake); }); } diff --git a/src/Fakes/WindowManagerFake.php b/src/Fakes/WindowManagerFake.php index c3cf791..8604224 100644 --- a/src/Fakes/WindowManagerFake.php +++ b/src/Fakes/WindowManagerFake.php @@ -2,10 +2,13 @@ namespace Native\Laravel\Fakes; +use Closure; use Illuminate\Support\Arr; +use Native\Laravel\Client\Client; use Native\Laravel\Contracts\WindowManager as WindowManagerContract; use Native\Laravel\Windows\Window; use PHPUnit\Framework\Assert as PHPUnit; +use Webmozart\Assert\Assert; class WindowManagerFake implements WindowManagerContract { @@ -17,6 +20,10 @@ class WindowManagerFake implements WindowManagerContract public array $forcedWindowReturnValues = []; + public function __construct( + protected Client $client + ) {} + /** * @param array $windows */ @@ -30,6 +37,21 @@ public function alwaysReturnWindows(array $windows): self public function open(string $id = 'main') { $this->opened[] = $id; + + $this->ensureForceReturnWindowsProvided(); + + $matchingWindows = array_filter( + $this->forcedWindowReturnValues, + fn (Window $window) => $window->getId() === $id + ); + + if (empty($matchingWindows)) { + return $this->forcedWindowReturnValues[array_rand($this->forcedWindowReturnValues)]->setClient($this->client); + } + + Assert::count($matchingWindows, 1); + + return Arr::first($matchingWindows)->setClient($this->client); } public function close($id = null) @@ -65,29 +87,92 @@ public function get(string $id): Window $matchingWindows = array_filter($this->forcedWindowReturnValues, fn (Window $window) => $window->getId() === $id); - PHPUnit::assertNotEmpty($matchingWindows); - PHPUnit::assertCount(1, $matchingWindows); + Assert::notEmpty($matchingWindows); + Assert::count($matchingWindows, 1); return Arr::first($matchingWindows); } - public function assertOpened(string $id): void + /** + * @param string|Closure(string): bool $id + */ + public function assertOpened(string|Closure $id): void + { + if (is_callable($id) === false) { + PHPUnit::assertContains($id, $this->opened); + + return; + } + + $hit = empty( + array_filter( + $this->opened, + fn (string $openedId) => $id($openedId) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param string|Closure(string): bool $id + */ + public function assertClosed(string|Closure $id): void + { + if (is_callable($id) === false) { + PHPUnit::assertContains($id, $this->closed); + + return; + } + + $hit = empty( + array_filter( + $this->closed, + fn (mixed $closedId) => $id($closedId) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param string|Closure(string): bool $id + */ + public function assertHidden(string|Closure $id): void + { + if (is_callable($id) === false) { + PHPUnit::assertContains($id, $this->hidden); + + return; + } + + $hit = empty( + array_filter( + $this->hidden, + fn (mixed $hiddenId) => $id($hiddenId) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + public function assertOpenedCount(int $expected): void { - PHPUnit::assertContains($id, $this->opened); + PHPUnit::assertCount($expected, $this->opened); } - public function assertClosed(?string $id): void + public function assertClosedCount(int $expected): void { - PHPUnit::assertContains($id, $this->closed); + PHPUnit::assertCount($expected, $this->closed); } - public function assertHidden(?string $id): void + public function assertHiddenCount(int $expected): void { - PHPUnit::assertContains($id, $this->hidden); + PHPUnit::assertCount($expected, $this->hidden); } private function ensureForceReturnWindowsProvided(): void { - PHPUnit::assertNotEmpty($this->forcedWindowReturnValues); + Assert::notEmpty($this->forcedWindowReturnValues, 'No windows were provided to return'); } } diff --git a/tests/Fakes/FakeWindowManagerTest.php b/tests/Fakes/FakeWindowManagerTest.php index 5f0fbb1..b2f4af2 100644 --- a/tests/Fakes/FakeWindowManagerTest.php +++ b/tests/Fakes/FakeWindowManagerTest.php @@ -1,10 +1,13 @@ Http::response(status: 200)]); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + $fake->alwaysReturnWindows([ + new PendingOpenWindow('doesnt-matter'), + ]); app(WindowManagerContract::class)->open('main'); app(WindowManagerContract::class)->open('secondary'); @@ -26,8 +34,30 @@ try { $fake->assertOpened('tertiary'); } catch (AssertionFailedError) { - expect(true)->toBeTrue(); + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts that a window was opened using callable', function () { + Http::fake(['*' => Http::response(status: 200)]); + + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + $fake->alwaysReturnWindows([ + new PendingOpenWindow('doesnt-matter'), + ]); + + app(WindowManagerContract::class)->open('main'); + app(WindowManagerContract::class)->open('secondary'); + $fake->assertOpened(fn (string $id) => $id === 'main'); + $fake->assertOpened(fn (string $id) => $id === 'secondary'); + + try { + $fake->assertOpened(fn (string $id) => $id === 'tertiary'); + } catch (AssertionFailedError) { return; } @@ -35,7 +65,7 @@ }); it('asserts that a window was closed', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); app(WindowManagerContract::class)->close('main'); app(WindowManagerContract::class)->close('secondary'); @@ -46,8 +76,24 @@ try { $fake->assertClosed('tertiary'); } catch (AssertionFailedError) { - expect(true)->toBeTrue(); + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts that a window was closed using callable', function () { + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + app(WindowManagerContract::class)->close('main'); + app(WindowManagerContract::class)->close('secondary'); + + $fake->assertClosed(fn (string $id) => $id === 'main'); + $fake->assertClosed(fn (string $id) => $id === 'secondary'); + + try { + $fake->assertClosed(fn (string $id) => $id === 'tertiary'); + } catch (AssertionFailedError) { return; } @@ -55,7 +101,7 @@ }); it('asserts that a window was hidden', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); app(WindowManagerContract::class)->hide('main'); app(WindowManagerContract::class)->hide('secondary'); @@ -66,8 +112,84 @@ try { $fake->assertHidden('tertiary'); } catch (AssertionFailedError) { - expect(true)->toBeTrue(); + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts that a window was hidden using callable', function () { + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + app(WindowManagerContract::class)->hide('main'); + app(WindowManagerContract::class)->hide('secondary'); + + $fake->assertHidden(fn (string $id) => $id === 'main'); + $fake->assertHidden(fn (string $id) => $id === 'secondary'); + + try { + $fake->assertHidden(fn (string $id) => $id === 'tertiary'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts opened count', function () { + Http::fake(['*' => Http::response(status: 200)]); + + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + $fake->alwaysReturnWindows([ + new PendingOpenWindow('doesnt-matter'), + ]); + + app(WindowManagerContract::class)->open('main'); + app(WindowManagerContract::class)->open(); + app(WindowManagerContract::class)->open(); + + $fake->assertOpenedCount(3); + + try { + $fake->assertOpenedCount(4); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts closed count', function () { + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + app(WindowManagerContract::class)->close('main'); + app(WindowManagerContract::class)->close(); + app(WindowManagerContract::class)->close(); + + $fake->assertClosedCount(3); + + try { + $fake->assertClosedCount(4); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts hidden count', function () { + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + app(WindowManagerContract::class)->hide('main'); + app(WindowManagerContract::class)->hide(); + app(WindowManagerContract::class)->hide(); + + $fake->assertHiddenCount(3); + + try { + $fake->assertHiddenCount(4); + } catch (AssertionFailedError) { return; } @@ -75,7 +197,7 @@ }); it('forces the return value of current window', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); $fake->alwaysReturnWindows($windows = [ new WindowClass('testA'), @@ -86,7 +208,7 @@ }); it('forces the return value of all windows', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); $fake->alwaysReturnWindows($windows = [ new WindowClass('testA'), @@ -97,7 +219,7 @@ }); it('forces the return value of a specific window', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); $fake->alwaysReturnWindows($windows = [ new WindowClass('testA'), @@ -109,7 +231,7 @@ }); test('that the get method throws an exception if multiple matching window ids exist', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); $fake->alwaysReturnWindows($windows = [ new WindowClass('testA'), @@ -117,26 +239,79 @@ ]); app(WindowManagerContract::class)->get('testA'); -})->throws(AssertionFailedError::class); +})->throws(InvalidArgumentException::class); test('that the get method throws an exception if no matching window id exists', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); $fake->alwaysReturnWindows($windows = [ new WindowClass('testA'), ]); app(WindowManagerContract::class)->get('testB'); -})->throws(AssertionFailedError::class); +})->throws(InvalidArgumentException::class); test('that the current method throws an exception if no forced window return values are provided', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); app(WindowManagerContract::class)->current(); -})->throws(AssertionFailedError::class); +})->throws(InvalidArgumentException::class); test('that the all method throws an exception if no forced window return values are provided', function () { - swap(WindowManagerContract::class, $fake = new WindowManagerFake); + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); app(WindowManagerContract::class)->all(); -})->throws(AssertionFailedError::class); +})->throws(InvalidArgumentException::class); + +test('that the open method throws an exception if no forced window return values are provided', function () { + Http::fake([ + '*' => Http::response(status: 200), + ]); + + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + app(WindowManagerContract::class)->open('test'); +})->throws(InvalidArgumentException::class); + +test('that the open method throws an exception if multiple matching window ids exist', function () { + Http::fake([ + '*' => Http::response(status: 200), + ]); + + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + $fake->alwaysReturnWindows($windows = [ + new WindowClass('testA'), + new WindowClass('testA'), + ]); + + app(WindowManagerContract::class)->open('testA'); +})->throws(InvalidArgumentException::class); + +test('that the open method returns a random window if none match the id provided', function () { + Http::fake([ + '*' => Http::response(status: 200), + ]); + + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + $fake->alwaysReturnWindows($windows = [ + new PendingOpenWindow('testA'), + ]); + + expect($windows)->toContain(app(WindowManagerContract::class)->open('testC')); +}); + +test('that the open method returns a window if a matching window id exists', function () { + Http::fake([ + '*' => Http::response(status: 200), + ]); + + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + $fake->alwaysReturnWindows($windows = [ + new PendingOpenWindow('testA'), + ]); + + expect(app(WindowManagerContract::class)->open('testA'))->toBe($windows[0]); +}); From 7b9096955bd033bd57e1665d01372a4c65ac812f Mon Sep 17 00:00:00 2001 From: simonhamp Date: Fri, 22 Nov 2024 11:26:17 +0000 Subject: [PATCH 144/224] Fix styling --- tests/Fakes/FakeChildProcessTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/Fakes/FakeChildProcessTest.php b/tests/Fakes/FakeChildProcessTest.php index 8fece8a..57b0c35 100644 --- a/tests/Fakes/FakeChildProcessTest.php +++ b/tests/Fakes/FakeChildProcessTest.php @@ -215,5 +215,3 @@ $this->fail('Expected assertion to fail'); }); - - From 98405aee00259d2ee80251f5cd6c204ef7eb9042 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Sat, 23 Nov 2024 11:27:07 +0100 Subject: [PATCH 145/224] fix: child process cmd: option except iterable array (#429) * fix: child process cmd: option except iterable array TypeError: settings.cmd is not iterable at startPhpProcess * fix: throw an exception if $cmd is not an indexed array * fix: array_values but with a hint for static analyzer --- src/ChildProcess.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/ChildProcess.php b/src/ChildProcess.php index 37cff65..634e3f4 100644 --- a/src/ChildProcess.php +++ b/src/ChildProcess.php @@ -52,6 +52,10 @@ public function all(): array return $hydrated; } + /** + * @param string|string[] $cmd + * @return $this + */ public function start( string|array $cmd, string $alias, @@ -59,10 +63,11 @@ public function start( ?array $env = null, bool $persistent = false ): static { + $cmd = is_array($cmd) ? array_values($cmd) : [$cmd]; $process = $this->client->post('child-process/start', [ 'alias' => $alias, - 'cmd' => (array) $cmd, + 'cmd' => $cmd, 'cwd' => $cwd ?? base_path(), 'env' => $env, 'persistent' => $persistent, @@ -71,11 +76,17 @@ public function start( return $this->fromRuntimeProcess($process); } + /** + * @param string|string[] $cmd + * @return $this + */ public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self { + $cmd = is_array($cmd) ? array_values($cmd) : [$cmd]; + $process = $this->client->post('child-process/start-php', [ 'alias' => $alias, - 'cmd' => (array) $cmd, + 'cmd' => $cmd, 'cwd' => $cwd ?? base_path(), 'env' => $env, 'persistent' => $persistent, @@ -84,9 +95,15 @@ public function php(string|array $cmd, string $alias, ?array $env = null, ?bool return $this->fromRuntimeProcess($process); } + /** + * @param string|string[] $cmd + * @return $this + */ public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self { - $cmd = ['artisan', ...(array) $cmd]; + $cmd = is_array($cmd) ? array_values($cmd) : [$cmd]; + + $cmd = ['artisan', ...$cmd]; return $this->php($cmd, $alias, env: $env, persistent: $persistent); } From 41459c2a9df696741febf960cfd46f669f89f636 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 25 Nov 2024 14:56:20 +0100 Subject: [PATCH 146/224] feature: improve Settings (#432) --- src/Facades/Settings.php | 6 ++++-- src/Settings.php | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Facades/Settings.php b/src/Facades/Settings.php index 2fc2fdd..527c0f9 100644 --- a/src/Facades/Settings.php +++ b/src/Facades/Settings.php @@ -5,8 +5,10 @@ use Illuminate\Support\Facades\Facade; /** - * @method static void set($key, $value) - * @method static mixed get($key, $default = null) + * @method static void set(string $key, $value) + * @method static mixed get(string $key, $default = null) + * @method static void forget(string $key) + * @method static void clear() */ class Settings extends Facade { diff --git a/src/Settings.php b/src/Settings.php index 68e65b5..e849c72 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -8,15 +8,25 @@ class Settings { public function __construct(protected Client $client) {} - public function set($key, $value): void + public function set(string $key, $value): void { $this->client->post('settings/'.$key, [ 'value' => $value, ]); } - public function get($key, $default = null): mixed + public function get(string $key, $default = null): mixed { return $this->client->get('settings/'.$key)->json('value') ?? $default; } + + public function forget(string $key): void + { + $this->client->delete('settings/'.$key); + } + + public function clear(): void + { + $this->client->delete('settings/'); + } } From 79f8966d6d711844e1917877cd61989710c72526 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 26 Nov 2024 14:15:03 +0000 Subject: [PATCH 147/224] Dock goodies (#421) * Dock goodies * Fix styling * fix --------- Co-authored-by: simonhamp --- src/Dock.php | 34 ++++++++++++++++++++++++++++++++++ src/Facades/Dock.php | 6 ++++++ 2 files changed, 40 insertions(+) diff --git a/src/Dock.php b/src/Dock.php index dbd091d..bdbb298 100644 --- a/src/Dock.php +++ b/src/Dock.php @@ -17,4 +17,38 @@ public function menu(Menu $menu) 'items' => $items, ]); } + + public function show() + { + $this->client->post('dock/show'); + } + + public function hide() + { + $this->client->post('dock/hide'); + } + + public function icon(string $path) + { + $this->client->post('dock/icon', ['path' => $path]); + } + + public function bounce(string $type = 'informational') + { + $this->client->post('dock/bounce', ['type' => $type]); + } + + public function cancelBounce() + { + $this->client->post('dock/cancel-bounce'); + } + + public function badge(?string $label = null): void|string + { + if (is_null($label)) { + return $this->client->get('dock/badge'); + } + + $this->client->post('dock/badge', ['label' => $label]); + } } diff --git a/src/Facades/Dock.php b/src/Facades/Dock.php index f938643..b088219 100644 --- a/src/Facades/Dock.php +++ b/src/Facades/Dock.php @@ -6,7 +6,13 @@ use Native\Laravel\Menu\Menu; /** + * @method static void bounce() + * @method static void|string badge(string $type = null) + * @method static void cancelBounce() + * @method static void hide() + * @method static void icon(string $Path) * @method static void menu(Menu $menu) + * @method static void show() */ class Dock extends Facade { From 49dee31a662aa7208c4b51745471978fad21fd41 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 26 Nov 2024 14:16:16 +0000 Subject: [PATCH 148/224] MenuBars continued (#420) * Remove `event` prop * Standardise events * Fix styling * Fix class name --------- Co-authored-by: simonhamp --- src/Events/MenuBar/MenuBarClicked.php | 23 +++++++++++++++++++ src/Events/MenuBar/MenuBarDoubleClicked.php | 23 +++++++++++++++++++ ...MenuOpened.php => MenuBarRightClicked.php} | 4 +++- src/MenuBar/MenuBar.php | 10 -------- 4 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 src/Events/MenuBar/MenuBarClicked.php create mode 100644 src/Events/MenuBar/MenuBarDoubleClicked.php rename src/Events/MenuBar/{MenuBarContextMenuOpened.php => MenuBarRightClicked.php} (77%) diff --git a/src/Events/MenuBar/MenuBarClicked.php b/src/Events/MenuBar/MenuBarClicked.php new file mode 100644 index 0000000..4ac8f9e --- /dev/null +++ b/src/Events/MenuBar/MenuBarClicked.php @@ -0,0 +1,23 @@ +event = $event; - - return $this; - } - public function withContextMenu(Menu $menu): self { $this->contextMenu = $menu; @@ -131,7 +122,6 @@ public function toArray(): array 'onlyShowContextMenu' => $this->onlyShowContextMenu, 'contextMenu' => ! is_null($this->contextMenu) ? $this->contextMenu->toArray()['submenu'] : null, 'alwaysOnTop' => $this->alwaysOnTop, - 'event' => $this->event, ]; } } From 7f4994d0c08208ea2df297ad355232927e4b3516 Mon Sep 17 00:00:00 2001 From: A G Date: Sun, 1 Dec 2024 18:15:00 -0500 Subject: [PATCH 149/224] Global shortcut test double: (#436) - GlobalShortcut::class now implements Contracts\GlobalShortcut::class interface - Facades\GlobalShortcut::fake() swaps implementations with a test double concrete - Implement new binding in NativeServiceProvider::clas - Implement GlobalShortcutFake::class with assertion helpers - Test that GlobalShortcutFake::class assertions work --- src/Contracts/GlobalShortcut.php | 14 +++ src/Facades/GlobalShortcut.php | 11 ++- src/Fakes/GlobalShortcutFake.php | 100 ++++++++++++++++++++ src/GlobalShortcut.php | 3 +- src/NativeServiceProvider.php | 6 ++ tests/Fakes/FakeGlobalShortcutTest.php | 124 +++++++++++++++++++++++++ 6 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 src/Contracts/GlobalShortcut.php create mode 100644 src/Fakes/GlobalShortcutFake.php create mode 100644 tests/Fakes/FakeGlobalShortcutTest.php diff --git a/src/Contracts/GlobalShortcut.php b/src/Contracts/GlobalShortcut.php new file mode 100644 index 0000000..2fff35e --- /dev/null +++ b/src/Contracts/GlobalShortcut.php @@ -0,0 +1,14 @@ +make(GlobalShortcutFake::class), function ($fake) { + static::swap($fake); + }); + } + protected static function getFacadeAccessor() { - return \Native\Laravel\GlobalShortcut::class; + return GlobalShortcutContract::class; } } diff --git a/src/Fakes/GlobalShortcutFake.php b/src/Fakes/GlobalShortcutFake.php new file mode 100644 index 0000000..13efa1e --- /dev/null +++ b/src/Fakes/GlobalShortcutFake.php @@ -0,0 +1,100 @@ + + */ + public array $keys = []; + + /** + * @var array + */ + public array $events = []; + + public int $registeredCount = 0; + + public int $unregisteredCount = 0; + + public function key(string $key): self + { + $this->keys[] = $key; + + return $this; + } + + public function event(string $event): self + { + $this->events[] = $event; + + return $this; + } + + public function register(): void + { + $this->registeredCount++; + } + + public function unregister(): void + { + $this->unregisteredCount++; + } + + /** + * @param string|Closure(string): bool $key + */ + public function assertKey(string|Closure $key): void + { + if (is_callable($key) === false) { + PHPUnit::assertContains($key, $this->keys); + + return; + } + + $hit = empty( + array_filter( + $this->keys, + fn (string $keyIteration) => $key($keyIteration) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + /** + * @param string|Closure(string): bool $event + */ + public function assertEvent(string|Closure $event): void + { + if (is_callable($event) === false) { + PHPUnit::assertContains($event, $this->events); + + return; + } + + $hit = empty( + array_filter( + $this->events, + fn (string $eventIteration) => $event($eventIteration) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + public function assertRegisteredCount(int $count): void + { + PHPUnit::assertSame($count, $this->registeredCount); + } + + public function assertUnregisteredCount(int $count): void + { + PHPUnit::assertSame($count, $this->unregisteredCount); + } +} diff --git a/src/GlobalShortcut.php b/src/GlobalShortcut.php index 991c341..3859e6a 100644 --- a/src/GlobalShortcut.php +++ b/src/GlobalShortcut.php @@ -3,8 +3,9 @@ namespace Native\Laravel; use Native\Laravel\Client\Client; +use Native\Laravel\Contracts\GlobalShortcut as GlobalShortcutContract; -class GlobalShortcut +class GlobalShortcut implements GlobalShortcutContract { protected string $key; diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index a17d953..9701766 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -15,9 +15,11 @@ use Native\Laravel\Commands\MinifyApplicationCommand; use Native\Laravel\Commands\SeedDatabaseCommand; use Native\Laravel\Contracts\ChildProcess as ChildProcessContract; +use Native\Laravel\Contracts\GlobalShortcut as GlobalShortcutContract; use Native\Laravel\Contracts\WindowManager as WindowManagerContract; use Native\Laravel\Events\EventWatcher; use Native\Laravel\Exceptions\Handler; +use Native\Laravel\GlobalShortcut as GlobalShortcutImplementation; use Native\Laravel\Logging\LogWatcher; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; use Spatie\LaravelPackageTools\Package; @@ -60,6 +62,10 @@ public function packageRegistered() return $app->make(ChildProcessImplementation::class); }); + $this->app->bind(GlobalShortcutContract::class, function (Foundation $app) { + return $app->make(GlobalShortcutImplementation::class); + }); + if (config('nativephp-internal.running')) { $this->app->singleton( \Illuminate\Contracts\Debug\ExceptionHandler::class, diff --git a/tests/Fakes/FakeGlobalShortcutTest.php b/tests/Fakes/FakeGlobalShortcutTest.php new file mode 100644 index 0000000..07bba84 --- /dev/null +++ b/tests/Fakes/FakeGlobalShortcutTest.php @@ -0,0 +1,124 @@ +toBeInstanceOf(GlobalShortcutFake::class); +}); + +it('asserts key using string', function () { + swap(GlobalShortcutContract::class, $fake = app(GlobalShortcutFake::class)); + + $fake->key('testA'); + $fake->key('testB'); + + $fake->assertKey('testA'); + $fake->assertKey('testB'); + + try { + $fake->assertKey('testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts key using callable', function () { + swap(GlobalShortcutContract::class, $fake = app(GlobalShortcutFake::class)); + + $fake->key('testA'); + $fake->key('testB'); + + $fake->assertKey(fn (string $key) => $key === 'testA'); + $fake->assertKey(fn (string $key) => $key === 'testB'); + + try { + $fake->assertKey(fn (string $key) => $key === 'testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts event using string', function () { + swap(GlobalShortcutContract::class, $fake = app(GlobalShortcutFake::class)); + + $fake->event('testA'); + $fake->event('testB'); + + $fake->assertEvent('testA'); + $fake->assertEvent('testB'); + + try { + $fake->assertEvent('testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts event using callable', function () { + swap(GlobalShortcutContract::class, $fake = app(GlobalShortcutFake::class)); + + $fake->event('testA'); + $fake->event('testB'); + + $fake->assertEvent(fn (string $event) => $event === 'testA'); + $fake->assertEvent(fn (string $event) => $event === 'testB'); + + try { + $fake->assertEvent(fn (string $event) => $event === 'testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts registered count', function () { + swap(GlobalShortcutContract::class, $fake = app(GlobalShortcutFake::class)); + + $fake->register(); + $fake->register(); + $fake->register(); + + $fake->assertRegisteredCount(3); + + try { + $fake->assertRegisteredCount(2); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts unregistered count', function () { + swap(GlobalShortcutContract::class, $fake = app(GlobalShortcutFake::class)); + + $fake->unregister(); + $fake->unregister(); + $fake->unregister(); + + $fake->assertUnregisteredCount(3); + + try { + $fake->assertUnregisteredCount(2); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + From a30505f842e0a906d1d8e059071698791c999ca7 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Sun, 1 Dec 2024 23:15:21 +0000 Subject: [PATCH 150/224] Fix styling --- tests/Fakes/FakeGlobalShortcutTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/Fakes/FakeGlobalShortcutTest.php b/tests/Fakes/FakeGlobalShortcutTest.php index 07bba84..0847cb9 100644 --- a/tests/Fakes/FakeGlobalShortcutTest.php +++ b/tests/Fakes/FakeGlobalShortcutTest.php @@ -1,9 +1,8 @@ fail('Expected assertion to fail'); }); - From 53c7fa2f882aaee55bb678ba656e5394bc28ff7e Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sun, 1 Dec 2024 23:38:14 +0000 Subject: [PATCH 151/224] Menu improvements (#423) * Extract MenuBuilder * Add more Electron MenuItem roles * Allow MenuItems to have submenus * enabled/disabled * Add GoToUrl convenience item * Fix styling * Add help and hide roles * Receive combo key data * Add id's to menu items * Support radio items * Style * Remove custom event menu item type * Support custom event firing on all menu items * Fix label * Type hints and consistency * Fix styling * Get rid of the yucky GoTo* stuff Fold it all into Link instead * Fix test * Add hotkey alias method * Update docblock * Make Menu JsonSerializable * Fix styling --------- Co-authored-by: simonhamp --- src/Enums/RolesEnum.php | 14 ++- src/Events/Menu/MenuItemClicked.php | 2 +- src/Facades/Menu.php | 51 +++++++++ src/Menu/Items/Checkbox.php | 7 +- src/Menu/Items/Event.php | 17 --- src/Menu/Items/Link.php | 10 ++ src/Menu/Items/MenuItem.php | 50 ++++++++- src/Menu/Items/Radio.php | 7 +- src/Menu/Menu.php | 103 +++-------------- src/Menu/MenuBuilder.php | 165 ++++++++++++++++++++++++++++ tests/MenuBar/MenuBarTest.php | 7 +- 11 files changed, 316 insertions(+), 117 deletions(-) create mode 100644 src/Facades/Menu.php delete mode 100644 src/Menu/Items/Event.php create mode 100644 src/Menu/MenuBuilder.php diff --git a/src/Enums/RolesEnum.php b/src/Enums/RolesEnum.php index 337c479..0039d72 100644 --- a/src/Enums/RolesEnum.php +++ b/src/Enums/RolesEnum.php @@ -4,12 +4,24 @@ enum RolesEnum: string { - case APP_MENU = 'appMenu'; + case APP_MENU = 'appMenu'; // macOS case FILE_MENU = 'fileMenu'; case EDIT_MENU = 'editMenu'; case VIEW_MENU = 'viewMenu'; case WINDOW_MENU = 'windowMenu'; + case HELP = 'help'; // macOS + case UNDO = 'undo'; + case REDO = 'redo'; + case CUT = 'cut'; + case COPY = 'copy'; + case PASTE = 'paste'; + case PASTE_STYLE = 'pasteAndMatchStyle'; + case RELOAD = 'reload'; + case HIDE = 'hide'; // macOS + case MINIMIZE = 'minimize'; + case CLOSE = 'close'; case QUIT = 'quit'; case TOGGLE_FULL_SCREEN = 'togglefullscreen'; case TOGGLE_DEV_TOOLS = 'toggleDevTools'; + case ABOUT = 'about'; } diff --git a/src/Events/Menu/MenuItemClicked.php b/src/Events/Menu/MenuItemClicked.php index d9daa74..961ed1c 100644 --- a/src/Events/Menu/MenuItemClicked.php +++ b/src/Events/Menu/MenuItemClicked.php @@ -12,7 +12,7 @@ class MenuItemClicked implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public array $item) {} + public function __construct(public array $item, public array $combo = []) {} public function broadcastOn() { diff --git a/src/Facades/Menu.php b/src/Facades/Menu.php new file mode 100644 index 0000000..e12c2cb --- /dev/null +++ b/src/Facades/Menu.php @@ -0,0 +1,51 @@ +label = $label; } } diff --git a/src/Menu/Items/Event.php b/src/Menu/Items/Event.php deleted file mode 100644 index 02af55e..0000000 --- a/src/Menu/Items/Event.php +++ /dev/null @@ -1,17 +0,0 @@ - 'event', - 'event' => $this->event, - 'label' => $this->label, - ]); - } -} diff --git a/src/Menu/Items/Link.php b/src/Menu/Items/Link.php index ec5a1cd..3655574 100644 --- a/src/Menu/Items/Link.php +++ b/src/Menu/Items/Link.php @@ -6,12 +6,22 @@ class Link extends MenuItem { protected string $type = 'link'; + protected bool $openInBrowser = false; + public function __construct(protected string $url, protected ?string $label, protected ?string $accelerator = null) {} + public function openInBrowser(bool $openInBrowser = true): self + { + $this->openInBrowser = $openInBrowser; + + return $this; + } + public function toArray(): array { return array_merge(parent::toArray(), [ 'url' => $this->url, + 'openInBrowser' => $this->openInBrowser, ]); } } diff --git a/src/Menu/Items/MenuItem.php b/src/Menu/Items/MenuItem.php index 34d41ba..7fe9051 100644 --- a/src/Menu/Items/MenuItem.php +++ b/src/Menu/Items/MenuItem.php @@ -3,11 +3,15 @@ namespace Native\Laravel\Menu\Items; use Native\Laravel\Contracts\MenuItem as MenuItemContract; +use Native\Laravel\Facades\Menu as MenuFacade; +use Native\Laravel\Menu\Menu; abstract class MenuItem implements MenuItemContract { protected string $type = 'normal'; + protected ?string $id = null; + protected ?string $label = null; protected ?string $sublabel = null; @@ -18,15 +22,33 @@ abstract class MenuItem implements MenuItemContract protected ?string $toolTip = null; + protected ?Menu $submenu = null; + protected bool $isEnabled = true; protected bool $isVisible = true; protected bool $isChecked = false; - public function enabled($enabled = true): self + protected ?string $event = null; + + public function enabled(): self + { + $this->isEnabled = true; + + return $this; + } + + public function disabled(): self + { + $this->isEnabled = false; + + return $this; + } + + public function id(string $id): self { - $this->isEnabled = $enabled; + $this->id = $id; return $this; } @@ -66,6 +88,11 @@ public function accelerator(string $accelerator): self return $this; } + public function hotkey(string $hotkey): self + { + return $this->accelerator($hotkey); + } + public function checked($checked = true): self { $this->isChecked = $checked; @@ -73,18 +100,34 @@ public function checked($checked = true): self return $this; } - public function toolTip(string $toolTip): self + public function tooltip(string $toolTip): self { $this->toolTip = $toolTip; return $this; } + public function submenu(MenuItemContract ...$items): self + { + $this->submenu = MenuFacade::make(...$items); + + return $this; + } + + public function event(string $event): self + { + $this->event = $event; + + return $this; + } + public function toArray(): array { return array_filter([ 'type' => $this->type, + 'id' => $this->id, 'label' => $this->label, + 'event' => $this->event, 'sublabel' => $this->sublabel, 'toolTip' => $this->toolTip, 'enabled' => $this->isEnabled, @@ -92,6 +135,7 @@ public function toArray(): array 'checked' => $this->isChecked, 'accelerator' => $this->accelerator, 'icon' => $this->icon, + 'submenu' => $this->submenu?->toArray(), ], fn ($value) => $value !== null); } } diff --git a/src/Menu/Items/Radio.php b/src/Menu/Items/Radio.php index 63587a2..0751522 100644 --- a/src/Menu/Items/Radio.php +++ b/src/Menu/Items/Radio.php @@ -6,8 +6,11 @@ class Radio extends MenuItem { protected string $type = 'radio'; - public function __construct(string $label) - { + public function __construct( + string $label, + protected bool $isChecked = false, + protected ?string $accelerator = null + ) { $this->label = $label; } } diff --git a/src/Menu/Menu.php b/src/Menu/Menu.php index 47a81b0..c97a30d 100644 --- a/src/Menu/Menu.php +++ b/src/Menu/Menu.php @@ -3,31 +3,20 @@ namespace Native\Laravel\Menu; use Illuminate\Support\Traits\Conditionable; +use JsonSerializable; use Native\Laravel\Client\Client; use Native\Laravel\Contracts\MenuItem; -use Native\Laravel\Enums\RolesEnum; -use Native\Laravel\Menu\Items\Checkbox; -use Native\Laravel\Menu\Items\Event; -use Native\Laravel\Menu\Items\Label; -use Native\Laravel\Menu\Items\Link; -use Native\Laravel\Menu\Items\Role; -use Native\Laravel\Menu\Items\Separator; -class Menu implements MenuItem +class Menu implements JsonSerializable, MenuItem { use Conditionable; protected array $items = []; - protected string $prepend = ''; + protected string $label = ''; public function __construct(protected Client $client) {} - public static function new(): static - { - return new static(new Client); - } - public function register(): void { $items = $this->toArray()['submenu']; @@ -37,81 +26,11 @@ public function register(): void ]); } - public function prepend(string $prepend): self - { - $this->prepend = $prepend; - - return $this; - } - - public function submenu(string $header, Menu $submenu): static - { - return $this->add($submenu->prepend($header)); - } - - public function separator(): static - { - return $this->add(new Separator); - } - - public function quit(): static - { - return $this->add(new Role(RolesEnum::QUIT)); - } - public function label(string $label): self { - return $this->add(new Label($label)); - } - - public function checkbox(string $label, bool $checked = false, ?string $hotkey = null): self - { - return $this->add(new Checkbox($label, $checked, $hotkey)); - } - - public function event(string $event, string $text, ?string $hotkey = null): self - { - return $this->add(new Event($event, $text, $hotkey)); - } - - public function link(string $url, string $text, ?string $hotkey = null): self - { - return $this->add(new Link($url, $text, $hotkey)); - } + $this->label = $label; - public function appMenu(): static - { - return $this->add(new Role(RolesEnum::APP_MENU)); - } - - public function fileMenu($label = 'File'): static - { - return $this->add(new Role(RolesEnum::FILE_MENU, $label)); - } - - public function editMenu($label = 'Edit'): static - { - return $this->add(new Role(RolesEnum::EDIT_MENU, $label)); - } - - public function viewMenu($label = 'View'): static - { - return $this->add(new Role(RolesEnum::VIEW_MENU, $label)); - } - - public function windowMenu($label = 'Window'): static - { - return $this->add(new Role(RolesEnum::WINDOW_MENU, $label)); - } - - public function toggleFullscreen(): static - { - return $this->add(new Role(RolesEnum::TOGGLE_FULL_SCREEN)); - } - - public function toggleDevTools(): static - { - return $this->add(new Role(RolesEnum::TOGGLE_DEV_TOOLS)); + return $this; } public function add(MenuItem $item): self @@ -123,12 +42,18 @@ public function add(MenuItem $item): self public function toArray(): array { - $items = collect($this->items)->map(fn (MenuItem $item) => $item->toArray())->toArray(); - $label = $this->prepend; + $items = collect($this->items) + ->map(fn (MenuItem $item) => $item->toArray()) + ->toArray(); return [ - 'label' => $label, + 'label' => $this->label, 'submenu' => $items, ]; } + + public function jsonSerialize(): array + { + return $this->toArray(); + } } diff --git a/src/Menu/MenuBuilder.php b/src/Menu/MenuBuilder.php new file mode 100644 index 0000000..52ca3c9 --- /dev/null +++ b/src/Menu/MenuBuilder.php @@ -0,0 +1,165 @@ +client); + + foreach ($items as $item) { + $menu->add($item); + } + + return $menu; + } + + public function create(MenuItem ...$items): void + { + $this->make(...$items) + ->register(); + } + + public function default(): void + { + $this->create( + $this->app(), + $this->file(), + $this->edit(), + $this->view(), + $this->window(), + ); + } + + public function label(string $label): Items\Label + { + return new Items\Label($label); + } + + public function checkbox(string $label, bool $checked = false, ?string $hotkey = null): Items\Checkbox + { + return new Items\Checkbox($label, $checked, $hotkey); + } + + public function radio(string $label, bool $checked = false, ?string $hotkey = null): Items\Radio + { + return new Items\Radio($label, $checked, $hotkey); + } + + public function link(string $url, ?string $label = null, ?string $hotkey = null): Items\Link + { + return new Items\Link($url, $label, $hotkey); + } + + public function route(string $route, ?string $label = null, ?string $hotkey = null): Items\Link + { + return new Items\Link(route($route), $label, $hotkey); + } + + public function app(): Items\Role + { + return new Items\Role(RolesEnum::APP_MENU); + } + + public function file(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::FILE_MENU, $label); + } + + public function edit(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::EDIT_MENU, $label); + } + + public function view(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::VIEW_MENU, $label); + } + + public function window(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::WINDOW_MENU, $label); + } + + public function separator(): Items\Separator + { + return new Items\Separator; + } + + public function fullscreen(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::TOGGLE_FULL_SCREEN, $label); + } + + public function devTools(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::TOGGLE_DEV_TOOLS, $label); + } + + public function undo(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::UNDO, $label); + } + + public function redo(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::REDO, $label); + } + + public function cut(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::CUT, $label); + } + + public function copy(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::COPY, $label); + } + + public function paste(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::PASTE, $label); + } + + public function pasteAndMatchStyle(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::PASTE_STYLE, $label); + } + + public function reload(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::RELOAD, $label); + } + + public function minimize(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::MINIMIZE, $label); + } + + public function close(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::CLOSE, $label); + } + + public function quit(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::QUIT, $label); + } + + public function help(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::HELP, $label); + } + + public function hide(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::HIDE, $label); + } +} diff --git a/tests/MenuBar/MenuBarTest.php b/tests/MenuBar/MenuBarTest.php index ec1c022..4b86aa9 100644 --- a/tests/MenuBar/MenuBarTest.php +++ b/tests/MenuBar/MenuBarTest.php @@ -1,7 +1,7 @@ set('nativephp-internal.api_url', 'https://jsonplaceholder.typicode.com/todos/1'); @@ -13,7 +13,10 @@ ->icon('nativephp.png') ->url('https://github.com/milwad-dev') ->withContextMenu( - Menu::new()->label('My Application')->quit(), + Menu::make( + Menu::label('My Application'), + Menu::quit(), + ), ); $menuBarArray = $menuBar->toArray(); From 3dae3bc891b6d59fb9493211ae489e7dc3476d65 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 3 Dec 2024 12:45:46 +0000 Subject: [PATCH 152/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index e84c04c..262bbd9 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -31,7 +31,7 @@ body: placeholder: When I do X I see Y. validations: required: true - - type: input + - type: markdown id: package-version attributes: label: Package Versions From 8bbef24d5889b789da220e6070acb4d750d68316 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 3 Dec 2024 12:49:34 +0000 Subject: [PATCH 153/224] Update bug.yml --- .github/ISSUE_TEMPLATE/bug.yml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index 262bbd9..f454785 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -1,12 +1,20 @@ name: Bug Report description: | - Found a bug in NativePHP? Before submitting your report, please make sure you've been through the section "Debugging" in the docs: https://nativephp.com/docs/getting-started/debugging. + Found a bug in NativePHP? You're in the right place! labels: ["bug"] body: - type: markdown attributes: value: | - We're sorry to hear you have a problem. Please help us solve it by providing the following details. + We're sorry to hear you have a problem. + + Before submitting your report, please make sure you've been through the section "[Debugging](https://nativephp.com/docs/getting-started/debugging)" in the docs. + + If nothing here has helped you, please provide as much useful context as you can here to help us solve help you. + + Note that reams and reams of logs isn't helpful - please share only relevant errors. + + If possible, please prepare a reproduction repo and link to it in the Notes field. - type: textarea id: what-doing attributes: @@ -31,7 +39,7 @@ body: placeholder: When I do X I see Y. validations: required: true - - type: markdown + - type: textarea id: package-version attributes: label: Package Versions @@ -84,6 +92,6 @@ body: id: notes attributes: label: Notes - description: Use this field to provide any other notes that you feel might be relevant to the issue. + description: Use this field to provide any other notes that you feel might be relevant to the issue. Include links to any reproduction repos you've created here. validations: required: false From 5bb2e17507a6ab93832028f50c7302e9ee63892a Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Wed, 18 Dec 2024 19:21:54 +0100 Subject: [PATCH 154/224] fix: database migration on first launch (#439) --- src/NativeServiceProvider.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 9701766..89c0740 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -84,6 +84,13 @@ public function packageRegistered() } } + public function bootingPackage() + { + if (config('nativephp-internal.running')) { + $this->rewriteDatabase(); + } + } + protected function configureApp() { if (config('app.debug')) { @@ -94,8 +101,6 @@ protected function configureApp() $this->rewriteStoragePath(); - $this->rewriteDatabase(); - $this->configureDisks(); config(['session.driver' => 'file']); From c96a7c5121ba830c4d24b4f77f031dc5461f6223 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Wed, 18 Dec 2024 19:25:08 +0100 Subject: [PATCH 155/224] Fixes and improvements to powerMonitor (#445) * fix: powerMonitor couldn't pass arguments with get methods * feat: additional events * fix: PowerMonitor Facade docblock * feat: added fake class for tests --- src/Client/Client.php | 4 +- src/Contracts/PowerMonitor.php | 17 +++ src/Events/PowerMonitor/ScreenLocked.php | 23 ++++ src/Events/PowerMonitor/ScreenUnlocked.php | 23 ++++ src/Events/PowerMonitor/Shutdown.php | 23 ++++ .../PowerMonitor/UserDidBecomeActive.php | 23 ++++ .../PowerMonitor/UserDidResignActive.php | 23 ++++ src/Facades/PowerMonitor.php | 15 ++- src/Fakes/PowerMonitorFake.php | 93 +++++++++++++ src/NativeServiceProvider.php | 6 + src/PowerMonitor.php | 3 +- tests/Fakes/FakePowerMonitorTest.php | 123 ++++++++++++++++++ 12 files changed, 370 insertions(+), 6 deletions(-) create mode 100644 src/Contracts/PowerMonitor.php create mode 100644 src/Events/PowerMonitor/ScreenLocked.php create mode 100644 src/Events/PowerMonitor/ScreenUnlocked.php create mode 100644 src/Events/PowerMonitor/Shutdown.php create mode 100644 src/Events/PowerMonitor/UserDidBecomeActive.php create mode 100644 src/Events/PowerMonitor/UserDidResignActive.php create mode 100644 src/Fakes/PowerMonitorFake.php create mode 100644 tests/Fakes/FakePowerMonitorTest.php diff --git a/src/Client/Client.php b/src/Client/Client.php index e444ea4..9a8ec81 100644 --- a/src/Client/Client.php +++ b/src/Client/Client.php @@ -21,9 +21,9 @@ public function __construct() ->asJson(); } - public function get(string $endpoint): Response + public function get(string $endpoint, array|string|null $query = null): Response { - return $this->client->get($endpoint); + return $this->client->get($endpoint, $query); } public function post(string $endpoint, array $data = []): Response diff --git a/src/Contracts/PowerMonitor.php b/src/Contracts/PowerMonitor.php new file mode 100644 index 0000000..e8ec3d5 --- /dev/null +++ b/src/Contracts/PowerMonitor.php @@ -0,0 +1,17 @@ +make(PowerMonitorFake::class), function ($fake) { + static::swap($fake); + }); + } + + protected static function getFacadeAccessor(): string + { + return PowerMonitorContract::class; } } diff --git a/src/Fakes/PowerMonitorFake.php b/src/Fakes/PowerMonitorFake.php new file mode 100644 index 0000000..2af9916 --- /dev/null +++ b/src/Fakes/PowerMonitorFake.php @@ -0,0 +1,93 @@ +getSystemIdleStateCount++; + + $this->getSystemIdleStateCalls[] = $threshold; + + return SystemIdleStatesEnum::UNKNOWN; + } + + public function getSystemIdleTime(): int + { + $this->getSystemIdleTimeCount++; + + return 0; + } + + public function getCurrentThermalState(): ThermalStatesEnum + { + $this->getCurrentThermalStateCount++; + + return ThermalStatesEnum::UNKNOWN; + } + + public function isOnBatteryPower(): bool + { + $this->isOnBatteryPowerCount++; + + return false; + } + + /** + * @param int|Closure(int): bool $key + */ + public function assertGetSystemIdleState(int|Closure $key): void + { + if (is_callable($key) === false) { + PHPUnit::assertContains($key, $this->getSystemIdleStateCalls); + + return; + } + + $hit = empty( + array_filter( + $this->getSystemIdleStateCalls, + fn (string $keyIteration) => $key($keyIteration) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + public function assertGetSystemIdleStateCount(int $count): void + { + PHPUnit::assertSame($count, $this->getSystemIdleStateCount); + } + + public function assertGetSystemIdleTimeCount(int $count): void + { + PHPUnit::assertSame($count, $this->getSystemIdleTimeCount); + } + + public function assertGetCurrentThermalStateCount(int $count): void + { + PHPUnit::assertSame($count, $this->getCurrentThermalStateCount); + } + + public function assertIsOnBatteryPowerCount(int $count): void + { + PHPUnit::assertSame($count, $this->isOnBatteryPowerCount); + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 89c0740..079bb0a 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -16,11 +16,13 @@ use Native\Laravel\Commands\SeedDatabaseCommand; use Native\Laravel\Contracts\ChildProcess as ChildProcessContract; use Native\Laravel\Contracts\GlobalShortcut as GlobalShortcutContract; +use Native\Laravel\Contracts\PowerMonitor as PowerMonitorContract; use Native\Laravel\Contracts\WindowManager as WindowManagerContract; use Native\Laravel\Events\EventWatcher; use Native\Laravel\Exceptions\Handler; use Native\Laravel\GlobalShortcut as GlobalShortcutImplementation; use Native\Laravel\Logging\LogWatcher; +use Native\Laravel\PowerMonitor as PowerMonitorImplementation; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -66,6 +68,10 @@ public function packageRegistered() return $app->make(GlobalShortcutImplementation::class); }); + $this->app->bind(PowerMonitorContract::class, function (Foundation $app) { + return $app->make(PowerMonitorImplementation::class); + }); + if (config('nativephp-internal.running')) { $this->app->singleton( \Illuminate\Contracts\Debug\ExceptionHandler::class, diff --git a/src/PowerMonitor.php b/src/PowerMonitor.php index ea0d587..c0307b1 100644 --- a/src/PowerMonitor.php +++ b/src/PowerMonitor.php @@ -3,10 +3,11 @@ namespace Native\Laravel; use Native\Laravel\Client\Client; +use Native\Laravel\Contracts\PowerMonitor as PowerMonitorContract; use Native\Laravel\Enums\SystemIdleStatesEnum; use Native\Laravel\Enums\ThermalStatesEnum; -class PowerMonitor +class PowerMonitor implements PowerMonitorContract { public function __construct(protected Client $client) {} diff --git a/tests/Fakes/FakePowerMonitorTest.php b/tests/Fakes/FakePowerMonitorTest.php new file mode 100644 index 0000000..4761877 --- /dev/null +++ b/tests/Fakes/FakePowerMonitorTest.php @@ -0,0 +1,123 @@ +toBeInstanceOf(PowerMonitorFake::class); +}); + +it('asserts getSystemIdleState using int', function () { + swap(PowerMonitorContract::class, $fake = app(PowerMonitorFake::class)); + + $fake->getSystemIdleState(10); + $fake->getSystemIdleState(60); + + $fake->assertGetSystemIdleState(10); + $fake->assertGetSystemIdleState(60); + + try { + $fake->assertGetSystemIdleState(20); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts getSystemIdleState using callable', function () { + swap(PowerMonitorContract::class, $fake = app(PowerMonitorFake::class)); + + $fake->getSystemIdleState(10); + $fake->getSystemIdleState(60); + + $fake->assertGetSystemIdleState(fn (int $key) => $key === 10); + $fake->assertGetSystemIdleState(fn (int $key) => $key === 60); + + try { + $fake->assertGetSystemIdleState(fn (int $key) => $key === 20); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts getSystemIdleState count', function () { + swap(PowerMonitorContract::class, $fake = app(PowerMonitorFake::class)); + + $fake->getSystemIdleState(10); + $fake->getSystemIdleState(20); + $fake->getSystemIdleState(60); + + $fake->assertGetSystemIdleStateCount(3); + + try { + $fake->assertGetSystemIdleStateCount(2); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts getSystemIdleTime count', function () { + swap(PowerMonitorContract::class, $fake = app(PowerMonitorFake::class)); + + $fake->getSystemIdleTime(); + $fake->getSystemIdleTime(); + $fake->getSystemIdleTime(); + + $fake->assertGetSystemIdleTimeCount(3); + + try { + $fake->assertGetSystemIdleTimeCount(2); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts getCurrentThermalState count', function () { + swap(PowerMonitorContract::class, $fake = app(PowerMonitorFake::class)); + + $fake->getCurrentThermalState(); + $fake->getCurrentThermalState(); + $fake->getCurrentThermalState(); + + $fake->assertGetCurrentThermalStateCount(3); + + try { + $fake->assertGetCurrentThermalStateCount(2); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts isOnBatteryPower count', function () { + swap(PowerMonitorContract::class, $fake = app(PowerMonitorFake::class)); + + $fake->isOnBatteryPower(); + $fake->isOnBatteryPower(); + $fake->isOnBatteryPower(); + + $fake->assertIsOnBatteryPowerCount(3); + + try { + $fake->assertIsOnBatteryPowerCount(2); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); From 1a8151f9efddf339bcf70acf6c11ae53ae7b84df Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Thu, 19 Dec 2024 15:44:09 +0100 Subject: [PATCH 156/224] feat: phpstan level 5 (#446) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: phpstan level 5 * fix: $database undefined * fix: Unsafe usage of new static() * fix: ignore NativeAppServiceProvider not existing * fix: FreshCommand constructor invoked with 1 parameter, 0 required * fix: MenuBuilder facade function duplicates and arguments * fix: Type void cannot be part of a union type declaration. * fix: Php compactor missing imports and return statement * fix: missing SeedDatabaseCommand@handle return statement * Fix: cannot assign a value to a public readonly property outside of the constructor * Fix: PowerMonitor invoked Client::get() with 2 parameters, 1 required * fix: alternative for FreshCommand migrator argument * Revert "fix: alternative for FreshCommand migrator argument" This reverts commit cac9ea1442e5a8a4019e97aa58fdc39b9b3aa4c9. * Revert "fix: FreshCommand constructor invoked with 1 parameter, 0 required" This reverts commit cc1cb879145df52c11751f2370471a298f25b0a2. * fix: trying something * fix: phpstan.yml * Revert "fix: trying something" This reverts commit 6b88d133254bcb8881df7b4fc88a4aa5f4edc72a. * fix: trying to lower the minimum laravel 10 dependency * fix: final fix 🎉 * Revert "Fix: cannot assign a value to a public readonly property outside of the constructor" This reverts commit 585fb4727ced16a729f18a32a188a99a7b1cd1ea. * fix: put back previous fixes and ignore phpstan errors --- .github/workflows/phpstan.yml | 40 +++++++++++++++++++--------- .gitignore | 1 - composer.json | 10 ++++--- phpstan-baseline.neon | 0 phpstan.neon | 18 +++++++++++++ phpstan.neon.dist | 13 --------- src/ChildProcess.php | 15 ++++++----- src/Commands/SeedDatabaseCommand.php | 2 +- src/Compactor/Php.php | 5 ++-- src/Dialog.php | 2 +- src/Dock.php | 4 ++- src/Facades/Menu.php | 5 ++-- src/NativeServiceProvider.php | 33 +++++++++++++---------- src/Notification.php | 2 +- src/ProgressBar.php | 2 +- 15 files changed, 92 insertions(+), 60 deletions(-) delete mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon delete mode 100644 phpstan.neon.dist diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 3855a08..84219d8 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -1,26 +1,42 @@ name: PHPStan on: + workflow_dispatch: push: - paths: - - '**.php' - - 'phpstan.neon.dist' + branches-ignore: + - 'dependabot/npm_and_yarn/*' jobs: phpstan: - name: phpstan - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + php: [8.3] + steps: - - uses: actions/checkout@v4 + + - name: Checkout code + uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.1' - coverage: none + php-version: ${{ matrix.php }} + + - name: Get composer cache directory + id: composer-cache + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + + - name: Cache Composer dependencies + uses: actions/cache@v4 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-${{ matrix.php }}-composer- - - name: Install composer dependencies - uses: ramsey/composer-install@v3 + - name: Install Dependencies + run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist - - name: Run PHPStan - run: ./vendor/bin/phpstan --error-format=github + - name: Run analysis + run: ./vendor/bin/phpstan analyse --error-format=github diff --git a/.gitignore b/.gitignore index e26945a..3dd7896 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,6 @@ composer.lock coverage docs phpunit.xml -phpstan.neon testbench.yaml vendor node_modules diff --git a/composer.json b/composer.json index c3950b1..9f7b760 100644 --- a/composer.json +++ b/composer.json @@ -38,9 +38,9 @@ }, "require-dev": { "guzzlehttp/guzzle": "^7.0", + "larastan/larastan": "^2.0|^3.0", "laravel/pint": "^1.0", "nunomaduro/collision": "^7.9", - "nunomaduro/larastan": "^2.0.1", "orchestra/testbench": "^8.0", "pestphp/pest": "^2.0", "pestphp/pest-plugin-arch": "^2.0", @@ -52,8 +52,7 @@ }, "autoload": { "psr-4": { - "Native\\Laravel\\": "src/", - "Native\\Laravel\\Database\\Factories\\": "database/factories/" + "Native\\Laravel\\": "src/" } }, "autoload-dev": { @@ -62,6 +61,11 @@ } }, "scripts": { + "qa" : [ + "@composer format", + "@composer analyse", + "@composer test" + ], "post-autoload-dump": "@php ./vendor/bin/testbench package:discover --ansi", "analyse": "vendor/bin/phpstan analyse", "test": "vendor/bin/pest", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon deleted file mode 100644 index e69de29..0000000 diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..33be1e3 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,18 @@ +parameters: + + paths: + - src/ + - config/ +# - tests/ + + + # Level 9 is the highest level + level: 5 + + ignoreErrors: + - '#Class App\\Providers\\NativeAppServiceProvider not found#' + - '#Class Native\\Laravel\\ChildProcess has an uninitialized readonly property#' + +# +# excludePaths: +# - ./*/*/FileToBeExcluded.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist deleted file mode 100644 index 260b5e1..0000000 --- a/phpstan.neon.dist +++ /dev/null @@ -1,13 +0,0 @@ -includes: - - phpstan-baseline.neon - -parameters: - level: 4 - paths: - - src - - config - - database - tmpDir: build/phpstan - checkOctaneCompatibility: true - checkModelProperties: true - diff --git a/src/ChildProcess.php b/src/ChildProcess.php index 634e3f4..f524370 100644 --- a/src/ChildProcess.php +++ b/src/ChildProcess.php @@ -19,9 +19,9 @@ class ChildProcess implements ChildProcessContract public readonly bool $persistent; - public function __construct(protected Client $client) {} + final public function __construct(protected Client $client) {} - public function get(?string $alias = null): ?static + public function get(?string $alias = null): ?self { $alias = $alias ?? $this->alias; @@ -62,7 +62,7 @@ public function start( ?string $cwd = null, ?array $env = null, bool $persistent = false - ): static { + ): self { $cmd = is_array($cmd) ? array_values($cmd) : [$cmd]; $process = $this->client->post('child-process/start', [ @@ -87,7 +87,7 @@ public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $process = $this->client->post('child-process/start-php', [ 'alias' => $alias, 'cmd' => $cmd, - 'cwd' => $cwd ?? base_path(), + 'cwd' => base_path(), 'env' => $env, 'persistent' => $persistent, ])->json(); @@ -115,7 +115,7 @@ public function stop(?string $alias = null): void ])->json(); } - public function restart(?string $alias = null): ?static + public function restart(?string $alias = null): ?self { $process = $this->client->post('child-process/restart', [ 'alias' => $alias ?? $this->alias, @@ -128,7 +128,7 @@ public function restart(?string $alias = null): ?static return $this->fromRuntimeProcess($process); } - public function message(string $message, ?string $alias = null): static + public function message(string $message, ?string $alias = null): self { $this->client->post('child-process/message', [ 'alias' => $alias ?? $this->alias, @@ -138,9 +138,10 @@ public function message(string $message, ?string $alias = null): static return $this; } - protected function fromRuntimeProcess($process): static + protected function fromRuntimeProcess($process) { if (isset($process['pid'])) { + // @phpstan-ignore-next-line $this->pid = $process['pid']; } diff --git a/src/Commands/SeedDatabaseCommand.php b/src/Commands/SeedDatabaseCommand.php index c83879e..cdc032e 100644 --- a/src/Commands/SeedDatabaseCommand.php +++ b/src/Commands/SeedDatabaseCommand.php @@ -15,6 +15,6 @@ public function handle() { (new NativeServiceProvider($this->laravel))->rewriteDatabase(); - parent::handle(); + return parent::handle(); } } diff --git a/src/Compactor/Php.php b/src/Compactor/Php.php index f4838bf..7b5d3ad 100644 --- a/src/Compactor/Php.php +++ b/src/Compactor/Php.php @@ -3,6 +3,8 @@ namespace Native\Laravel\Compactor; use PhpToken; +use RuntimeException; +use Webmozart\Assert\Assert; class Php { @@ -17,7 +19,7 @@ public function compact(string $file, string $contents): string return $this->compactContent($contents); } - $this->compactContent($contents); + return $this->compactContent($contents); } protected function compactContent(string $contents): string @@ -145,7 +147,6 @@ private function retokenizeAttribute(array &$tokens, int $opener): ?array { Assert::keyExists($tokens, $opener); - /** @var PhpToken $token */ $token = $tokens[$opener]; $attributeBody = mb_substr($token->text, 2); $subTokens = PhpToken::tokenize('client->post('dock/cancel-bounce'); } - public function badge(?string $label = null): void|string + public function badge(?string $label = null): ?string { if (is_null($label)) { return $this->client->get('dock/badge'); } $this->client->post('dock/badge', ['label' => $label]); + + return null; } } diff --git a/src/Facades/Menu.php b/src/Facades/Menu.php index e12c2cb..332de24 100644 --- a/src/Facades/Menu.php +++ b/src/Facades/Menu.php @@ -3,6 +3,7 @@ namespace Native\Laravel\Facades; use Illuminate\Support\Facades\Facade; +use Native\Laravel\Contracts\MenuItem; use Native\Laravel\Menu\Items\Checkbox; use Native\Laravel\Menu\Items\Label; use Native\Laravel\Menu\Items\Link; @@ -11,7 +12,7 @@ use Native\Laravel\Menu\Items\Separator; /** - * @method static \Native\Laravel\Menu\Menu make(\Native\Laravel\Menu\Items\MenuItem ...$items) + * @method static \Native\Laravel\Menu\Menu make(MenuItem ...$items) * @method static Checkbox checkbox(string $label, bool $checked = false, ?string $hotkey = null) * @method static Label label(string $label) * @method static Link link(string $url, string $label = null, ?string $hotkey = null) @@ -23,7 +24,6 @@ * @method static Role view() * @method static Role window() * @method static Role help() - * @method static Role window() * @method static Role fullscreen() * @method static Role separator() * @method static Role devTools() @@ -37,7 +37,6 @@ * @method static Role minimize() * @method static Role close() * @method static Role quit() - * @method static Role help() * @method static Role hide() * @method static void create(MenuItem ...$items) * @method static void default() diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 079bb0a..22e3991 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -49,6 +49,7 @@ public function packageRegistered() $this->mergeConfigFrom($this->package->basePath('/../config/nativephp-internal.php'), 'nativephp-internal'); $this->app->singleton(FreshCommand::class, function ($app) { + /* @phpstan-ignore-next-line (beacause we support Laravel 10 & 11) */ return new FreshCommand($app['migrator']); }); @@ -148,13 +149,15 @@ public function rewriteDatabase() } } - config(['database.connections.nativephp' => [ - 'driver' => 'sqlite', - 'url' => env('DATABASE_URL'), - 'database' => $databasePath, - 'prefix' => '', - 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), - ]]); + config([ + 'database.connections.nativephp' => [ + 'driver' => 'sqlite', + 'url' => env('DATABASE_URL'), + 'database' => $databasePath, + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + ], + ]); config(['database.default' => 'nativephp']); @@ -174,7 +177,7 @@ public function removeDatabase() @unlink($databasePath); @unlink($databasePath.'-shm'); - @unlink($database.'-wal'); + @unlink($databasePath.'-wal'); } protected function configureDisks(): void @@ -197,12 +200,14 @@ protected function configureDisks(): void continue; } - config(['filesystems.disks.'.$disk => [ - 'driver' => 'local', - 'root' => env($env, ''), - 'throw' => false, - 'links' => 'skip', - ]]); + config([ + 'filesystems.disks.'.$disk => [ + 'driver' => 'local', + 'root' => env($env, ''), + 'throw' => false, + 'links' => 'skip', + ], + ]); } } } diff --git a/src/Notification.php b/src/Notification.php index 85c7a73..82d13d8 100644 --- a/src/Notification.php +++ b/src/Notification.php @@ -12,7 +12,7 @@ class Notification protected string $event = ''; - public function __construct(protected Client $client) {} + final public function __construct(protected Client $client) {} public static function new() { diff --git a/src/ProgressBar.php b/src/ProgressBar.php index 74ca9d7..c9e318f 100644 --- a/src/ProgressBar.php +++ b/src/ProgressBar.php @@ -16,7 +16,7 @@ class ProgressBar protected float $maxSecondsBetweenRedraws = 1; - public function __construct(protected int $maxSteps, protected Client $client) {} + final public function __construct(protected int $maxSteps, protected Client $client) {} public static function create(int $maxSteps): static { From 1cf8438a85bacf565b175d048fff5a3e8424ce4d Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 19 Dec 2024 14:49:06 +0000 Subject: [PATCH 157/224] Consistency --- src/Menu/Items/Checkbox.php | 6 ++---- src/Menu/Items/Label.php | 8 ++++---- src/Menu/Items/Link.php | 6 +++++- src/Menu/Items/Radio.php | 6 ++---- src/Menu/Items/Role.php | 5 ++++- src/Menu/MenuBuilder.php | 9 +++++++-- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/Menu/Items/Checkbox.php b/src/Menu/Items/Checkbox.php index afc550e..baa44fc 100644 --- a/src/Menu/Items/Checkbox.php +++ b/src/Menu/Items/Checkbox.php @@ -7,10 +7,8 @@ class Checkbox extends MenuItem protected string $type = 'checkbox'; public function __construct( - string $label, + protected ?string $label, protected bool $isChecked = false, protected ?string $accelerator = null - ) { - $this->label = $label; - } + ) {} } diff --git a/src/Menu/Items/Label.php b/src/Menu/Items/Label.php index 571c5ae..cd03d09 100644 --- a/src/Menu/Items/Label.php +++ b/src/Menu/Items/Label.php @@ -4,8 +4,8 @@ class Label extends MenuItem { - public function __construct(string $label) - { - $this->label = $label; - } + public function __construct( + protected ?string $label, + protected ?string $accelerator = null + ) {} } diff --git a/src/Menu/Items/Link.php b/src/Menu/Items/Link.php index 3655574..25bc3c1 100644 --- a/src/Menu/Items/Link.php +++ b/src/Menu/Items/Link.php @@ -8,7 +8,11 @@ class Link extends MenuItem protected bool $openInBrowser = false; - public function __construct(protected string $url, protected ?string $label, protected ?string $accelerator = null) {} + public function __construct( + protected string $url, + protected ?string $label, + protected ?string $accelerator = null + ) {} public function openInBrowser(bool $openInBrowser = true): self { diff --git a/src/Menu/Items/Radio.php b/src/Menu/Items/Radio.php index 0751522..759af45 100644 --- a/src/Menu/Items/Radio.php +++ b/src/Menu/Items/Radio.php @@ -7,10 +7,8 @@ class Radio extends MenuItem protected string $type = 'radio'; public function __construct( - string $label, + protected ?string $label, protected bool $isChecked = false, protected ?string $accelerator = null - ) { - $this->label = $label; - } + ) {} } diff --git a/src/Menu/Items/Role.php b/src/Menu/Items/Role.php index 3fa3b24..bde40a4 100644 --- a/src/Menu/Items/Role.php +++ b/src/Menu/Items/Role.php @@ -8,7 +8,10 @@ class Role extends MenuItem { protected string $type = 'role'; - public function __construct(protected RolesEnum $role, protected ?string $label = '') {} + public function __construct( + protected RolesEnum $role, + protected ?string $label = '' + ) {} public function toArray(): array { diff --git a/src/Menu/MenuBuilder.php b/src/Menu/MenuBuilder.php index 52ca3c9..f0627f7 100644 --- a/src/Menu/MenuBuilder.php +++ b/src/Menu/MenuBuilder.php @@ -38,9 +38,9 @@ public function default(): void ); } - public function label(string $label): Items\Label + public function label(string $label, ?string $hotkey = null): Items\Label { - return new Items\Label($label); + return new Items\Label($label, $hotkey); } public function checkbox(string $label, bool $checked = false, ?string $hotkey = null): Items\Checkbox @@ -162,4 +162,9 @@ public function hide(?string $label = null): Items\Role { return new Items\Role(RolesEnum::HIDE, $label); } + + public function about(?string $label = null): Items\Role + { + return new Items\Role(RolesEnum::ABOUT, $label); + } } From 8267087b21b322f4d26954bacbba048f3e311ae1 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Thu, 19 Dec 2024 14:53:56 +0000 Subject: [PATCH 158/224] Update CHANGELOG --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a866e6..7c33f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,32 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 0.7.0 - 2024-12-19 + +### What's Changed + +* Fix Settings facade DocBloc by @SRWieZ in https://github.com/NativePHP/laravel/pull/419 +* Fake test double for WindowManager::Class by @XbNz in https://github.com/NativePHP/laravel/pull/422 +* Child process test double by @XbNz in https://github.com/NativePHP/laravel/pull/430 +* fix: Notification facade docbloc by @SRWieZ in https://github.com/NativePHP/laravel/pull/428 +* Improvements to window test doubles by @XbNz in https://github.com/NativePHP/laravel/pull/426 +* fix: child process cmd: option except iterable array by @SRWieZ in https://github.com/NativePHP/laravel/pull/429 +* feat: improve Settings by @SRWieZ in https://github.com/NativePHP/laravel/pull/432 +* Dock goodies by @simonhamp in https://github.com/NativePHP/laravel/pull/421 +* MenuBars continued by @simonhamp in https://github.com/NativePHP/laravel/pull/420 +* Global shortcut test double by @XbNz in https://github.com/NativePHP/laravel/pull/436 +* Menu improvements by @simonhamp in https://github.com/NativePHP/laravel/pull/423 +* fix: database migration on first launch by @SRWieZ in https://github.com/NativePHP/laravel/pull/439 +* Fixes and improvements to powerMonitor by @SRWieZ in https://github.com/NativePHP/laravel/pull/445 +* feat: phpstan level 5 by @SRWieZ in https://github.com/NativePHP/laravel/pull/446 + +### New Contributors + +* @SRWieZ made their first contribution in https://github.com/NativePHP/laravel/pull/419 +* @XbNz made their first contribution in https://github.com/NativePHP/laravel/pull/422 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.6.4...0.7.0 + ## 0.6.4 - 2024-11-17 ### What's Changed From 101ddf0947c07d43ab71d5864b8a3e3806928a98 Mon Sep 17 00:00:00 2001 From: A G Date: Sun, 29 Dec 2024 10:20:24 -0500 Subject: [PATCH 159/224] Child process queue workers (#450) * Child process queue workers - Remove `ShouldBroadcast` in favor of `ShouldBroadcastNow` in `Events\\ChildProcess` namespace - Implement `QueueWorker::class` - Add new binding to `NativeServiceProvider::class` - Fire up workers: iterate through queue worker config in `NativeServiceProvider::configureApp()` - Test `QueueWorker::up()`, `QueueWorker::down()` - Test `QueueWorkerFake::class` assertions work as expected * Prevent attempting to boot workers on CLI calls * Remove creating workers just by string Rely on keys of the config array to assert uniqueness of worker aliases * Allow workers to be instantiated directly by alias * Fix styling * Fix tests --------- Co-authored-by: Simon Hamp Co-authored-by: simonhamp --- config/nativephp.php | 8 +++ src/Contracts/QueueWorker.php | 12 ++++ src/DTOs/QueueConfig.php | 35 +++++++++++ src/Events/ChildProcess/ErrorReceived.php | 4 +- src/Events/ChildProcess/MessageReceived.php | 4 +- src/Events/ChildProcess/ProcessExited.php | 4 +- src/Events/ChildProcess/ProcessSpawned.php | 4 +- src/Facades/QueueWorker.php | 29 +++++++++ src/Fakes/QueueWorkerFake.php | 61 ++++++++++++++++++ src/NativeServiceProvider.php | 20 ++++++ src/QueueWorker.php | 47 ++++++++++++++ tests/DTOs/QueueWorkerTest.php | 66 ++++++++++++++++++++ tests/Fakes/FakeQueueWorkerTest.php | 69 +++++++++++++++++++++ tests/QueueWorker/QueueWorkerTest.php | 39 ++++++++++++ 14 files changed, 394 insertions(+), 8 deletions(-) create mode 100644 src/Contracts/QueueWorker.php create mode 100644 src/DTOs/QueueConfig.php create mode 100644 src/Facades/QueueWorker.php create mode 100644 src/Fakes/QueueWorkerFake.php create mode 100644 src/QueueWorker.php create mode 100644 tests/DTOs/QueueWorkerTest.php create mode 100644 tests/Fakes/FakeQueueWorkerTest.php create mode 100644 tests/QueueWorker/QueueWorkerTest.php diff --git a/config/nativephp.php b/config/nativephp.php index b24afec..5c6e7a8 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -114,4 +114,12 @@ ], ], ], + + 'queue_workers' => [ + 'default' => [ + 'queues' => ['default'], + 'memory_limit' => 128, + 'timeout' => 60, + ], + ], ]; diff --git a/src/Contracts/QueueWorker.php b/src/Contracts/QueueWorker.php new file mode 100644 index 0000000..a2c4cf9 --- /dev/null +++ b/src/Contracts/QueueWorker.php @@ -0,0 +1,12 @@ + $queuesToConsume + */ + public function __construct( + public readonly string $alias, + public readonly array $queuesToConsume, + public readonly int $memoryLimit, + public readonly int $timeout, + ) {} + + /** + * @return array + */ + public static function fromConfigArray(array $config): array + { + return array_map( + function (array|string $worker, string $alias) { + return new self( + $alias, + $worker['queues'] ?? ['default'], + $worker['memory_limit'] ?? 128, + $worker['timeout'] ?? 60, + ); + }, + $config, + array_keys($config), + ); + } +} diff --git a/src/Events/ChildProcess/ErrorReceived.php b/src/Events/ChildProcess/ErrorReceived.php index 65db9c6..334e9cc 100644 --- a/src/Events/ChildProcess/ErrorReceived.php +++ b/src/Events/ChildProcess/ErrorReceived.php @@ -3,11 +3,11 @@ namespace Native\Laravel\Events\ChildProcess; use Illuminate\Broadcasting\Channel; -use Illuminate\Contracts\Broadcasting\ShouldBroadcast; +use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; -class ErrorReceived implements ShouldBroadcast +class ErrorReceived implements ShouldBroadcastNow { use Dispatchable, SerializesModels; diff --git a/src/Events/ChildProcess/MessageReceived.php b/src/Events/ChildProcess/MessageReceived.php index 5f7a432..04a51c2 100644 --- a/src/Events/ChildProcess/MessageReceived.php +++ b/src/Events/ChildProcess/MessageReceived.php @@ -3,11 +3,11 @@ namespace Native\Laravel\Events\ChildProcess; use Illuminate\Broadcasting\Channel; -use Illuminate\Contracts\Broadcasting\ShouldBroadcast; +use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; -class MessageReceived implements ShouldBroadcast +class MessageReceived implements ShouldBroadcastNow { use Dispatchable, SerializesModels; diff --git a/src/Events/ChildProcess/ProcessExited.php b/src/Events/ChildProcess/ProcessExited.php index bf570d8..0dcd589 100644 --- a/src/Events/ChildProcess/ProcessExited.php +++ b/src/Events/ChildProcess/ProcessExited.php @@ -3,11 +3,11 @@ namespace Native\Laravel\Events\ChildProcess; use Illuminate\Broadcasting\Channel; -use Illuminate\Contracts\Broadcasting\ShouldBroadcast; +use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; -class ProcessExited implements ShouldBroadcast +class ProcessExited implements ShouldBroadcastNow { use Dispatchable, SerializesModels; diff --git a/src/Events/ChildProcess/ProcessSpawned.php b/src/Events/ChildProcess/ProcessSpawned.php index 91fc917..a49b31b 100644 --- a/src/Events/ChildProcess/ProcessSpawned.php +++ b/src/Events/ChildProcess/ProcessSpawned.php @@ -3,11 +3,11 @@ namespace Native\Laravel\Events\ChildProcess; use Illuminate\Broadcasting\Channel; -use Illuminate\Contracts\Broadcasting\ShouldBroadcast; +use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; -class ProcessSpawned implements ShouldBroadcast +class ProcessSpawned implements ShouldBroadcastNow { use Dispatchable, SerializesModels; diff --git a/src/Facades/QueueWorker.php b/src/Facades/QueueWorker.php new file mode 100644 index 0000000..3b504be --- /dev/null +++ b/src/Facades/QueueWorker.php @@ -0,0 +1,29 @@ +make(QueueWorkerFake::class), function ($fake) { + static::swap($fake); + }); + } + + protected static function getFacadeAccessor(): string + { + self::clearResolvedInstance(QueueWorkerContract::class); + + return QueueWorkerContract::class; + } +} diff --git a/src/Fakes/QueueWorkerFake.php b/src/Fakes/QueueWorkerFake.php new file mode 100644 index 0000000..6482dd9 --- /dev/null +++ b/src/Fakes/QueueWorkerFake.php @@ -0,0 +1,61 @@ + + */ + public array $ups = []; + + /** + * @var array + */ + public array $downs = []; + + public function up(QueueConfig $config): void + { + $this->ups[] = $config; + } + + public function down(string $alias): void + { + $this->downs[] = $alias; + } + + public function assertUp(Closure $callback): void + { + $hit = empty( + array_filter( + $this->ups, + fn (QueueConfig $up) => $callback($up) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + + public function assertDown(string|Closure $alias): void + { + if (is_callable($alias) === false) { + PHPUnit::assertContains($alias, $this->downs); + + return; + } + + $hit = empty( + array_filter( + $this->downs, + fn (string $down) => $alias($down) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 22e3991..6ca8d62 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -17,7 +17,9 @@ use Native\Laravel\Contracts\ChildProcess as ChildProcessContract; use Native\Laravel\Contracts\GlobalShortcut as GlobalShortcutContract; use Native\Laravel\Contracts\PowerMonitor as PowerMonitorContract; +use Native\Laravel\Contracts\QueueWorker as QueueWorkerContract; use Native\Laravel\Contracts\WindowManager as WindowManagerContract; +use Native\Laravel\DTOs\QueueConfig; use Native\Laravel\Events\EventWatcher; use Native\Laravel\Exceptions\Handler; use Native\Laravel\GlobalShortcut as GlobalShortcutImplementation; @@ -73,6 +75,10 @@ public function packageRegistered() return $app->make(PowerMonitorImplementation::class); }); + $this->app->bind(QueueWorkerContract::class, function (Foundation $app) { + return $app->make(QueueWorker::class); + }); + if (config('nativephp-internal.running')) { $this->app->singleton( \Illuminate\Contracts\Debug\ExceptionHandler::class, @@ -112,6 +118,11 @@ protected function configureApp() config(['session.driver' => 'file']); config(['queue.default' => 'database']); + + // XXX: This logic may need to change when we ditch the internal web server + if (! $this->app->runningInConsole()) { + $this->fireUpQueueWorkers(); + } } protected function rewriteStoragePath() @@ -210,4 +221,13 @@ protected function configureDisks(): void ]); } } + + protected function fireUpQueueWorkers(): void + { + $queueConfigs = QueueConfig::fromConfigArray(config('nativephp.queue_workers')); + + foreach ($queueConfigs as $queueConfig) { + $this->app->make(QueueWorkerContract::class)->up($queueConfig); + } + } } diff --git a/src/QueueWorker.php b/src/QueueWorker.php new file mode 100644 index 0000000..1eb0c00 --- /dev/null +++ b/src/QueueWorker.php @@ -0,0 +1,47 @@ +has("nativephp.queue_workers.{$config}")) { + $config = QueueConfig::fromConfigArray([ + $config => config("nativephp.queue_workers.{$config}"), + ])[0]; + } + + if (! $config instanceof QueueConfig) { + throw new \InvalidArgumentException("Invalid queue configuration alias [$config]"); + } + + $this->childProcess->php( + [ + '-d', + "memory_limit={$config->memoryLimit}M", + 'artisan', + 'queue:work', + "--name={$config->alias}", + '--queue='.implode(',', $config->queuesToConsume), + "--memory={$config->memoryLimit}", + "--timeout={$config->timeout}", + ], + $config->alias, + persistent: true, + ); + } + + public function down(string $alias): void + { + $this->childProcess->stop($alias); + } +} diff --git a/tests/DTOs/QueueWorkerTest.php b/tests/DTOs/QueueWorkerTest.php new file mode 100644 index 0000000..bc1b764 --- /dev/null +++ b/tests/DTOs/QueueWorkerTest.php @@ -0,0 +1,66 @@ +toBeArray(); + expect($configObject)->toHaveCount(count($config)); + + foreach ($config as $alias => $worker) { + if (is_string($worker)) { + expect( + Arr::first( + array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)) + )->queuesToConsume->toBe(['default'] + ); + + expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)))->memoryLimit->toBe(128); + expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)))->timeout->toBe(60); + + continue; + } + + expect( + Arr::first( + array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)) + )->queuesToConsume->toBe($worker['queues'] ?? ['default'] + ); + + expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)))->memoryLimit->toBe($worker['memory_limit'] ?? 128); + expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)))->timeout->toBe($worker['timeout'] ?? 60); + } +})->with([ + [ + 'queue_workers' => [ + 'some_worker' => [ + 'queues' => ['default'], + 'memory_limit' => 64, + 'timeout' => 60, + ], + ], + ], + [ + 'queue_workers' => [ + 'some_worker' => [], + 'another_worker' => [], + ], + ], + [ + 'queue_workers' => [ + 'some_worker' => [ + ], + 'another_worker' => [ + 'queues' => ['default', 'another'], + ], + 'yet_another_worker' => [ + 'memory_limit' => 256, + ], + 'one_more_worker' => [ + 'timeout' => 120, + ], + ], + ], +]); diff --git a/tests/Fakes/FakeQueueWorkerTest.php b/tests/Fakes/FakeQueueWorkerTest.php new file mode 100644 index 0000000..4b22f34 --- /dev/null +++ b/tests/Fakes/FakeQueueWorkerTest.php @@ -0,0 +1,69 @@ +toBeInstanceOf(QueueWorkerFake::class); +}); + +it('asserts up using callable', function () { + swap(QueueWorkerContract::class, $fake = app(QueueWorkerFake::class)); + + $fake->up(new QueueConfig('testA', ['default'], 123, 123)); + $fake->up(new QueueConfig('testB', ['default'], 123, 123)); + + $fake->assertUp(fn (QueueConfig $up) => $up->alias === 'testA'); + $fake->assertUp(fn (QueueConfig $up) => $up->alias === 'testB'); + + try { + $fake->assertUp(fn (QueueConfig $up) => $up->alias === 'testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts down using string', function () { + swap(QueueWorkerContract::class, $fake = app(QueueWorkerFake::class)); + + $fake->down('testA'); + $fake->down('testB'); + + $fake->assertDown('testA'); + $fake->assertDown('testB'); + + try { + $fake->assertDown('testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + +it('asserts down using callable', function () { + swap(QueueWorkerContract::class, $fake = app(QueueWorkerFake::class)); + + $fake->down('testA'); + $fake->down('testB'); + + $fake->assertDown(fn (string $alias) => $alias === 'testA'); + $fake->assertDown(fn (string $alias) => $alias === 'testB'); + + try { + $fake->assertDown(fn (string $alias) => $alias === 'testC'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); diff --git a/tests/QueueWorker/QueueWorkerTest.php b/tests/QueueWorker/QueueWorkerTest.php new file mode 100644 index 0000000..a3fbd57 --- /dev/null +++ b/tests/QueueWorker/QueueWorkerTest.php @@ -0,0 +1,39 @@ +toBe([ + '-d', + 'memory_limit=128M', + 'artisan', + 'queue:work', + "--name={$alias}", + '--queue=default', + '--memory=128', + '--timeout=61', + ]); + + expect($alias)->toBe('some_worker'); + expect($env)->toBeNull(); + expect($persistent)->toBeTrue(); + + return true; + }); +}); + +it('hits the child process with relevant alias spin down a queue worker', function () { + ChildProcess::fake(); + + QueueWorker::down('some_worker'); + + ChildProcess::assertStop('some_worker'); +}); From b719cccf84d426795b5e3418f4775cefc11104c9 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Sun, 29 Dec 2024 16:21:38 +0100 Subject: [PATCH 160/224] fix: static analysis (#452) * fix: static analysis * fix: removed warnings * fix: migrated phpunit.xml.dist --- .github/workflows/phpstan.yml | 5 +- phpunit.xml.dist | 67 ++++++++++++------------- src/Fakes/PowerMonitorFake.php | 2 +- tests/ChildProcess/ChildProcessTest.php | 1 - 4 files changed, 37 insertions(+), 38 deletions(-) diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 84219d8..871c602 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -3,8 +3,9 @@ name: PHPStan on: workflow_dispatch: push: - branches-ignore: - - 'dependabot/npm_and_yarn/*' + branches: [main] + pull_request: + branches: [main] jobs: phpstan: diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8b18acd..266bd0e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,36 +1,35 @@ - - - - tests - - - - - ./src - - - - - - - - - - + + + + tests + + + + + + + + + + + + + + + ./src + + diff --git a/src/Fakes/PowerMonitorFake.php b/src/Fakes/PowerMonitorFake.php index 2af9916..caaf282 100644 --- a/src/Fakes/PowerMonitorFake.php +++ b/src/Fakes/PowerMonitorFake.php @@ -64,7 +64,7 @@ public function assertGetSystemIdleState(int|Closure $key): void $hit = empty( array_filter( $this->getSystemIdleStateCalls, - fn (string $keyIteration) => $key($keyIteration) === true + fn (int $keyIteration) => $key($keyIteration) === true ) ) === false; diff --git a/tests/ChildProcess/ChildProcessTest.php b/tests/ChildProcess/ChildProcessTest.php index 7bd13b7..c78db8c 100644 --- a/tests/ChildProcess/ChildProcessTest.php +++ b/tests/ChildProcess/ChildProcessTest.php @@ -2,7 +2,6 @@ use Illuminate\Http\Client\Request; use Illuminate\Support\Facades\Http; -use Mockery; use Native\Laravel\ChildProcess as ChildProcessImplement; use Native\Laravel\Client\Client; use Native\Laravel\Facades\ChildProcess; From a0cc73263a1a8b3c6a01d6e8b9781da315d09b92 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Sun, 29 Dec 2024 16:21:56 +0100 Subject: [PATCH 161/224] feat: default notification title (#451) --- src/Notification.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Notification.php b/src/Notification.php index 82d13d8..fe290e7 100644 --- a/src/Notification.php +++ b/src/Notification.php @@ -12,7 +12,9 @@ class Notification protected string $event = ''; - final public function __construct(protected Client $client) {} + final public function __construct(protected Client $client) { + $this->title = config('app.name'); + } public static function new() { From 4ec5c58b2fe261c6422c9e8bb0bf28d7e5b8a535 Mon Sep 17 00:00:00 2001 From: simonhamp Date: Sun, 29 Dec 2024 15:22:57 +0000 Subject: [PATCH 162/224] Fix styling --- src/Notification.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Notification.php b/src/Notification.php index fe290e7..8bde4d5 100644 --- a/src/Notification.php +++ b/src/Notification.php @@ -12,7 +12,8 @@ class Notification protected string $event = ''; - final public function __construct(protected Client $client) { + final public function __construct(protected Client $client) + { $this->title = config('app.name'); } From e700c62587b3b534d5be46834804d61cfe6a9c9b Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Sun, 29 Dec 2024 16:46:30 +0100 Subject: [PATCH 163/224] Fix menubar not ready (#453) * fix: menubar not ready * fix: menubar not ready * feat: new menubar event * Revert "fix: menubar not ready" This reverts commit 4c89091307cd69b21de429d77ee4fabc432448f9. * Revert "fix: menubar not ready" This reverts commit 345b37a291cdd442cf58d497a49467da32501786. --- src/Events/MenuBar/MenuBarCreated.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/Events/MenuBar/MenuBarCreated.php diff --git a/src/Events/MenuBar/MenuBarCreated.php b/src/Events/MenuBar/MenuBarCreated.php new file mode 100644 index 0000000..07891a1 --- /dev/null +++ b/src/Events/MenuBar/MenuBarCreated.php @@ -0,0 +1,21 @@ + Date: Sun, 29 Dec 2024 15:47:25 -0600 Subject: [PATCH 164/224] Add support for Window::show() (#454) --- src/Fakes/WindowManagerFake.php | 33 ++++++++++++++++++++++++ src/Windows/WindowManager.php | 7 ++++++ tests/Fakes/FakeWindowManagerTest.php | 36 +++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/src/Fakes/WindowManagerFake.php b/src/Fakes/WindowManagerFake.php index 8604224..64112b3 100644 --- a/src/Fakes/WindowManagerFake.php +++ b/src/Fakes/WindowManagerFake.php @@ -18,6 +18,8 @@ class WindowManagerFake implements WindowManagerContract public array $hidden = []; + public array $shown = []; + public array $forcedWindowReturnValues = []; public function __construct( @@ -64,6 +66,11 @@ public function hide($id = null) $this->hidden[] = $id; } + public function show($id = null) + { + $this->shown[] = $id; + } + public function current(): Window { $this->ensureForceReturnWindowsProvided(); @@ -156,6 +163,27 @@ public function assertHidden(string|Closure $id): void PHPUnit::assertTrue($hit); } + /** + * @param string|Closure(string): bool $id + */ + public function assertShown(string|Closure $id): void + { + if (is_callable($id) === false) { + PHPUnit::assertContains($id, $this->shown); + + return; + } + + $hit = empty( + array_filter( + $this->shown, + fn (mixed $shownId) => $id($shownId) === true + ) + ) === false; + + PHPUnit::assertTrue($hit); + } + public function assertOpenedCount(int $expected): void { PHPUnit::assertCount($expected, $this->opened); @@ -171,6 +199,11 @@ public function assertHiddenCount(int $expected): void PHPUnit::assertCount($expected, $this->hidden); } + public function assertShownCount(int $expected): void + { + PHPUnit::assertCount($expected, $this->shown); + } + private function ensureForceReturnWindowsProvided(): void { Assert::notEmpty($this->forcedWindowReturnValues, 'No windows were provided to return'); diff --git a/src/Windows/WindowManager.php b/src/Windows/WindowManager.php index 6404686..bdd7f90 100644 --- a/src/Windows/WindowManager.php +++ b/src/Windows/WindowManager.php @@ -31,6 +31,13 @@ public function hide($id = null) ]); } + public function show($id = null) + { + $this->client->post('window/show', [ + 'id' => $id ?? $this->detectId(), + ]); + } + public function current(): Window { $window = (object) $this->client->get('window/current')->json(); diff --git a/tests/Fakes/FakeWindowManagerTest.php b/tests/Fakes/FakeWindowManagerTest.php index b2f4af2..f6c4804 100644 --- a/tests/Fakes/FakeWindowManagerTest.php +++ b/tests/Fakes/FakeWindowManagerTest.php @@ -136,6 +136,24 @@ $this->fail('Expected assertion to fail'); }); +it('asserts that a window was shown', function () { + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + app(WindowManagerContract::class)->show('main'); + app(WindowManagerContract::class)->show('secondary'); + + $fake->assertShown('main'); + $fake->assertShown('secondary'); + + try { + $fake->assertShown('tertiary'); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + it('asserts opened count', function () { Http::fake(['*' => Http::response(status: 200)]); @@ -196,6 +214,24 @@ $this->fail('Expected assertion to fail'); }); +it('asserts shown count', function () { + swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); + + app(WindowManagerContract::class)->show('main'); + app(WindowManagerContract::class)->show(); + app(WindowManagerContract::class)->show(); + + $fake->assertShownCount(3); + + try { + $fake->assertShownCount(4); + } catch (AssertionFailedError) { + return; + } + + $this->fail('Expected assertion to fail'); +}); + it('forces the return value of current window', function () { swap(WindowManagerContract::class, $fake = app(WindowManagerFake::class)); From 15b01f51d2fbbe849cba0d5c9d7619b1e9f9f1d0 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Mon, 30 Dec 2024 20:53:34 +0000 Subject: [PATCH 165/224] Remove sponsor --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 4de29bb..a233cdd 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,6 @@ Thanks to the following sponsors for funding NativePHP development. Please consi - [Laradevs](https://laradevs.com/?ref=nativephp-docs) - Connecting the best Laravel Developers with the best Laravel Teams. - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. -- [ServerAuth](https://serverauth.com) - Website Deployment & Server Management, made simple! - [KaasHosting](https://www.kaashosting.nl/?lang=en) - Minecraft Server and VPS hosting from The Netherlands. ## Changelog From 2bd28872d07f7b2066d4af18a55e41f562b08ed4 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Sat, 11 Jan 2025 23:00:50 +0000 Subject: [PATCH 166/224] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a233cdd..45e26d3 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Thanks to the following sponsors for funding NativePHP development. Please consi - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. - [KaasHosting](https://www.kaashosting.nl/?lang=en) - Minecraft Server and VPS hosting from The Netherlands. +- [Borah Digital Labs](https://borah.digital/) - An MVP building studio from the sunny Canary Islands focusing on AI, SaaS and online platforms. ## Changelog From 36abbb6953dcb325f0ec5b498fc0650db6d12b18 Mon Sep 17 00:00:00 2001 From: Chikondi Kamwendo Date: Sun, 12 Jan 2025 01:12:32 +0200 Subject: [PATCH 167/224] Fix: return type mismatch between screen facade and screen class methods. (#463) --- src/Screen.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Screen.php b/src/Screen.php index c15d4e1..9f34c10 100644 --- a/src/Screen.php +++ b/src/Screen.php @@ -18,12 +18,12 @@ public function displays(): array return $this->client->get('screen/displays')->json('displays'); } - public function primary(): object + public function primary(): array { return $this->client->get('screen/primary-display')->json('primaryDisplay'); } - public function active(): object + public function active(): array { return $this->client->get('screen/active')->json(); } From 34bcfd84b1b74ed6d35cbea86578577b8dfe9e62 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Thu, 16 Jan 2025 17:44:03 +0100 Subject: [PATCH 168/224] fix: Dock facade (#470) --- src/Facades/Dock.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Facades/Dock.php b/src/Facades/Dock.php index b088219..ddeaffb 100644 --- a/src/Facades/Dock.php +++ b/src/Facades/Dock.php @@ -6,8 +6,8 @@ use Native\Laravel\Menu\Menu; /** - * @method static void bounce() - * @method static void|string badge(string $type = null) + * @method static void bounce(string $type = 'informational') + * @method static void|string badge(?string $type = null) * @method static void cancelBounce() * @method static void hide() * @method static void icon(string $Path) From 4235d2c17cd177ac031efb3e4e81405077cda140 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Thu, 16 Jan 2025 17:44:29 +0100 Subject: [PATCH 169/224] fix: child process facade (#471) --- src/Facades/ChildProcess.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Facades/ChildProcess.php b/src/Facades/ChildProcess.php index 0436507..d6793c8 100644 --- a/src/Facades/ChildProcess.php +++ b/src/Facades/ChildProcess.php @@ -8,7 +8,7 @@ /** * @method static \Native\Laravel\ChildProcess[] all() - * @method static \Native\Laravel\ChildProcess get(string $alias = null) + * @method static \Native\Laravel\ChildProcess|null get(string $alias = null) * @method static \Native\Laravel\ChildProcess message(string $message, string $alias = null) * @method static \Native\Laravel\ChildProcess restart(string $alias = null) * @method static \Native\Laravel\ChildProcess start(string|array $cmd, string $alias, string $cwd = null, array $env = null, bool $persistent = false) From d643e194b92f47369dd348de1d7baa29976914a4 Mon Sep 17 00:00:00 2001 From: simonhamp <31628+simonhamp@users.noreply.github.com> Date: Tue, 21 Jan 2025 13:38:19 +0000 Subject: [PATCH 170/224] Update CHANGELOG --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c33f8d..1e89890 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,23 @@ All notable changes to `nativephp-laravel` will be documented in this file. +## 1.0.0-beta.1 - 2025-01-21 + +### What's Changed + +* Child process queue workers by @XbNz in https://github.com/NativePHP/laravel/pull/450 +* fix: static analysis by @SRWieZ in https://github.com/NativePHP/laravel/pull/452 +* feat: default notification title by @SRWieZ in https://github.com/NativePHP/laravel/pull/451 +* Fix menubar not ready by @SRWieZ in https://github.com/NativePHP/laravel/pull/453 +* Add support for Window::show() by @curtisblackwell in https://github.com/NativePHP/laravel/pull/454 +* Fix: Return type mismatch between screen facade and screen class methods. by @kondi3 in https://github.com/NativePHP/laravel/pull/463 + +### New Contributors + +* @kondi3 made their first contribution in https://github.com/NativePHP/laravel/pull/463 + +**Full Changelog**: https://github.com/NativePHP/laravel/compare/0.7.0...0.8.0 + ## 0.7.0 - 2024-12-19 ### What's Changed From 1fe65da9dba54d2d5e7e959b50fc2a9a93a5546b Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Wed, 22 Jan 2025 08:42:50 +0100 Subject: [PATCH 171/224] Add queue worker config docblock --- config/nativephp.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/nativephp.php b/config/nativephp.php index 5c6e7a8..da17b0b 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -115,6 +115,9 @@ ], ], + /** + * The queue workers that get auto-started on your application start. + */ 'queue_workers' => [ 'default' => [ 'queues' => ['default'], From 597e0dc0056e6356cf38149cc3e8e2c450604c52 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Thu, 23 Jan 2025 10:58:18 +0000 Subject: [PATCH 172/224] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 45e26d3..4308c95 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Please review [our security policy](../../security/policy) on how to report secu ## Credits - [Marcel Pociot](https://github.com/mpociot) +- [Simon Hamp](https://github.com/simonhamp) - [All Contributors](../../contributors) ## License From 3ccd85ed1c294ca76bd50c60b9d539fce1bbce5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Jan 2025 00:35:48 +0000 Subject: [PATCH 173/224] Bump dependabot/fetch-metadata from 2.2.0 to 2.3.0 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.2.0 to 2.3.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.2.0...v2.3.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index eb537d8..2cb1d5e 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.2.0 + uses: dependabot/fetch-metadata@v2.3.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From 7eae6d8e115608cfa27c2cc571675dc1c3f241eb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2025 00:36:22 +0000 Subject: [PATCH 174/224] Bump aglipanci/laravel-pint-action from 2.4 to 2.5 Bumps [aglipanci/laravel-pint-action](https://github.com/aglipanci/laravel-pint-action) from 2.4 to 2.5. - [Release notes](https://github.com/aglipanci/laravel-pint-action/releases) - [Commits](https://github.com/aglipanci/laravel-pint-action/compare/2.4...2.5) --- updated-dependencies: - dependency-name: aglipanci/laravel-pint-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/fix-php-code-style-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 255506b..0edbd38 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -19,7 +19,7 @@ jobs: ref: ${{ github.head_ref }} - name: Fix PHP code style issues - uses: aglipanci/laravel-pint-action@2.4 + uses: aglipanci/laravel-pint-action@2.5 - name: Commit changes uses: stefanzweifel/git-auto-commit-action@v5 From 1f8831baabf8d169bd139a6877814a9f6d9eaba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20K=C3=A4llstrand=20Modig?= Date: Thu, 13 Feb 2025 15:39:54 +0100 Subject: [PATCH 175/224] Add endpoint to resize MenuBar window (#490) --- src/Facades/MenuBar.php | 4 ++++ src/MenuBar/MenuBarManager.php | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/Facades/MenuBar.php b/src/Facades/MenuBar.php index 97abad9..15d9879 100644 --- a/src/Facades/MenuBar.php +++ b/src/Facades/MenuBar.php @@ -10,6 +10,9 @@ * @method static void show() * @method static void hide() * @method static void label(string $label) + * @method static void tooltip(string $label) + * @method static void icon(string $icon) + * @method static void resize(int $width, int $height) * @method static void contextMenu(Menu $contextMenu) */ class MenuBar extends Facade @@ -19,3 +22,4 @@ protected static function getFacadeAccessor() return \Native\Laravel\MenuBar\MenuBarManager::class; } } + diff --git a/src/MenuBar/MenuBarManager.php b/src/MenuBar/MenuBarManager.php index b10992d..f9c2bde 100644 --- a/src/MenuBar/MenuBarManager.php +++ b/src/MenuBar/MenuBarManager.php @@ -45,6 +45,14 @@ public function icon(string $icon) ]); } + public function resize(int $width, int $height) + { + $this->client->post('menu-bar/resize', [ + 'width' => $width, + 'height' => $height, + ]); + } + public function contextMenu(Menu $contextMenu) { $this->client->post('menu-bar/context-menu', [ From 182c5d86fa272df01b7b9c8345419f7ef6c7bfe0 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 17 Feb 2025 16:52:09 +0100 Subject: [PATCH 176/224] feat: add missing facades into composer.json (#495) --- composer.json | 16 ++++++++++++++-- src/Facades/MenuBar.php | 1 - 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index 9f7b760..850270b 100644 --- a/composer.json +++ b/composer.json @@ -85,11 +85,23 @@ "Native\\Laravel\\NativeServiceProvider" ], "aliases": { + "App": "Native\\Laravel\\Facades\\App", + "ChildProcess": "Native\\Laravel\\Facades\\ChildProcess", + "Clipboard": "Native\\Laravel\\Facades\\Clipboard", "ContextMenu": "Native\\Laravel\\Facades\\ContextMenu", "Dock": "Native\\Laravel\\Facades\\Dock", + "GlobalShortcut": "Native\\Laravel\\Facades\\GlobalShortcut", + "Menu": "Native\\Laravel\\Facades\\Menu", + "MenuBar": "Native\\Laravel\\Facades\\MenuBar", + "Notification": "Native\\Laravel\\Facades\\Notification", + "PowerMonitor": "Native\\Laravel\\Facades\\PowerMonitor", "Process": "Native\\Laravel\\Facades\\Process", - "Window": "Native\\Laravel\\Facades\\Window", - "Clipboard": "Native\\Laravel\\Facades\\Clipboard" + "QueueWorker": "Native\\Laravel\\Facades\\QueueWorker", + "Screen": "Native\\Laravel\\Facades\\Screen", + "Settings": "Native\\Laravel\\Facades\\Settings", + "Shell": "Native\\Laravel\\Facades\\Shell", + "System": "Native\\Laravel\\Facades\\System", + "Window": "Native\\Laravel\\Facades\\Window" } } }, diff --git a/src/Facades/MenuBar.php b/src/Facades/MenuBar.php index 15d9879..b1d4972 100644 --- a/src/Facades/MenuBar.php +++ b/src/Facades/MenuBar.php @@ -22,4 +22,3 @@ protected static function getFacadeAccessor() return \Native\Laravel\MenuBar\MenuBarManager::class; } } - From dfcd9e29958ade01c693d2264a2e96b91e3a4a6a Mon Sep 17 00:00:00 2001 From: Andreas Creten Date: Fri, 21 Feb 2025 15:24:51 +0100 Subject: [PATCH 177/224] Notification improvements (#498) * Add support for notification reference * Add reference to Notification clicked class * Support for more notification actions * Make reference public * Support for actions and reply * Add missing methods to the facade * Properly send the actions --- .../NotificationActionClicked.php | 23 ++++++++++ .../Notifications/NotificationClicked.php | 2 + .../Notifications/NotificationClosed.php | 23 ++++++++++ .../Notifications/NotificationReply.php | 23 ++++++++++ src/Facades/Notification.php | 3 ++ src/Notification.php | 45 ++++++++++++++++++- 6 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 src/Events/Notifications/NotificationActionClicked.php create mode 100644 src/Events/Notifications/NotificationClosed.php create mode 100644 src/Events/Notifications/NotificationReply.php diff --git a/src/Events/Notifications/NotificationActionClicked.php b/src/Events/Notifications/NotificationActionClicked.php new file mode 100644 index 0000000..de658b3 --- /dev/null +++ b/src/Events/Notifications/NotificationActionClicked.php @@ -0,0 +1,23 @@ +title = config('app.name'); @@ -22,6 +30,13 @@ public static function new() return new static(new Client); } + public function reference(string $reference): self + { + $this->reference = $reference; + + return $this; + } + public function title(string $title): self { $this->title = $title; @@ -36,6 +51,21 @@ public function event(string $event): self return $this; } + public function hasReply(string $placeholder = ''): self + { + $this->hasReply = true; + $this->replyPlaceholder = $placeholder; + + return $this; + } + + public function addAction(string $label): self + { + $this->actions[] = $label; + + return $this; + } + public function message(string $body): self { $this->body = $body; @@ -43,12 +73,23 @@ public function message(string $body): self return $this; } - public function show(): void + public function show(): self { - $this->client->post('notification', [ + $response = $this->client->post('notification', [ + 'reference' => $this->reference, 'title' => $this->title, 'body' => $this->body, 'event' => $this->event, + 'hasReply' => $this->hasReply, + 'replyPlaceholder' => $this->replyPlaceholder, + 'actions' => array_map(fn(string $label) => [ + 'type' => 'button', + 'text' => $label + ], $this->actions), ]); + + $this->reference = $response->json('reference'); + + return $this; } } From 2844fe831b4fb2b1b9021a7b7ef169ecb2f6597e Mon Sep 17 00:00:00 2001 From: Willem Leuverink Date: Fri, 21 Feb 2025 20:52:59 +0100 Subject: [PATCH 178/224] Update cleanup directory defaults (#467) * update cleanup files defaults * add default cleanup_exclude_files to internal config * remove vendor/bin & add */tests to exclude list * remove MinifyApplication command * remove php compactor * moved internal cleanup_exclude files back again This is hard to test when the config I'm asserting on lives on a different repo from the test itself. --- config/nativephp.php | 4 +- src/Commands/MinifyApplicationCommand.php | 111 ------------- src/Compactor/Php.php | 189 ---------------------- src/NativeServiceProvider.php | 2 - 4 files changed, 2 insertions(+), 304 deletions(-) delete mode 100644 src/Commands/MinifyApplicationCommand.php delete mode 100644 src/Compactor/Php.php diff --git a/config/nativephp.php b/config/nativephp.php index da17b0b..45f8225 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -61,8 +61,8 @@ */ 'cleanup_exclude_files' => [ 'content', - 'storage/app/framework/{sessions,testing,cache}', - 'storage/logs/laravel.log', + 'node_modules', + '*/tests' ], /** diff --git a/src/Commands/MinifyApplicationCommand.php b/src/Commands/MinifyApplicationCommand.php deleted file mode 100644 index 37d8378..0000000 --- a/src/Commands/MinifyApplicationCommand.php +++ /dev/null @@ -1,111 +0,0 @@ -argument('app')); - - if (! is_dir($appPath)) { - $this->error('The app path is not a directory'); - - return; - } - - $this->info('Minifying application…'); - - $this->cleanUpEnvFile($appPath); - $this->removeIgnoredFilesAndFolders($appPath); - - $compactor = new Php; - - $phpFiles = Finder::create() - ->files() - ->name('*.php') - ->in($appPath); - - foreach ($phpFiles as $phpFile) { - $minifiedContent = $compactor->compact($phpFile->getRealPath(), $phpFile->getContents()); - file_put_contents($phpFile->getRealPath(), $minifiedContent); - } - } - - protected function cleanUpEnvFile(string $appPath): void - { - $envFile = $appPath.'/.env'; - - if (! file_exists($envFile)) { - return; - } - - $this->info('Cleaning up .env file…'); - - $cleanUpKeys = config('nativephp.cleanup_env_keys', []); - - $envContent = file_get_contents($envFile); - $envValues = collect(explode("\n", $envContent)) - ->filter(function (string $line) use ($cleanUpKeys) { - $key = Str::before($line, '='); - - return ! Str::is($cleanUpKeys, $key); - }) - ->join("\n"); - - file_put_contents($envFile, $envValues); - } - - protected function removeIgnoredFilesAndFolders(string $appPath): void - { - $this->info('Cleaning up ignored files and folders…'); - - $itemsToRemove = config('nativephp.cleanup_exclude_files', []); - - foreach ($itemsToRemove as $item) { - $fullPath = $appPath.'/'.$item; - - if (file_exists($fullPath)) { - if (is_dir($fullPath)) { - $this->deleteDirectoryRecursive($fullPath); - } else { - array_map('unlink', glob($fullPath)); - } - } else { - foreach (glob($item) as $pathFound) { - unlink($pathFound); - } - } - } - } - - private function deleteDirectoryRecursive(string $directory): bool - { - if (! file_exists($directory)) { - return true; - } - - if (! is_dir($directory)) { - return unlink($directory); - } - - foreach (scandir($directory) as $item) { - if ($item == '.' || $item == '..') { - continue; - } - - if (! $this->deleteDirectoryRecursive($directory.'/'.$item)) { - return false; - } - } - - return rmdir($directory); - } -} diff --git a/src/Compactor/Php.php b/src/Compactor/Php.php deleted file mode 100644 index 7b5d3ad..0000000 --- a/src/Compactor/Php.php +++ /dev/null @@ -1,189 +0,0 @@ -canProcessFile($file)) { - return $this->compactContent($contents); - } - - return $this->compactContent($contents); - } - - protected function compactContent(string $contents): string - { - $output = ''; - $tokens = PhpToken::tokenize($contents); - $tokenCount = count($tokens); - - for ($index = 0; $index < $tokenCount; $index++) { - $token = $tokens[$index]; - $tokenText = $token->text; - - if ($token->is([T_COMMENT, T_DOC_COMMENT])) { - if (str_starts_with($tokenText, '#[')) { - // This is, in all likelihood, the start of a PHP >= 8.0 attribute. - // Note: $tokens may be updated by reference as well! - $retokenized = $this->retokenizeAttribute($tokens, $index); - - if ($retokenized !== null) { - array_splice($tokens, $index, 1, $retokenized); - $tokenCount = count($tokens); - } - - $attributeCloser = self::findAttributeCloser($tokens, $index); - - if (is_int($attributeCloser)) { - $output .= '#['; - } else { - // Turns out this was not an attribute. Treat it as a plain comment. - $output .= str_repeat("\n", mb_substr_count($tokenText, "\n")); - } - } elseif (str_contains($tokenText, '@')) { - try { - $output .= $this->compactAnnotations($tokenText); - } catch (RuntimeException) { - $output .= $tokenText; - } - } else { - $output .= str_repeat("\n", mb_substr_count($tokenText, "\n")); - } - } elseif ($token->is(T_WHITESPACE)) { - $whitespace = $tokenText; - $previousIndex = ($index - 1); - - // Handle whitespace potentially being split into two tokens after attribute retokenization. - $nextToken = $tokens[$index + 1] ?? null; - - if ($nextToken !== null - && $nextToken->is(T_WHITESPACE) - ) { - $whitespace .= $nextToken->text; - $index++; - } - - // reduce wide spaces - $whitespace = preg_replace('{[ \t]+}', ' ', $whitespace); - - // normalize newlines to \n - $whitespace = preg_replace('{(?:\r\n|\r|\n)}', "\n", $whitespace); - - // If the new line was split off from the whitespace token due to it being included in - // the previous (comment) token (PHP < 8), remove leading spaces. - - $previousToken = $tokens[$previousIndex]; - - if ($previousToken->is(T_COMMENT) - && str_contains($previousToken->text, "\n") - ) { - $whitespace = ltrim($whitespace, ' '); - } - - // trim leading spaces - $whitespace = preg_replace('{\n +}', "\n", $whitespace); - - $output .= $whitespace; - } else { - $output .= $tokenText; - } - } - - return $output; - } - - private function compactAnnotations(string $docblock): string - { - return $docblock; - } - - /** - * @param list $tokens - */ - private static function findAttributeCloser(array $tokens, int $opener): ?int - { - $tokenCount = count($tokens); - $brackets = [$opener]; - $closer = null; - - for ($i = ($opener + 1); $i < $tokenCount; $i++) { - $tokenText = $tokens[$i]->text; - - // Allow for short arrays within attributes. - if ($tokenText === '[') { - $brackets[] = $i; - - continue; - } - - if ($tokenText === ']') { - array_pop($brackets); - - if (count($brackets) === 0) { - $closer = $i; - break; - } - } - } - - return $closer; - } - - /** - * @param non-empty-list $tokens - */ - private function retokenizeAttribute(array &$tokens, int $opener): ?array - { - Assert::keyExists($tokens, $opener); - - $token = $tokens[$opener]; - $attributeBody = mb_substr($token->text, 2); - $subTokens = PhpToken::tokenize('text; - } - - $subTokens = PhpToken::tokenize('hasConfigFile() ->hasRoute('api') From dc1d2f1d69a13bf50829dd055b2c21f43465c2c9 Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Sat, 22 Feb 2025 14:41:53 +0000 Subject: [PATCH 179/224] Implement default config for pre and post build keys (#496) --- config/nativephp.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/config/nativephp.php b/config/nativephp.php index 45f8225..8c62e00 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -125,4 +125,15 @@ 'timeout' => 60, ], ], + + /** + * Define your own scripts to run before and after the build process. + */ + 'prebuild' => [ + // 'npm run build', + ], + + 'postbuild' => [ + // 'rm -rf public/build', + ], ]; From a2183f2f1196286edc101ae5334c6f67a1c949f3 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 24 Feb 2025 14:04:19 +0100 Subject: [PATCH 180/224] chore: delete outdated tests (#500) --- config/nativephp.php | 2 +- src/Notification.php | 4 +- tests/Command/IgnoreFilesAndFoldersTest.php | 88 --------------------- 3 files changed, 3 insertions(+), 91 deletions(-) delete mode 100644 tests/Command/IgnoreFilesAndFoldersTest.php diff --git a/config/nativephp.php b/config/nativephp.php index 8c62e00..6e4edcf 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -62,7 +62,7 @@ 'cleanup_exclude_files' => [ 'content', 'node_modules', - '*/tests' + '*/tests', ], /** diff --git a/src/Notification.php b/src/Notification.php index a1da484..578d860 100644 --- a/src/Notification.php +++ b/src/Notification.php @@ -82,9 +82,9 @@ public function show(): self 'event' => $this->event, 'hasReply' => $this->hasReply, 'replyPlaceholder' => $this->replyPlaceholder, - 'actions' => array_map(fn(string $label) => [ + 'actions' => array_map(fn (string $label) => [ 'type' => 'button', - 'text' => $label + 'text' => $label, ], $this->actions), ]); diff --git a/tests/Command/IgnoreFilesAndFoldersTest.php b/tests/Command/IgnoreFilesAndFoldersTest.php deleted file mode 100644 index e805cc0..0000000 --- a/tests/Command/IgnoreFilesAndFoldersTest.php +++ /dev/null @@ -1,88 +0,0 @@ -artisan('native:minify resources/app'); - $this->assertFalse(file_exists($laravelLog)); - - // Clean up after ourselves - if (file_exists($laravelLog)) { - unlink($laravelLog); - } - if (file_exists('resources/app/storage/logs')) { - rmdir('resources/app/storage/logs'); - } - if (file_exists('resources/app/storage')) { - rmdir('resources/app/storage'); - } - removeAppFolder(); -}); - -it('will remove the content folder by default before building', function () { - $contentPath = 'resources/app/content'; - - // Create a dummy copy of the folder - if (! file_exists($contentPath)) { - mkdir($contentPath, 0755, true); - } - - // Run the test - $this->artisan('native:minify resources/app'); - $this->assertFalse(file_exists($contentPath)); - - // Clean up after ourselves - if (file_exists($contentPath)) { - unlink($contentPath); - } - removeAppFolder(); -}); - -it('will remove only files that match a globbed path', function () { - $wildcardPath = 'resources/app/wildcardPath'; - $yes1DeletePath = $wildcardPath.'/YES1.txt'; - $yes2DeletePath = $wildcardPath.'/YES2.txt'; - $noDeletePath = $wildcardPath.'/NO.txt'; - - config()->set('nativephp.cleanup_exclude_files', [$wildcardPath.'/YES*']); - - // Create some dummy files - if (! file_exists($wildcardPath)) { - mkdir($wildcardPath, 0755, true); - } - file_put_contents($yes1DeletePath, 'PLEASE DELETE ME'); - file_put_contents($yes2DeletePath, 'PLEASE DELETE ME TOO'); - file_put_contents($noDeletePath, 'DO NOT DELETE ME'); - - // Run the test - $this->artisan('native:minify resources/app'); - $this->assertFalse(file_exists($yes1DeletePath)); - $this->assertFalse(file_exists($yes2DeletePath)); - $this->assertTrue(file_exists($noDeletePath)); - - // Clean up after ourselves - foreach ([$yes1DeletePath, $yes2DeletePath, $noDeletePath] as $remove) { - if (file_exists($remove)) { - unlink($remove); - } - } - if (file_exists($wildcardPath)) { - rmdir($wildcardPath); - } - removeAppFolder(); -}); - -function removeAppFolder() -{ - if (file_exists('resources/app')) { - rmdir('resources/app'); - } -} From cea2b0d606d16db831c42eed33a9e376e86dfcdc Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 24 Feb 2025 16:11:28 +0100 Subject: [PATCH 181/224] fix: linting workflow (#499) --- .../workflows/fix-php-code-style-issues.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index 0edbd38..eb79b6e 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -1,9 +1,15 @@ -name: Fix PHP code style issues +# Check and fix PHP code style issues +# Pull request: automatically fix PHP code style issues +# Main branch: only check PHP code style issues since we don't have write permission +name: Check and fix PHP code style issues on: push: paths: - '**.php' + pull_request: + paths: + - '**.php' permissions: contents: write @@ -18,10 +24,20 @@ jobs: with: ref: ${{ github.head_ref }} + - name: Check PHP code style issues + if: github.event_name == 'push' + uses: aglipanci/laravel-pint-action@2.5 + with: + verboseMode: true + testMode: true + - name: Fix PHP code style issues + if: github.event_name == 'pull_request' uses: aglipanci/laravel-pint-action@2.5 - name: Commit changes + if: github.event_name == 'pull_request' uses: stefanzweifel/git-auto-commit-action@v5 with: commit_message: Fix styling + From 0ff6ae6042a60450d3086d21073f902e5ad3d726 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 24 Feb 2025 16:11:38 +0100 Subject: [PATCH 182/224] fix: deprecated error in tests (#501) --- tests/DTOs/QueueWorkerTest.php | 56 ++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/tests/DTOs/QueueWorkerTest.php b/tests/DTOs/QueueWorkerTest.php index bc1b764..76209c8 100644 --- a/tests/DTOs/QueueWorkerTest.php +++ b/tests/DTOs/QueueWorkerTest.php @@ -17,8 +17,10 @@ )->queuesToConsume->toBe(['default'] ); - expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)))->memoryLimit->toBe(128); - expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)))->timeout->toBe(60); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $worker)))->memoryLimit->toBe(128); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $worker)))->timeout->toBe(60); continue; } @@ -29,37 +31,45 @@ )->queuesToConsume->toBe($worker['queues'] ?? ['default'] ); - expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)))->memoryLimit->toBe($worker['memory_limit'] ?? 128); - expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)))->timeout->toBe($worker['timeout'] ?? 60); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $alias)))->memoryLimit->toBe($worker['memory_limit'] ?? 128); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $alias)))->timeout->toBe($worker['timeout'] ?? 60); } })->with([ [ - 'queue_workers' => [ - 'some_worker' => [ - 'queues' => ['default'], - 'memory_limit' => 64, - 'timeout' => 60, + [ + 'queue_workers' => [ + 'some_worker' => [ + 'queues' => ['default'], + 'memory_limit' => 64, + 'timeout' => 60, + ], ], ], ], [ - 'queue_workers' => [ - 'some_worker' => [], - 'another_worker' => [], + [ + 'queue_workers' => [ + 'some_worker' => [], + 'another_worker' => [], + ], ], ], [ - 'queue_workers' => [ - 'some_worker' => [ - ], - 'another_worker' => [ - 'queues' => ['default', 'another'], - ], - 'yet_another_worker' => [ - 'memory_limit' => 256, - ], - 'one_more_worker' => [ - 'timeout' => 120, + [ + 'queue_workers' => [ + 'some_worker' => [ + ], + 'another_worker' => [ + 'queues' => ['default', 'another'], + ], + 'yet_another_worker' => [ + 'memory_limit' => 256, + ], + 'one_more_worker' => [ + 'timeout' => 120, + ], ], ], ], From 0102a92c7eec291bf12e1477a31a59f67698034b Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 24 Feb 2025 17:00:58 +0100 Subject: [PATCH 183/224] Support Laravel 12.x & PHP 8.4 (#494) --- .github/workflows/run-tests.yml | 27 ++++++---------- composer.json | 18 +++++------ phpstan.neon | 9 ++++-- src/Commands/LoadPHPConfigurationCommand.php | 2 ++ src/Concerns/InteractsWithNativeApp.php | 34 -------------------- 5 files changed, 27 insertions(+), 63 deletions(-) delete mode 100644 src/Concerns/InteractsWithNativeApp.php diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 107761b..a1909f6 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -10,28 +10,18 @@ jobs: test: runs-on: ${{ matrix.os }} strategy: - fail-fast: true + fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - php: [8.3, 8.2, 8.1] - laravel: [11.*, 10.*] + php: [8.4, 8.3, 8.2, 8.1] + laravel: [12.*, 11.*, 10.*] stability: [prefer-lowest, prefer-stable] - include: - - laravel: 11.* - testbench: 9.* - carbon: ^3.2 - laravel-package-tools: ^1.16.4 - collision: ^8.1.1 - - - laravel: 10.* - testbench: 8.* - carbon: ^2.63 - laravel-package-tools: ^1.16.4 - collision: 7.* exclude: - laravel: 11.* php: 8.1 + - laravel: 12.* + php: 8.1 name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} @@ -53,11 +43,14 @@ jobs: - name: Install dependencies run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" "spatie/laravel-package-tools:${{ matrix.laravel-package-tools }}" "nunomaduro/collision:${{ matrix.collision }}" --no-interaction --no-update + composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-update composer update --${{ matrix.stability }} --prefer-dist --no-interaction - name: List Installed Dependencies - run: composer show -D + run: composer show + +# - name: Debug PhpUnit version +# run: composer why phpunit/phpunit -t - name: Execute tests run: vendor/bin/pest diff --git a/composer.json b/composer.json index 850270b..71336ed 100644 --- a/composer.json +++ b/composer.json @@ -32,22 +32,22 @@ ], "require": { "php": "^8.1", - "illuminate/contracts": "^10.0|^11.0", + "illuminate/contracts": "^10.0|^11.0|^12.0", "spatie/laravel-package-tools": "^1.16.4", "symfony/finder": "^6.2|^7.0" }, "require-dev": { "guzzlehttp/guzzle": "^7.0", - "larastan/larastan": "^2.0|^3.0", "laravel/pint": "^1.0", - "nunomaduro/collision": "^7.9", - "orchestra/testbench": "^8.0", - "pestphp/pest": "^2.0", - "pestphp/pest-plugin-arch": "^2.0", - "pestphp/pest-plugin-laravel": "^2.0", + "larastan/larastan": "^2.0|^3.1", + "nunomaduro/collision": "^7.11|^8.1.1", + "orchestra/testbench": "^8.0|^9.0|^10.0", + "pestphp/pest": "^v2.30|^3.0", + "pestphp/pest-plugin-arch": "^2.0|^3.0", + "pestphp/pest-plugin-laravel": "^2.0|^3.1", "phpstan/extension-installer": "^1.1", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-deprecation-rules": "^1.0|^2.0", + "phpstan/phpstan-phpunit": "^1.0|^2.0", "spatie/laravel-ray": "^1.26" }, "autoload": { diff --git a/phpstan.neon b/phpstan.neon index 33be1e3..b6543b0 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -9,10 +9,13 @@ parameters: # Level 9 is the highest level level: 5 + + noEnvCallsOutsideOfConfig: false # Don't know why he doesn't consider our config/ directory as config + ignoreErrors: - '#Class App\\Providers\\NativeAppServiceProvider not found#' - '#Class Native\\Laravel\\ChildProcess has an uninitialized readonly property#' -# -# excludePaths: -# - ./*/*/FileToBeExcluded.php + + excludePaths: + - ./src/NativeServiceProvider.php diff --git a/src/Commands/LoadPHPConfigurationCommand.php b/src/Commands/LoadPHPConfigurationCommand.php index b3b7a71..1a2ba57 100644 --- a/src/Commands/LoadPHPConfigurationCommand.php +++ b/src/Commands/LoadPHPConfigurationCommand.php @@ -14,6 +14,8 @@ public function handle() /** @var ProvidesPhpIni $provider */ $provider = app(config('nativephp.provider')); $phpIni = []; + + /* * @phpstan-ignore-next-line */ if (method_exists($provider, 'phpIni')) { $phpIni = $provider->phpIni(); } diff --git a/src/Concerns/InteractsWithNativeApp.php b/src/Concerns/InteractsWithNativeApp.php deleted file mode 100644 index 7dd6ee7..0000000 --- a/src/Concerns/InteractsWithNativeApp.php +++ /dev/null @@ -1,34 +0,0 @@ -start(); - - if (is_iterable($totalSteps)) { - foreach ($totalSteps as $value) { - $callback($value, $bar); - - $bar->advance(); - } - } else { - $callback($bar); - } - - $bar->finish(); - - if (is_iterable($totalSteps)) { - return $totalSteps; - } - } -} From 212f11b7b9590c6cb4a0ed16ef11f27310a3677d Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 4 Mar 2025 14:12:45 +0100 Subject: [PATCH 184/224] feat: zephpyr configs --- config/nativephp-internal.php | 9 +++++++++ config/nativephp.php | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/config/nativephp-internal.php b/config/nativephp-internal.php index 4210df9..a9d97c7 100644 --- a/config/nativephp-internal.php +++ b/config/nativephp-internal.php @@ -29,4 +29,13 @@ * The URL to the NativePHP API. */ 'api_url' => env('NATIVEPHP_API_URL', 'http://localhost:4000/api/'), + + /** + * Configuration for the Zephpyr API. + */ + 'zephpyr' => [ + 'host' => env('ZEPHPYR_HOST', 'https://zephpyr.com'), + 'token' => env('ZEPHPYR_TOKEN'), + 'key' => env('ZEPHPYR_KEY'), + ], ]; diff --git a/config/nativephp.php b/config/nativephp.php index 6e4edcf..49eacd8 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -48,6 +48,7 @@ 'GITHUB_*', 'DO_SPACES_*', '*_SECRET', + 'ZEPHPYR_*', 'NATIVEPHP_UPDATER_PATH', 'NATIVEPHP_APPLE_ID', 'NATIVEPHP_APPLE_ID_PASS', @@ -60,6 +61,8 @@ * You may use glob / wildcard patterns here. */ 'cleanup_exclude_files' => [ + 'build', + 'temp', 'content', 'node_modules', '*/tests', @@ -136,4 +139,9 @@ 'postbuild' => [ // 'rm -rf public/build', ], + + /** + * Custom PHP binary path. + */ + 'binary_path' => env('NATIVEPHP_BINARY_PATH', null), ]; From 334b5dedfeb901763906a1ff128c432bb51f546e Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 4 Mar 2025 14:14:12 +0100 Subject: [PATCH 185/224] fix: don't create database inside a phar --- src/NativeServiceProvider.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index b5b3225..1c13403 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -25,6 +25,7 @@ use Native\Laravel\Logging\LogWatcher; use Native\Laravel\PowerMonitor as PowerMonitorImplementation; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; +use Phar; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; @@ -148,7 +149,8 @@ public function rewriteDatabase() { $databasePath = config('nativephp-internal.database_path'); - if (config('app.debug')) { + // Automatically create the database in development mode but not if we are running in a Phar + if (config('app.debug') && ! Phar::running()) { $databasePath = database_path('nativephp.sqlite'); if (! file_exists($databasePath)) { From 6103ed50222679e48e8672625c59e6bf63b9530c Mon Sep 17 00:00:00 2001 From: SRWieZ <1408020+SRWieZ@users.noreply.github.com> Date: Tue, 4 Mar 2025 13:14:59 +0000 Subject: [PATCH 186/224] Fix styling --- src/NativeServiceProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 1c13403..526c8cf 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -150,7 +150,7 @@ public function rewriteDatabase() $databasePath = config('nativephp-internal.database_path'); // Automatically create the database in development mode but not if we are running in a Phar - if (config('app.debug') && ! Phar::running()) { + if (config('app.debug') && ! Phar::running()) { $databasePath = database_path('nativephp.sqlite'); if (! file_exists($databasePath)) { From 15d04bd9705abad0349ace2453ac0a72d5964536 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Mon, 10 Mar 2025 12:46:53 +0100 Subject: [PATCH 187/224] feat: isRunningBundled --- src/App.php | 6 ++++++ src/Facades/App.php | 1 + 2 files changed, 7 insertions(+) diff --git a/src/App.php b/src/App.php index 81f1a26..b45dd11 100644 --- a/src/App.php +++ b/src/App.php @@ -3,6 +3,7 @@ namespace Native\Laravel; use Native\Laravel\Client\Client; +use Phar; class App { @@ -57,4 +58,9 @@ public function clearRecentDocuments(): void { $this->client->delete('app/recent-documents'); } + + public function isRunningBundled(): bool + { + return Phar::running() !== ''; + } } diff --git a/src/Facades/App.php b/src/Facades/App.php index 6f3d99a..4bbf331 100644 --- a/src/Facades/App.php +++ b/src/Facades/App.php @@ -13,6 +13,7 @@ * @method static void addRecentDocument(string $path) * @method static array recentDocuments() * @method static void clearRecentDocuments() + * @method static bool isRunningBundled() */ class App extends Facade { From 35ab017a6e5c54ed75d766413695b92b75211a26 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 11 Mar 2025 14:16:56 +0100 Subject: [PATCH 188/224] wip: fix running artisan commands in bundle --- src/QueueWorker.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/QueueWorker.php b/src/QueueWorker.php index 1eb0c00..3a820f1 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -24,11 +24,11 @@ public function up(string|QueueConfig $config): void throw new \InvalidArgumentException("Invalid queue configuration alias [$config]"); } - $this->childProcess->php( + $this->childProcess->artisan( [ - '-d', - "memory_limit={$config->memoryLimit}M", - 'artisan', + // '-d', + // "memory_limit={$config->memoryLimit}M", + // 'artisan', 'queue:work', "--name={$config->alias}", '--queue='.implode(',', $config->queuesToConsume), From f2584d00b45405064d458e30f7f50d63c3cb41bf Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 11 Mar 2025 14:39:53 +0100 Subject: [PATCH 189/224] feat: artisan commands in bundles --- src/ChildProcess.php | 7 ++++--- src/Contracts/ChildProcess.php | 4 ++-- src/Events/ChildProcess/StartupError.php | 22 ++++++++++++++++++++++ src/Fakes/ChildProcessFake.php | 8 ++++++-- src/QueueWorker.php | 3 --- 5 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 src/Events/ChildProcess/StartupError.php diff --git a/src/ChildProcess.php b/src/ChildProcess.php index f524370..19a9420 100644 --- a/src/ChildProcess.php +++ b/src/ChildProcess.php @@ -80,7 +80,7 @@ public function start( * @param string|string[] $cmd * @return $this */ - public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self + public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self { $cmd = is_array($cmd) ? array_values($cmd) : [$cmd]; @@ -90,6 +90,7 @@ public function php(string|array $cmd, string $alias, ?array $env = null, ?bool 'cwd' => base_path(), 'env' => $env, 'persistent' => $persistent, + 'iniSettings' => $iniSettings, ])->json(); return $this->fromRuntimeProcess($process); @@ -99,13 +100,13 @@ public function php(string|array $cmd, string $alias, ?array $env = null, ?bool * @param string|string[] $cmd * @return $this */ - public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self + public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self { $cmd = is_array($cmd) ? array_values($cmd) : [$cmd]; $cmd = ['artisan', ...$cmd]; - return $this->php($cmd, $alias, env: $env, persistent: $persistent); + return $this->php($cmd, $alias, env: $env, persistent: $persistent, iniSettings: $iniSettings); } public function stop(?string $alias = null): void diff --git a/src/Contracts/ChildProcess.php b/src/Contracts/ChildProcess.php index 9859e3e..0a4f877 100644 --- a/src/Contracts/ChildProcess.php +++ b/src/Contracts/ChildProcess.php @@ -16,9 +16,9 @@ public function start( bool $persistent = false ): self; - public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self; + public function php(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self; - public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false): self; + public function artisan(string|array $cmd, string $alias, ?array $env = null, ?bool $persistent = false, ?array $iniSettings = null): self; public function stop(?string $alias = null): void; diff --git a/src/Events/ChildProcess/StartupError.php b/src/Events/ChildProcess/StartupError.php new file mode 100644 index 0000000..8adb2ed --- /dev/null +++ b/src/Events/ChildProcess/StartupError.php @@ -0,0 +1,22 @@ +phps[] = [ 'cmd' => $cmd, 'alias' => $alias, 'env' => $env, 'persistent' => $persistent, + 'iniSettings' => $iniSettings, ]; return $this; @@ -93,13 +95,15 @@ public function artisan( array|string $cmd, string $alias, ?array $env = null, - ?bool $persistent = false + ?bool $persistent = false, + ?array $iniSettings = null ): self { $this->artisans[] = [ 'cmd' => $cmd, 'alias' => $alias, 'env' => $env, 'persistent' => $persistent, + 'iniSettings' => $iniSettings, ]; return $this; diff --git a/src/QueueWorker.php b/src/QueueWorker.php index 3a820f1..e39803f 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -26,9 +26,6 @@ public function up(string|QueueConfig $config): void $this->childProcess->artisan( [ - // '-d', - // "memory_limit={$config->memoryLimit}M", - // 'artisan', 'queue:work', "--name={$config->alias}", '--queue='.implode(',', $config->queuesToConsume), From 3228b9880ada90469531d30208843a98c6923cdc Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 11 Mar 2025 14:49:09 +0100 Subject: [PATCH 190/224] feat: artisan commands in bundles --- src/QueueWorker.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/QueueWorker.php b/src/QueueWorker.php index e39803f..875a5c2 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -32,13 +32,16 @@ public function up(string|QueueConfig $config): void "--memory={$config->memoryLimit}", "--timeout={$config->timeout}", ], - $config->alias, + 'queue_'.$config->alias, persistent: true, + iniSettings: [ + 'memory_limit' => "{$config->memoryLimit}M", + ] ); } public function down(string $alias): void { - $this->childProcess->stop($alias); + $this->childProcess->stop('queue_'.$alias); } } From f7b8f528a7b497022266d7d57b8f32436cb15652 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Wed, 12 Mar 2025 14:01:14 +0100 Subject: [PATCH 191/224] refactor: this should not be necessary anymore --- src/NativeServiceProvider.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 526c8cf..1adad86 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -149,8 +149,8 @@ public function rewriteDatabase() { $databasePath = config('nativephp-internal.database_path'); - // Automatically create the database in development mode but not if we are running in a Phar - if (config('app.debug') && ! Phar::running()) { + // Automatically create the database in development mode + if (config('app.debug')) { $databasePath = database_path('nativephp.sqlite'); if (! file_exists($databasePath)) { From fbf7b236d7b69820d4442b7c222119f12df12be8 Mon Sep 17 00:00:00 2001 From: SRWieZ <1408020+SRWieZ@users.noreply.github.com> Date: Wed, 12 Mar 2025 13:01:42 +0000 Subject: [PATCH 192/224] Fix styling --- src/NativeServiceProvider.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 1adad86..ce1537f 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -25,7 +25,6 @@ use Native\Laravel\Logging\LogWatcher; use Native\Laravel\PowerMonitor as PowerMonitorImplementation; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; -use Phar; use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\PackageServiceProvider; From ee3945576e5e78645877dfbae9f7670168cf8f6a Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Sat, 15 Mar 2025 14:06:33 +0100 Subject: [PATCH 193/224] fix: NATIVEPHP_PHP_BINARY_PATH --- config/nativephp.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/nativephp.php b/config/nativephp.php index 49eacd8..1ecd30a 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -143,5 +143,5 @@ /** * Custom PHP binary path. */ - 'binary_path' => env('NATIVEPHP_BINARY_PATH', null), + 'binary_path' => env('NATIVEPHP_PHP_BINARY_PATH', null), ]; From 3e27e0b186664b05be4a2a09cf0198e3665beb2e Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Tue, 18 Mar 2025 03:20:39 +0000 Subject: [PATCH 194/224] Test fixes --- tests/Fakes/FakeChildProcessTest.php | 12 ++++++------ tests/QueueWorker/QueueWorkerTest.php | 20 ++++++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/tests/Fakes/FakeChildProcessTest.php b/tests/Fakes/FakeChildProcessTest.php index 57b0c35..aae9d26 100644 --- a/tests/Fakes/FakeChildProcessTest.php +++ b/tests/Fakes/FakeChildProcessTest.php @@ -82,18 +82,18 @@ $fake->php('cmdA', 'aliasA', ['envA'], true); $fake->php('cmdB', 'aliasB', ['envB'], false); - $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasA' && + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasA' && $cmd === 'cmdA' && $env === ['envA'] && $persistent === true); - $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasB' && + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasB' && $cmd === 'cmdB' && $env === ['envB'] && $persistent === false); try { - $fake->assertPhp(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasC'); + $fake->assertPhp(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasC'); } catch (AssertionFailedError) { return; } @@ -107,18 +107,18 @@ $fake->artisan('cmdA', 'aliasA', ['envA'], true); $fake->artisan('cmdB', 'aliasB', ['envB'], false); - $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasA' && + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasA' && $cmd === 'cmdA' && $env === ['envA'] && $persistent === true); - $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasB' && + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasB' && $cmd === 'cmdB' && $env === ['envB'] && $persistent === false); try { - $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent) => $alias === 'aliasC'); + $fake->assertArtisan(fn ($cmd, $alias, $env, $persistent, $iniSettings) => $alias === 'aliasC'); } catch (AssertionFailedError) { return; } diff --git a/tests/QueueWorker/QueueWorkerTest.php b/tests/QueueWorker/QueueWorkerTest.php index a3fbd57..2a6c137 100644 --- a/tests/QueueWorker/QueueWorkerTest.php +++ b/tests/QueueWorker/QueueWorkerTest.php @@ -6,23 +6,27 @@ it('hits the child process with relevant queue config to spin up a new queue worker', function () { ChildProcess::fake(); - $config = new QueueConfig('some_worker', ['default'], 128, 61); + + $workerName = 'some_worker'; + + $config = new QueueConfig($workerName, ['default'], 128, 61); QueueWorker::up($config); - ChildProcess::assertPhp(function (array $cmd, string $alias, $env, $persistent) { + ChildProcess::assertArtisan(function (array $cmd, string $alias, $env, $persistent, $iniSettings) use ($workerName) { expect($cmd)->toBe([ - '-d', - 'memory_limit=128M', - 'artisan', 'queue:work', - "--name={$alias}", + "--name={$workerName}", '--queue=default', '--memory=128', '--timeout=61', ]); - expect($alias)->toBe('some_worker'); + expect($iniSettings)->toBe([ + 'memory_limit' => '128M', + ]); + + expect($alias)->toBe('queue_some_worker'); expect($env)->toBeNull(); expect($persistent)->toBeTrue(); @@ -35,5 +39,5 @@ QueueWorker::down('some_worker'); - ChildProcess::assertStop('some_worker'); + ChildProcess::assertStop('queue_some_worker'); }); From 60ac44a4693e6524ff3a6f92f7481c0b8b70e0e9 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Tue, 18 Mar 2025 10:35:10 +0100 Subject: [PATCH 195/224] feat: add quit method to App class (#519) * feat: add quit method to App class * Method for facade added --- src/App.php | 5 +++++ src/Facades/App.php | 1 + 2 files changed, 6 insertions(+) diff --git a/src/App.php b/src/App.php index 81f1a26..3239026 100644 --- a/src/App.php +++ b/src/App.php @@ -8,6 +8,11 @@ class App { public function __construct(protected Client $client) {} + public function quit(): void + { + $this->client->post('app/quit'); + } + public function focus(): void { $this->client->post('app/focus'); diff --git a/src/Facades/App.php b/src/Facades/App.php index 6f3d99a..41817cf 100644 --- a/src/Facades/App.php +++ b/src/Facades/App.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Facade; /** + * @method static void quit() * @method static void focus() * @method static void hide() * @method static bool isHidden() From 372614dff197401aee651bc772bd88846826c7ea Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Tue, 18 Mar 2025 10:37:28 +0100 Subject: [PATCH 196/224] feat: add openAtLogin method to manage app startup behavior (#520) * feat: add openAtLogin method to manage app startup behavior * Method for facade added --- src/App.php | 13 +++++++++++++ src/Facades/App.php | 1 + 2 files changed, 14 insertions(+) diff --git a/src/App.php b/src/App.php index 3239026..bb8ef2e 100644 --- a/src/App.php +++ b/src/App.php @@ -62,4 +62,17 @@ public function clearRecentDocuments(): void { $this->client->delete('app/recent-documents'); } + + public function openAtLogin(?bool $open = null): bool + { + if ($open === null) { + return (bool) $this->client->get('app/open-at-login')->json('open'); + } + + $this->client->post('app/open-at-login', [ + 'open' => $open, + ]); + + return $open; + } } diff --git a/src/Facades/App.php b/src/Facades/App.php index 41817cf..dbc2591 100644 --- a/src/Facades/App.php +++ b/src/Facades/App.php @@ -14,6 +14,7 @@ * @method static void addRecentDocument(string $path) * @method static array recentDocuments() * @method static void clearRecentDocuments() + * @method static bool openAtLogin(?bool $open = null) */ class App extends Facade { From b8a753a4084df43207dff52a8555b186cfc8d6c3 Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Wed, 19 Mar 2025 13:04:06 +0000 Subject: [PATCH 197/224] Implement Debug Command (#516) * Implement Debug Command * Fix styling * Output to Clipboard support * Windows support for path detection * Fix styling * z vs s - z wins * Remove error log parsing for now * Implement config vars for notarization * Add PHP Binary Path to config --- config/nativephp-internal.php | 14 +++ src/Commands/DebugCommand.php | 165 ++++++++++++++++++++++++++++++++++ src/NativeServiceProvider.php | 4 +- 3 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 src/Commands/DebugCommand.php diff --git a/config/nativephp-internal.php b/config/nativephp-internal.php index 4210df9..2fbb4a3 100644 --- a/config/nativephp-internal.php +++ b/config/nativephp-internal.php @@ -29,4 +29,18 @@ * The URL to the NativePHP API. */ 'api_url' => env('NATIVEPHP_API_URL', 'http://localhost:4000/api/'), + + /** + * The credentials to use Apples Notarization service. + */ + 'notarization' => [ + 'apple_id' => env('NATIVEPHP_APPLE_ID'), + 'apple_id_pass' => env('NATIVEPHP_APPLE_ID_PASS'), + 'apple_team_id' => env('NATIVEPHP_APPLE_TEAM_ID'), + ], + + /** + * The binary path of PHP for NativePHP to use at build. + */ + 'php_binary_path' => env('NATIVEPHP_PHP_BINARY_PATH'), ]; diff --git a/src/Commands/DebugCommand.php b/src/Commands/DebugCommand.php new file mode 100644 index 0000000..3900d3c --- /dev/null +++ b/src/Commands/DebugCommand.php @@ -0,0 +1,165 @@ +debugInfo = collect(); + intro('Generating Debug Information...'); + + $this->processEnvironment() + ->processNativePHP(); + + switch ($this->argument('output')) { + case 'File': + $this->outputToFile(); + break; + case 'Clipboard': + $this->outputToClipboard(); + break; + case 'Console': + $this->outputToConsole(); + break; + default: + error('Invalid output option specified.'); + } + + outro('Debug Information Generated.'); + } + + private function processEnvironment(): static + { + $locationCommand = 'which'; + + if (PHP_OS_FAMILY === 'Windows') { + $locationCommand = 'where'; + } + + info('Generating Environment Data...'); + $environment = [ + 'PHP' => [ + 'Version' => phpversion(), + 'Path' => PHP_BINARY, + ], + 'Laravel' => [ + 'Version' => app()->version(), + 'ConfigCached' => file_exists($this->laravel->getCachedConfigPath()), + 'DebugEnabled' => $this->laravel->hasDebugModeEnabled(), + ], + 'Node' => [ + 'Version' => trim(Process::run('node -v')->output()), + 'Path' => trim(Process::run("$locationCommand node")->output()), + ], + 'NPM' => [ + 'Version' => trim(Process::run('npm -v')->output()), + 'Path' => trim(Process::run("$locationCommand npm")->output()), + ], + 'OperatingSystem' => PHP_OS, + ]; + + $this->debugInfo->put('Environment', $environment); + + return $this; + } + + private function processNativePHP(): static + { + info('Processing NativePHP Data...'); + // Get composer versions + $versions = collect([ + 'nativephp/electron' => null, + 'nativephp/laravel' => null, + 'nativephp/php-bin' => null, + ])->mapWithKeys(function ($version, $key) { + try { + $version = InstalledVersions::getVersion($key); + } catch (\OutOfBoundsException) { + $version = 'Not Installed'; + } + + return [$key => $version]; + }); + + $isNotarizationConfigured = config('nativephp-internal.notarization.apple_id') + && config('nativephp-internal.notarization.apple_id_pass') + && config('nativephp-internal.notarization.apple_team_id'); + + $this->debugInfo->put( + 'NativePHP', + [ + 'Versions' => $versions, + 'Configuration' => [ + 'Provider' => config('nativephp.provider'), + 'BuildHooks' => [ + 'Pre' => config('nativephp.prebuild'), + 'Post' => config('nativephp.postbuild'), + ], + 'NotarizationEnabled' => $isNotarizationConfigured, + 'CustomPHPBinary' => config('nativephp-internal.php_binary_path') ?? false, + ], + ] + ); + + return $this; + } + + protected function promptForMissingArgumentsUsing(): array + { + return [ + 'output' => fn () => select( + 'Where would you like to output the debug information?', + ['File', 'Clipboard', 'Console'], + 'File' + ), + ]; + } + + private function outputToFile(): void + { + File::put(base_path('nativephp_debug.json'), json_encode($this->debugInfo->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + note('Debug information saved to '.base_path('nativephp_debug.json')); + } + + private function outputToConsole(): void + { + $this->output->writeln( + print_r($this->debugInfo->toArray(), true) + ); + } + + private function outputToClipboard(): void + { + $json = json_encode($this->debugInfo->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + + // Copy json to clipboard + if (PHP_OS_FAMILY === 'Windows') { + Process::run('echo '.escapeshellarg($json).' | clip'); + } elseif (PHP_OS_FAMILY === 'Linux') { + Process::run('echo '.escapeshellarg($json).' | xclip -selection clipboard'); + } else { + Process::run('echo '.escapeshellarg($json).' | pbcopy'); + } + } +} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index b5b3225..c425e56 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; use Native\Laravel\ChildProcess as ChildProcessImplementation; +use Native\Laravel\Commands\DebugCommand; use Native\Laravel\Commands\FreshCommand; use Native\Laravel\Commands\LoadPHPConfigurationCommand; use Native\Laravel\Commands\LoadStartupConfigurationCommand; @@ -35,8 +36,9 @@ public function configurePackage(Package $package): void $package ->name('nativephp') ->hasCommands([ - MigrateCommand::class, + DebugCommand::class, FreshCommand::class, + MigrateCommand::class, SeedDatabaseCommand::class, ]) ->hasConfigFile() From 6899c2cb5ab784e6ee1ebd46397c98df0a18e905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20S=C3=A1nchez=20Palma?= <40817962+JA-Developer@users.noreply.github.com> Date: Mon, 24 Mar 2025 06:24:12 -0600 Subject: [PATCH 198/224] Fixed error "method_exists(): Argument #1 ($object_or_class) must be of type object|string, array given" when using Livewire and AdminLTE. (#524) * Fixed error 'method_exists(): Argument #1 ($object_or_class) must be of type object|string, array given' when using Darryldecode\Cart\Cart. * Check if the $event variable is an object before checking if it was dispatched by NativePHP. --- src/Events/EventWatcher.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Events/EventWatcher.php b/src/Events/EventWatcher.php index bae9ae7..8163e1a 100644 --- a/src/Events/EventWatcher.php +++ b/src/Events/EventWatcher.php @@ -14,6 +14,10 @@ public function register(): void Event::listen('*', function (string $eventName, array $data) { $event = $data[0] ?? (object) null; + if(! is_object($event)) { + return; + } + if (! method_exists($event, 'broadcastOn')) { return; } From 5992b012af721d3fb48cfdcc105753c123a1b012 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Tue, 25 Mar 2025 06:56:45 +0100 Subject: [PATCH 199/224] feat: implement Alert class and facade for alert management (#523) * feat: implement Alert class and facade for alert management * refactor: remove unused methods from Alert class --- src/Alert.php | 94 +++++++++++++++++++++++++++++++++++++++++++ src/Facades/Alert.php | 23 +++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/Alert.php create mode 100644 src/Facades/Alert.php diff --git a/src/Alert.php b/src/Alert.php new file mode 100644 index 0000000..4ddcb8f --- /dev/null +++ b/src/Alert.php @@ -0,0 +1,94 @@ +type = $type; + + return $this; + } + + public function title(string $title): self + { + $this->title = $title; + + return $this; + } + + public function detail(string $detail): self + { + $this->detail = $detail; + + return $this; + } + + public function buttons(array $buttons): self + { + $this->buttons = $buttons; + + return $this; + } + + public function defaultId(int $defaultId): self + { + $this->defaultId = $defaultId; + + return $this; + } + + public function cancelId(int $cancelId): self + { + $this->cancelId = $cancelId; + + return $this; + } + + public function show(string $message): int + { + $response = $this->client->post('alert/message', [ + 'message' => $message, + 'type' => $this->type, + 'title' => $this->title, + 'detail' => $this->detail, + 'buttons' => $this->buttons, + 'defaultId' => $this->defaultId, + 'cancelId' => $this->cancelId + ]); + + return (int) $response->json('result'); + } + + public function error(string $title, string $message): bool + { + $response = $this->client->post('alert/error', [ + 'title' => $title, + 'message' => $message, + ]); + + return (bool) $response->json('result'); + } +} diff --git a/src/Facades/Alert.php b/src/Facades/Alert.php new file mode 100644 index 0000000..a4b151f --- /dev/null +++ b/src/Facades/Alert.php @@ -0,0 +1,23 @@ + Date: Thu, 27 Mar 2025 16:57:44 +0000 Subject: [PATCH 200/224] Environment Helper (#527) * Add Environment Class with OS Helpers * Abstract all usages of PHP_OS_FAMILY to Environment class * Fix styling --------- Co-authored-by: Pete Bishop --- src/Alert.php | 14 +++++++------- src/Commands/DebugCommand.php | 7 ++++--- src/Events/EventWatcher.php | 2 +- src/Support/Environment.php | 31 +++++++++++++++++++++++++++++++ src/System.php | 3 ++- 5 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 src/Support/Environment.php diff --git a/src/Alert.php b/src/Alert.php index 4ddcb8f..d00e7ef 100644 --- a/src/Alert.php +++ b/src/Alert.php @@ -2,23 +2,23 @@ namespace Native\Laravel; -use Illuminate\Support\Traits\Conditionable; -use Illuminate\Support\Traits\Macroable; use Native\Laravel\Client\Client; -use Native\Laravel\Facades\Window; class Alert { protected ?string $type; + protected ?string $title; + protected ?string $detail; + protected ?array $buttons; + protected ?int $defaultId; + protected ?int $cancelId; - final public function __construct(protected Client $client) - { - } + final public function __construct(protected Client $client) {} public static function new() { @@ -76,7 +76,7 @@ public function show(string $message): int 'detail' => $this->detail, 'buttons' => $this->buttons, 'defaultId' => $this->defaultId, - 'cancelId' => $this->cancelId + 'cancelId' => $this->cancelId, ]); return (int) $response->json('result'); diff --git a/src/Commands/DebugCommand.php b/src/Commands/DebugCommand.php index 3900d3c..ad79c3b 100644 --- a/src/Commands/DebugCommand.php +++ b/src/Commands/DebugCommand.php @@ -8,6 +8,7 @@ use Illuminate\Support\Collection; use Illuminate\Support\Facades\File; use Illuminate\Support\Facades\Process; +use Native\Laravel\Support\Environment; use function Laravel\Prompts\error; use function Laravel\Prompts\info; @@ -53,7 +54,7 @@ private function processEnvironment(): static { $locationCommand = 'which'; - if (PHP_OS_FAMILY === 'Windows') { + if (Environment::isWindows()) { $locationCommand = 'where'; } @@ -154,9 +155,9 @@ private function outputToClipboard(): void $json = json_encode($this->debugInfo->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); // Copy json to clipboard - if (PHP_OS_FAMILY === 'Windows') { + if (Environment::isWindows()) { Process::run('echo '.escapeshellarg($json).' | clip'); - } elseif (PHP_OS_FAMILY === 'Linux') { + } elseif (Environment::isLinux()) { Process::run('echo '.escapeshellarg($json).' | xclip -selection clipboard'); } else { Process::run('echo '.escapeshellarg($json).' | pbcopy'); diff --git a/src/Events/EventWatcher.php b/src/Events/EventWatcher.php index 8163e1a..6df7e24 100644 --- a/src/Events/EventWatcher.php +++ b/src/Events/EventWatcher.php @@ -14,7 +14,7 @@ public function register(): void Event::listen('*', function (string $eventName, array $data) { $event = $data[0] ?? (object) null; - if(! is_object($event)) { + if (! is_object($event)) { return; } diff --git a/src/Support/Environment.php b/src/Support/Environment.php new file mode 100644 index 0000000..70f2036 --- /dev/null +++ b/src/Support/Environment.php @@ -0,0 +1,31 @@ +translateFromWindowsString(exec('tzutil /g')); } else { $timezone = $timezones->translateFromAbbreviatedString(exec('date +%Z')); From 29b877947e75a09339b54a943df3909a7423ccf5 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 31 Mar 2025 10:59:10 +0200 Subject: [PATCH 201/224] fix: initialize properties in Alert class and update new method signature (#529) --- src/Alert.php | 14 +++++++------- src/Facades/Alert.php | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Alert.php b/src/Alert.php index d00e7ef..1303721 100644 --- a/src/Alert.php +++ b/src/Alert.php @@ -6,21 +6,21 @@ class Alert { - protected ?string $type; + protected ?string $type = null; - protected ?string $title; + protected ?string $title = null; - protected ?string $detail; + protected ?string $detail = null; - protected ?array $buttons; + protected ?array $buttons = null; - protected ?int $defaultId; + protected ?int $defaultId = null; - protected ?int $cancelId; + protected ?int $cancelId = null; final public function __construct(protected Client $client) {} - public static function new() + public static function new(): self { return new static(new Client); } diff --git a/src/Facades/Alert.php b/src/Facades/Alert.php index a4b151f..2d5e1f2 100644 --- a/src/Facades/Alert.php +++ b/src/Facades/Alert.php @@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Facade; /** + * @method static static new() * @method static static type(string $type) * @method static static title(string $title) * @method static static detail(string $detail) From afe7316242a51789e5e943ebac749dddc7b78240 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 31 Mar 2025 11:01:42 +0200 Subject: [PATCH 202/224] feat: add theme method to System class and create SystemThemesEnum (#530) --- src/Enums/SystemThemesEnum.php | 10 ++++++++++ src/Facades/System.php | 2 ++ src/System.php | 14 ++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 src/Enums/SystemThemesEnum.php diff --git a/src/Enums/SystemThemesEnum.php b/src/Enums/SystemThemesEnum.php new file mode 100644 index 0000000..e290dbc --- /dev/null +++ b/src/Enums/SystemThemesEnum.php @@ -0,0 +1,10 @@ +client->post('system/theme', [ + 'theme' => $theme, + ])->json('result'); + } else { + $result = $this->client->get('system/theme')->json('result'); + } + + return SystemThemesEnum::from($result); + } } From 15b6d75b98d4ea9bf69b0fb8aab9001061fa571d Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Mon, 31 Mar 2025 15:47:23 +0100 Subject: [PATCH 203/224] PHP Support Sync (#532) * Set PHP support to min 8.3 * Drop PHP 8.1 and 8.2 support from workflows --- .github/workflows/run-tests.yml | 8 +------- composer.json | 2 +- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index a1909f6..18fb032 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -13,16 +13,10 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, windows-latest] - php: [8.4, 8.3, 8.2, 8.1] + php: [8.4, 8.3] laravel: [12.*, 11.*, 10.*] stability: [prefer-lowest, prefer-stable] - exclude: - - laravel: 11.* - php: 8.1 - - laravel: 12.* - php: 8.1 - name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} steps: diff --git a/composer.json b/composer.json index 71336ed..73e68c5 100644 --- a/composer.json +++ b/composer.json @@ -31,7 +31,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.3", "illuminate/contracts": "^10.0|^11.0|^12.0", "spatie/laravel-package-tools": "^1.16.4", "symfony/finder": "^6.2|^7.0" From c1f334dc268103b5772d46f455de93a846c0c042 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 31 Mar 2025 17:20:40 +0200 Subject: [PATCH 204/224] feat: add copyright notice configuration to nativephp.php (#534) --- config/nativephp.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/nativephp.php b/config/nativephp.php index 1ecd30a..817bc12 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -31,6 +31,11 @@ */ 'author' => env('NATIVEPHP_APP_AUTHOR'), + /** + * The copyright notice for your application. + */ + 'copyright' => env('NATIVEPHP_APP_COPYRIGHT'), + /** * The default service provider for your application. This provider * takes care of bootstrapping your application and configuring From 5ca07c4450233a397d4258abf7764a61ba6da129 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 1 Apr 2025 14:57:07 +0200 Subject: [PATCH 205/224] fix: $iniSettings on ChildProcess.php (#535) * fix: $iniSettings on ChildProcess.php * fix: ensure properties are set only if they exist * fix: throw exception for non-existent properties in ChildProcess --- src/ChildProcess.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ChildProcess.php b/src/ChildProcess.php index 19a9420..6ba9972 100644 --- a/src/ChildProcess.php +++ b/src/ChildProcess.php @@ -19,6 +19,8 @@ class ChildProcess implements ChildProcessContract public readonly bool $persistent; + public readonly ?array $iniSettings; + final public function __construct(protected Client $client) {} public function get(?string $alias = null): ?self @@ -147,6 +149,10 @@ protected function fromRuntimeProcess($process) } foreach ($process['settings'] as $key => $value) { + if (! property_exists($this, $key)) { + throw new \RuntimeException("Property {$key} does not exist on ".__CLASS__); + } + $this->{$key} = $value; } From 1e525896b0af75dec8cd1e6cd74035a0983d99f7 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Wed, 2 Apr 2025 14:52:13 +0200 Subject: [PATCH 206/224] fix: menu facade + better default for quit (#536) --- src/Facades/Menu.php | 37 +++++++++++++++++++------------------ src/Menu/MenuBuilder.php | 4 ++++ 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/Facades/Menu.php b/src/Facades/Menu.php index 332de24..d197305 100644 --- a/src/Facades/Menu.php +++ b/src/Facades/Menu.php @@ -19,25 +19,26 @@ * @method static Link route(string $url, string $label = null, ?string $hotkey = null) * @method static Radio radio(string $label, bool $checked = false, ?string $hotkey = null) * @method static Role app() - * @method static Role file() - * @method static Role edit() - * @method static Role view() - * @method static Role window() - * @method static Role help() - * @method static Role fullscreen() + * @method static Role about(?string $label = null) + * @method static Role file(?string $label = null) + * @method static Role edit(?string $label = null) + * @method static Role view(?string $label = null) + * @method static Role window(?string $label = null) + * @method static Role help(?string $label = null) + * @method static Role fullscreen(?string $label = null) * @method static Role separator() - * @method static Role devTools() - * @method static Role undo() - * @method static Role redo() - * @method static Role cut() - * @method static Role copy() - * @method static Role paste() - * @method static Role pasteAndMatchStyle() - * @method static Role reload() - * @method static Role minimize() - * @method static Role close() - * @method static Role quit() - * @method static Role hide() + * @method static Role devTools(?string $label = null) + * @method static Role undo(?string $label = null) + * @method static Role redo(?string $label = null) + * @method static Role cut(?string $label = null) + * @method static Role copy(?string $label = null) + * @method static Role paste(?string $label = null) + * @method static Role pasteAndMatchStyle(?string $label = null) + * @method static Role reload(?string $label = null) + * @method static Role minimize(?string $label = null) + * @method static Role close(?string $label = null) + * @method static Role quit(?string $label = null) + * @method static Role hide(?string $label = null) * @method static void create(MenuItem ...$items) * @method static void default() */ diff --git a/src/Menu/MenuBuilder.php b/src/Menu/MenuBuilder.php index f0627f7..f2ef764 100644 --- a/src/Menu/MenuBuilder.php +++ b/src/Menu/MenuBuilder.php @@ -150,6 +150,10 @@ public function close(?string $label = null): Items\Role public function quit(?string $label = null): Items\Role { + if (is_null($label)) { + $label = __('Quit').' '.config('app.name'); + } + return new Items\Role(RolesEnum::QUIT, $label); } From 91f487cb40fdea5ce737fc7128f4f17dc2a2e92f Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Thu, 3 Apr 2025 14:37:25 +0200 Subject: [PATCH 207/224] fix: failed jobs on the nativephp database (#538) * fix: failed jobs on the nativephp database * fix: add batching database configuration for nativephp queue * fix: add database connection configuration for nativephp queue --- src/NativeServiceProvider.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index 7e000a7..a1910a4 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -172,6 +172,9 @@ public function rewriteDatabase() ]); config(['database.default' => 'nativephp']); + config(['queue.failed.database' => 'nativephp']); + config(['queue.batching.database' => 'nativephp']); + config(['queue.connections.database.connection' => 'nativephp']); if (file_exists($databasePath)) { DB::statement('PRAGMA journal_mode=WAL;'); From 9e9166d698e55e1877ba1726ba7d25999c85065f Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Mon, 7 Apr 2025 15:52:57 +0100 Subject: [PATCH 208/224] Remove L10 from test matrix (#541) * Remove L10 from test matrix * Remove PHPStan ignore line... --- .github/workflows/run-tests.yml | 2 +- src/NativeServiceProvider.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 18fb032..68e6ca9 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -14,7 +14,7 @@ jobs: matrix: os: [ubuntu-latest, windows-latest] php: [8.4, 8.3] - laravel: [12.*, 11.*, 10.*] + laravel: [12.*, 11.*] stability: [prefer-lowest, prefer-stable] name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index a1910a4..ad222f9 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -51,7 +51,6 @@ public function packageRegistered() $this->mergeConfigFrom($this->package->basePath('/../config/nativephp-internal.php'), 'nativephp-internal'); $this->app->singleton(FreshCommand::class, function ($app) { - /* @phpstan-ignore-next-line (beacause we support Laravel 10 & 11) */ return new FreshCommand($app['migrator']); }); From e4b8e0accf74395670828c6dea4c17c8fbad196e Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Mon, 7 Apr 2025 19:09:12 +0100 Subject: [PATCH 209/224] Reduce number of fields on bug report, replacing many with native:debug (#545) --- .github/ISSUE_TEMPLATE/bug.yml | 47 ++++++++-------------------------- 1 file changed, 11 insertions(+), 36 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml index f454785..29e7381 100644 --- a/.github/ISSUE_TEMPLATE/bug.yml +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -7,9 +7,11 @@ body: attributes: value: | We're sorry to hear you have a problem. - + Before submitting your report, please make sure you've been through the section "[Debugging](https://nativephp.com/docs/getting-started/debugging)" in the docs. + Please also ensure that you have the latest version of NativePHP packages installed, and are using [supported versions](https://nativephp.com/docs/desktop/1/getting-started/support-policy) of PHP and Laravel. + If nothing here has helped you, please provide as much useful context as you can here to help us solve help you. Note that reams and reams of logs isn't helpful - please share only relevant errors. @@ -23,6 +25,7 @@ body: placeholder: Trying to build my app for production validations: required: true + - type: textarea id: what-happened attributes: @@ -31,6 +34,7 @@ body: placeholder: I cannot currently do X thing because when I do, it breaks X thing. validations: required: true + - type: textarea id: how-to-reproduce attributes: @@ -39,37 +43,15 @@ body: placeholder: When I do X I see Y. validations: required: true + - type: textarea - id: package-version - attributes: - label: Package Versions - description: What versions of the NativePHP packages are you running? Output of `composer show "nativephp/*" --format=json` - validations: - required: true - - type: input - id: php-version + id: debug attributes: - label: PHP Version - description: What version of PHP are you running? Please be as specific as possible - placeholder: 8.2.0 + label: Debug Output + description: Please provide output from the NativePHP Debug command. This will help us understand your environment and the issue you're facing. (`php artisan native:debug`) validations: required: true - - type: input - id: laravel-version - attributes: - label: Laravel Version - description: What version of Laravel are you running? Please be as specific as possible - placeholder: 9.0.0 - validations: - required: true - - type: input - id: node-version - attributes: - label: Node Version - description: What version of Node are you running? Please be as specific as possible - placeholder: '18.17' - validations: - required: true + - type: dropdown id: operating-systems attributes: @@ -80,14 +62,7 @@ body: - macOS - Windows - Linux - - type: input - id: os-version - attributes: - label: OS version - description: Which version of these OSes are you using? - placeholder: 'win11 (23H2), macos14.1 (23B74)' - validations: - required: true + - type: textarea id: notes attributes: From 31e630b9ac315a1e5b0779b1203eafa58e0cac33 Mon Sep 17 00:00:00 2001 From: Simon Hamp Date: Wed, 9 Apr 2025 02:33:19 +0100 Subject: [PATCH 210/224] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 4308c95..c1284be 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ Thanks to the following sponsors for funding NativePHP development. Please consi - [RedGalaxy](https://www.redgalaxy.co.uk) - A web application development studio based in Cambridgeshire, building solutions to help businesses improve efficiency and profitability. - [Sevalla](https://sevalla.com/?utm_source=nativephp&utm_medium=Referral&utm_campaign=homepage) - Host and manage your applications, databases, and static sites in a single, intuitive platform. - [KaasHosting](https://www.kaashosting.nl/?lang=en) - Minecraft Server and VPS hosting from The Netherlands. -- [Borah Digital Labs](https://borah.digital/) - An MVP building studio from the sunny Canary Islands focusing on AI, SaaS and online platforms. ## Changelog From 540e9a474cb9248a941b7dbe7b5c22bb13a45fc6 Mon Sep 17 00:00:00 2001 From: Justas Raudonius <10882793+justRau@users.noreply.github.com> Date: Mon, 14 Apr 2025 12:30:09 +0300 Subject: [PATCH 211/224] Update DebugCommand.php (#550) --- src/Commands/DebugCommand.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Commands/DebugCommand.php b/src/Commands/DebugCommand.php index ad79c3b..2bb7633 100644 --- a/src/Commands/DebugCommand.php +++ b/src/Commands/DebugCommand.php @@ -66,7 +66,8 @@ private function processEnvironment(): static ], 'Laravel' => [ 'Version' => app()->version(), - 'ConfigCached' => file_exists($this->laravel->getCachedConfigPath()), + 'ConfigCached' => $this->laravel->configurationIsCached(), + 'RoutesCached' => $this->laravel->routesAreCached(), 'DebugEnabled' => $this->laravel->hasDebugModeEnabled(), ], 'Node' => [ From ff9adc83be4120268c659e5dde0e3cc83da88cde Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 28 Apr 2025 12:13:19 +0200 Subject: [PATCH 212/224] Add 'description' and 'website' fields to nativephp config (#571) * Add 'description' and 'website' fields to nativephp config These new fields allow developers to define a description and website for their application via environment variables. This enhances configurability and provides more application metadata. * Added Defaults - config/nativephp.php Co-authored-by: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> * Added Defaults - config/nativephp.php Co-authored-by: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> --------- Co-authored-by: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> --- config/nativephp.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/config/nativephp.php b/config/nativephp.php index 817bc12..96b6b1e 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -36,6 +36,16 @@ */ 'copyright' => env('NATIVEPHP_APP_COPYRIGHT'), + /** + * The description of your application. + */ + 'description' => env('NATIVEPHP_APP_DESCRIPTION', 'An awesome app built with NativePHP'), + + /** + * The Website of your application. + */ + 'website' => env('NATIVEPHP_APP_WEBSITE', 'https://nativephp.com'), + /** * The default service provider for your application. This provider * takes care of bootstrapping your application and configuring From e3d5974dafc0d4d51e426db0eb7fd5a0a0d67475 Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Mon, 28 Apr 2025 14:12:29 +0200 Subject: [PATCH 213/224] Add relaunch functionality to App and its facade (#569) --- src/App.php | 5 +++++ src/Facades/App.php | 1 + 2 files changed, 6 insertions(+) diff --git a/src/App.php b/src/App.php index 039579e..f7fa1c3 100644 --- a/src/App.php +++ b/src/App.php @@ -14,6 +14,11 @@ public function quit(): void $this->client->post('app/quit'); } + public function relaunch(): void + { + $this->client->post('app/relaunch'); + } + public function focus(): void { $this->client->post('app/focus'); diff --git a/src/Facades/App.php b/src/Facades/App.php index 69abb2e..14e42f8 100644 --- a/src/Facades/App.php +++ b/src/Facades/App.php @@ -6,6 +6,7 @@ /** * @method static void quit() + * @method static void relaunch() * @method static void focus() * @method static void hide() * @method static bool isHidden() From 5af2e3ee8c416d4cd0cfba460420ed8866dc063e Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Tue, 29 Apr 2025 12:38:32 +0200 Subject: [PATCH 214/224] Add "showOnAllWorkspaces" option to MenuBar (#568) Introduce a new `showOnAllWorkspaces` property and its corresponding method to configure this behavior. Update the `toArray` method to include this property and adjust tests to validate its functionality. --- src/MenuBar/MenuBar.php | 10 ++++++++++ tests/MenuBar/MenuBarTest.php | 2 ++ 2 files changed, 12 insertions(+) diff --git a/src/MenuBar/MenuBar.php b/src/MenuBar/MenuBar.php index 13a5709..c3b6ce8 100644 --- a/src/MenuBar/MenuBar.php +++ b/src/MenuBar/MenuBar.php @@ -32,6 +32,8 @@ class MenuBar protected bool $showDockIcon = false; + protected bool $showOnAllWorkspaces = false; + protected Client $client; public function __construct() @@ -95,6 +97,13 @@ public function alwaysOnTop($alwaysOnTop = true): self return $this; } + public function showOnAllWorkspaces($showOnAllWorkspaces = true): self + { + $this->showOnAllWorkspaces = $showOnAllWorkspaces; + + return $this; + } + public function withContextMenu(Menu $menu): self { $this->contextMenu = $menu; @@ -122,6 +131,7 @@ public function toArray(): array 'onlyShowContextMenu' => $this->onlyShowContextMenu, 'contextMenu' => ! is_null($this->contextMenu) ? $this->contextMenu->toArray()['submenu'] : null, 'alwaysOnTop' => $this->alwaysOnTop, + 'showOnAllWorkspaces' => $this->showOnAllWorkspaces, ]; } } diff --git a/tests/MenuBar/MenuBarTest.php b/tests/MenuBar/MenuBarTest.php index 4b86aa9..79dbb80 100644 --- a/tests/MenuBar/MenuBarTest.php +++ b/tests/MenuBar/MenuBarTest.php @@ -9,6 +9,7 @@ $menuBar = MenuBar::create() ->showDockIcon() ->alwaysOnTop() + ->showOnAllWorkspaces() ->label('milwad') ->icon('nativephp.png') ->url('https://github.com/milwad-dev') @@ -22,6 +23,7 @@ $this->assertTrue($menuBarArray['showDockIcon']); $this->assertTrue($menuBarArray['alwaysOnTop']); + $this->assertTrue($menuBarArray['showOnAllWorkspaces']); $this->assertEquals('milwad', $menuBarArray['label']); $this->assertEquals('https://github.com/milwad-dev', $menuBarArray['url']); $this->assertEquals('nativephp.png', $menuBarArray['icon']); From 949c1ac15d75a3c5f0c619f9731cfb17b211a583 Mon Sep 17 00:00:00 2001 From: Peter Bishop <9081809+PeteBishwhip@users.noreply.github.com> Date: Tue, 29 Apr 2025 20:19:53 +0100 Subject: [PATCH 215/224] Update fix-php-code-style-issues.yml (#573) --- .github/workflows/fix-php-code-style-issues.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/fix-php-code-style-issues.yml b/.github/workflows/fix-php-code-style-issues.yml index eb79b6e..4ae67bf 100644 --- a/.github/workflows/fix-php-code-style-issues.yml +++ b/.github/workflows/fix-php-code-style-issues.yml @@ -22,7 +22,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 with: - ref: ${{ github.head_ref }} + ref: ${{ github.head_ref || github.sha }} - name: Check PHP code style issues if: github.event_name == 'push' From a19e54fa778182c25786051ded8bf46afd831fac Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Thu, 8 May 2025 10:15:27 +0200 Subject: [PATCH 216/224] Add AutoUpdater feature with events and facade support (#570) * Add AutoUpdater feature with events and facade support Introduces the `AutoUpdater` class to manage update processes via the client. Adds events such as `UpdateAvailable`, `UpdateDownloaded`, and others for broadcasting update states. A facade is also provided for convenient usage. * Add DownloadProgress event for real-time update broadcasting This event handles broadcasting download progress updates through a 'nativephp' channel. It includes details such as total size, delta, transferred bytes, percentage completed, and speed. * fix: update property types in DownloadProgress constructor Adjusted the types of total, delta, and bytesPerSecond from float to int to ensure type consistency and accuracy. This change prevents potential precision issues and aligns with expected data formats. --- src/AutoUpdater.php | 20 ++++++++++++++++ src/Events/AutoUpdater/CheckingForUpdate.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/DownloadProgress.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/Error.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/UpdateAvailable.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/UpdateDownloaded.php | 23 +++++++++++++++++++ src/Events/AutoUpdater/UpdateNotAvailable.php | 21 +++++++++++++++++ src/Facades/AutoUpdater.php | 17 ++++++++++++++ 8 files changed, 173 insertions(+) create mode 100644 src/AutoUpdater.php create mode 100644 src/Events/AutoUpdater/CheckingForUpdate.php create mode 100644 src/Events/AutoUpdater/DownloadProgress.php create mode 100644 src/Events/AutoUpdater/Error.php create mode 100644 src/Events/AutoUpdater/UpdateAvailable.php create mode 100644 src/Events/AutoUpdater/UpdateDownloaded.php create mode 100644 src/Events/AutoUpdater/UpdateNotAvailable.php create mode 100644 src/Facades/AutoUpdater.php diff --git a/src/AutoUpdater.php b/src/AutoUpdater.php new file mode 100644 index 0000000..e714a0f --- /dev/null +++ b/src/AutoUpdater.php @@ -0,0 +1,20 @@ +client->post('auto-updater/check-for-updates'); + } + + public function quitAndInstall(): void + { + $this->client->post('auto-updater/quit-and-install'); + } +} diff --git a/src/Events/AutoUpdater/CheckingForUpdate.php b/src/Events/AutoUpdater/CheckingForUpdate.php new file mode 100644 index 0000000..a646d32 --- /dev/null +++ b/src/Events/AutoUpdater/CheckingForUpdate.php @@ -0,0 +1,23 @@ + Date: Thu, 8 May 2025 09:27:47 +0100 Subject: [PATCH 217/224] Include sleep option in queue config (#564) * feat/add-sleep-option-to-queue-config | expose sleep option to QueueConfig * feat/add-sleep-option-to-queue-config | include default sleep option in nativephp config file --- config/nativephp.php | 1 + src/DTOs/QueueConfig.php | 2 ++ src/QueueWorker.php | 1 + tests/DTOs/QueueWorkerTest.php | 5 +++++ tests/Fakes/FakeQueueWorkerTest.php | 4 ++-- tests/QueueWorker/QueueWorkerTest.php | 3 ++- 6 files changed, 13 insertions(+), 3 deletions(-) diff --git a/config/nativephp.php b/config/nativephp.php index 96b6b1e..d68245f 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -141,6 +141,7 @@ 'queues' => ['default'], 'memory_limit' => 128, 'timeout' => 60, + 'sleep' => 3, ], ], diff --git a/src/DTOs/QueueConfig.php b/src/DTOs/QueueConfig.php index 0ec3ca0..df04d0c 100644 --- a/src/DTOs/QueueConfig.php +++ b/src/DTOs/QueueConfig.php @@ -12,6 +12,7 @@ public function __construct( public readonly array $queuesToConsume, public readonly int $memoryLimit, public readonly int $timeout, + public readonly int $sleep, ) {} /** @@ -26,6 +27,7 @@ function (array|string $worker, string $alias) { $worker['queues'] ?? ['default'], $worker['memory_limit'] ?? 128, $worker['timeout'] ?? 60, + $worker['sleep'] ?? 3, ); }, $config, diff --git a/src/QueueWorker.php b/src/QueueWorker.php index 875a5c2..f9c2ea1 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -31,6 +31,7 @@ public function up(string|QueueConfig $config): void '--queue='.implode(',', $config->queuesToConsume), "--memory={$config->memoryLimit}", "--timeout={$config->timeout}", + "--sleep={$config->sleep}", ], 'queue_'.$config->alias, persistent: true, diff --git a/tests/DTOs/QueueWorkerTest.php b/tests/DTOs/QueueWorkerTest.php index 76209c8..01197aa 100644 --- a/tests/DTOs/QueueWorkerTest.php +++ b/tests/DTOs/QueueWorkerTest.php @@ -21,6 +21,8 @@ fn (QueueConfig $config) => $config->alias === $worker)))->memoryLimit->toBe(128); expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $worker)))->timeout->toBe(60); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $worker)))->sleep->toBe(3); continue; } @@ -35,6 +37,8 @@ fn (QueueConfig $config) => $config->alias === $alias)))->memoryLimit->toBe($worker['memory_limit'] ?? 128); expect(Arr::first(array_filter($configObject, fn (QueueConfig $config) => $config->alias === $alias)))->timeout->toBe($worker['timeout'] ?? 60); + expect(Arr::first(array_filter($configObject, + fn (QueueConfig $config) => $config->alias === $alias)))->sleep->toBe($worker['sleep'] ?? 3); } })->with([ [ @@ -44,6 +48,7 @@ 'queues' => ['default'], 'memory_limit' => 64, 'timeout' => 60, + 'sleep' => 3, ], ], ], diff --git a/tests/Fakes/FakeQueueWorkerTest.php b/tests/Fakes/FakeQueueWorkerTest.php index 4b22f34..150f2a2 100644 --- a/tests/Fakes/FakeQueueWorkerTest.php +++ b/tests/Fakes/FakeQueueWorkerTest.php @@ -17,8 +17,8 @@ it('asserts up using callable', function () { swap(QueueWorkerContract::class, $fake = app(QueueWorkerFake::class)); - $fake->up(new QueueConfig('testA', ['default'], 123, 123)); - $fake->up(new QueueConfig('testB', ['default'], 123, 123)); + $fake->up(new QueueConfig('testA', ['default'], 123, 123, 0)); + $fake->up(new QueueConfig('testB', ['default'], 123, 123, 0)); $fake->assertUp(fn (QueueConfig $up) => $up->alias === 'testA'); $fake->assertUp(fn (QueueConfig $up) => $up->alias === 'testB'); diff --git a/tests/QueueWorker/QueueWorkerTest.php b/tests/QueueWorker/QueueWorkerTest.php index 2a6c137..7605a56 100644 --- a/tests/QueueWorker/QueueWorkerTest.php +++ b/tests/QueueWorker/QueueWorkerTest.php @@ -9,7 +9,7 @@ $workerName = 'some_worker'; - $config = new QueueConfig($workerName, ['default'], 128, 61); + $config = new QueueConfig($workerName, ['default'], 128, 61, 5); QueueWorker::up($config); @@ -20,6 +20,7 @@ '--queue=default', '--memory=128', '--timeout=61', + '--sleep=5', ]); expect($iniSettings)->toBe([ From 11cb34fdfeb5a30cc450296ae3f204024c54cd89 Mon Sep 17 00:00:00 2001 From: AJ <60591772+devajmeireles@users.noreply.github.com> Date: Thu, 8 May 2025 05:53:06 -0300 Subject: [PATCH 218/224] Updated get method in Settings.php to handle default values better (#562) --- src/Settings.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Settings.php b/src/Settings.php index e849c72..ddcc030 100644 --- a/src/Settings.php +++ b/src/Settings.php @@ -17,7 +17,13 @@ public function set(string $key, $value): void public function get(string $key, $default = null): mixed { - return $this->client->get('settings/'.$key)->json('value') ?? $default; + $response = $this->client->get('settings/'.$key)->json('value'); + + if ($response === null) { + return $default instanceof \Closure ? $default() : $default; + } + + return $response; } public function forget(string $key): void From 9d1fc92db58474650f87d4a94e0846f6ad7e85d7 Mon Sep 17 00:00:00 2001 From: Willem Leuverink Date: Mon, 12 May 2025 13:09:22 +0200 Subject: [PATCH 219/224] Automatically apply PreventBrowserAccess middleware (#551) * skip when running tests * skip when not in Electron context * automatically apply middleware to 'web' group * apply middleware to all routes --- src/Http/Middleware/PreventRegularBrowserAccess.php | 4 ++++ src/NativeServiceProvider.php | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/src/Http/Middleware/PreventRegularBrowserAccess.php b/src/Http/Middleware/PreventRegularBrowserAccess.php index de1c72b..6722a3d 100644 --- a/src/Http/Middleware/PreventRegularBrowserAccess.php +++ b/src/Http/Middleware/PreventRegularBrowserAccess.php @@ -9,6 +9,10 @@ class PreventRegularBrowserAccess { public function handle(Request $request, Closure $next) { + if (! config('nativephp-internal.running')) { + return $next($request); + } + // Explicitly skip for the cookie-setting route if ($request->path() === '_native/api/cookie') { return $next($request); diff --git a/src/NativeServiceProvider.php b/src/NativeServiceProvider.php index ad222f9..74dfba3 100644 --- a/src/NativeServiceProvider.php +++ b/src/NativeServiceProvider.php @@ -4,6 +4,7 @@ use Illuminate\Console\Application; use Illuminate\Foundation\Application as Foundation; +use Illuminate\Foundation\Http\Kernel; use Illuminate\Support\Arr; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\DB; @@ -23,6 +24,7 @@ use Native\Laravel\Events\EventWatcher; use Native\Laravel\Exceptions\Handler; use Native\Laravel\GlobalShortcut as GlobalShortcutImplementation; +use Native\Laravel\Http\Middleware\PreventRegularBrowserAccess; use Native\Laravel\Logging\LogWatcher; use Native\Laravel\PowerMonitor as PowerMonitorImplementation; use Native\Laravel\Windows\WindowManager as WindowManagerImplementation; @@ -84,6 +86,11 @@ public function packageRegistered() Handler::class ); + // Automatically prevent browser access + $this->app->make(Kernel::class)->pushMiddleware( + PreventRegularBrowserAccess::class, + ); + Application::starting(function ($app) { $app->resolveCommands([ LoadStartupConfigurationCommand::class, From 9175e4648f5f5f16f60adff33b2427020eebc953 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Tue, 13 May 2025 08:19:02 +0200 Subject: [PATCH 220/224] fix: use queue:listen in local environment for QueueWorker (#587) --- src/QueueWorker.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/QueueWorker.php b/src/QueueWorker.php index f9c2ea1..2c99808 100644 --- a/src/QueueWorker.php +++ b/src/QueueWorker.php @@ -24,9 +24,13 @@ public function up(string|QueueConfig $config): void throw new \InvalidArgumentException("Invalid queue configuration alias [$config]"); } + $command = app()->isLocal() + ? 'queue:listen' + : 'queue:work'; + $this->childProcess->artisan( [ - 'queue:work', + $command, "--name={$config->alias}", '--queue='.implode(',', $config->queuesToConsume), "--memory={$config->memoryLimit}", From 584033d7c0d3d5ea466ca0371b09e5c5cfb380ae Mon Sep 17 00:00:00 2001 From: Chris Keller <67823070+chr15k@users.noreply.github.com> Date: Sat, 17 May 2025 11:30:37 -0400 Subject: [PATCH 221/224] feat/queue-sleep-option-config-type-hint-update | update sleep type hint to allow float values (#583) --- src/DTOs/QueueConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DTOs/QueueConfig.php b/src/DTOs/QueueConfig.php index df04d0c..29308a0 100644 --- a/src/DTOs/QueueConfig.php +++ b/src/DTOs/QueueConfig.php @@ -12,7 +12,7 @@ public function __construct( public readonly array $queuesToConsume, public readonly int $memoryLimit, public readonly int $timeout, - public readonly int $sleep, + public readonly int|float $sleep, ) {} /** From 2aa5e4ff01b65baaaea9dc0528872167d99721f3 Mon Sep 17 00:00:00 2001 From: Eser DENIZ Date: Wed, 21 May 2025 20:12:51 +0200 Subject: [PATCH 222/224] fix: remove App facade from composer.json aliases (#586) --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 73e68c5..7d55ade 100644 --- a/composer.json +++ b/composer.json @@ -85,7 +85,6 @@ "Native\\Laravel\\NativeServiceProvider" ], "aliases": { - "App": "Native\\Laravel\\Facades\\App", "ChildProcess": "Native\\Laravel\\Facades\\ChildProcess", "Clipboard": "Native\\Laravel\\Facades\\Clipboard", "ContextMenu": "Native\\Laravel\\Facades\\ContextMenu", From 3b79aa9cef55acc17893854af74db822d1f059ae Mon Sep 17 00:00:00 2001 From: WINBIGFOX Date: Thu, 22 May 2025 14:41:58 +0200 Subject: [PATCH 223/224] Add support for detailed auto-updater event handling (#590) Expanded event constructors to include more detailed update metadata such as version, files, release information, and system requirements. Added a `downloadUpdate` method to the AutoUpdater facade. These updates enhance event broadcasting and improve client interaction with the auto-updater. --- src/AutoUpdater.php | 5 +++ src/Events/AutoUpdater/DownloadProgress.php | 8 ++++- src/Events/AutoUpdater/Error.php | 6 +++- src/Events/AutoUpdater/UpdateAvailable.php | 10 +++++- src/Events/AutoUpdater/UpdateCancelled.php | 31 +++++++++++++++++++ src/Events/AutoUpdater/UpdateDownloaded.php | 11 ++++++- src/Events/AutoUpdater/UpdateNotAvailable.php | 10 ++++++ src/Facades/AutoUpdater.php | 1 + 8 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 src/Events/AutoUpdater/UpdateCancelled.php diff --git a/src/AutoUpdater.php b/src/AutoUpdater.php index e714a0f..7950045 100644 --- a/src/AutoUpdater.php +++ b/src/AutoUpdater.php @@ -17,4 +17,9 @@ public function quitAndInstall(): void { $this->client->post('auto-updater/quit-and-install'); } + + public function downloadUpdate(): void + { + $this->client->post('auto-updater/download-update'); + } } diff --git a/src/Events/AutoUpdater/DownloadProgress.php b/src/Events/AutoUpdater/DownloadProgress.php index 42045b2..2339315 100644 --- a/src/Events/AutoUpdater/DownloadProgress.php +++ b/src/Events/AutoUpdater/DownloadProgress.php @@ -12,7 +12,13 @@ class DownloadProgress implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public int $total, public int $delta, public int $transferred, public float $percent, public int $bytesPerSecond) {} + public function __construct( + public int $total, + public int $delta, + public int $transferred, + public float $percent, + public int $bytesPerSecond + ) {} public function broadcastOn() { diff --git a/src/Events/AutoUpdater/Error.php b/src/Events/AutoUpdater/Error.php index 8444dcd..9d2219d 100644 --- a/src/Events/AutoUpdater/Error.php +++ b/src/Events/AutoUpdater/Error.php @@ -12,7 +12,11 @@ class Error implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct(public string $error) {} + public function __construct( + public string $name, + public string $message, + public ?string $stack, + ) {} public function broadcastOn() { diff --git a/src/Events/AutoUpdater/UpdateAvailable.php b/src/Events/AutoUpdater/UpdateAvailable.php index 5dc55cd..1fb05fb 100644 --- a/src/Events/AutoUpdater/UpdateAvailable.php +++ b/src/Events/AutoUpdater/UpdateAvailable.php @@ -12,7 +12,15 @@ class UpdateAvailable implements ShouldBroadcastNow { use Dispatchable, InteractsWithSockets, SerializesModels; - public function __construct() {} + public function __construct( + public string $version, + public array $files, + public string $releaseDate, + public ?string $releaseName, + public string|array|null $releaseNotes, + public ?int $stagingPercentage, + public ?string $minimumSystemVersion, + ) {} public function broadcastOn() { diff --git a/src/Events/AutoUpdater/UpdateCancelled.php b/src/Events/AutoUpdater/UpdateCancelled.php new file mode 100644 index 0000000..09d01b6 --- /dev/null +++ b/src/Events/AutoUpdater/UpdateCancelled.php @@ -0,0 +1,31 @@ + Date: Thu, 22 May 2025 13:43:16 +0100 Subject: [PATCH 224/224] chore(deps): bump dependabot/fetch-metadata from 2.3.0 to 2.4.0 (#585) Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2.3.0 to 2.4.0. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v2.3.0...v2.4.0) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-version: 2.4.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 2cb1d5e..1a13177 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v2.3.0 + uses: dependabot/fetch-metadata@v2.4.0 with: github-token: "${{ secrets.GITHUB_TOKEN }}"