mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-08 04:20:07 +02:00
Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
ff61d8c52e | |||
da41673855 | |||
5bda727981 | |||
d3053b8fe3 | |||
7159ca8612 | |||
141c06d14b | |||
d714d7ad4c | |||
07b17f3f84 | |||
7f0f7ff3e9 | |||
c7c143c760 | |||
8790b30706 | |||
c42188b717 | |||
cc251686f9 | |||
8a46b9d374 | |||
a62ebcff92 | |||
541378f3f9 | |||
e6f1d7e834 | |||
20d19f2f92 | |||
91bc347e57 | |||
e05300b25b | |||
1ae7a20870 | |||
5594130ccd | |||
b9c7cdb3cc | |||
00b4760b85 | |||
9a35014d2a | |||
7cba25b52e | |||
c6c3996c7b | |||
03c96a1d16 | |||
a6fa4b240f | |||
7e78026d06 |
@ -92,8 +92,8 @@
|
||||
C40FE73B282ABB2E00A302C2 /* AppVersionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */; };
|
||||
C412E5FC25700D5300A1FB67 /* HomebrewDecodable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C412E5FB25700D5300A1FB67 /* HomebrewDecodable.swift */; };
|
||||
C413E43528DA3EB100AE33C7 /* TestableShellTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C413E43428DA3EB100AE33C7 /* TestableShellTest.swift */; };
|
||||
C415937F27A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */; };
|
||||
C415938027A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */; };
|
||||
C415937F27A1B54F00D2E1B7 /* ProjectTypeDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* ProjectTypeDetection.swift */; };
|
||||
C415938027A1B54F00D2E1B7 /* ProjectTypeDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* ProjectTypeDetection.swift */; };
|
||||
C4159AF728E4D40400545349 /* RealShellTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4159AF628E4D40400545349 /* RealShellTest.swift */; };
|
||||
C415D3B72770F294005EF286 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415D3B62770F294005EF286 /* Actions.swift */; };
|
||||
C415D3B82770F294005EF286 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415D3B62770F294005EF286 /* Actions.swift */; };
|
||||
@ -132,6 +132,7 @@
|
||||
C42CFB1627DFDE7900862737 /* nginx-site.test in Resources */ = {isa = PBXBuildFile; fileRef = C42CFB1527DFDE7900862737 /* nginx-site.test */; };
|
||||
C42CFB1827DFDFDC00862737 /* nginx-site-isolated.test in Resources */ = {isa = PBXBuildFile; fileRef = C42CFB1727DFDFDC00862737 /* nginx-site-isolated.test */; };
|
||||
C42CFB1A27DFE8BD00862737 /* NginxConfigurationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */; };
|
||||
C42E3F772AB0D2880096DFC2 /* ConfigManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42E3F762AB0D2880096DFC2 /* ConfigManagerWindowController.swift */; };
|
||||
C42F26732805B4B400938AC7 /* ValetListable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42F26722805B4B400938AC7 /* ValetListable.swift */; };
|
||||
C42F26742805B4B400938AC7 /* ValetListable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42F26722805B4B400938AC7 /* ValetListable.swift */; };
|
||||
C42F26762805FEE200938AC7 /* nginx-secure-proxy.test in Resources */ = {isa = PBXBuildFile; fileRef = C42F26752805FEE200938AC7 /* nginx-secure-proxy.test */; };
|
||||
@ -161,6 +162,10 @@
|
||||
C44067F727E258410045BD4E /* DomainListPhpCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F627E258410045BD4E /* DomainListPhpCell.swift */; };
|
||||
C44067F927E2585E0045BD4E /* DomainListTypeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */; };
|
||||
C44067FB27E25FD70045BD4E /* DomainListTLSCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */; };
|
||||
C441CC562AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||
C441CC572AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||
C441CC582AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||
C441CC592AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */; };
|
||||
C44264BE2850B86C007400F1 /* SwiftUIHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */; };
|
||||
C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */; };
|
||||
C4463FCC29804BCB007B93D5 /* RCFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4463FCB29804BCB007B93D5 /* RCFile.swift */; };
|
||||
@ -227,6 +232,15 @@
|
||||
C45E2A77291992DA005C7CFD /* FeatureTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E2A76291992DA005C7CFD /* FeatureTestCase.swift */; };
|
||||
C45E76142854A65300B4FE0C /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
||||
C45E76152854A65300B4FE0C /* ServicesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C45E76132854A65300B4FE0C /* ServicesManager.swift */; };
|
||||
C4611E5A2AEAD2E20010BE24 /* ConfigManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42E3F762AB0D2880096DFC2 /* ConfigManagerWindowController.swift */; };
|
||||
C4611E5B2AEAD2E30010BE24 /* ConfigManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42E3F762AB0D2880096DFC2 /* ConfigManagerWindowController.swift */; };
|
||||
C4611E5C2AEAD2E30010BE24 /* ConfigManagerWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42E3F762AB0D2880096DFC2 /* ConfigManagerWindowController.swift */; };
|
||||
C4611E5D2AEAD2FA0010BE24 /* ConfigManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44DFA7B2A67043000B98ED5 /* ConfigManagerView.swift */; };
|
||||
C4611E5E2AEAD2FB0010BE24 /* ConfigManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44DFA7B2A67043000B98ED5 /* ConfigManagerView.swift */; };
|
||||
C4611E5F2AEAD2FB0010BE24 /* ConfigManagerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44DFA7B2A67043000B98ED5 /* ConfigManagerView.swift */; };
|
||||
C4611E602AEAD3100010BE24 /* ByteLimitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5857B2A7038DB00DDBB63 /* ByteLimitView.swift */; };
|
||||
C4611E612AEAD3110010BE24 /* ByteLimitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5857B2A7038DB00DDBB63 /* ByteLimitView.swift */; };
|
||||
C4611E622AEAD3110010BE24 /* ByteLimitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5857B2A7038DB00DDBB63 /* ByteLimitView.swift */; };
|
||||
C463E380284930EE00422731 /* PresetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C463E37F284930EE00422731 /* PresetHelper.swift */; };
|
||||
C463E381284930EE00422731 /* PresetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C463E37F284930EE00422731 /* PresetHelper.swift */; };
|
||||
C464ADAC275A7A3F003FCD53 /* DomainListWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C464ADAB275A7A3F003FCD53 /* DomainListWindowController.swift */; };
|
||||
@ -342,10 +356,10 @@
|
||||
C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; };
|
||||
C471E81F28F9BB290021E251 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
||||
C471E82028F9BB290021E251 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
|
||||
C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */; };
|
||||
C471E82128F9BB2E0021E251 /* ProjectTypeDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* ProjectTypeDetection.swift */; };
|
||||
C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
|
||||
C471E82328F9BB2E0021E251 /* ComposerJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D89BC52783C99400A02B68 /* ComposerJson.swift */; };
|
||||
C471E82428F9BB2E0021E251 /* PhpFrameworks.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */; };
|
||||
C471E82428F9BB2E0021E251 /* ProjectTypeDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* ProjectTypeDetection.swift */; };
|
||||
C471E82528F9BB2E0021E251 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
|
||||
C471E82628F9BB2E0021E251 /* ComposerJson.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D89BC52783C99400A02B68 /* ComposerJson.swift */; };
|
||||
C471E82728F9BB310021E251 /* BrewDiagnostics.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F2E4362752F0870020E974 /* BrewDiagnostics.swift */; };
|
||||
@ -423,7 +437,7 @@
|
||||
C471E87828F9BB650021E251 /* TerminalProgressWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */; };
|
||||
C471E87928F9BB650021E251 /* ProgressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A874728905BB000498BC4 /* ProgressVC.swift */; };
|
||||
C471E87B28F9BB650021E251 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||
C471E87C28F9BB650021E251 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
||||
C471E87C28F9BB650021E251 /* ConfigWatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */; };
|
||||
C471E87D28F9BB650021E251 /* Preset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C5C9B2846A40600E28255 /* Preset.swift */; };
|
||||
C471E87E28F9BB650021E251 /* PresetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C463E37F284930EE00422731 /* PresetHelper.swift */; };
|
||||
C471E87F28F9BB650021E251 /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4297F7928970D59004C4630 /* WarningView.swift */; };
|
||||
@ -511,7 +525,7 @@
|
||||
C471E8DB28F9BB8F0021E251 /* TerminalProgressWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44C198C276E3A1C0072762D /* TerminalProgressWindowController.swift */; };
|
||||
C471E8DC28F9BB8F0021E251 /* ProgressVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44A874728905BB000498BC4 /* ProgressVC.swift */; };
|
||||
C471E8DE28F9BB8F0021E251 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||
C471E8DF28F9BB8F0021E251 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
||||
C471E8DF28F9BB8F0021E251 /* ConfigWatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */; };
|
||||
C471E8E028F9BB8F0021E251 /* Preset.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40C5C9B2846A40600E28255 /* Preset.swift */; };
|
||||
C471E8E128F9BB8F0021E251 /* PresetHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C463E37F284930EE00422731 /* PresetHelper.swift */; };
|
||||
C471E8E228F9BB8F0021E251 /* WarningView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4297F7928970D59004C4630 /* WarningView.swift */; };
|
||||
@ -677,8 +691,8 @@
|
||||
C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */; };
|
||||
C4C8E818276F54D8003AC782 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */; };
|
||||
C4C8E81B276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
||||
C4C8E81C276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */; };
|
||||
C4C8E81B276F54E5003AC782 /* ConfigWatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */; };
|
||||
C4C8E81C276F54E5003AC782 /* ConfigWatchManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */; };
|
||||
C4CB250529B28BB800CA4492 /* MainMenuTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB250429B28BB800CA4492 /* MainMenuTest.swift */; };
|
||||
C4CB6E65292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
||||
C4CB6E66292C362C002E9027 /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CB6E64292C362C002E9027 /* Homebrew.swift */; };
|
||||
@ -850,6 +864,7 @@
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0336CAAF2B0D0CDA009A1034 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
03E36FE628D9219000636F7F /* ActiveShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveShell.swift; sourceTree = "<group>"; };
|
||||
5420395826135DC100FB00FA /* PreferencesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesVC.swift; sourceTree = "<group>"; };
|
||||
5420395E2613607600FB00FA /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
|
||||
@ -897,7 +912,7 @@
|
||||
C40FE739282ABB2E00A302C2 /* AppVersionTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppVersionTest.swift; sourceTree = "<group>"; };
|
||||
C412E5FB25700D5300A1FB67 /* HomebrewDecodable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomebrewDecodable.swift; sourceTree = "<group>"; };
|
||||
C413E43428DA3EB100AE33C7 /* TestableShellTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShellTest.swift; sourceTree = "<group>"; };
|
||||
C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpFrameworks.swift; sourceTree = "<group>"; };
|
||||
C415937E27A1B54F00D2E1B7 /* ProjectTypeDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectTypeDetection.swift; sourceTree = "<group>"; };
|
||||
C4159AF628E4D40400545349 /* RealShellTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShellTest.swift; sourceTree = "<group>"; };
|
||||
C415D3B62770F294005EF286 /* Actions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
|
||||
C415D3E72770F692005EF286 /* AppDelegate+InterApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+InterApp.swift"; sourceTree = "<group>"; };
|
||||
@ -929,6 +944,7 @@
|
||||
C42CFB1527DFDE7900862737 /* nginx-site.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-site.test"; sourceTree = "<group>"; };
|
||||
C42CFB1727DFDFDC00862737 /* nginx-site-isolated.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-site-isolated.test"; sourceTree = "<group>"; };
|
||||
C42CFB1927DFE8BD00862737 /* NginxConfigurationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationTest.swift; sourceTree = "<group>"; };
|
||||
C42E3F762AB0D2880096DFC2 /* ConfigManagerWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigManagerWindowController.swift; sourceTree = "<group>"; };
|
||||
C42F26722805B4B400938AC7 /* ValetListable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ValetListable.swift; sourceTree = "<group>"; };
|
||||
C42F26752805FEE200938AC7 /* nginx-secure-proxy.test */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "nginx-secure-proxy.test"; sourceTree = "<group>"; };
|
||||
C436039F275E67610028EFC6 /* AppDelegate+Notifications.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Notifications.swift"; sourceTree = "<group>"; };
|
||||
@ -944,6 +960,7 @@
|
||||
C44067F627E258410045BD4E /* DomainListPhpCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListPhpCell.swift; sourceTree = "<group>"; };
|
||||
C44067F827E2585E0045BD4E /* DomainListTypeCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTypeCell.swift; sourceTree = "<group>"; };
|
||||
C44067FA27E25FD70045BD4E /* DomainListTLSCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainListTLSCell.swift; sourceTree = "<group>"; };
|
||||
C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigFSNotifier.swift; sourceTree = "<group>"; };
|
||||
C44264BD2850B86C007400F1 /* SwiftUIHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIHelper.swift; sourceTree = "<group>"; };
|
||||
C44264BF2850BD2A007400F1 /* VersionPopoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionPopoverView.swift; sourceTree = "<group>"; };
|
||||
C4463FCB29804BCB007B93D5 /* RCFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RCFile.swift; sourceTree = "<group>"; };
|
||||
@ -1052,7 +1069,7 @@
|
||||
C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealFileSystem.swift; sourceTree = "<group>"; };
|
||||
C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveFileSystem.swift; sourceTree = "<group>"; };
|
||||
C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "App+ConfigWatch.swift"; sourceTree = "<group>"; };
|
||||
C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhpConfigWatcher.swift; sourceTree = "<group>"; };
|
||||
C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigWatchManager.swift; sourceTree = "<group>"; };
|
||||
C4CB250429B28BB800CA4492 /* MainMenuTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenuTest.swift; sourceTree = "<group>"; };
|
||||
C4CB6E64292C362C002E9027 /* Homebrew.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Homebrew.swift; sourceTree = "<group>"; };
|
||||
C4CCBA6B275C567B008C7055 /* PMWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMWindowController.swift; sourceTree = "<group>"; };
|
||||
@ -1499,6 +1516,7 @@
|
||||
children = (
|
||||
C44DFA7B2A67043000B98ED5 /* ConfigManagerView.swift */,
|
||||
C4D5857B2A7038DB00DDBB63 /* ByteLimitView.swift */,
|
||||
C42E3F762AB0D2880096DFC2 /* ConfigManagerWindowController.swift */,
|
||||
);
|
||||
path = UI;
|
||||
sourceTree = "<group>";
|
||||
@ -1742,7 +1760,6 @@
|
||||
C4B5635D276AB09000F12CCB /* VersionExtractor.swift */,
|
||||
C4D3660A29113F20006BD146 /* System.swift */,
|
||||
C4D36614291160A1006BD146 /* WIP.swift */,
|
||||
C41ADCE72970CCC700120423 /* FSNotifier.swift */,
|
||||
C47DF1AE299D5A3B0007055D /* LoginItemManager.swift */,
|
||||
C49EAA5129B12A5A00AB28FC /* Measurements.swift */,
|
||||
);
|
||||
@ -1961,9 +1978,11 @@
|
||||
C4C8E81D276F5686003AC782 /* Watcher */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
C4C8E81A276F54E5003AC782 /* ConfigWatchManager.swift */,
|
||||
C441CC552AE8249400DDFACD /* ConfigFSNotifier.swift */,
|
||||
C41ADCE72970CCC700120423 /* FSNotifier.swift */,
|
||||
C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */,
|
||||
C4C8E817276F54D8003AC782 /* App+ConfigWatch.swift */,
|
||||
C4C8E81A276F54E5003AC782 /* PhpConfigWatcher.swift */,
|
||||
);
|
||||
path = Watcher;
|
||||
sourceTree = "<group>";
|
||||
@ -1980,7 +1999,7 @@
|
||||
children = (
|
||||
C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */,
|
||||
C4D89BC52783C99400A02B68 /* ComposerJson.swift */,
|
||||
C415937E27A1B54F00D2E1B7 /* PhpFrameworks.swift */,
|
||||
C415937E27A1B54F00D2E1B7 /* ProjectTypeDetection.swift */,
|
||||
);
|
||||
path = Composer;
|
||||
sourceTree = "<group>";
|
||||
@ -2249,6 +2268,7 @@
|
||||
de,
|
||||
"pt-PT",
|
||||
Base,
|
||||
fr,
|
||||
);
|
||||
mainGroup = C41C1B2A22B0097F00E7CF16;
|
||||
packageReferences = (
|
||||
@ -2475,7 +2495,7 @@
|
||||
C4B97B78275CF1B5003F3378 /* App+ActivationPolicy.swift in Sources */,
|
||||
C4CE3BB827B31F2E0086CA49 /* MainMenu+Switcher.swift in Sources */,
|
||||
C456A0CB2AA6166F0080144F /* BytePhpPreference.swift in Sources */,
|
||||
C415937F27A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */,
|
||||
C415937F27A1B54F00D2E1B7 /* ProjectTypeDetection.swift in Sources */,
|
||||
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */,
|
||||
C44DFA7C2A67043000B98ED5 /* ConfigManagerView.swift in Sources */,
|
||||
C40934A2298EEB2C00D25014 /* CaskFile.swift in Sources */,
|
||||
@ -2503,8 +2523,9 @@
|
||||
C4D4CB3729C109CF00DB9F93 /* InternalSwitcher+Valet.swift in Sources */,
|
||||
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */,
|
||||
C4068CAA27B0890D00544CD5 /* MenuBarIcons.swift in Sources */,
|
||||
C441CC562AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||
C44264C02850BD2A007400F1 /* VersionPopoverView.swift in Sources */,
|
||||
C4C8E81B276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */,
|
||||
C4C8E81B276F54E5003AC782 /* ConfigWatchManager.swift in Sources */,
|
||||
C417DC74277614690015E6EE /* Helpers.swift in Sources */,
|
||||
C415D3E82770F692005EF286 /* AppDelegate+InterApp.swift in Sources */,
|
||||
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */,
|
||||
@ -2568,6 +2589,7 @@
|
||||
C4B97B75275CF08C003F3378 /* AppDelegate+MenuOutlets.swift in Sources */,
|
||||
C464ADAC275A7A3F003FCD53 /* DomainListWindowController.swift in Sources */,
|
||||
C4CB6E65292C362C002E9027 /* Homebrew.swift in Sources */,
|
||||
C42E3F772AB0D2880096DFC2 /* ConfigManagerWindowController.swift in Sources */,
|
||||
C464ADB2275A87CA003FCD53 /* DomainListCellProtocol.swift in Sources */,
|
||||
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */,
|
||||
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */,
|
||||
@ -2633,8 +2655,10 @@
|
||||
C4B79EBE29CA38DB00A483EE /* BrewCommand.swift in Sources */,
|
||||
C47DF1B1299D5A3B0007055D /* LoginItemManager.swift in Sources */,
|
||||
C471E85928F9BB650021E251 /* DomainListPhpCell.swift in Sources */,
|
||||
C4611E5B2AEAD2E30010BE24 /* ConfigManagerWindowController.swift in Sources */,
|
||||
C471E85A28F9BB650021E251 /* DomainListTypeCell.swift in Sources */,
|
||||
C471E85B28F9BB650021E251 /* DomainListKindCell.swift in Sources */,
|
||||
C4611E5E2AEAD2FB0010BE24 /* ConfigManagerView.swift in Sources */,
|
||||
C4BF56AD2949381100379603 /* FakeValetInteractor.swift in Sources */,
|
||||
C471E85C28F9BB650021E251 /* DomainListWindowController.swift in Sources */,
|
||||
C471E85D28F9BB650021E251 /* DomainListVC.swift in Sources */,
|
||||
@ -2679,7 +2703,7 @@
|
||||
C471E87828F9BB650021E251 /* TerminalProgressWindowController.swift in Sources */,
|
||||
C471E87928F9BB650021E251 /* ProgressVC.swift in Sources */,
|
||||
C471E87B28F9BB650021E251 /* App+ConfigWatch.swift in Sources */,
|
||||
C471E87C28F9BB650021E251 /* PhpConfigWatcher.swift in Sources */,
|
||||
C471E87C28F9BB650021E251 /* ConfigWatchManager.swift in Sources */,
|
||||
C471E87D28F9BB650021E251 /* Preset.swift in Sources */,
|
||||
C471E87E28F9BB650021E251 /* PresetHelper.swift in Sources */,
|
||||
C471E87F28F9BB650021E251 /* WarningView.swift in Sources */,
|
||||
@ -2720,10 +2744,11 @@
|
||||
C471E81828F9BAE80021E251 /* StringExtension.swift in Sources */,
|
||||
C471E7FA28F9BACB0021E251 /* InternalSwitcher.swift in Sources */,
|
||||
C471E82628F9BB2E0021E251 /* ComposerJson.swift in Sources */,
|
||||
C471E82428F9BB2E0021E251 /* PhpFrameworks.swift in Sources */,
|
||||
C471E82428F9BB2E0021E251 /* ProjectTypeDetection.swift in Sources */,
|
||||
C471E7E828F9BAC20021E251 /* Actions.swift in Sources */,
|
||||
C40D72612A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
||||
C471E82528F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
||||
C441CC582AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||
C471E80828F9BAD40021E251 /* PhpExtension.swift in Sources */,
|
||||
C471E7F928F9BACB0021E251 /* PhpSwitcher.swift in Sources */,
|
||||
C471E82A28F9BB330021E251 /* ValetListable.swift in Sources */,
|
||||
@ -2752,6 +2777,7 @@
|
||||
C471E7FD28F9BACE0021E251 /* HomebrewService.swift in Sources */,
|
||||
C471E7E428F9BAC20021E251 /* Helpers.swift in Sources */,
|
||||
C4CB6E67292C362C002E9027 /* Homebrew.swift in Sources */,
|
||||
C4611E602AEAD3100010BE24 /* ByteLimitView.swift in Sources */,
|
||||
C489E0BD2A220A4200323F5E /* FakeBrewFormulaeHandler.swift in Sources */,
|
||||
C45E2A77291992DA005C7CFD /* FeatureTestCase.swift in Sources */,
|
||||
C471E82028F9BB290021E251 /* NginxConfigurationFile.swift in Sources */,
|
||||
@ -2781,6 +2807,7 @@
|
||||
C471E89228F9BB8F0021E251 /* Alert.swift in Sources */,
|
||||
C471E89328F9BB8F0021E251 /* Application.swift in Sources */,
|
||||
C471E89428F9BB8F0021E251 /* LocalNotification.swift in Sources */,
|
||||
C441CC592AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||
C40934A5298EEB2C00D25014 /* CaskFile.swift in Sources */,
|
||||
C471E89528F9BB8F0021E251 /* MenuBarImageGenerator.swift in Sources */,
|
||||
C40D725D2A018ACC0054A067 /* PhpFormulaeStatus.swift in Sources */,
|
||||
@ -2862,12 +2889,13 @@
|
||||
C471E8D528F9BB8F0021E251 /* CheckboxPreferenceView.swift in Sources */,
|
||||
C471E8D728F9BB8F0021E251 /* SelectPreferenceView.swift in Sources */,
|
||||
C471E8D928F9BB8F0021E251 /* HotkeyPreferenceView.swift in Sources */,
|
||||
C4611E5D2AEAD2FA0010BE24 /* ConfigManagerView.swift in Sources */,
|
||||
C471E8DA28F9BB8F0021E251 /* Keys.swift in Sources */,
|
||||
C471E8DB28F9BB8F0021E251 /* TerminalProgressWindowController.swift in Sources */,
|
||||
C471E8DC28F9BB8F0021E251 /* ProgressVC.swift in Sources */,
|
||||
C490E3BF29BCA376006D2DE6 /* Measurements.swift in Sources */,
|
||||
C471E8DE28F9BB8F0021E251 /* App+ConfigWatch.swift in Sources */,
|
||||
C471E8DF28F9BB8F0021E251 /* PhpConfigWatcher.swift in Sources */,
|
||||
C471E8DF28F9BB8F0021E251 /* ConfigWatchManager.swift in Sources */,
|
||||
C4CB250529B28BB800CA4492 /* MainMenuTest.swift in Sources */,
|
||||
C40D72622A018AE30054A067 /* BrewFormula+UI.swift in Sources */,
|
||||
C4B79ECE29CA475900A483EE /* RemovePhpVersionCommand.swift in Sources */,
|
||||
@ -2904,6 +2932,7 @@
|
||||
C471E7F628F9BAC80021E251 /* PhpHelper.swift in Sources */,
|
||||
C471E7EE28F9BAC30021E251 /* Constants.swift in Sources */,
|
||||
C40934A0298EE8E900D25014 /* AppUpdater.swift in Sources */,
|
||||
C4611E5A2AEAD2E20010BE24 /* ConfigManagerWindowController.swift in Sources */,
|
||||
C471E80E28F9BAE80021E251 /* DateExtension.swift in Sources */,
|
||||
C490E3BA29BCA368006D2DE6 /* App+BrewWatch.swift in Sources */,
|
||||
C471E7D028F9BA630021E251 /* FileSystemProtocol.swift in Sources */,
|
||||
@ -2919,7 +2948,7 @@
|
||||
C48DDD1029C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */,
|
||||
C471E7F828F9BACB0021E251 /* InternalSwitcher.swift in Sources */,
|
||||
C471E82328F9BB2E0021E251 /* ComposerJson.swift in Sources */,
|
||||
C471E82128F9BB2E0021E251 /* PhpFrameworks.swift in Sources */,
|
||||
C471E82128F9BB2E0021E251 /* ProjectTypeDetection.swift in Sources */,
|
||||
C471E7EF28F9BAC30021E251 /* Actions.swift in Sources */,
|
||||
C471E82228F9BB2E0021E251 /* ComposerWindow.swift in Sources */,
|
||||
C4D3660E29113F20006BD146 /* System.swift in Sources */,
|
||||
@ -2951,6 +2980,7 @@
|
||||
C471E7EB28F9BAC30021E251 /* Helpers.swift in Sources */,
|
||||
C4CB6E68292C362C002E9027 /* Homebrew.swift in Sources */,
|
||||
C4181F1128FAF9330042EA28 /* UITestCase.swift in Sources */,
|
||||
C4611E622AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
||||
C4AFC4B129C4F32F00BF4E0D /* BrewFormula.swift in Sources */,
|
||||
C471E81F28F9BB290021E251 /* NginxConfigurationFile.swift in Sources */,
|
||||
C471E7BF28F9B90F0021E251 /* StartupTest.swift in Sources */,
|
||||
@ -3014,7 +3044,7 @@
|
||||
C43A8A2425D9D20D00591B77 /* HomebrewPackageTest.swift in Sources */,
|
||||
C485707928BF456C00539B36 /* ArrayExtension.swift in Sources */,
|
||||
C4F780CA25D80B75000DBC97 /* HomebrewDecodable.swift in Sources */,
|
||||
C4C8E81C276F54E5003AC782 /* PhpConfigWatcher.swift in Sources */,
|
||||
C4C8E81C276F54E5003AC782 /* ConfigWatchManager.swift in Sources */,
|
||||
C4F319C927B034A500AFF46F /* Stats.swift in Sources */,
|
||||
C4F30B04278E16BA00755FCE /* HomebrewService.swift in Sources */,
|
||||
54D9E0B527E4F51E003B9AD9 /* Key.swift in Sources */,
|
||||
@ -3030,6 +3060,7 @@
|
||||
C4CCBA6D275C567B008C7055 /* PMWindowController.swift in Sources */,
|
||||
C4B5635F276AB09000F12CCB /* VersionExtractor.swift in Sources */,
|
||||
C463E381284930EE00422731 /* PresetHelper.swift in Sources */,
|
||||
C441CC572AE8249400DDFACD /* ConfigFSNotifier.swift in Sources */,
|
||||
C46FA98C2822F08F00D78807 /* PhpConfigurationFileTest.swift in Sources */,
|
||||
C4D5576529C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
|
||||
C4BF90C127C57C220054E78C /* MainMenu+FixMyValet.swift in Sources */,
|
||||
@ -3037,6 +3068,7 @@
|
||||
C4F2E4382752F08D0020E974 /* BrewDiagnostics.swift in Sources */,
|
||||
C485707428BF454E00539B36 /* ServicesView.swift in Sources */,
|
||||
C4B79EC729CA474200A483EE /* FakeCommand.swift in Sources */,
|
||||
C4611E5F2AEAD2FB0010BE24 /* ConfigManagerView.swift in Sources */,
|
||||
C4F780AE25D80B37000DBC97 /* PhpExtensionTest.swift in Sources */,
|
||||
C456A0C72AA614BD0080144F /* PhpPreference.swift in Sources */,
|
||||
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
|
||||
@ -3077,6 +3109,7 @@
|
||||
C4E49DEE28F764A00026AC4E /* TestableCommand.swift in Sources */,
|
||||
C4AF9F78275447F100D44ED0 /* ValetConfigurationTest.swift in Sources */,
|
||||
C490E3B529BC9FEA006D2DE6 /* ProgressWindowView.swift in Sources */,
|
||||
C4611E612AEAD3110010BE24 /* ByteLimitView.swift in Sources */,
|
||||
C40175B92903108900763A68 /* ValetInteractor.swift in Sources */,
|
||||
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */,
|
||||
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */,
|
||||
@ -3105,6 +3138,7 @@
|
||||
C4D936CA27E3EB6100BD69FE /* PhpHelper.swift in Sources */,
|
||||
C4D36611291140BE006BD146 /* TestableFileSystemTest.swift in Sources */,
|
||||
C45B91542956123A00F4EC78 /* FakeServicesManager.swift in Sources */,
|
||||
C4611E5C2AEAD2E30010BE24 /* ConfigManagerWindowController.swift in Sources */,
|
||||
C4E2E84B28FC1E70003B070C /* DataExtension.swift in Sources */,
|
||||
C449B4F127EE7FC200C47E8A /* DomainListNameCell.swift in Sources */,
|
||||
C4F780BA25D80B62000DBC97 /* AppDelegate.swift in Sources */,
|
||||
@ -3117,7 +3151,7 @@
|
||||
C44C198E276E3A1C0072762D /* TerminalProgressWindowController.swift in Sources */,
|
||||
C4B79EBD29CA38DB00A483EE /* BrewCommand.swift in Sources */,
|
||||
C485707828BF456300539B36 /* Warning.swift in Sources */,
|
||||
C415938027A1B54F00D2E1B7 /* PhpFrameworks.swift in Sources */,
|
||||
C415938027A1B54F00D2E1B7 /* ProjectTypeDetection.swift in Sources */,
|
||||
C40F505628ECA64E004AD45B /* TestableConfigurations.swift in Sources */,
|
||||
C4D9ADC9277611A0007277F4 /* InternalSwitcher.swift in Sources */,
|
||||
C449B4F227EE7FC400C47E8A /* DomainListPhpCell.swift in Sources */,
|
||||
@ -3215,6 +3249,7 @@
|
||||
C4FC8D442A4981BC00FBBD16 /* nl */,
|
||||
C4DD662A2A4A1B4E00D6A731 /* de */,
|
||||
C4622F572A7593CB0016F8FB /* pt-PT */,
|
||||
0336CAAF2B0D0CDA009A1034 /* fr */,
|
||||
);
|
||||
name = Localizable.strings;
|
||||
sourceTree = "<group>";
|
||||
@ -3488,7 +3523,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1306;
|
||||
CURRENT_PROJECT_VERSION = 1350;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -3501,7 +3536,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.2.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -3519,7 +3554,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1306;
|
||||
CURRENT_PROJECT_VERSION = 1350;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -3532,7 +3567,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.2.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
|
||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -3759,7 +3794,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1306;
|
||||
CURRENT_PROJECT_VERSION = 1350;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -3772,7 +3807,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.2.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
||||
@ -3875,7 +3910,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1306;
|
||||
CURRENT_PROJECT_VERSION = 1350;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -3888,7 +3923,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.2.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
|
||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||
PRODUCT_NAME = "$(TARGET_NAME) DEV";
|
||||
@ -3991,7 +4026,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1306;
|
||||
CURRENT_PROJECT_VERSION = 1350;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = YES;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -4004,7 +4039,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.2.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
|
||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||
PRODUCT_NAME = "$(TARGET_NAME) EAP";
|
||||
@ -4172,7 +4207,7 @@
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 1306;
|
||||
CURRENT_PROJECT_VERSION = 1350;
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
DEBUG = NO;
|
||||
DEVELOPMENT_TEAM = 8M54J5J787;
|
||||
@ -4185,7 +4220,7 @@
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MACOSX_DEPLOYMENT_TARGET = 12.4;
|
||||
MARKETING_VERSION = 6.1;
|
||||
MARKETING_VERSION = 6.2.2;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
|
||||
PRODUCT_MODULE_NAME = PHP_Monitor;
|
||||
PRODUCT_NAME = "$(TARGET_NAME) EAP";
|
||||
|
@ -6,7 +6,7 @@ Generally speaking, only the latest version of **PHP Monitor** is supported, exc
|
||||
|
||||
| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Recommended Valet Version |
|
||||
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
|
||||
| 6.1 | ✅ Universal binary | ✅ Yes | Monterey (12.4+)<br/>Ventura (13.0+)<br/>Sonoma (14.0) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.4 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.4 (w/ Valet 4.x)| 3.0 or higher recommended<br/> 2.16.2 minimum |
|
||||
| 6.2 | ✅ Universal binary | ✅ Yes | Monterey (12.4+)<br/>Ventura (13.0+)<br/>Sonoma (14.0) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.4 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.4 (w/ Valet 4.x)| 3.0 or higher recommended<br/> 2.16.2 minimum |
|
||||
|
||||
## Legacy versions
|
||||
|
||||
@ -14,6 +14,7 @@ These versions of PHP Monitor are no longer supported, but if you’re using an
|
||||
|
||||
| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Minimum Required Valet Version |
|
||||
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
|
||||
| 6.1 | ✅ Universal binary | ❌ | Monterey (12.4+)<br/>Ventura (13.0+)<br/>Sonoma (14.0) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.4 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.4 (w/ Valet 4.x)| 3.0 or higher recommended<br/> 2.16.2 minimum |
|
||||
| 6.0 | ✅ Universal binary | ❌ | Monterey (12.4+)<br/>Ventura (13.0+) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.2 (w/ Valet 4.x) | 3.0 or higher recommended<br/> 2.16.2 minimum |
|
||||
| 5.8 | ✅ Universal binary | ❌ | Monterey (12.4+)<br/>Ventura (13.0+) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.2 (w/ Valet 4.x) | 3.0 or higher recommended<br/> 2.16.2 minimum |
|
||||
| 5.7 | ✅ Universal binary | ❌ | Big Sur (11.0)<br/>Monterey (12.0)<br/>Ventura (13.0) | macOS 11+ | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.2 (w/ Valet 4.x) | 3.0 or higher recommended<br/> 2.16.2 minimum |
|
||||
|
@ -20,10 +20,26 @@ struct Constants {
|
||||
|
||||
/**
|
||||
* The PHP versions that are considered pre-release versions.
|
||||
* Past a certain date, an experimental version "graduates"
|
||||
* to a release version and is no longer marked as experimental.
|
||||
*/
|
||||
static let ExperimentalPhpVersions: Set = [
|
||||
"8.3", "8.4"
|
||||
]
|
||||
static var ExperimentalPhpVersions: Set<String> {
|
||||
let releaseDates = [
|
||||
"8.4": Date.fromString("2024-12-01"), // PLACEHOLDER DATE
|
||||
"8.3": Date.fromString("2023-11-23") // OFFICIAL RELEASE
|
||||
]
|
||||
|
||||
return Set(releaseDates
|
||||
.filter { (_: String, date: Date?) in
|
||||
guard let date else {
|
||||
return false
|
||||
}
|
||||
|
||||
return date > Date.now
|
||||
}.map { (version: String, _: Date?) in
|
||||
return version
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* The PHP versions supported by this application.
|
||||
@ -91,6 +107,8 @@ struct Constants {
|
||||
string: "https://raw.githubusercontent.com/nicoverbruggen/homebrew-cask/master/Casks/phpmon-dev.rb"
|
||||
)!
|
||||
|
||||
// EAP URLs
|
||||
|
||||
static let EarlyAccessCaskFile = URL(
|
||||
string: "https://phpmon.app/builds/early-access/sponsors/phpmon-eap.rb"
|
||||
)!
|
||||
|
@ -17,6 +17,7 @@ public class Paths {
|
||||
|
||||
internal var baseDir: Paths.HomebrewDir
|
||||
private var userName: String
|
||||
private var preferredShell: String
|
||||
|
||||
init() {
|
||||
// Assume the default directory is correct
|
||||
@ -31,9 +32,11 @@ public class Paths {
|
||||
}
|
||||
|
||||
userName = identity()
|
||||
preferredShell = preferred_shell()
|
||||
|
||||
if !isRunningSwiftUIPreview {
|
||||
Log.info("The current username is `\(userName)`.")
|
||||
Log.info("The user's shell is `\(preferredShell)`.")
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +107,10 @@ public class Paths {
|
||||
+ (App.identifier.contains(".dev") ? "phpmon-dev" : "phpmon")
|
||||
}
|
||||
|
||||
public static var shell: String {
|
||||
return shared.preferredShell
|
||||
}
|
||||
|
||||
// MARK: - Flexible Binaries
|
||||
// (these can be in multiple locations, so we scan common places because)
|
||||
// (PHP Monitor will not use the user's own PATH)
|
||||
|
@ -15,4 +15,10 @@ extension Date {
|
||||
return dateFormatter.string(from: self)
|
||||
}
|
||||
|
||||
static func fromString(_ string: String) -> Date? {
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd"
|
||||
return dateFormatter.date(from: string)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ class PMWindowController: NSWindowController, NSWindowDelegate {
|
||||
|
||||
extension NSWindowController {
|
||||
|
||||
public func positionWindowInTopLeftCorner(offsetY: CGFloat = 0, offsetX: CGFloat = 0) {
|
||||
public func positionWindowInTopRightCorner(offsetY: CGFloat = 0, offsetX: CGFloat = 0) {
|
||||
guard let frame = NSScreen.main?.frame else { return }
|
||||
guard let window = self.window else { return }
|
||||
|
||||
|
@ -65,3 +65,11 @@ public func identity() -> String {
|
||||
|
||||
return output.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
/**
|
||||
Retrieves the user's preferred shell.
|
||||
*/
|
||||
public func preferred_shell() -> String {
|
||||
return system("dscl . -read ~/ UserShell | sed 's/UserShell: //'")
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ class PhpEnvironments {
|
||||
// MARK: - Initializer
|
||||
|
||||
/**
|
||||
|
||||
Loads the currently active PHP installation upon startup. May be empty.
|
||||
*/
|
||||
init() {
|
||||
self.currentInstall = ActivePhpInstallation.load()
|
||||
@ -29,7 +29,7 @@ class PhpEnvironments {
|
||||
/**
|
||||
Determine which PHP version the `php` formula is aliased to.
|
||||
*/
|
||||
func determinePhpAlias() async {
|
||||
@MainActor func determinePhpAlias() async {
|
||||
let brewPhpAlias = await Shell.pipe("\(Paths.brew) info php --json").out
|
||||
|
||||
self.homebrewPackage = try! JSONDecoder().decode(
|
||||
@ -37,7 +37,28 @@ class PhpEnvironments {
|
||||
from: brewPhpAlias.data(using: .utf8)!
|
||||
).first!
|
||||
|
||||
Log.info("[BREW] On your system, the `php` formula means version \(homebrewPackage.version)!")
|
||||
PhpEnvironments.brewPhpAlias = self.homebrewPackage.version
|
||||
Log.info("[BREW] On your system, the `php` formula means version \(homebrewPackage.version).")
|
||||
|
||||
// Check if that version actually corresponds to an older version
|
||||
let phpConfigExecutablePath = "\(Paths.optPath)/php/bin/php-config"
|
||||
if FileSystem.fileExists(phpConfigExecutablePath) {
|
||||
let longVersionString = Command.execute(
|
||||
path: phpConfigExecutablePath,
|
||||
arguments: ["--version"],
|
||||
trimNewlines: false
|
||||
).trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
||||
if let version = try? VersionNumber.parse(longVersionString) {
|
||||
PhpEnvironments.brewPhpAlias = version.short
|
||||
if version.short != homebrewPackage.version {
|
||||
Log.info("[BREW] An older version of `php` is actually installed (\(version.short)).")
|
||||
}
|
||||
} else {
|
||||
Log.warn("Could not determine the actual version of the php binary; assuming Homebrew is correct.")
|
||||
PhpEnvironments.brewPhpAlias = homebrewPackage.version
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Properties
|
||||
@ -49,12 +70,10 @@ class PhpEnvironments {
|
||||
static let shared = PhpEnvironments()
|
||||
|
||||
/** Whether the switcher is busy performing any actions. */
|
||||
var isBusy: Bool = false {
|
||||
@MainActor var isBusy: Bool = false {
|
||||
didSet {
|
||||
Task { @MainActor in
|
||||
MainMenu.shared.setBusyImage()
|
||||
MainMenu.shared.rebuild()
|
||||
}
|
||||
MainMenu.shared.refreshIcon()
|
||||
MainMenu.shared.rebuild()
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +98,12 @@ class PhpEnvironments {
|
||||
|
||||
As such, we take that information from Homebrew.
|
||||
*/
|
||||
static var brewPhpAlias: String {
|
||||
static var brewPhpAlias: String = ""
|
||||
|
||||
/**
|
||||
It's possible for the alias to be newer than the actual installed version of PHP.
|
||||
*/
|
||||
static var homebrewBrewPhpAlias: String {
|
||||
if PhpEnvironments.shared.homebrewPackage == nil { return "8.2" }
|
||||
|
||||
return PhpEnvironments.shared.homebrewPackage.version
|
||||
@ -146,7 +170,12 @@ class PhpEnvironments {
|
||||
|
||||
// Avoid inserting a duplicate
|
||||
if !supportedVersions.contains(phpAlias) && FileSystem.fileExists("\(Paths.optPath)/php/bin/php") {
|
||||
supportedVersions.insert(phpAlias)
|
||||
let phpAliasInstall = PhpInstallation(phpAlias)
|
||||
// Before inserting, ensure that the actual output matches the alias
|
||||
// if that isn't the case, our formula remains out-of-date
|
||||
if !phpAliasInstall.missingBinary {
|
||||
supportedVersions.insert(phpAlias)
|
||||
}
|
||||
}
|
||||
|
||||
availablePhpVersions = Array(supportedVersions)
|
||||
|
@ -49,8 +49,10 @@ class PhpHelper {
|
||||
let path = URL(fileURLWithPath: "\(Paths.optPath)/php@\(version)/bin")
|
||||
.resolvingSymlinksInPath().path
|
||||
|
||||
// The contents of the script!
|
||||
let script = script(path, keyPhrase, version, dotless)
|
||||
// Check if the user uses Fish
|
||||
let script = Paths.shell.contains("/fish")
|
||||
? fishScript(path, keyPhrase, version, dotless)
|
||||
: zshScript(path, keyPhrase, version, dotless)
|
||||
|
||||
Task { @MainActor in
|
||||
try FileSystem.writeAtomicallyToFile(destination, content: script)
|
||||
@ -78,7 +80,7 @@ class PhpHelper {
|
||||
}
|
||||
}
|
||||
|
||||
private static func script(
|
||||
private static func zshScript(
|
||||
_ path: String,
|
||||
_ keyPhrase: String,
|
||||
_ version: String,
|
||||
@ -96,6 +98,22 @@ class PhpHelper {
|
||||
"""
|
||||
}
|
||||
|
||||
private static func fishScript(
|
||||
_ path: String,
|
||||
_ keyPhrase: String,
|
||||
_ version: String,
|
||||
_ dotless: String
|
||||
) -> String {
|
||||
return """
|
||||
#!\(Paths.binPath)/fish
|
||||
# \(keyPhrase)
|
||||
# It reflects the location of PHP \(version)'s binaries on your system.
|
||||
# Usage: . pm\(dotless)
|
||||
echo "PHP Monitor has enabled this terminal to use PHP \(version)."; \\
|
||||
set -x PATH \(path) $PATH
|
||||
"""
|
||||
}
|
||||
|
||||
private static func createSymlink(_ dotless: String) async {
|
||||
let source = "\(Paths.homePath)/.config/phpmon/bin/pm\(dotless)"
|
||||
let destination = "/usr/local/bin/pm\(dotless)"
|
||||
|
@ -69,8 +69,9 @@ class PhpConfigurationFile: CreatedFromFile {
|
||||
return nil
|
||||
}
|
||||
|
||||
enum ReplacementErrors: Error {
|
||||
public enum ReplacementErrors: Error {
|
||||
case missingKey
|
||||
case missingFile
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,10 +96,16 @@ class PhpConfigurationFile: CreatedFromFile {
|
||||
// Replace the specific line
|
||||
self.lines[item.lineIndex] = components.joined(separator: "=")
|
||||
|
||||
// Ensure the watchers aren't tripped up by config changes
|
||||
ConfigWatchManager.ignoresModificationsToConfigValues = true
|
||||
|
||||
// Finally, join the string and save the file atomatically again
|
||||
try self.lines.joined(separator: "\n")
|
||||
.write(toFile: self.filePath, atomically: true, encoding: .utf8)
|
||||
|
||||
// Ensure watcher behaviour is reverted
|
||||
ConfigWatchManager.ignoresModificationsToConfigValues = false
|
||||
|
||||
// Reload the original file
|
||||
self.reload()
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class PhpExtension {
|
||||
|
||||
self.name = String(fullPath.split(separator: "/").last!) // take last segment
|
||||
|
||||
self.enabled = !line.contains(";")
|
||||
self.enabled = !line.starts(with: ";")
|
||||
self.file = file
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ class PhpExtension {
|
||||
You may need to restart the other services in order for this change to apply.
|
||||
*/
|
||||
func toggle() async {
|
||||
let newLine = enabled
|
||||
let newLine = !line.starts(with: ";")
|
||||
// DISABLED: Commented out line
|
||||
? "; \(line)"
|
||||
// ENABLED: Line where the comment delimiter (;) is removed
|
||||
@ -84,14 +84,14 @@ class PhpExtension {
|
||||
|
||||
await sed(file: file, original: line, replacement: newLine)
|
||||
|
||||
enabled.toggle()
|
||||
self.enabled = !newLine.starts(with: ";")
|
||||
self.line = newLine
|
||||
|
||||
if !isRunningTests {
|
||||
Task { @MainActor in
|
||||
MainMenu.shared.rebuild()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Static Methods
|
||||
|
@ -12,6 +12,8 @@ class PhpInstallation {
|
||||
|
||||
var versionNumber: VersionNumber
|
||||
|
||||
var missingBinary: Bool = false
|
||||
|
||||
var isHealthy: Bool = true
|
||||
|
||||
/**
|
||||
@ -35,6 +37,10 @@ class PhpInstallation {
|
||||
// The parser should always work, or the string has to be very unusual.
|
||||
// If so, the app SHOULD crash, so that the users report what's up.
|
||||
self.versionNumber = try! VersionNumber.parse(longVersionString)
|
||||
} else {
|
||||
// Keep track that the `php-config` binary is missing; this often means there's a mismatch between
|
||||
// the `php` version alias and the actual installed version (e.g. you haven't upgraded `php`)
|
||||
missingBinary = true
|
||||
}
|
||||
|
||||
if FileSystem.fileExists(phpExecutablePath) {
|
||||
|
@ -43,6 +43,7 @@ public struct TestableConfiguration: Codable {
|
||||
private var primaryPhpVersion: VersionNumber?
|
||||
private var secondaryPhpVersions: [VersionNumber] = []
|
||||
|
||||
// swiftlint:disable function_body_length
|
||||
mutating func addPhpVersion(_ version: VersionNumber, primary: Bool) {
|
||||
if primary {
|
||||
if primaryPhpVersion != nil {
|
||||
@ -62,8 +63,8 @@ public struct TestableConfiguration: Codable {
|
||||
: .fake(.binary),
|
||||
"/opt/homebrew/Cellar/php/\(version.long)/bin/php-config"
|
||||
: .fake(.binary),
|
||||
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/www.conf"
|
||||
: .fake(.text),
|
||||
// "/opt/homebrew/etc/php/\(version.short)/php-fpm.d/www.conf"
|
||||
// : .fake(.text),
|
||||
"/opt/homebrew/etc/php/\(version.short)/php-fpm.d/valet-fpm.conf"
|
||||
: .fake(.text),
|
||||
"/opt/homebrew/etc/php/\(version.short)/php.ini"
|
||||
@ -93,7 +94,7 @@ public struct TestableConfiguration: Codable {
|
||||
/opt/homebrew/etc/php/\(version.short)/conf.d/php-memory-limits.ini,
|
||||
"""
|
||||
} else {
|
||||
|
||||
self.shellOutput["sudo /opt/homebrew/bin/brew services stop php@\(version.short)"] = .instant("")
|
||||
self.shellOutput["ls /opt/homebrew/opt | grep php@"] =
|
||||
BatchFakeShellOutput.instant(
|
||||
self.secondaryPhpVersions
|
||||
|
@ -46,8 +46,10 @@ extension App {
|
||||
}
|
||||
|
||||
hotkey.keyDownHandler = {
|
||||
MainMenu.shared.statusItem.button?.performClick(nil)
|
||||
NSApplication.shared.activate(ignoringOtherApps: true)
|
||||
Task { @MainActor in
|
||||
MainMenu.shared.statusItem.button?.performClick(nil)
|
||||
NSApplication.shared.activate(ignoringOtherApps: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,10 +74,13 @@ class App {
|
||||
/** The window controller of the onboarding window. */
|
||||
var onboardingWindowController: OnboardingWindowController?
|
||||
|
||||
/** The window controller of the config manager window. */
|
||||
var phpConfigManagerWindowController: PhpConfigManagerWindowController?
|
||||
|
||||
/** The window controller of the warnings window. */
|
||||
var phpDoctorWindowController: PhpDoctorWindowController?
|
||||
|
||||
/** The window controller of the warnings window. */
|
||||
/** The window controller of the PHP version manager window. */
|
||||
var phpVersionManagerWindowController: PhpVersionManagerWindowController?
|
||||
|
||||
/** List of detected (installed) applications that PHP Monitor can work with. */
|
||||
@ -86,9 +89,6 @@ class App {
|
||||
/** The warning manager, responsible for keeping track of warnings. */
|
||||
var warnings = WarningManager.shared
|
||||
|
||||
/** The filesystem watchers, responsible for keeping track of changes to the PHP installation. */
|
||||
var watchers: [FSNotifier.Kind: FSNotifier] = [:]
|
||||
|
||||
/** Timer that will periodically reload info about the user's PHP installation. */
|
||||
var timer: Timer?
|
||||
|
||||
@ -117,8 +117,12 @@ class App {
|
||||
|
||||
// MARK: - App Watchers
|
||||
|
||||
/**
|
||||
The `PhpConfigWatcher` is responsible for watching the `.ini` files and the `.conf.d` folder.
|
||||
/** Individual filesystem watchers, which are, i.e. responsible for watching the Homebrew folders. */
|
||||
var watchers: [String: FSNotifier] = [:]
|
||||
|
||||
/**
|
||||
The `ConfigWatchManager` is responsible for watching the `.ini` files and the `.conf.d` folder.
|
||||
This manager object can immediately start or stop all watchers (or pause them) all at once.
|
||||
*/
|
||||
var watcher: PhpConfigWatcher!
|
||||
var watchManager: ConfigWatchManager!
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="22155" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21701"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="22155"/>
|
||||
<capability name="Image references" minToolsVersion="12.0"/>
|
||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||
<capability name="Search Toolbar Item" minToolsVersion="12.0" minSystemVersion="11.0"/>
|
||||
@ -429,7 +429,7 @@
|
||||
</toolbarItem>
|
||||
<searchToolbarItem implicitItemIdentifier="7C834FBE-7118-4082-A09F-7CBECEC1356A" label="Search" paletteLabel="Search" visibilityPriority="1001" id="G2g-jS-RVc">
|
||||
<nil key="toolTip"/>
|
||||
<searchField key="view" verticalHuggingPriority="750" textCompletion="NO" id="0gE-Yr-MLy">
|
||||
<searchField key="view" focusRingType="none" verticalHuggingPriority="750" textCompletion="NO" id="0gE-Yr-MLy">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<searchFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" usesSingleLineMode="YES" bezelStyle="round" sendsSearchStringImmediately="YES" id="vp9-vH-goQ">
|
||||
@ -521,9 +521,6 @@
|
||||
<subviews>
|
||||
<button wantsLayer="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="8zu-cF-KCX">
|
||||
<rect key="frame" x="383" y="13" width="104" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="90" id="4Uf-fh-jWJ"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="Primary" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="F26-vf-hFH">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -531,15 +528,15 @@
|
||||
DQ
|
||||
</string>
|
||||
</buttonCell>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="90" id="4Uf-fh-jWJ"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="primaryButtonAction:" target="hkw-9V-NxP" id="W7d-3b-pZT"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button wantsLayer="YES" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="TCp-nS-HN2">
|
||||
<rect key="frame" x="281" y="13" width="104" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="90" id="QWZ-BA-0g9"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="Secondary" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="eCk-FC-9Zr">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -547,6 +544,9 @@ DQ
|
||||
Gw
|
||||
</string>
|
||||
</buttonCell>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="90" id="QWZ-BA-0g9"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="secondaryButtonAction:" target="hkw-9V-NxP" id="YJs-Hu-lFP"/>
|
||||
</connections>
|
||||
@ -575,7 +575,7 @@ Gw
|
||||
<constraint firstAttribute="bottom" secondItem="8zu-cF-KCX" secondAttribute="bottom" constant="20" symbolic="YES" id="wIl-uw-y3p"/>
|
||||
</constraints>
|
||||
</visualEffectView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="U1c-qS-cIm">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="U1c-qS-cIm">
|
||||
<rect key="frame" x="98" y="153" width="384" height="19"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="380" id="WgB-hj-d4P"/>
|
||||
@ -586,7 +586,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yI6-qf-htf">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="yI6-qf-htf">
|
||||
<rect key="frame" x="98" y="127" width="384" height="16"/>
|
||||
<textFieldCell key="cell" selectable="YES" title="This is a slightly more expanded explanation." id="rY3-Nd-Iit">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -610,7 +610,7 @@ Gw
|
||||
</constraints>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="7eT-Hw-EL9"/>
|
||||
</imageView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hml-dl-Cah">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="hml-dl-Cah">
|
||||
<rect key="frame" x="98" y="70" width="384" height="42"/>
|
||||
<textFieldCell key="cell" selectable="YES" id="7iW-Lc-DqO">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
@ -685,9 +685,6 @@ DQ
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SwS-o8-pbl">
|
||||
<rect key="frame" x="13" y="13" width="114" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="qCP-Sp-gxm"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="[i18n] Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="WHE-HW-jwp">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -695,11 +692,14 @@ DQ
|
||||
Gw
|
||||
</string>
|
||||
</buttonCell>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="qCP-Sp-gxm"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="pressedCancel:" target="glS-wF-sEU" id="q0L-YZ-F3J"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZX9-s1-23i">
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZX9-s1-23i">
|
||||
<rect key="frame" x="20" y="150" width="440" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter a domain name here." drawsBackground="YES" id="NFa-1D-Bi4">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -710,7 +710,7 @@ Gw
|
||||
<outlet property="delegate" destination="glS-wF-sEU" id="Dyf-0M-Gwj"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VzR-5a-cmT">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="VzR-5a-cmT">
|
||||
<rect key="frame" x="18" y="128" width="444" height="14"/>
|
||||
<textFieldCell key="cell" title="[i18n] Preview text here" id="bJr-s6-tdP">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
@ -728,7 +728,7 @@ Gw
|
||||
<action selector="pressedSecure:" target="glS-wF-sEU" id="OIj-Pz-5Ea"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mmQ-7e-dlb">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mmQ-7e-dlb">
|
||||
<rect key="frame" x="18" y="60" width="444" height="28"/>
|
||||
<textFieldCell key="cell" title="[i18n] Securing a domain requires administrative privileges.
You may be prompted for your password or Touch ID." id="4gd-KM-5Fu">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
@ -743,7 +743,7 @@ Gw
|
||||
<url key="url" string="file:///Users/"/>
|
||||
</pathCell>
|
||||
</pathControl>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P0B-Ht-R8n">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="P0B-Ht-R8n">
|
||||
<rect key="frame" x="18" y="209" width="128" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="[i18n] Link a Folder" id="S4j-ZC-ddT">
|
||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||
@ -751,7 +751,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="900-Z2-tID">
|
||||
<textField hidden="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="900-Z2-tID">
|
||||
<rect key="frame" x="140" y="23" width="180" height="14"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="That domain name already exists." id="jOt-n6-TQf">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
@ -886,7 +886,7 @@ Gw
|
||||
<rect key="frame" x="69" y="0.0" width="200" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="XJL-Uw-frD">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="XJL-Uw-frD">
|
||||
<rect key="frame" x="3" y="26" width="145" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="my-domain-name.test" id="SGC-Gm-Mxd">
|
||||
<font key="font" metaFont="systemSemibold" size="13"/>
|
||||
@ -894,7 +894,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="CXK-Q9-CpO">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="CXK-Q9-CpO">
|
||||
<rect key="frame" x="3" y="12" width="75" height="14"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="~/path/to/site" id="fe7-Ha-mR9">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
@ -937,13 +937,13 @@ Gw
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ZXQ-bg-Xba">
|
||||
<rect key="frame" x="27" y="18" width="70" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="70" id="MBa-bB-DTB"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="inline" title="PHP X.X" bezelStyle="inline" alignment="center" borderStyle="border" inset="2" id="Tfk-YR-L4B">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="smallSystemBold"/>
|
||||
</buttonCell>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="70" id="MBa-bB-DTB"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="pressedPhpVersion:" target="T49-0U-d58" id="jVO-TS-F6d"/>
|
||||
</connections>
|
||||
@ -987,11 +987,11 @@ Gw
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="domainListKindCell" wantsLayer="YES" id="AhT-xR-16a" customClass="DomainListKindCell" customModule="PHP_Monitor" customModuleProvider="target">
|
||||
<rect key="frame" x="403" y="0.0" width="48" height="54"/>
|
||||
<rect key="frame" x="403" y="0.0" width="50" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="sYR-vb-OW1">
|
||||
<rect key="frame" x="15" y="18" width="18" height="18"/>
|
||||
<rect key="frame" x="16" y="18" width="18" height="18"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="18" id="XcB-uw-szU"/>
|
||||
<constraint firstAttribute="height" constant="18" id="bGN-Vh-Sh0"/>
|
||||
@ -1024,10 +1024,10 @@ Gw
|
||||
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
|
||||
<prototypeCellViews>
|
||||
<tableCellView identifier="domainListTypeCell" wantsLayer="YES" id="ntU-Rl-ciP" customClass="DomainListTypeCell" customModule="PHP_Monitor" customModuleProvider="target">
|
||||
<rect key="frame" x="468" y="0.0" width="97" height="54"/>
|
||||
<rect key="frame" x="470" y="0.0" width="97" height="54"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ljl-8B-key">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ljl-8B-key">
|
||||
<rect key="frame" x="6" y="26" width="93" height="14"/>
|
||||
<textFieldCell key="cell" alignment="left" title="Laravel" id="0lu-L6-oKr">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
@ -1035,7 +1035,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aPK-Xc-J4B">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="aPK-Xc-J4B">
|
||||
<rect key="frame" x="6" y="15" width="93" height="11"/>
|
||||
<textFieldCell key="cell" alignment="left" title="PHP 8.0" id="puf-Jh-ham">
|
||||
<font key="font" metaFont="miniSystem"/>
|
||||
@ -1125,7 +1125,7 @@ Gw
|
||||
<rect key="frame" x="0.0" y="0.0" width="540" height="286"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QCK-Z9-w7g">
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QCK-Z9-w7g">
|
||||
<rect key="frame" x="20" y="196" width="500" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="http://127.0.0.1:80" placeholderString="http://127.0.0.1:80" drawsBackground="YES" id="muS-8M-KSy">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -1136,7 +1136,7 @@ Gw
|
||||
<outlet property="delegate" destination="dwh-CF-6iv" id="lNE-OI-G93"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Uib-vA-HRc">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Uib-vA-HRc">
|
||||
<rect key="frame" x="18" y="221" width="325" height="14"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="[i18n] Proxy subject (usually: protocol, IP address and port)" id="G1Z-3f-BhL">
|
||||
<font key="font" metaFont="systemMedium" size="11"/>
|
||||
@ -1144,7 +1144,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mlA-Zt-Hu8">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mlA-Zt-Hu8">
|
||||
<rect key="frame" x="18" y="172" width="112" height="14"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="[i18n] Domain name" id="dQs-oZ-80e">
|
||||
<font key="font" metaFont="systemMedium" size="11"/>
|
||||
@ -1152,7 +1152,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNw-oQ-bnb">
|
||||
<textField focusRingType="none" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNw-oQ-bnb">
|
||||
<rect key="frame" x="20" y="147" width="500" height="21"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter a domain name here." drawsBackground="YES" id="gTQ-Y2-Y9w">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -1194,9 +1194,6 @@ DQ
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="nC0-dk-QaF">
|
||||
<rect key="frame" x="13" y="13" width="114" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="uCc-fF-wS2"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="[i18n] Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="D8g-GE-7TU">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -1204,11 +1201,14 @@ DQ
|
||||
Gw
|
||||
</string>
|
||||
</buttonCell>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="uCc-fF-wS2"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="pressedCancel:" target="dwh-CF-6iv" id="J2T-Zj-A0j"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSZ-x8-Pqi">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSZ-x8-Pqi">
|
||||
<rect key="frame" x="18" y="128" width="504" height="14"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="500" id="sF1-RG-URI"/>
|
||||
@ -1229,7 +1229,7 @@ Gw
|
||||
<action selector="pressedSecure:" target="dwh-CF-6iv" id="b74-8T-AzO"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5x7-ll-2f7">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5x7-ll-2f7">
|
||||
<rect key="frame" x="18" y="60" width="504" height="28"/>
|
||||
<textFieldCell key="cell" title="[i18n] Securing a domain requires administrative privileges.
You may be prompted for your password or Touch ID." id="IMB-O5-ZOy">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
@ -1237,7 +1237,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="DAh-br-Dfx">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="DAh-br-Dfx">
|
||||
<rect key="frame" x="18" y="250" width="123" height="16"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="[i18n] Add a Proxy" id="AZ1-04-kUl">
|
||||
<font key="font" textStyle="headline" name=".SFNS-Bold"/>
|
||||
@ -1245,7 +1245,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="w0k-CK-0u4">
|
||||
<textField hidden="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="w0k-CK-0u4">
|
||||
<rect key="frame" x="191" y="23" width="180" height="14"/>
|
||||
<textFieldCell key="cell" lineBreakMode="clipping" title="That domain name already exists." id="4sH-94-UJl">
|
||||
<font key="font" metaFont="smallSystem"/>
|
||||
@ -1340,9 +1340,6 @@ Gw
|
||||
<subviews>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="FhN-AM-SkI">
|
||||
<rect key="frame" x="13" y="13" width="114" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="Zhu-D8-cLK"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="push" title="[i18n] Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="LxP-t4-H2W">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -1350,6 +1347,9 @@ Gw
|
||||
Gw
|
||||
</string>
|
||||
</buttonCell>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="80" id="Zhu-D8-cLK"/>
|
||||
</constraints>
|
||||
<connections>
|
||||
<action selector="pressedCancel:" target="gOD-Gu-zDG" id="wMp-sM-0A4"/>
|
||||
</connections>
|
||||
@ -1389,7 +1389,7 @@ Gw
|
||||
<real value="3.4028234663852886e+38"/>
|
||||
</customSpacing>
|
||||
</stackView>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fJK-Ke-IK3">
|
||||
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fJK-Ke-IK3">
|
||||
<rect key="frame" x="18" y="138" width="504" height="19"/>
|
||||
<textFieldCell key="cell" selectable="YES" alignment="left" title="[i18n] What kind of domain would you like to set up?" id="agk-Nj-FLd">
|
||||
<font key="font" metaFont="systemBold" size="15"/>
|
||||
@ -1397,7 +1397,7 @@ Gw
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField wantsLayer="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="urj-Xq-TrJ">
|
||||
<textField wantsLayer="YES" focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="urj-Xq-TrJ">
|
||||
<rect key="frame" x="18" y="60" width="504" height="70"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="500" id="tbl-AV-4qB"/>
|
||||
|
@ -241,6 +241,20 @@ class Startup {
|
||||
descriptionText: "startup.errors.which_alias_issue.desc".localized
|
||||
),
|
||||
// =================================================================================
|
||||
// Determine that Laravel Herd is not running (may cause conflicts)
|
||||
// =================================================================================
|
||||
EnvironmentCheck(
|
||||
command: {
|
||||
return NSWorkspace.shared.runningApplications.contains(where: { app in
|
||||
return app.bundleIdentifier == "de.beyondco.herd"
|
||||
})
|
||||
},
|
||||
name: "Herd is not running",
|
||||
titleText: "startup.errors.herd_running.title".localized,
|
||||
subtitleText: "startup.errors.herd_running.subtitle".localized,
|
||||
descriptionText: "startup.errors.herd_running.desc".localized
|
||||
),
|
||||
// =================================================================================
|
||||
// Determine that Valet works correctly (no issues in platform detected)
|
||||
// =================================================================================
|
||||
EnvironmentCheck(
|
||||
|
@ -62,12 +62,13 @@ struct ComposerJson: Decodable {
|
||||
public func getNotableDependencies() -> [String: String] {
|
||||
var notable: [String: String] = [:]
|
||||
|
||||
var scan = Array(PhpFrameworks.DependencyList.keys)
|
||||
scan.append("php")
|
||||
let scan = Array(ProjectTypeDetection.CommonDependencyList.keys) +
|
||||
Array(ProjectTypeDetection.SpecificDependencyList.keys) +
|
||||
["php"]
|
||||
|
||||
scan.forEach { dependency in
|
||||
if dependencies?[dependency] != nil {
|
||||
notable[dependency] = dependencies![dependency]
|
||||
if let resolvedDependency = dependencies?[dependency] {
|
||||
notable[dependency] = resolvedDependency
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,6 @@ import Foundation
|
||||
}
|
||||
|
||||
PhpEnvironments.shared.isBusy = true
|
||||
MainMenu.shared.setBusyImage()
|
||||
MainMenu.shared.rebuild()
|
||||
|
||||
window = TerminalProgressWindowController.display(
|
||||
title: "alert.composer_progress.title".localized,
|
||||
@ -106,14 +104,11 @@ import Foundation
|
||||
|
||||
private func removeBusyStatus() {
|
||||
PhpEnvironments.shared.isBusy = false
|
||||
Task { @MainActor in
|
||||
MainMenu.shared.updatePhpVersionInStatusBar()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Alert
|
||||
|
||||
@MainActor private func presentMissingAlert() {
|
||||
private func presentMissingAlert() {
|
||||
BetterAlert()
|
||||
.withInformation(
|
||||
title: "alert.composer_missing.title".localized,
|
||||
|
@ -8,20 +8,20 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct PhpFrameworks {
|
||||
|
||||
struct ProjectTypeDetection {
|
||||
/**
|
||||
This list should probably be reversed when checked, because some of these
|
||||
will also require either `laravel/framework` or `symfony/symfony`.
|
||||
This list is only checked if the specific dependency list doesn't report a match.
|
||||
*/
|
||||
public static let DependencyList = [
|
||||
|
||||
// COMMON FRAMEWORKS
|
||||
public static let CommonDependencyList = [
|
||||
"laravel/framework": "Laravel",
|
||||
"symfony/symfony": "Symfony",
|
||||
"laravel/lumen": "Lumen",
|
||||
"laravel/lumen": "Lumen"
|
||||
]
|
||||
|
||||
// VARIOUS CMS
|
||||
/**
|
||||
This list is checked first to see if a project dependency can be mapped to a certain project type.
|
||||
*/
|
||||
public static let SpecificDependencyList = [
|
||||
"roots/bedrock": "Bedrock",
|
||||
"cakephp/app": "CakePHP",
|
||||
"craftcms/craft": "Craft",
|
||||
@ -37,30 +37,8 @@ struct PhpFrameworks {
|
||||
"johnpbloch/wordpress-core": "WordPress",
|
||||
"zendframework/zendframework": "Zend",
|
||||
"zendframework/zend-mvc": "Zend",
|
||||
"typo3/cms-core": "Typo3"
|
||||
// "magento/*": "Magento",
|
||||
// "concrete5/*": "Concrete5",
|
||||
// "contao/*": "Contao",
|
||||
// "slim/*": "Slim",
|
||||
]
|
||||
|
||||
public static let FileMapping: [String: [String]] = [
|
||||
"Drupal": [
|
||||
// Legacy installations
|
||||
"/misc/drupal.js",
|
||||
"/core/lib/Drupal.php",
|
||||
// The default (new) installation w/ Composer puts the modules in /web
|
||||
"/web/misc/drupal.js",
|
||||
"/web/core/lib/Drupal.php"
|
||||
],
|
||||
"WordPress": [
|
||||
"/wp-config.php",
|
||||
"/wp-config-sample.php"
|
||||
],
|
||||
"Typo3": [
|
||||
"/typo3",
|
||||
"/public/typo3"
|
||||
]
|
||||
"typo3/cms-core": "Typo3",
|
||||
"slim/slim": "Slim"
|
||||
]
|
||||
|
||||
/**
|
||||
@ -82,4 +60,25 @@ struct PhpFrameworks {
|
||||
return nil
|
||||
}
|
||||
|
||||
/**
|
||||
File mapping is used as a fallback if neither specific nor framework matches could be done.
|
||||
*/
|
||||
public static let FileMapping: [String: [String]] = [
|
||||
"Drupal": [
|
||||
// Legacy installations
|
||||
"/misc/drupal.js",
|
||||
"/core/lib/Drupal.php",
|
||||
// The default (new) installation w/ Composer puts the modules in /web
|
||||
"/web/misc/drupal.js",
|
||||
"/web/core/lib/Drupal.php"
|
||||
],
|
||||
"WordPress": [
|
||||
"/wp-config.php",
|
||||
"/wp-config-sample.php"
|
||||
],
|
||||
"Typo3": [
|
||||
"/typo3",
|
||||
"/public/typo3"
|
||||
]
|
||||
]
|
||||
}
|
@ -45,10 +45,11 @@ class Brew {
|
||||
|
||||
/// Each formula for each PHP version that can be installed.
|
||||
public static let phpVersionFormulae = [
|
||||
"8.3": "shivammathur/php/php@8.3",
|
||||
"8.4": "shivammathur/php/php@8.4",
|
||||
"8.3": "php@8.3",
|
||||
"8.2": "php@8.2",
|
||||
"8.1": "php@8.1",
|
||||
"8.0": "php@8.0",
|
||||
"8.0": "shivammathur/php/php@8.0",
|
||||
"7.4": "shivammathur/php/php@7.4",
|
||||
"7.3": "shivammathur/php/php@7.3",
|
||||
"7.2": "shivammathur/php/php@7.2",
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
struct BrewFormula {
|
||||
struct BrewFormula: Equatable {
|
||||
/// Name of the formula.
|
||||
let name: String
|
||||
|
||||
@ -48,6 +48,25 @@ struct BrewFormula {
|
||||
return upgradeVersion != nil
|
||||
}
|
||||
|
||||
/// Whether this formula alias is different.
|
||||
var hasUpgradedFormulaAlias: Bool {
|
||||
return self.shortVersion == PhpEnvironments.homebrewBrewPhpAlias
|
||||
&& PhpEnvironments.homebrewBrewPhpAlias != PhpEnvironments.brewPhpAlias
|
||||
}
|
||||
|
||||
var unavailableAfterUpgrade: Bool {
|
||||
if installedVersion == nil || upgradeVersion == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if let installed = try? VersionNumber.parse(self.installedVersion!),
|
||||
let upgrade = try? VersionNumber.parse(self.upgradeVersion!) {
|
||||
return upgrade.short != installed.short
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
/// The associated Homebrew folder with this PHP formula.
|
||||
var homebrewFolder: String {
|
||||
let resolved = name
|
||||
@ -60,7 +79,7 @@ struct BrewFormula {
|
||||
/// The short version associated with this formula, if installed.
|
||||
var shortVersion: String? {
|
||||
guard let version = self.installedVersion else {
|
||||
return nil
|
||||
return self.displayName.replacingOccurrences(of: "PHP ", with: "")
|
||||
}
|
||||
|
||||
return VersionNumber.make(from: version)?.short ?? nil
|
||||
|
@ -17,6 +17,7 @@ extension HandlesBrewFormulae {
|
||||
public func refreshPhpVersions(loadOutdated: Bool) async {
|
||||
let items = await loadPhpVersions(loadOutdated: loadOutdated)
|
||||
Task { @MainActor in
|
||||
await PhpEnvironments.shared.determinePhpAlias()
|
||||
Brew.shared.formulae.phpVersions = items
|
||||
}
|
||||
}
|
||||
@ -43,7 +44,8 @@ class BrewFormulaeHandler: HandlesBrewFormulae {
|
||||
}
|
||||
|
||||
return Brew.phpVersionFormulae.map { (version, formula) in
|
||||
let fullVersion = PhpEnvironments.shared.cachedPhpInstallations[version]?.versionNumber.text
|
||||
let fullVersion = PhpEnvironments.shared.cachedPhpInstallations[version]?
|
||||
.versionNumber.text
|
||||
|
||||
var upgradeVersion: String?
|
||||
|
||||
@ -53,13 +55,15 @@ class BrewFormulaeHandler: HandlesBrewFormulae {
|
||||
})?.current_version
|
||||
}
|
||||
|
||||
return BrewFormula(
|
||||
let formula = BrewFormula(
|
||||
name: formula,
|
||||
displayName: "PHP \(version)",
|
||||
installedVersion: fullVersion,
|
||||
upgradeVersion: upgradeVersion,
|
||||
prerelease: Constants.ExperimentalPhpVersions.contains(version)
|
||||
)
|
||||
|
||||
return formula
|
||||
}.sorted { $0.displayName > $1.displayName }
|
||||
}
|
||||
}
|
||||
|
@ -41,9 +41,22 @@ class InstallAndUpgradeCommand: BrewCommand {
|
||||
description: "PHP Monitor is preparing Homebrew..."
|
||||
))
|
||||
|
||||
// Try to run all upgrade and installation operations
|
||||
try await self.upgradePackages(onProgress)
|
||||
try await self.installPackages(onProgress)
|
||||
let unavailable = upgrading.first(where: { formula in
|
||||
formula.unavailableAfterUpgrade
|
||||
})
|
||||
|
||||
// Make sure the tap is installed
|
||||
try await self.checkPhpTap(onProgress)
|
||||
|
||||
if unavailable == nil {
|
||||
// Try to run all upgrade and installation operations
|
||||
try await self.upgradePackages(onProgress)
|
||||
try await self.installPackages(onProgress)
|
||||
} else {
|
||||
// Simply upgrade `php` to the latest version
|
||||
try await self.upgradeMainPhpFormula(unavailable!, onProgress)
|
||||
await PhpEnvironments.shared.determinePhpAlias()
|
||||
}
|
||||
|
||||
// Re-check the installed versions
|
||||
await PhpEnvironments.detectPhpVersions()
|
||||
@ -55,6 +68,39 @@ class InstallAndUpgradeCommand: BrewCommand {
|
||||
await self.completedOperations(onProgress)
|
||||
}
|
||||
|
||||
private func upgradeMainPhpFormula(
|
||||
_ unavailable: BrewFormula,
|
||||
_ onProgress: @escaping (BrewCommandProgress) -> Void
|
||||
) async throws {
|
||||
// Determine which version was previously available (that will become unavailable)
|
||||
guard let short = try? VersionNumber
|
||||
.parse(unavailable.installedVersion!).short else {
|
||||
return
|
||||
}
|
||||
|
||||
// Upgrade the main formula
|
||||
let command = """
|
||||
export HOMEBREW_NO_INSTALL_CLEANUP=true; \
|
||||
\(Paths.brew) upgrade php;
|
||||
\(Paths.brew) install php@\(short);
|
||||
"""
|
||||
|
||||
// Run the upgrade command
|
||||
try await run(command, onProgress)
|
||||
}
|
||||
|
||||
private func checkPhpTap(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||
if !BrewDiagnostics.installedTaps.contains("shivammathur/php") {
|
||||
let command = "brew tap shivammathur/php"
|
||||
try await run(command, onProgress)
|
||||
}
|
||||
|
||||
if !BrewDiagnostics.installedTaps.contains("shivammathur/extensions") {
|
||||
let command = "brew tap shivammathur/extensions"
|
||||
try await run(command, onProgress)
|
||||
}
|
||||
}
|
||||
|
||||
private func upgradePackages(_ onProgress: @escaping (BrewCommandProgress) -> Void) async throws {
|
||||
// If no upgrades are needed, early exit
|
||||
if self.upgrading.isEmpty {
|
||||
|
@ -141,7 +141,7 @@ class ValetSite: ValetListable {
|
||||
self.determineDriverViaComposer()
|
||||
|
||||
if self.driver == nil {
|
||||
self.driver = PhpFrameworks.detectFallbackDependency(self.absolutePath)
|
||||
self.driver = ProjectTypeDetection.detectFallbackDependency(self.absolutePath)
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,10 +155,16 @@ class ValetSite: ValetListable {
|
||||
private func determineDriverViaComposer() {
|
||||
self.driverDeterminedByComposer = true
|
||||
|
||||
PhpFrameworks.DependencyList.reversed().forEach { (key: String, value: String) in
|
||||
if self.notableComposerDependencies.keys.contains(key) {
|
||||
self.driver = value
|
||||
}
|
||||
for (key, value) in ProjectTypeDetection.SpecificDependencyList
|
||||
where notableComposerDependencies.keys.contains(key) {
|
||||
self.driver = value
|
||||
return
|
||||
}
|
||||
|
||||
for (key, value) in ProjectTypeDetection.CommonDependencyList
|
||||
where notableComposerDependencies.keys.contains(key) {
|
||||
self.driver = value
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,6 @@ extension MainMenu {
|
||||
return
|
||||
}
|
||||
|
||||
setBusyImage()
|
||||
PhpEnvironments.shared.isBusy = true
|
||||
PhpEnvironments.shared.delegate = self
|
||||
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
||||
@ -298,7 +297,6 @@ extension MainMenu {
|
||||
}
|
||||
|
||||
@objc func switchToPhpVersion(_ version: String) {
|
||||
setBusyImage()
|
||||
PhpEnvironments.shared.isBusy = true
|
||||
PhpEnvironments.shared.delegate = self
|
||||
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
||||
@ -325,7 +323,6 @@ extension MainMenu {
|
||||
*/
|
||||
func switchToPhp(_ version: String) async {
|
||||
Task { @MainActor [self] in
|
||||
setBusyImage()
|
||||
PhpEnvironments.shared.isBusy = true
|
||||
PhpEnvironments.shared.delegate = self
|
||||
PhpEnvironments.shared.delegate?.switcherDidStartSwitching(to: version)
|
||||
|
@ -45,21 +45,16 @@ extension MainMenu {
|
||||
.broadcastServicesUpdate
|
||||
]
|
||||
) {
|
||||
if behaviours.contains(.reloadsPhpInstallation) {
|
||||
if behaviours.contains(.reloadsPhpInstallation) || behaviours.contains(.setsBusyUI) {
|
||||
PhpEnvironments.shared.isBusy = true
|
||||
}
|
||||
|
||||
if behaviours.contains(.setsBusyUI) {
|
||||
setBusyImage()
|
||||
}
|
||||
|
||||
Task(priority: .userInitiated) { [unowned self] in
|
||||
var error: Error?
|
||||
|
||||
do { try execute() } catch let e { error = e }
|
||||
|
||||
if behaviours.contains(.setsBusyUI) {
|
||||
PhpEnvironments.shared.isBusy = false
|
||||
do { try execute() } catch let e {
|
||||
error = e
|
||||
Log.err(e)
|
||||
}
|
||||
|
||||
Task { @MainActor [self, error] in
|
||||
@ -69,14 +64,16 @@ extension MainMenu {
|
||||
|
||||
if behaviours.contains(.updatesMenuBarContents) {
|
||||
updatePhpVersionInStatusBar()
|
||||
} else if behaviours.contains(.setsBusyUI) {
|
||||
refreshIcon()
|
||||
}
|
||||
|
||||
if behaviours.contains(.broadcastServicesUpdate) {
|
||||
Task { await ServicesManager.shared.reloadServicesStatus() }
|
||||
}
|
||||
|
||||
if behaviours.contains(.setsBusyUI) {
|
||||
PhpEnvironments.shared.isBusy = false
|
||||
}
|
||||
|
||||
if error != nil {
|
||||
return failure(error!)
|
||||
}
|
||||
|
@ -105,6 +105,9 @@ extension MainMenu {
|
||||
Valet.shared.notifyAboutUnsupportedTLD()
|
||||
}
|
||||
|
||||
// Keep track of which PHP versions are currently about to release
|
||||
Log.info("Experimental PHP versions: \(Constants.ExperimentalPhpVersions)")
|
||||
|
||||
// Find out which services are active
|
||||
Log.info("The services manager knows about \(ServicesManager.shared.services.count) services.")
|
||||
|
||||
|
@ -16,7 +16,9 @@ extension MainMenu {
|
||||
|
||||
nonisolated func switcherDidCompleteSwitch(to version: String) {
|
||||
// Mark as no longer busy
|
||||
PhpEnvironments.shared.isBusy = false
|
||||
Task { @MainActor in
|
||||
PhpEnvironments.shared.isBusy = false
|
||||
}
|
||||
|
||||
Task { // Things to do after reloading domain list data
|
||||
if Valet.installed {
|
||||
|
@ -87,6 +87,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
}
|
||||
|
||||
/** Updates the icon (refresh icon) and rebuilds the menu. */
|
||||
@available(*, deprecated, message: "Use the busy status instead")
|
||||
@objc func updatePhpVersionInStatusBar() {
|
||||
refreshIcon()
|
||||
rebuild()
|
||||
@ -139,7 +140,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
@objc func reloadPhpMonitorMenuInBackground() {
|
||||
asyncExecution({
|
||||
// This automatically reloads the menu
|
||||
Log.info("Reloading information about the PHP installation (in the background)...")
|
||||
Log.perf("Reloading information about the PHP installation (in the background)...")
|
||||
}, behaviours: [
|
||||
.setsBusyUI,
|
||||
.reloadsPhpInstallation,
|
||||
@ -150,10 +151,13 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
|
||||
/** Refreshes the icon with the PHP version. */
|
||||
@objc func refreshIcon() {
|
||||
|
||||
Task { @MainActor [self] in
|
||||
if PhpEnvironments.shared.isBusy {
|
||||
Log.perf("Refreshing icon: currently busy")
|
||||
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
||||
} else {
|
||||
Log.perf("Refreshing icon: no longer busy")
|
||||
if Preferences.preferences[.shouldDisplayDynamicIcon] as! Bool == false {
|
||||
// Static icon has been requested
|
||||
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIconStatic"))!)
|
||||
@ -172,13 +176,6 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the icon to be displayed as busy. */
|
||||
@objc func setBusyImage() {
|
||||
Task { @MainActor [self] in
|
||||
setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Menu Item Functionality
|
||||
|
||||
@objc func openAbout() {
|
||||
@ -206,6 +203,10 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
|
||||
PhpDoctorWindowController.show()
|
||||
}
|
||||
|
||||
@objc func openConfigGUI() {
|
||||
PhpConfigManagerWindowController.show()
|
||||
}
|
||||
|
||||
@objc func openDomainList() {
|
||||
DomainListVC.show()
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import Cocoa
|
||||
|
||||
extension StatusMenu {
|
||||
|
||||
func addPhpVersionMenuItems() {
|
||||
@MainActor func addPhpVersionMenuItems() {
|
||||
if PhpEnvironments.phpInstall == nil {
|
||||
addItem(HeaderView.asMenuItem(text: "⚠️ " + "mi_no_php_linked".localized, minimumWidth: 280))
|
||||
addItems([
|
||||
@ -34,7 +34,7 @@ extension StatusMenu {
|
||||
))
|
||||
}
|
||||
|
||||
func addPhpActionMenuItems() {
|
||||
@MainActor func addPhpActionMenuItems() {
|
||||
if PhpEnvironments.shared.isBusy {
|
||||
addItem(NSMenuItem(title: "mi_busy".localized))
|
||||
return
|
||||
@ -54,7 +54,7 @@ extension StatusMenu {
|
||||
self.addItem(NSMenuItem.separator())
|
||||
}
|
||||
|
||||
func addServicesManagerMenuItem() {
|
||||
@MainActor func addServicesManagerMenuItem() {
|
||||
if PhpEnvironments.shared.isBusy {
|
||||
return
|
||||
}
|
||||
@ -65,7 +65,7 @@ extension StatusMenu {
|
||||
])
|
||||
}
|
||||
|
||||
func addSwitchToPhpMenuItems() {
|
||||
@MainActor func addSwitchToPhpMenuItems() {
|
||||
var shortcutKey = 1
|
||||
for index in (0..<PhpEnvironments.shared.availablePhpVersions.count) {
|
||||
// Get the short and long version
|
||||
@ -102,14 +102,14 @@ extension StatusMenu {
|
||||
}
|
||||
}
|
||||
|
||||
func addLiteModeMenuItem() {
|
||||
@MainActor func addLiteModeMenuItem() {
|
||||
addItems([
|
||||
NSMenuItem.separator(),
|
||||
NSMenuItem(title: "mi_lite_mode".localized, action: #selector(MainMenu.openLiteModeInfo))
|
||||
])
|
||||
}
|
||||
|
||||
func addPreferencesMenuItems() {
|
||||
@MainActor func addPreferencesMenuItems() {
|
||||
addItems([
|
||||
NSMenuItem.separator(),
|
||||
NSMenuItem(title: "mi_preferences".localized,
|
||||
@ -119,7 +119,7 @@ extension StatusMenu {
|
||||
])
|
||||
}
|
||||
|
||||
func addCoreMenuItems() {
|
||||
@MainActor func addCoreMenuItems() {
|
||||
addItems([
|
||||
NSMenuItem.separator(),
|
||||
NSMenuItem(title: "mi_about".localized,
|
||||
@ -131,7 +131,7 @@ extension StatusMenu {
|
||||
|
||||
// MARK: - Valet
|
||||
|
||||
func addValetMenuItems() {
|
||||
@MainActor func addValetMenuItems() {
|
||||
addItems([
|
||||
HeaderView.asMenuItem(text: "mi_valet".localized),
|
||||
NSMenuItem(title: "mi_valet_config".localized,
|
||||
@ -146,7 +146,7 @@ extension StatusMenu {
|
||||
|
||||
// MARK: - PHP Configuration
|
||||
|
||||
func addConfigurationMenuItems() {
|
||||
@MainActor func addConfigurationMenuItems() {
|
||||
addItems([
|
||||
HeaderView.asMenuItem(text: "mi_configuration".localized),
|
||||
NSMenuItem(title: "mi_php_version_manager".localized,
|
||||
@ -166,7 +166,7 @@ extension StatusMenu {
|
||||
|
||||
// MARK: - Composer
|
||||
|
||||
func addComposerMenuItems() {
|
||||
@MainActor func addComposerMenuItems() {
|
||||
addItems([
|
||||
HeaderView.asMenuItem(text: "mi_composer".localized),
|
||||
NSMenuItem(
|
||||
@ -187,7 +187,7 @@ extension StatusMenu {
|
||||
|
||||
// MARK: - Stats
|
||||
|
||||
func addStatsMenuItem() {
|
||||
@MainActor func addStatsMenuItem() {
|
||||
guard let install = PhpEnvironments.phpInstall else {
|
||||
Log.info("Not showing stats menu item if no PHP version is linked.")
|
||||
return
|
||||
@ -200,11 +200,21 @@ extension StatusMenu {
|
||||
post: stats.post_max_size,
|
||||
upload: stats.upload_max_filesize)
|
||||
)
|
||||
|
||||
// TODO: As soon as this does more than just edit memory limits, move this
|
||||
/*
|
||||
addItem(NSMenuItem.separator())
|
||||
addItem(NSMenuItem(
|
||||
title: "mi_manage_limits".localized,
|
||||
action: #selector(MainMenu.openConfigGUI),
|
||||
keyEquivalent: "l")
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
|
||||
func addExtensionsMenuItems() {
|
||||
@MainActor func addExtensionsMenuItems() {
|
||||
guard let install = PhpEnvironments.phpInstall else {
|
||||
Log.info("Not showing extensions menu items if no PHP version is linked.")
|
||||
return
|
||||
@ -225,7 +235,7 @@ extension StatusMenu {
|
||||
|
||||
// MARK: - Presets
|
||||
|
||||
func addPresetsMenuItem() {
|
||||
@MainActor func addPresetsMenuItem() {
|
||||
guard let presets = Preferences.custom.presets else {
|
||||
addEmptyPresetHelp()
|
||||
return
|
||||
|
@ -9,7 +9,7 @@ import Cocoa
|
||||
|
||||
class StatusMenu: NSMenu {
|
||||
// swiftlint:disable cyclomatic_complexity
|
||||
func addMenuItems() {
|
||||
@MainActor func addMenuItems() {
|
||||
addPhpVersionMenuItems()
|
||||
addItem(NSMenuItem.separator())
|
||||
|
||||
|
@ -91,6 +91,7 @@ class BetterAlert {
|
||||
}
|
||||
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
|
||||
windowController.window?.makeKeyAndOrderFront(nil)
|
||||
windowController.window?.setCenterPosition(offsetY: 70)
|
||||
return NSApplication.shared.runModal(for: windowController.window!)
|
||||
|
@ -65,7 +65,7 @@ class PreferencesWindowController: PMWindowController {
|
||||
App.shared.preferencesWindowController?.showWindow(self)
|
||||
|
||||
if justCreated {
|
||||
App.shared.preferencesWindowController?.positionWindowInTopLeftCorner()
|
||||
App.shared.preferencesWindowController?.positionWindowInTopRightCorner()
|
||||
}
|
||||
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
|
@ -18,5 +18,6 @@ struct SectionHeaderView: View {
|
||||
.fontWeight(.medium)
|
||||
.foregroundColor(.appSecondary)
|
||||
.background(Color.debug)
|
||||
.minimumScaleFactor(0.8)
|
||||
}
|
||||
}
|
||||
|
@ -60,27 +60,39 @@ struct StatsView: View {
|
||||
.padding(.leading, 30)
|
||||
.padding(.trailing, 30)
|
||||
} else {
|
||||
HStack(alignment: .firstTextBaseline, spacing: 30) {
|
||||
HStack(alignment: .center, spacing: 10) {
|
||||
VStack(alignment: .center, spacing: 3) {
|
||||
SectionHeaderView(text: "mi_memory_limit".localized.uppercased())
|
||||
Text(memoryLimit)
|
||||
.fontWeight(.medium)
|
||||
.font(.system(size: 16))
|
||||
}
|
||||
Divider()
|
||||
VStack(alignment: .center, spacing: 3) {
|
||||
SectionHeaderView(text: "mi_post_max_size".localized.uppercased())
|
||||
Text(maxPostSize)
|
||||
.fontWeight(.medium)
|
||||
.font(.system(size: 16))
|
||||
}
|
||||
Divider()
|
||||
VStack(alignment: .center, spacing: 3) {
|
||||
SectionHeaderView(text: "mi_upload_max_filesize".localized.uppercased())
|
||||
Text(maxUploadSize)
|
||||
.fontWeight(.medium)
|
||||
.font(.system(size: 16))
|
||||
}
|
||||
Divider().hidden()
|
||||
Button {
|
||||
Task { @MainActor in
|
||||
MainMenu.shared.openConfigGUI()
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "gearshape.fill")
|
||||
}
|
||||
.focusable(false)
|
||||
.frame(minWidth: 30, alignment: .center)
|
||||
}
|
||||
.padding(10)
|
||||
.padding(5)
|
||||
.background(Color.debug)
|
||||
}
|
||||
}
|
||||
@ -92,6 +104,6 @@ struct StatsView_Previews: PreviewProvider {
|
||||
memoryLimit: "1024 MB",
|
||||
maxPostSize: "1024 MB",
|
||||
maxUploadSize: "1024 MB"
|
||||
)
|
||||
).frame(height: 100)
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ struct ProgressWindowView: View {
|
||||
window.contentView = NSHostingView(rootView: view)
|
||||
let controller = NSWindowController(window: window)
|
||||
controller.showWindow(nil)
|
||||
controller.positionWindowInTopLeftCorner()
|
||||
controller.positionWindowInTopRightCorner()
|
||||
controller.window?.makeKeyAndOrderFront(self)
|
||||
// NSApp.activate(ignoringOtherApps: true)
|
||||
return controller
|
||||
|
@ -20,7 +20,7 @@ class TerminalProgressWindowController: NSWindowController, NSWindowDelegate {
|
||||
|
||||
windowController.showWindow(windowController)
|
||||
windowController.window?.makeKeyAndOrderFront(nil)
|
||||
windowController.positionWindowInTopLeftCorner()
|
||||
windowController.positionWindowInTopRightCorner()
|
||||
|
||||
windowController.progressView?.labelTitle.stringValue = title
|
||||
windowController.progressView?.labelDescription.stringValue = description
|
||||
|
@ -17,13 +17,13 @@ extension App {
|
||||
onChange: { Task { await self.onHomebrewPhpModification() } }
|
||||
)
|
||||
|
||||
App.shared.watchers[.homebrewBinaries] = notifier
|
||||
App.shared.watchers["homebrewBinaries"] = notifier
|
||||
}
|
||||
|
||||
public func destroyHomebrewWatchers() {
|
||||
// Removing requires termination and then removing reference
|
||||
self.watchers[.homebrewBinaries]?.terminate()
|
||||
self.watchers[.homebrewBinaries] = nil
|
||||
self.watchers["homebrewBinaries"]?.terminate()
|
||||
self.watchers["homebrewBinaries"] = nil
|
||||
}
|
||||
|
||||
public func onHomebrewPhpModification() async {
|
||||
@ -31,10 +31,13 @@ extension App {
|
||||
Log.info("Something changed in the Homebrew binary directory...")
|
||||
await PhpEnvironments.detectPhpVersions()
|
||||
await MainMenu.shared.refreshActiveInstallation()
|
||||
// let new = PhpEnvironments.shared.currentInstall?.version.text
|
||||
|
||||
// TODO:
|
||||
// Check if the new and previous version are different
|
||||
// if so, we can show a notification if needed
|
||||
//
|
||||
// TODO: PHP Guard 2.0
|
||||
// Check if the new and previous version of PHP are different
|
||||
// if so, we can show a notification if needed or alert the user
|
||||
//
|
||||
// let new = PhpEnvironments.shared.currentInstall?.version.text
|
||||
//
|
||||
}
|
||||
}
|
||||
|
@ -10,52 +10,52 @@ import Foundation
|
||||
|
||||
extension App {
|
||||
|
||||
func startWatcher(_ url: URL) {
|
||||
Log.perf("No watcher currently active...")
|
||||
self.watcher = PhpConfigWatcher(for: url)
|
||||
func startWatchManager(_ url: URL) {
|
||||
Log.perf("Starting config watch manager...")
|
||||
self.watchManager = ConfigWatchManager(for: url)
|
||||
|
||||
self.watcher.didChange = { url in
|
||||
self.watchManager.didChange = { url in
|
||||
Log.perf("Something has changed in: \(url)")
|
||||
|
||||
// Check if the watcher has last updated the menu less than 0.75s ago
|
||||
let distance = self.watcher.lastUpdate?.distance(to: Date().timeIntervalSince1970)
|
||||
let distance = self.watchManager.lastUpdate?.distance(to: Date().timeIntervalSince1970)
|
||||
if distance == nil || distance != nil && distance! > 0.75 {
|
||||
Log.perf("Refreshing menu...")
|
||||
Task { @MainActor in MainMenu.shared.reloadPhpMonitorMenuInBackground() }
|
||||
self.watcher.lastUpdate = Date().timeIntervalSince1970
|
||||
self.watchManager.lastUpdate = Date().timeIntervalSince1970
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func handlePhpConfigWatcher(forceReload: Bool = false) {
|
||||
if ActiveFileSystem.shared is TestableFileSystem {
|
||||
Log.warn("FS watcher is disabled when using testable filesystem.")
|
||||
Log.warn("Config watch manager is disabled when using testable filesystem.")
|
||||
return
|
||||
}
|
||||
|
||||
guard let install = PhpEnvironments.phpInstall else {
|
||||
Log.info("It appears as if no PHP installation is currently active.")
|
||||
Log.info("The FS watcher will be disabled until a PHP install is active.")
|
||||
Log.info("The config watch manager be disabled until a PHP install is active.")
|
||||
return
|
||||
}
|
||||
|
||||
let url = URL(fileURLWithPath: "\(Paths.etcPath)/php/\(install.version.short)")
|
||||
|
||||
// Check whether the watcher exists and schedule on the main thread
|
||||
// Check whether the manager exists and schedule on the main thread
|
||||
// if we don't consistently do this, the app will create duplicate watchers
|
||||
// due to timing issues, which creates retain cycles.
|
||||
// due to timing issues, which creates retain cycles
|
||||
Task { @MainActor in
|
||||
// Watcher needs to be created
|
||||
if self.watcher == nil {
|
||||
self.startWatcher(url)
|
||||
if self.watchManager == nil {
|
||||
self.startWatchManager(url)
|
||||
}
|
||||
|
||||
// Watcher needs to be updated
|
||||
if self.watcher.url != url || forceReload {
|
||||
self.watcher.disable()
|
||||
self.watcher = nil
|
||||
if self.watchManager.url != url || forceReload {
|
||||
self.watchManager.disable()
|
||||
self.watchManager = nil
|
||||
Log.perf("Watcher has stopped watching files. Starting new one...")
|
||||
self.startWatcher(url)
|
||||
self.startWatchManager(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
77
phpmon/Domain/Watcher/ConfigFSNotifier.swift
Normal file
77
phpmon/Domain/Watcher/ConfigFSNotifier.swift
Normal file
@ -0,0 +1,77 @@
|
||||
//
|
||||
// ConfigFSNotifier.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 24/10/2023.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class ConfigFSNotifier {
|
||||
|
||||
enum Behaviour {
|
||||
case reloadsMenu
|
||||
case reloadsWatchers
|
||||
}
|
||||
|
||||
private var parent: ConfigWatchManager!
|
||||
|
||||
private var monitoredFolderFileDescriptor: CInt = -1
|
||||
|
||||
private var folderMonitorSource: DispatchSourceFileSystemObject?
|
||||
|
||||
let url: URL
|
||||
|
||||
init(
|
||||
for url: URL,
|
||||
eventMask: DispatchSource.FileSystemEvent,
|
||||
parent: ConfigWatchManager,
|
||||
behaviour: ConfigFSNotifier.Behaviour = .reloadsMenu
|
||||
) {
|
||||
self.url = url
|
||||
self.parent = parent
|
||||
self.startMonitoring(eventMask, behaviour: behaviour)
|
||||
}
|
||||
|
||||
func startMonitoring(
|
||||
_ eventMask: DispatchSource.FileSystemEvent,
|
||||
behaviour: ConfigFSNotifier.Behaviour
|
||||
) {
|
||||
guard folderMonitorSource == nil && monitoredFolderFileDescriptor == -1 else {
|
||||
return
|
||||
}
|
||||
|
||||
monitoredFolderFileDescriptor = open(url.path, O_EVTONLY)
|
||||
folderMonitorSource = DispatchSource.makeFileSystemObjectSource(
|
||||
fileDescriptor: monitoredFolderFileDescriptor,
|
||||
eventMask: eventMask,
|
||||
queue: parent.folderMonitorQueue
|
||||
)
|
||||
|
||||
folderMonitorSource?.setEventHandler { [weak self] in
|
||||
if behaviour == .reloadsWatchers
|
||||
&& !ConfigWatchManager.ignoresModificationsToConfigValues {
|
||||
// Reload all configuration watchers
|
||||
return App.shared.handlePhpConfigWatcher(forceReload: true)
|
||||
}
|
||||
|
||||
|
||||
self?.parent.didChange?(self!.url)
|
||||
}
|
||||
|
||||
folderMonitorSource?.setCancelHandler { [weak self] in
|
||||
guard let self = self else { return }
|
||||
close(self.monitoredFolderFileDescriptor)
|
||||
self.monitoredFolderFileDescriptor = -1
|
||||
self.folderMonitorSource = nil
|
||||
}
|
||||
|
||||
folderMonitorSource?.resume()
|
||||
}
|
||||
|
||||
func stopMonitoring() {
|
||||
folderMonitorSource?.cancel()
|
||||
self.parent = nil
|
||||
}
|
||||
}
|
82
phpmon/Domain/Watcher/ConfigWatchManager.swift
Normal file
82
phpmon/Domain/Watcher/ConfigWatchManager.swift
Normal file
@ -0,0 +1,82 @@
|
||||
//
|
||||
// ConfigWatchManager.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 30/03/2021.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class ConfigWatchManager {
|
||||
|
||||
static var ignoresModificationsToConfigValues: Bool = false
|
||||
|
||||
let folderMonitorQueue = DispatchQueue(label: "FolderMonitorQueue", attributes: .concurrent)
|
||||
|
||||
let url: URL
|
||||
var didChange: ((URL) -> Void)?
|
||||
var lastUpdate: TimeInterval?
|
||||
|
||||
var watchers: [ConfigFSNotifier] = []
|
||||
|
||||
init(for url: URL) {
|
||||
if FileSystem is TestableFileSystem {
|
||||
fatalError("""
|
||||
ConfigWatchManager is currently incompatible with a testable filesystem!"
|
||||
You are not allowed to instantiate these while using a testable filesystem.
|
||||
""")
|
||||
}
|
||||
|
||||
self.url = url
|
||||
|
||||
// Add a watcher for php.ini
|
||||
self.addWatcher(for: self.url.appendingPathComponent("php.ini"), eventMask: .write)
|
||||
|
||||
// Add a watcher for conf.d (in case a new file is added or a file is deleted)
|
||||
// This watcher, when triggered, will restart all watchers
|
||||
self.addWatcher(for: self.url.appendingPathComponent("conf.d"), eventMask: .all, behaviour: .reloadsWatchers)
|
||||
|
||||
// Scan the conf.d folder for .ini files, and add a watcher for each file
|
||||
let filePaths = FileManager.default.enumerator(
|
||||
atPath: self.url.appendingPathComponent("conf.d").path
|
||||
)?.allObjects as! [String]
|
||||
|
||||
// Loop over the .ini files that we discovered
|
||||
filePaths.filter { $0.contains(".ini") }.forEach { (file) in
|
||||
// Add a watcher for each file we have discovered
|
||||
self.addWatcher(for: self.url.appendingPathComponent("conf.d/\(file)"), eventMask: .write)
|
||||
}
|
||||
|
||||
Log.perf("A watcher exists for the following config paths:")
|
||||
Log.perf(self.watchers.map({ watcher in
|
||||
return watcher.url.relativePath
|
||||
}))
|
||||
}
|
||||
|
||||
func addWatcher(
|
||||
for url: URL,
|
||||
eventMask: DispatchSource.FileSystemEvent,
|
||||
behaviour: ConfigFSNotifier.Behaviour = .reloadsMenu
|
||||
) {
|
||||
if !FileSystem.anyExists(url.path) {
|
||||
Log.warn("No watcher was created for \(url.path) because the requested file does not exist.")
|
||||
return
|
||||
}
|
||||
|
||||
let watcher = ConfigFSNotifier(for: url, eventMask: eventMask, parent: self, behaviour: behaviour)
|
||||
self.watchers.append(watcher)
|
||||
}
|
||||
|
||||
func disable() {
|
||||
Log.perf("Turning off all individual existing watchers...")
|
||||
self.watchers.forEach { (watcher) in
|
||||
watcher.stopMonitoring()
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
Log.perf("deinit: \(String(describing: self)).\(#function)")
|
||||
}
|
||||
|
||||
}
|
@ -6,12 +6,9 @@
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import Foundation
|
||||
|
||||
class FSNotifier {
|
||||
enum Kind {
|
||||
case homebrewLocks, homebrewBinaries
|
||||
}
|
||||
|
||||
public static var shared: FSNotifier! = nil
|
||||
|
||||
@ -66,4 +63,5 @@ class FSNotifier {
|
||||
deinit {
|
||||
Log.perf("FSNotifier for \(self.url) will be deinitialized.")
|
||||
}
|
||||
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
//
|
||||
// FolderWatcher.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 30/03/2021.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
class PhpConfigWatcher {
|
||||
|
||||
let folderMonitorQueue = DispatchQueue(label: "FolderMonitorQueue", attributes: .concurrent)
|
||||
|
||||
let url: URL
|
||||
|
||||
var didChange: ((URL) -> Void)?
|
||||
|
||||
var lastUpdate: TimeInterval?
|
||||
|
||||
var watchers: [FSWatcher] = []
|
||||
|
||||
init(for url: URL) {
|
||||
if FileSystem is TestableFileSystem {
|
||||
fatalError("""
|
||||
PhpConfigWatcher is not compatible with testable FS! "
|
||||
You are not allowed to instantiate these while using a testable FS.
|
||||
""")
|
||||
}
|
||||
|
||||
self.url = url
|
||||
|
||||
// Add a watcher for php.ini
|
||||
self.addWatcher(for: self.url.appendingPathComponent("php.ini"), eventMask: .write)
|
||||
|
||||
// Add a watcher for conf.d (in case a new file is added or a file is deleted)
|
||||
// This watcher, when triggered, will restart all watchers
|
||||
self.addWatcher(for: self.url.appendingPathComponent("conf.d"), eventMask: .all, behaviour: .reloadsWatchers)
|
||||
|
||||
// Scan the conf.d folder for .ini files, and add a watcher for each file
|
||||
let enumerator = FileManager.default.enumerator(atPath: self.url.appendingPathComponent("conf.d").path)
|
||||
let filePaths = enumerator?.allObjects as! [String]
|
||||
|
||||
// Loop over the .ini files that we discovered
|
||||
filePaths.filter { $0.contains(".ini") }.forEach { (file) in
|
||||
// Add a watcher for each file we have discovered
|
||||
self.addWatcher(for: self.url.appendingPathComponent("conf.d/\(file)"), eventMask: .write)
|
||||
}
|
||||
|
||||
Log.perf("A watcher exists for the following config paths:")
|
||||
Log.perf(self.watchers.map({ watcher in
|
||||
return watcher.url.relativePath
|
||||
}))
|
||||
}
|
||||
|
||||
func addWatcher(
|
||||
for url: URL,
|
||||
eventMask: DispatchSource.FileSystemEvent,
|
||||
behaviour: FSWatcherBehaviour = .reloadsMenu
|
||||
) {
|
||||
if !FileSystem.anyExists(url.path) {
|
||||
Log.warn("No watcher was created for \(url.path) because the requested file does not exist.")
|
||||
return
|
||||
}
|
||||
|
||||
let watcher = FSWatcher(for: url, eventMask: eventMask, parent: self, behaviour: behaviour)
|
||||
self.watchers.append(watcher)
|
||||
}
|
||||
|
||||
func disable() {
|
||||
Log.perf("Turning off all individual existing watchers...")
|
||||
self.watchers.forEach { (watcher) in
|
||||
watcher.stopMonitoring()
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
Log.perf("deinit: \(String(describing: self)).\(#function)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
enum FSWatcherBehaviour {
|
||||
case reloadsMenu
|
||||
case reloadsWatchers
|
||||
}
|
||||
|
||||
class FSWatcher {
|
||||
|
||||
private var parent: PhpConfigWatcher!
|
||||
|
||||
private var monitoredFolderFileDescriptor: CInt = -1
|
||||
|
||||
private var folderMonitorSource: DispatchSourceFileSystemObject?
|
||||
|
||||
let url: URL
|
||||
|
||||
init(
|
||||
for url: URL,
|
||||
eventMask: DispatchSource.FileSystemEvent,
|
||||
parent: PhpConfigWatcher,
|
||||
behaviour: FSWatcherBehaviour = .reloadsMenu
|
||||
) {
|
||||
self.url = url
|
||||
self.parent = parent
|
||||
self.startMonitoring(eventMask, behaviour: behaviour)
|
||||
}
|
||||
|
||||
func startMonitoring(
|
||||
_ eventMask: DispatchSource.FileSystemEvent,
|
||||
behaviour: FSWatcherBehaviour
|
||||
) {
|
||||
guard folderMonitorSource == nil && monitoredFolderFileDescriptor == -1 else {
|
||||
return
|
||||
}
|
||||
|
||||
// Open the file or folder referenced by URL for monitoring only.
|
||||
monitoredFolderFileDescriptor = open(url.path, O_EVTONLY)
|
||||
folderMonitorSource = DispatchSource.makeFileSystemObjectSource(
|
||||
fileDescriptor: monitoredFolderFileDescriptor,
|
||||
eventMask: eventMask,
|
||||
queue: parent.folderMonitorQueue
|
||||
)
|
||||
|
||||
// Define the block to call when a file change is detected.
|
||||
folderMonitorSource?.setEventHandler { [weak self] in
|
||||
// The default behaviour is to reload the menu
|
||||
switch behaviour {
|
||||
case .reloadsMenu:
|
||||
// Default behaviour: reload the menu items
|
||||
self?.parent.didChange?(self!.url)
|
||||
case .reloadsWatchers:
|
||||
// Alternative behaviour: reload all watchers
|
||||
App.shared.handlePhpConfigWatcher(forceReload: true)
|
||||
}
|
||||
}
|
||||
|
||||
// Define a cancel handler to ensure the directory is closed when the source is cancelled.
|
||||
folderMonitorSource?.setCancelHandler { [weak self] in
|
||||
guard let self = self else { return }
|
||||
close(self.monitoredFolderFileDescriptor)
|
||||
self.monitoredFolderFileDescriptor = -1
|
||||
self.folderMonitorSource = nil
|
||||
}
|
||||
|
||||
// Start monitoring the directory via the source.
|
||||
folderMonitorSource?.resume()
|
||||
}
|
||||
|
||||
func stopMonitoring() {
|
||||
folderMonitorSource?.cancel()
|
||||
self.parent = nil
|
||||
}
|
||||
}
|
@ -85,6 +85,7 @@ class DomainListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource
|
||||
|
||||
App.shared.domainListWindowController!.showWindow(self)
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
App.shared.domainListWindowController?.window?.orderFrontRegardless()
|
||||
}
|
||||
|
||||
// MARK: - Lifecycle
|
||||
|
@ -31,7 +31,7 @@ struct OnboardingTextItem: View {
|
||||
.opacity(self.unavailable ? 0.5 : 1)
|
||||
Text(description.localizedForSwiftUI)
|
||||
.foregroundColor(Color.secondary)
|
||||
.font(.system(size: 13))
|
||||
.font(.system(size: 12))
|
||||
.lineLimit(4)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.frame(minWidth: 0, maxWidth: 800, alignment: .leading)
|
||||
@ -51,7 +51,7 @@ struct OnboardingView: View {
|
||||
HStack {
|
||||
Image(nsImage: NSApp.applicationIconImage)
|
||||
.resizable()
|
||||
.frame(width: 80, height: 80)
|
||||
.frame(width: 100, height: 100)
|
||||
.padding(.bottom, 5)
|
||||
.padding(.trailing, 25)
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
@ -126,13 +126,16 @@ struct OnboardingView: View {
|
||||
Button("onboarding.tour.close".localized) {
|
||||
App.shared.onboardingWindowController?.close()
|
||||
}
|
||||
.padding(.bottom, 5)
|
||||
.padding(.bottom, 15)
|
||||
.padding(.top, 10)
|
||||
}
|
||||
}
|
||||
.padding(.leading)
|
||||
.padding(.trailing)
|
||||
.padding(.bottom, 0)
|
||||
}
|
||||
.frame(width: 600)
|
||||
.fixedSize(horizontal: true, vertical: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ class OnboardingWindowController: PMWindowController {
|
||||
window.titlebarAppearsTransparent = true
|
||||
window.delegate = delegate ?? windowController
|
||||
window.contentView = NSHostingView(rootView: OnboardingView())
|
||||
window.setContentSize(NSSize(width: 600, height: 600))
|
||||
window.setContentSize(window.contentView!.fittingSize)
|
||||
|
||||
App.shared.onboardingWindowController = windowController
|
||||
}
|
||||
|
@ -52,7 +52,20 @@ class BytePhpPreference: PhpPreference {
|
||||
// MARK: Save Value
|
||||
|
||||
private func updatedFieldValue() {
|
||||
internalValue = "\(value)\(unit.rawValue)"
|
||||
if value == -1 {
|
||||
// In case we're dealing with unlimited value, we don't need a unit
|
||||
internalValue = "-1"
|
||||
} else {
|
||||
// We need to append the unit otherwise
|
||||
internalValue = "\(value)\(unit.rawValue)"
|
||||
}
|
||||
|
||||
do {
|
||||
try PhpPreference.persistToIniFile(key: self.key, value: self.internalValue)
|
||||
Log.info("The preference \(key) was updated to: \(value)")
|
||||
} catch {
|
||||
Log.info("The preference \(key) could not be updated")
|
||||
}
|
||||
}
|
||||
|
||||
public static func readFrom(internalValue: String) -> (UnitOption, Int)? {
|
||||
|
@ -15,6 +15,14 @@ class PhpPreference {
|
||||
init(key: String) {
|
||||
self.key = key
|
||||
}
|
||||
|
||||
internal static func persistToIniFile(key: String, value: String) throws {
|
||||
if let file = PhpEnvironments.shared.getConfigFile(forKey: key) {
|
||||
return try file.replace(key: key, value: value)
|
||||
}
|
||||
|
||||
throw PhpConfigurationFile.ReplacementErrors.missingFile
|
||||
}
|
||||
}
|
||||
|
||||
class BoolPhpPreference: PhpPreference {
|
||||
|
@ -35,12 +35,12 @@ struct PreferenceContainer<ControlView: View>: View {
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
controlView
|
||||
|
||||
Text(self.description.localizedForSwiftUI)
|
||||
.lineLimit(nil)
|
||||
.font(.subheadline)
|
||||
.foregroundColor(Color.secondary)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .topLeading)
|
||||
}
|
||||
}
|
||||
.padding(5)
|
||||
@ -51,6 +51,7 @@ struct ByteLimitView: View {
|
||||
@State private var unit: BytePhpPreference.UnitOption
|
||||
@State private var numberText: String
|
||||
@State private var unlimited: Bool
|
||||
@State private var timer: Timer?
|
||||
|
||||
private var preference: BytePhpPreference
|
||||
|
||||
@ -65,9 +66,11 @@ struct ByteLimitView: View {
|
||||
if !unlimited {
|
||||
HStack {
|
||||
TextField("", text: $numberText)
|
||||
.onChange(of: numberText) { newText in
|
||||
self.preference.value = Int(newText) ?? 256
|
||||
print(self.preference.internalValue)
|
||||
.onChange(of: numberText) { [weak preference] newText in
|
||||
timer?.invalidate()
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { _ in
|
||||
preference?.value = Int(newText) ?? 256
|
||||
}
|
||||
}
|
||||
Picker("Limit Name", selection: $unit) {
|
||||
ForEach(BytePhpPreference.UnitOption.allCases, id: \.self) {
|
||||
@ -79,22 +82,32 @@ struct ByteLimitView: View {
|
||||
.pickerStyle(.menu)
|
||||
.onChange(of: unit) { newValue in
|
||||
self.preference.unit = newValue
|
||||
print(self.preference.internalValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Toggle(isOn: $unlimited) {
|
||||
Label("Allow unlimited usage", systemImage: "heart").labelStyle(.titleOnly)
|
||||
}
|
||||
Text("confman.byte_limit.unlimited".localizedForSwiftUI)
|
||||
}.onChange(of: unlimited, perform: { [weak preference] unlimited in
|
||||
timer?.invalidate()
|
||||
timer = Timer.scheduledTimer(withTimeInterval: 0.8, repeats: false) { _ in
|
||||
preference?.value = unlimited ? -1 : 512
|
||||
preference?.unit = .megabyte
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct ByteLimitView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
PreferenceContainer(name: "Max Size", description: "Some maximum size") {
|
||||
PreferenceContainer(
|
||||
name: "Max Size",
|
||||
description:
|
||||
"Here's an extensive description that is obviously way too long but it should wrap." +
|
||||
"The point of the wrapping text is that is allows us to see what's going on with the layout here."
|
||||
) {
|
||||
ByteLimitView(preference: BytePhpPreference(key: "max_memory"))
|
||||
}
|
||||
}.frame(width: 600, height: 200)
|
||||
|
||||
ConfigManagerView()
|
||||
.frame(width: 600, height: .infinity)
|
||||
|
@ -13,14 +13,14 @@ struct ConfigManagerView: View {
|
||||
var preferences: [PhpPreference] = [
|
||||
BytePhpPreference(key: "memory_limit"),
|
||||
BytePhpPreference(key: "post_max_size"),
|
||||
BoolPhpPreference(key: "file_uploads"),
|
||||
// BoolPhpPreference(key: "file_uploads"),
|
||||
BytePhpPreference(key: "upload_max_filesize")
|
||||
]
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack(alignment: .center, spacing: 15) {
|
||||
Image(systemName: "square.and.pencil.circle.fill")
|
||||
Image(systemName: "gearshape.fill")
|
||||
.resizable()
|
||||
.frame(width: 40, height: 40)
|
||||
.foregroundColor(Color.blue)
|
||||
@ -51,6 +51,7 @@ struct ConfigManagerView: View {
|
||||
if let preference = preference as? BytePhpPreference {
|
||||
ByteLimitView(preference: preference)
|
||||
}
|
||||
/*
|
||||
if let preference = preference as? BoolPhpPreference {
|
||||
Toggle("", isOn: preference.$value)
|
||||
.toggleStyle(.switch)
|
||||
@ -59,6 +60,7 @@ struct ConfigManagerView: View {
|
||||
if let preference = preference as? StringPhpPreference {
|
||||
TextField("Placeholder", text: preference.$value)
|
||||
}
|
||||
*/
|
||||
}.frame(maxWidth: .infinity)
|
||||
}
|
||||
}.padding(10)
|
||||
@ -67,7 +69,7 @@ struct ConfigManagerView: View {
|
||||
|
||||
VStack(alignment: .trailing) {
|
||||
Button("Close", action: {
|
||||
|
||||
App.shared.phpConfigManagerWindowController?.close()
|
||||
})
|
||||
}
|
||||
.padding(.vertical, 10)
|
||||
@ -78,7 +80,7 @@ struct ConfigManagerView: View {
|
||||
alignment: .topTrailing
|
||||
)
|
||||
}
|
||||
}
|
||||
}.frame(maxHeight: 485)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,46 @@
|
||||
//
|
||||
// ConfigManagerWindowController.swift
|
||||
// PHP Monitor
|
||||
//
|
||||
// Created by Nico Verbruggen on 12/09/2023.
|
||||
// Copyright © 2023 Nico Verbruggen. All rights reserved.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import SwiftUI
|
||||
|
||||
class PhpConfigManagerWindowController: PMWindowController {
|
||||
|
||||
// MARK: - Window Identifier
|
||||
|
||||
override var windowName: String {
|
||||
return "ConfigManager"
|
||||
}
|
||||
|
||||
public static func create(delegate: NSWindowDelegate?) {
|
||||
let windowController = Self()
|
||||
windowController.window = NSWindow()
|
||||
|
||||
guard let window = windowController.window else { return }
|
||||
window.title = ""
|
||||
window.styleMask = [.titled, .closable, .miniaturizable]
|
||||
window.titlebarAppearsTransparent = true
|
||||
window.delegate = delegate ?? windowController
|
||||
window.contentView = NSHostingView(rootView: ConfigManagerView())
|
||||
window.setContentSize(NSSize(width: 600, height: 480))
|
||||
|
||||
App.shared.phpConfigManagerWindowController = windowController
|
||||
}
|
||||
|
||||
public static func show(delegate: NSWindowDelegate? = nil) {
|
||||
if App.shared.phpConfigManagerWindowController == nil {
|
||||
Self.create(delegate: delegate)
|
||||
}
|
||||
|
||||
App.shared.phpConfigManagerWindowController?.showWindow(self)
|
||||
App.shared.phpConfigManagerWindowController?.positionWindowInTopRightCorner()
|
||||
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
App.shared.phpConfigManagerWindowController?.window?.orderFrontRegardless()
|
||||
}
|
||||
}
|
@ -89,8 +89,10 @@ struct PhpDoctorView: View {
|
||||
}
|
||||
.listRowInsets(EdgeInsets())
|
||||
.listStyle(.plain)
|
||||
.frame(maxHeight: .infinity, alignment: .top)
|
||||
.frame(minHeight: 350, maxHeight: .infinity, alignment: .top)
|
||||
}
|
||||
.frame(width: 600)
|
||||
.fixedSize(horizontal: true, vertical: false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ class PhpDoctorWindowController: PMWindowController {
|
||||
window.titlebarAppearsTransparent = true
|
||||
window.delegate = delegate ?? windowController
|
||||
window.contentView = NSHostingView(rootView: PhpDoctorView())
|
||||
window.setContentSize(NSSize(width: 600, height: 480))
|
||||
window.setContentSize(window.contentView!.fittingSize)
|
||||
|
||||
App.shared.phpDoctorWindowController = windowController
|
||||
}
|
||||
@ -41,5 +41,6 @@ class PhpDoctorWindowController: PMWindowController {
|
||||
App.shared.phpDoctorWindowController?.window?.setCenterPosition(offsetY: 70)
|
||||
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
App.shared.phpDoctorWindowController?.window?.orderFrontRegardless()
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +157,11 @@ struct PhpVersionManagerView: View {
|
||||
}
|
||||
}
|
||||
|
||||
if formula.isInstalled && formula.hasUpgrade {
|
||||
if formula.hasUpgradedFormulaAlias {
|
||||
Text("phpman.version.automatic_upgrade".localized(formula.shortVersion!))
|
||||
.font(.system(size: 11))
|
||||
.foregroundColor(.gray)
|
||||
} else if formula.isInstalled && formula.hasUpgrade {
|
||||
Text("phpman.version.has_update".localized(
|
||||
formula.installedVersion!,
|
||||
formula.upgradeVersion!
|
||||
@ -195,7 +199,7 @@ struct PhpVersionManagerView: View {
|
||||
} else {
|
||||
Button("phpman.buttons.install".localizedForSwiftUI) {
|
||||
Task { await self.install(formula) }
|
||||
}
|
||||
}.disabled(formula.hasUpgradedFormulaAlias)
|
||||
}
|
||||
}
|
||||
.listRowBackground(index % 2 == 0 ? Color.gray.opacity(0): Color.gray.opacity(0.08))
|
||||
@ -330,18 +334,9 @@ struct PhpVersionManagerView: View {
|
||||
}
|
||||
|
||||
public func setBusyStatus(_ busy: Bool) {
|
||||
PhpEnvironments.shared.isBusy = busy
|
||||
if busy {
|
||||
Task { @MainActor in
|
||||
MainMenu.shared.setBusyImage()
|
||||
MainMenu.shared.rebuild()
|
||||
self.status.busy = busy
|
||||
}
|
||||
} else {
|
||||
Task { @MainActor in
|
||||
MainMenu.shared.updatePhpVersionInStatusBar()
|
||||
self.status.busy = busy
|
||||
}
|
||||
Task { @MainActor in
|
||||
PhpEnvironments.shared.isBusy = busy
|
||||
self.status.busy = busy
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,10 @@ class PhpVersionManagerWindowController: PMWindowController {
|
||||
}
|
||||
|
||||
App.shared.phpVersionManagerWindowController?.showWindow(self)
|
||||
App.shared.phpVersionManagerWindowController?.positionWindowInTopLeftCorner()
|
||||
App.shared.phpVersionManagerWindowController?.positionWindowInTopRightCorner()
|
||||
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
|
||||
App.shared.phpVersionManagerWindowController?.window?.orderFrontRegardless()
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,7 @@
|
||||
"phpman.version.has_update" = "Version %@ installiert, %@ verfügbar.";
|
||||
"phpman.version.installed" = "Version %@ ist derzeit installiert.";
|
||||
"phpman.version.available_for_installation" = "Diese Version kann installiert werden.";
|
||||
"phpman.version.automatic_upgrade" = "Diese Version wird automatisch installiert, indem eine ältere Version aktualisiert wird.";
|
||||
"phpman.buttons.uninstall" = "Deinstallieren";
|
||||
"phpman.buttons.install" = "Installieren";
|
||||
"phpman.buttons.update" = "Aktualisieren";
|
||||
@ -653,6 +654,11 @@ Wenn Sie diese Meldung sehen, aber nicht wissen, warum dieser Ordner verschwunde
|
||||
"startup.errors.which_alias_issue.subtitle" = "Es scheint, dass es eine Datei in `/usr/local/bin/which` gibt. Diese wird normalerweise von NodeJS eingerichtet, aber `node` ist nicht im PATH in `/usr/local/bin`. Um dies zu beheben, lesen Sie weiter.";
|
||||
"startup.errors.which_alias_issue.desc" = "Sie müssen einen Symlink von `node` in das Verzeichnis `/usr/local/bin` setzen, um sicherzustellen, dass PHP Monitor erfolgreich starten kann. Für weitere Informationen siehe: https://github.com/nicoverbruggen/phpmon/issues/174";
|
||||
|
||||
// Laravel Herd conflicts
|
||||
"startup.errors.herd_running.title" = "Laravel Herd scheint aktiv zu sein";
|
||||
"startup.errors.herd_running.subtitle" = "Es scheint, dass Laravel Herd derzeit aktiv ist. Die integrierte Valet-Konfiguration von Herd kann mit Ihrer regulären Valet-Installation kollidieren. Beenden Sie daher Herd, bevor Sie fortfahren. (Sie können Herd und reguläres Valet problemlos kombinieren, sollten sie jedoch nicht gleichzeitig ausführen.)";
|
||||
"startup.errors.herd_running.desc" = "Möglicherweise stellt der von Herd zu Ihrem $PATH hinzugefügte `php`-Alias eine Behinderung für das Aliasen von PHP Monitor als `php` dar. Beachten Sie dies bitte. Schauen Sie in die Datei `~/.zshrc`, um zu sehen, was Herd zu Ihrem $PATH hinzugefügt hat.";
|
||||
|
||||
// Warning about a different PHP version linked than last time
|
||||
"startup.version_mismatch.title" = "Die aktive PHP-Version hat sich geändert.";
|
||||
"startup.version_mismatch.subtitle" = "Seitdem PHP Monitor das letzte Mal aktiv war, wurde Ihre verlinkte PHP-Version auf PHP %@ geändert. Möchten Sie zurück zu PHP %@ wechseln oder möchten Sie die aktuelle Version weiter verwenden?";
|
||||
|
@ -13,6 +13,8 @@
|
||||
"mi_fix_php_link" = "Fix Automatically...";
|
||||
"mi_no_php_linked_explain" = "What's This?";
|
||||
"mi_php_version_manager" = "PHP Version Manager...";
|
||||
"mi_php_config_manager" = "PHP Configuration Editor...";
|
||||
"mi_manage_limits" = "Manage Limits...";
|
||||
|
||||
"mi_diagnostics" = "Diagnostics";
|
||||
"mi_active_services" = "Active Services";
|
||||
@ -84,7 +86,8 @@
|
||||
// CONFMAN
|
||||
|
||||
"confman.title" = "PHP Configuration Editor";
|
||||
"confman.description" = "This feature lets you customize your PHP installation with ease. Changes are automatically applied.";
|
||||
"confman.description" = "This feature lets you customize your PHP installation's configuration with ease.\nPlease note that any changes you make are immediately and automatically applied.";
|
||||
"confman.byte_limit.unlimited" = "Allow unlimited usage";
|
||||
|
||||
"php_ini.memory_limit.title" = "Memory Limit";
|
||||
"php_ini.memory_limit.description" = "This sets the maximum amount of memory in bytes that a script is allowed to allocate. This helps prevent poorly written scripts for eating up all available memory on a server.";
|
||||
@ -104,6 +107,7 @@
|
||||
"phpman.version.has_update" = "Version %@ installed, %@ available.";
|
||||
"phpman.version.installed" = "Version %@ is currently installed.";
|
||||
"phpman.version.available_for_installation" = "This version can be installed.";
|
||||
"phpman.version.automatic_upgrade" = "This version will be automatically installed by upgrading an older version.";
|
||||
"phpman.buttons.uninstall" = "Uninstall";
|
||||
"phpman.buttons.install" = "Install";
|
||||
"phpman.buttons.update" = "Update";
|
||||
@ -667,6 +671,11 @@ If you are seeing this message but are confused why this folder has gone missing
|
||||
"startup.errors.which_alias_issue.subtitle" = "It appears that there's a file in `/usr/local/bin/which`. This is usually set up by NodeJS, but `node` isn't in the PATH in `/usr/local/bin`. To fix this, keep reading.";
|
||||
"startup.errors.which_alias_issue.desc" = "You will need to symlink `node` into the `/usr/local/bin` directory to make sure PHP Monitor can start successfully. For more info, see: https://github.com/nicoverbruggen/phpmon/issues/174";
|
||||
|
||||
/// Laravel Herd conflicts
|
||||
"startup.errors.herd_running.title" = "Laravel Herd appears to be running";
|
||||
"startup.errors.herd_running.subtitle" = "It seems that Laravel Herd is currently running. Herd's built-in Valet setup may conflict with your regular Valet installation, so please quit Herd before continuing. (You can perfectly mix usage of Herd and regular Valet but you shouldn't run both at the same time.)";
|
||||
"startup.errors.herd_running.desc" = "You may also find that the `php` alias by Herd added to your $PATH may prevent `php` aliasing of PHP Monitor from working, so keep that in mind. You can check out `~/.zshrc` and see what Herd has added to your $PATH.";
|
||||
|
||||
// Warning about a different PHP version linked than last time
|
||||
"startup.version_mismatch.title" = "Your active PHP version has changed.";
|
||||
"startup.version_mismatch.subtitle" = "Since PHP Monitor was last active, your linked PHP version has been changed to PHP %@. Would you like to switch back to PHP %@, or do you want to keep using the current version?";
|
||||
|
805
phpmon/fr.lproj/Localizable.strings
Normal file
805
phpmon/fr.lproj/Localizable.strings
Normal file
@ -0,0 +1,805 @@
|
||||
// MENU ITEMS (MI)
|
||||
|
||||
"mi_busy" = "PHP Monitor est occupé...";
|
||||
"mi_unsure" = "Nous ne sommes pas sûrs de quelle version de PHP vous utilisez.";
|
||||
"mi_php_version" = "Version globale: PHP";
|
||||
"mi_php_switch" = "Passer à PHP";
|
||||
"mi_php_unsupported" = "Certaines versions de PHP installées ne sont pas affichées.";
|
||||
"mi_php_broken_1" = "Oups ! Il semblerait que votre installation de PHP soit endommagée...";
|
||||
"mi_php_broken_2" = "Essayez d'exécuter `php -v` dans votre terminal.";
|
||||
"mi_php_broken_3" = "Vous pouvez également essayer de passer à une autre version.";
|
||||
"mi_php_broken_4" = "Exécuter `brew reinstall php` (ou la commande équivalente pour votre version désirée) pourrait aider.";
|
||||
"mi_no_php_linked" = "Aucune version de PHP n'est liée !";
|
||||
"mi_fix_php_link" = "Réparer Automatiquement...";
|
||||
"mi_no_php_linked_explain" = "Qu'est-ce que c'est ?";
|
||||
"mi_php_version_manager" = "Gestionnaire de Versions PHP...";
|
||||
"mi_php_config_manager" = "Éditeur de Configuration PHP...";
|
||||
"mi_manage_limits" = "Gérer les Limites...";
|
||||
|
||||
"mi_diagnostics" = "Diagnostiques";
|
||||
"mi_active_services" = "Services actifs";
|
||||
"mi_restart_php_fpm" = "Redémarrer le service: php";
|
||||
"mi_restart_nginx" = "Redémarrer le service: nginx";
|
||||
"mi_restart_dnsmasq" = "Redémarrer le service: dnsmasq";
|
||||
"mi_manage_services" = "Gérer les services";
|
||||
"mi_restart_valet_services" = "Redémarrer les services Valet";
|
||||
"mi_stop_valet_services" = "Arrêter les services Valet";
|
||||
|
||||
"mi_fix_my_valet" = "Réparer mon Valet...";
|
||||
"mi_fix_my_valet_tooltip" = "Un problème avec votre installation de Valet ? Essayez les correctifs automatiques de PHP Monitor qui vous permettront d'être à nouveau opérationnel en un rien de temps !";
|
||||
"mi_fix_brew_permissions" = "Restaurer les permissions Homebrew";
|
||||
"mi_fix_brew_permissions_tooltip" = "Des problèmes de permission lors de l'exécution de `brew upgrade` ? PHP Monitor vient à votre rescousse !";
|
||||
|
||||
"mi_php_refresh" = "Actualiser les informations";
|
||||
|
||||
"mi_configuration" = "Configuration PHP";
|
||||
"mi_limits" = "Configuration des limites";
|
||||
"mi_memory_limit" = "Limite de mémoire";
|
||||
"mi_post_max_size" = "Taille maximale POST";
|
||||
"mi_upload_max_filesize" = "Taille maximal d'upload";
|
||||
"mi_manual_actions" = "Actions manuelles";
|
||||
"mi_services" = "Services";
|
||||
"mi_other" = "Dépannage & services";
|
||||
"mi_first_aid" = "Dépannage";
|
||||
|
||||
"mi_xdebug_mode" = "Gérer Xdebug";
|
||||
|
||||
"mi_composer" = "Composer";
|
||||
"mi_valet_config" = "Localiser le dossier Valet (.config/valet)";
|
||||
"mi_php_config" = "Localiser le fichier de configuration de PHP (php.ini)";
|
||||
"mi_phpmon_config" = "Localiser le dossier de PHP Monitor (.config/phpmon)";
|
||||
"mi_global_composer" = "Localiser le fichier Composer global (.composer)";
|
||||
"mi_phpinfo" = "Afficher la configuration actuelle (phpinfo)";
|
||||
"mi_update_global_composer" = "Mettre à jour les dépendances globales de Composer...";
|
||||
"mi_detected_extensions" = "Extensions détectées";
|
||||
"mi_no_extensions_detected" = "Aucune extension supplémentaire détectée.";
|
||||
|
||||
"mi_php_doctor" = "PHP Doctor";
|
||||
"mi_fa_php_doctor" = "Ouvrir PHP Doctor...";
|
||||
"mi_recommendations_count" = "%i problèmes(s) détecté(s)!";
|
||||
"mi_view_recommendations" = "Afficher les recommandations...";
|
||||
|
||||
"mi_valet" = "Laravel Valet";
|
||||
"mi_domain_list" = "Afficher la liste des domaines...";
|
||||
|
||||
"mi_preferences" = "Préférences...";
|
||||
"mi_donate" = "Faire un don...";
|
||||
"mi_check_for_updates" = "Vérifier les mises à jour...";
|
||||
"mi_lite_mode" = "À propos du mode Standalone...";
|
||||
"mi_quit" = "Quitter PHP Monitor";
|
||||
"mi_about" = "À propos de PHP Monitor";
|
||||
|
||||
"mi_presets_title" = "Paramètres de configuration";
|
||||
"mi_apply_presets_title" = "Appliquer les paramètres de configuration";
|
||||
"mi_revert_to_prev_config" = "Revenir à la configuration précédente...";
|
||||
"mi_profiles_loaded" = "%i profils chargés à partir du fichier de configuration";
|
||||
|
||||
"mi_no_presets" = "Aucun paramètre disponible.";
|
||||
"mi_set_up_presets" = "En savoir plus sur les paramètres...";
|
||||
|
||||
"mi_view_onboarding" = "Ouvrir la visite guidée de bienvenue...";
|
||||
|
||||
"mi_xdebug_available_modes" = "Modes disponibles";
|
||||
"mi_xdebug_actions" = "Actions";
|
||||
"mi_xdebug_disable_all" = "Désactiver tous les modes";
|
||||
|
||||
// CONFMAN
|
||||
|
||||
"confman.title" = "Éditeur de configuration PHP";
|
||||
"confman.description" = "Cette fonction vous permet de personnaliser facilement votre installation PHP. Les modifications sont appliquées automatiquement.";
|
||||
"confman.byte_limit.unlimited" = "Autoriser l'utilisation sans limite";
|
||||
|
||||
"php_ini.memory_limit.title" = "Limite de mémoire";
|
||||
"php_ini.memory_limit.description" = "Ce paramètre définit la quantité maximale de mémoire (en octets) qu'un script est autorisé à allouer. Cela permet d'éviter que des scripts mal écrits ne consomment toute la mémoire disponible sur un serveur.";
|
||||
"php_ini.post_max_size.title" = "POST Taille maximale";
|
||||
"php_ini.post_max_size.description" = "Définit la taille maximale des message POST autorisées. Ce paramètre affecte également le téléchargement montant de fichiers. Pour envoyer des fichiers volumineux, cette valeur doit être supérieure à la taille maximale de téléchargement montant. D'une manière générale, la limite de mémoire doit être supérieure à la taille maximale des messages POST.";
|
||||
"php_ini.file_uploads.title" = "Téléchargement montant de fichiers";
|
||||
"php_ini.file_uploads.description" = "Activer ou désactiver complètement les téléchargements montant de fichiers. Il est recommandé de laisser cette option activée.";
|
||||
"php_ini.upload_max_filesize.title" = "Taille maximale de téléchargement montant";
|
||||
"php_ini.upload_max_filesize.description" = "Taille maximale d'un téléchargement montant. La taille maximale POST doit être supérieure à cette valeur.";
|
||||
|
||||
// PHPMAN
|
||||
|
||||
"phpman.busy.title" = "Vérification des mises à jour en cours !";
|
||||
"phpman.busy.description.outdated" = "Vérification des versions PHP obsolètes en cours...";
|
||||
|
||||
"phpman.version.broken" = "Cette version semble être endommagée. Vous pouvez tenter de la réparer.";
|
||||
"phpman.version.has_update" = "Version %@ installée, %@ disponible.";
|
||||
"phpman.version.installed" = "La version %@ est actuellement installée.";
|
||||
"phpman.version.available_for_installation" = "Cette version peut être installée.";
|
||||
"phpman.version.automatic_upgrade" = "Cette version sera installée automatiquement en mettant à jour une version plus ancienne.";
|
||||
"phpman.buttons.uninstall" = "Désinstaller";
|
||||
"phpman.buttons.install" = "Installer";
|
||||
"phpman.buttons.update" = "Mettre à jour";
|
||||
"phpman.buttons.repair" = "Réparer";
|
||||
"phpman.version.prerelease" = "Pré-version";
|
||||
|
||||
"phpman.title" = "Gestionnaire de versions PHP";
|
||||
"phpman.description" = "Le **gestionnaire de versions PHP** vous permet d'installer, de mettre à niveau et de supprimer différentes versions de PHP via Homebrew sans avoir à exécuter les commandes vous-même dans le terminal.";
|
||||
"phpman.disclaimer" = "Veuillez noter que l'installation ou la mise à niveau des versions de PHP peut entraîner la mise à niveau d'autres packages Homebrew. La plupart des étapes d'installation prennent généralement un certain temps, donc veuillez patienter pendant que Homebrew fait son travail.";
|
||||
"phpman.refresh.button" = "Rechercher des mises à jour";
|
||||
"phpman.refresh.button.description" = "Vous pouvez appuyer sur le bouton de rafraîchissement pour vérifier si des mises à jour sont disponibles pour les versions de PHP installées.";
|
||||
|
||||
"phpman.has_updates.description" = "Une ou plusieurs mises à jour sont disponibles. (Veuillez noter que PHP Monitor installera ou mettra toujours à jour les versions de PHP en bloc, vous mettrez donc à jour toutes les installations en une seule fois.)";
|
||||
"phpman.has_updates.button" = "Tout mettre à jour";
|
||||
|
||||
"phpman.warnings.unsupported.title" = "Votre version de Homebrew peut causer des problèmes";
|
||||
"phpman.warnings.unsupported.desc" = "Aucune fonctionnalité n'est désactivée, mais certaines commandes peuvent ne pas fonctionner comme prévu. Vous utilisez actuellement Homebrew %@.
|
||||
|
||||
Actuellement, Homebrew 4 est la seule version prise en charge par le gestionnaire de versions PHP. Si vous utilisez une version plus récente de Homebrew, vous pouvez vérifier si une version plus récente de PHP Monitor est disponible.";
|
||||
|
||||
"phpman.warnings.removal.title" = "Êtes-vous sûr de vouloir désinstaller %@ ?";
|
||||
"phpman.warnings.removal.desc" = "Veuillez noter que les fichiers de configuration ne seront pas supprimés, il sera donc facile de réinstaller ultérieurement si nécessaire.
|
||||
|
||||
Il se peut que vous deviez saisir votre mot de passe pendant le processus de désinstallation si les autorisations des fichiers ne permettent pas une suppression simple.";
|
||||
"phpman.warnings.removal.button" = "Désinstaller";
|
||||
|
||||
"phpman.failures.install.title" = "L'installation a échoué !";
|
||||
"phpman.failures.install.desc" = "Malheureusement, l'opération a renvoyé un code d'erreur pour une raison inconnue. Il se peut que les formules aient été correctement installées ou mises à niveau. Malheureusement, je ne peux pas faire grand-chose à ce sujet. Veuillez consulter les derniers messages de Homebrew ici pour plus d'informations sur ce qui s'est passé :
|
||||
|
||||
%@";
|
||||
|
||||
"phpman.action_prevented_busy.title" = "PHP Monitor est actuellement occupé.";
|
||||
"phpman.action_prevented_busy.desc" = "PHP Monitor est actuellement occupé à effectuer une opération telle que le changement de versions de PHP. Pour garantir que votre système ne se casse pas, vous devez attendre que PHP Monitor soit prêt avant de réessayer.";
|
||||
|
||||
"phpman.uninstall_prevented.title" = "Vous ne pouvez pas désinstaller la version de PHP actuellement active via PHP Monitor.";
|
||||
"phpman.uninstall_prevented.desc" = "Afin de prévenir les problèmes avec PHP Monitor et d'autres plantages, il n'est pas possible de désinstaller la version actuellement liée de PHP via cette interface utilisateur. Vous pouvez changer de version et réessayer, ou désinstaller cette version manuellement via le terminal.\n\nVeuillez noter que PHP Monitor peut planter si vous désinstallez la version de PHP actuellement liée.";
|
||||
|
||||
"phpman.failures.uninstall.title" = "La désinstallation a échoué !";
|
||||
"phpman.failures.uninstall.desc" = "Malheureusement, la désinstallation automatique a échoué. Vous pouvez essayer de lancer manuellement cette commande : `%@` et découvrir ce qui ne fonctionne pas. N'oubliez pas de redémarrer PHP Monitor (ou d'appuyer sur le bouton de rafraîchissement) une fois terminé.";
|
||||
|
||||
"phpman.unlinked.title" = "Aucune des versions de PHP installées sur votre système n'est actuellement liée.";
|
||||
"phpman.unlinked.desc" = "Il est probable que vous ayez toujours une version de PHP installée, mais actuellement aucune version de PHP n'est liée.";
|
||||
"phpman.unlinked.detail" = "Sans aucune version de PHP liée, le binaire php n'est pas accessible sur votre système et vous ne pouvez pas exécuter de scripts PHP sans être explicitement inclus dans le PATH. PHP Monitor peut résoudre automatiquement ce problème (choisissez Réparer automatiquement dans le menu principal) ou vous pouvez le résoudre vous-même en exécutant la commande `brew link php --force`.";
|
||||
|
||||
"phpman.operations.repairing" = "Réparation des installations en cours...";
|
||||
"phpman.operations.updating" = "Installation des mises à jour en cours...";
|
||||
"phpman.operations.installing" = "Installation de %@ en cours...";
|
||||
|
||||
"phpman.steps.fetching" = "Récupération en cours...";
|
||||
"phpman.steps.downloading" = "Téléchargement des données du package en cours...";
|
||||
"phpman.steps.installing" = "Installation de certaines données du package en cours...";
|
||||
"phpman.steps.pouring" = "Versement en cours... Cela peut prendre un certain temps...";
|
||||
"phpman.steps.summary" = "L'installation d'un package est terminée...";
|
||||
|
||||
"phpman.services.loading" = "Chargement...";
|
||||
"phpman.services.not_installed" = "Un service nécessaire n'est pas installé.";
|
||||
"phpman.services.error" = "Un service nécessaire rapporte une érreur.";
|
||||
"phpman.services.inactive" = "Un service nécessaire n'est pas lancé.";
|
||||
"phpman.services.all_ok" = "Tout les services Valet sont OK.";
|
||||
|
||||
// LITE MODE
|
||||
|
||||
"lite_mode_explanation.title" = "Vous utilisez actuellement PHP Monitor en mode Standalone.";
|
||||
"lite_mode_explanation.subtitle" = "PHP Monitor dispose de fonctionnalités supplémentaires qui sont disponibles si vous utilisez Laravel Valet. Actuellement, PHP Monitor n'a pas détecté d'installation active de Valet sur votre système, ces fonctionnalités ne sont donc pas disponibles.";
|
||||
"lite_mode_explanation.description" = "Pour plus d'informations, je vous recommande de consulter le README (accessible sur GitHub) qui expliquera les étapes à suivre pour installer Valet et faire fonctionner correctement PHP Monitor avec cette installation. Vous devrez redémarrer PHP Monitor après avoir installé Laravel Valet avant de quitter le mode Standalone.";
|
||||
|
||||
// GENERIC
|
||||
|
||||
"generic.ok" = "OK";
|
||||
"generic.cancel" = "Annuler";
|
||||
"generic.retry" = "Réessayer";
|
||||
"generic.notice" = "Notice";
|
||||
|
||||
// PRESET LOADING
|
||||
|
||||
"preset_help_title" = "Utilisation des paramètres de configuration";
|
||||
"preset_help_info" = "Vous pouvez configurer des paramètres de configuration dans le fichier config.json, situé dans ~/.config/phpmon/config.json. Ces paramètres peuvent appliquer une sélection de valeurs de configuration en une seule fois. Il s'agit d'une fonctionnalité puissante, mais qui doit actuellement être configurée manuellement.";
|
||||
"preset_help_desc" = "Après avoir redémarré PHP Monitor, tous les paramètres présents dans le fichier seront chargés. Si aucun paramètre n'apparaît, il est probable que le fichier n'ait pas pu être analysé correctement.\n\nVous pouvez cliquer sur le point d'interrogation dans cette alerte pour accéder à la FAQ sur GitHub, où vous trouverez plus d'informations sur cette fonctionnalité, y compris un exemple de fichier.";
|
||||
|
||||
// MENU ITEMS (if window is open)
|
||||
|
||||
"mm_add_folder_as_link" = "Ajouter un dossier en tant que lien...";
|
||||
"mm_reload_domain_list" = "Recharger la liste des domaines";
|
||||
"mm_find_in_domain_list" = "Rechercher dans la liste des domaines";
|
||||
|
||||
// SITE LIST
|
||||
|
||||
"domain_list.title" = "Domaines";
|
||||
"domain_list.subtitle" = "";
|
||||
|
||||
"domain_list.no_domains" = "Vous n'avez pas encore configuré de domaines ou de proxies.";
|
||||
"domain_list.no_domains_for_search_query" = "Votre recherche ne retourne aucun résultat.";
|
||||
|
||||
"domain_list.tooltips.isolated" = "Ce domaine est isolé et utilise PHP %@ au lieu de la version de PHP liée globalement.";
|
||||
"domain_list.tooltips.checkmark" = "Ce domaine est servi avec une version de PHP compatible avec cette exigence (PHP %@). Cliquez sur la version de PHP à côté de cette coche pour obtenir plus d'informations sur la manière dont cette exigence a été déterminée.";
|
||||
|
||||
"domain_list.alerts_isolation_failed.title" = "Oups ! L'isolation du site n'a pas été appliquée.";
|
||||
"domain_list.alerts_isolation_failed.subtitle" = "Quelque chose s'est mal passé lors de la tentative de modification du statut d'isolation pour ce site. Si c'est votre site par défaut mais qu'il n'est pas lié, je vous recommande de le lier manuellement avant de configurer l'isolation.";
|
||||
"domain_list.alerts_isolation_failed.desc" = "Pour déterminer ce qui ne fonctionne pas, vous pouvez essayer d'exécuter la commande manuellement dans votre terminal : %@";
|
||||
|
||||
"domain_list.alerts_status_not_changed.title" = "Oups ! Le statut SSL n'a pas été modifié.";
|
||||
"domain_list.alerts_status_not_changed.desc" = "Quelque chose s'est mal passé. Essayez d'exécuter la commande manuellement dans votre terminal : %@";
|
||||
|
||||
"domain_list.alerts_status_changed.title" = "Statut SSL modifié";
|
||||
"domain_list.alerts_status_changed.desc" = "Le domaine '%@' est maintenant %@.";
|
||||
"domain_list.alerts_status_secure" = "sécurisé";
|
||||
"domain_list.alerts_status_unsecure" = "non sécurisé";
|
||||
|
||||
"domain_list.confirm_unlink" = "Êtes-vous sûr de vouloir dissocier '%@' ?";
|
||||
"domain_list.confirm_unlink_desc" = "Aucun fichier ne sera supprimé. Vous pouvez toujours lier à nouveau le dossier en cliquant sur le bouton + et en sélectionnant le dossier d'origine.";
|
||||
"site_link.close" = "Fermer";
|
||||
"site_link.switch_to_php" = "Basculer vers PHP %@";
|
||||
|
||||
"domain_list.confirm_unproxy" = "Êtes-vous sûr de vouloir supprimer le proxy '%@' ?";
|
||||
"domain_list.confirm_unproxy_desc" = "Vous pouvez toujours recréer le proxy en cliquant à nouveau sur le bouton +.";
|
||||
|
||||
"domain_list.columns.secure" = "TLS";
|
||||
"domain_list.columns.domain" = "Domaine";
|
||||
"domain_list.columns.active" = "Actif";
|
||||
"domain_list.columns.kind" = "Sorte";
|
||||
"domain_list.columns.project_type" = "Type de Projet";
|
||||
|
||||
// CHOOSE WHAT TO ADD
|
||||
|
||||
"selection.title" = "Quel type de domaine souhaitez-vous configurer ?";
|
||||
"selection.description" = "Les liens sont utilisés pour servir directement les projets. Si vous avez un dossier Laravel, Symfony, WordPress, etc. contenant du code, vous voudrez créer un lien et choisir le dossier où se trouve votre code.\n\nSi vous avez besoin d'un proxy, vous pouvez proxyer par exemple un conteneur vers un nom de domaine particulier. Cela peut être utile en combinaison avec Docker, par exemple.";
|
||||
"selection.create_link" = "Créer un lien";
|
||||
"selection.create_proxy" = "Créer un Proxy";
|
||||
"selection.cancel" = "Annuler";
|
||||
|
||||
// ADD PROXY TO DOMAINS LIST
|
||||
|
||||
"domain_list.add.set_up_proxy" = "Configurer un Proxy";
|
||||
"domain_list.add.proxy_subject" = "Sujet du proxy (doit inclure le protocole et le port)";
|
||||
"domain_list.add.domain_name" = "Nom de domaine";
|
||||
"domain_list.add.create_proxy" = "Créer le Proxy";
|
||||
"domain_list.add.proxy_available" = "%@ sera proxy et sera disponible via : %@://%@.%@";
|
||||
"domain_list.add.proxy_https_warning" = "%@ sera proxy et sera disponible via : %@://%@.%@.
|
||||
|
||||
( !) IMPORTANT : Ce proxy peut ne pas fonctionner jusqu'à ce que vous ajoutiez manuellement `proxy_ssl_verify off;` au fichier de configuration de nginx pour ce domaine. Il est recommandé d'utiliser un domaine non sécurisé comme sujet du proxy.";
|
||||
|
||||
// ADD SITE TO DOMAINS LIST
|
||||
|
||||
"domain_list.add.link_folder" = "Lier un dossier";
|
||||
"domain_list.add.domain_name_placeholder" = "Entrez un nom de domaine ici";
|
||||
"domain_list.add.secure_after_creation" = "Sécuriser %@.%@ après la création";
|
||||
"domain_list.add.secure_description" = "La sécurisation d'un domaine nécessite des privilèges administrateurs.\nIl se peut que l'on vous demande votre mot de passe ou votre Touch ID.";
|
||||
"domain_list.add.create_link" = "Créer Lien";
|
||||
"domain_list.add.cancel" = "Annuler";
|
||||
"domain_list.add.folder_available" = "Ce site sera accessible via l'URL suivante : %@://%@.%@";
|
||||
|
||||
"domain_list.add.empty_fields" = "Un ou plusieurs champs sont vides. Veuillez remplir tous les champs obligatoires.";
|
||||
"domain_list.add.errors.empty" = "Vous devez saisir un nom de domaine.";
|
||||
"domain_list.add.errors.empty_proxy" = "Vous devez indiquer ce qui sera proxy.";
|
||||
"domain_list.add.errors.subject_invalid" = "Le sujet que vous avez saisi n'est pas valide.\nVous devez inclure le protocole et le port.";
|
||||
"domain_list.add.errors.already_exists" = "Un lien portant ce nom existe déjà.";
|
||||
|
||||
// ADD SITE ERROR: FOLDER MISSING SINCE SELECTION
|
||||
|
||||
"domain_list.alert.folder_missing.desc" = "Le dossier que vous avez choisi ne semble plus exister. Voulez-vous annuler l'ajout de ce dossier ? Si vous avez déplacé le dossier, vous pouvez toujours le remettre en place et réessayer.";
|
||||
"domain_list.alert.folder_missing.title" = "Dossier manquant !";
|
||||
"domain_list.alert.folder_missing.cancel" = "Annuler le Lien";
|
||||
"domain_list.alert.folder_missing.return" = "OK";
|
||||
|
||||
"domain_list.add.modal_description" = "Sélectionnez d'abord le dossier que vous souhaitez lier.";
|
||||
|
||||
// SITE LIST ACTIONS
|
||||
|
||||
"domain_list.isolate" = "Changer la Version de PHP";
|
||||
"domain_list.site_isolation" = "Isolation du site";
|
||||
"domain_list.remove_isolation" = "Supprimer l'isolation";
|
||||
"domain_list.always_use_php" = "Tojours utiliser PHP %@";
|
||||
"domain_list.isolation_unavailable" = "Isolement non pris en charge (dans Valet 2)";
|
||||
|
||||
"domain_list.actions" = "Actions";
|
||||
"domain_list.unlink" = "Supprimer le Lien vers le Dossier";
|
||||
"domain_list.secure" = "Sécuriser le Domaine";
|
||||
"domain_list.unsecure" = "Supprimer la Sécurisation du Domaine";
|
||||
"domain_list.open_in" = "Ouvrir avec %@";
|
||||
"domain_list.open_in_finder" = "Ouvrir dans le Finder";
|
||||
"domain_list.open_in_browser" = "Ouvrir dans le Navigateur";
|
||||
"domain_list.open_in_terminal" = "Ouvrir dans le Terminal";
|
||||
"domain_list.detected_apps" = "Applications Détectées";
|
||||
"domain_list.system_apps" = "Applications Système";
|
||||
"domain_list.unproxy" = "Supprimer le Proxy";
|
||||
"domain_list.use_in_terminal" = "Ouvrir PHP %@ dans le Terminal";
|
||||
|
||||
"domain_list.alerts_isolated_php_terminal.title" = "Vous pouvez utiliser PHP %@ dans un terminal spécifique!";
|
||||
"domain_list.alerts_isolated_php_terminal.subtitle" = "Malheureusement, PHP Monitor ne peut pas ouvrir un terminal pour vous (et taper les commandes appropriées). Vous devrez donc manuellement créer le script d'aide afin d'utiliser cette version spécifique de PHP. Pour ce faire, vous pouvez taper ce qui suit dans le terminal de votre choix :
|
||||
|
||||
. pm%@
|
||||
|
||||
Ceci va générer le script d'aide tel qu'il est généré par PHP Monitor et permettre l'utilisation de PHP %@ pour ce terminal spécifique.
|
||||
|
||||
Cela n'a pas d'effet sur les autres terminaux, mais uniquement sur la session de terminal particulière sur laquelle vous l'utilisez. (par exemple, si vous avez plusieurs onglets dans votre application de terminal, les autres onglets et fenêtres ne sont pas affectés).";
|
||||
"domain_list.alerts_isolated_php_terminal.desc" = "Si cela ne fonctionne pas, vous pouvez vérifier PHP Doctor via le menu Dépannage ici dans PHP Monitor. Plus d'informations sur cette fonctionnalité peuvent être trouvées sur GitHub (sur le wiki du dépôt de PHP Monitor). Cette alerte est incluse pour améliorer la visibilité de cette fonctionnalité.";
|
||||
|
||||
|
||||
"domain_list.warning.spaces" = "Attention ! Ce site a un espace dans son dossier.\nLe site ne sera pas accessible via le navigateur.";
|
||||
|
||||
"domain_list.alert.invalid_folder_name" = "Nom de dossier non valide";
|
||||
"domain_list.alert.invalid_folder_name_desc" = "Ce dossier n'a pas pu être résolu en une URL valide. Cela est généralement dû à la présence d'un espace dans le nom du dossier. Veuillez renommer le dossier, recharger la liste des sites et réessayer.";
|
||||
|
||||
"domain_list.columns.tls" = "TLS";
|
||||
"domain_list.columns.php" = "PHP";
|
||||
"domain_list.columns.type" = "Type";
|
||||
|
||||
// DRIVERS
|
||||
|
||||
"driver.not_detected" = "Autres";
|
||||
|
||||
// PRESET
|
||||
|
||||
"preset.extension" = "%i extension";
|
||||
"preset.extensions" = "%i extensions";
|
||||
"preset.preference" = "%i préférence";
|
||||
"preset.preferences" = "%i préférences";
|
||||
|
||||
// EDITORS
|
||||
|
||||
"editors.alert.try_again" = "Essayez à nouveau";
|
||||
"editors.alert.cancel" = "Annuler";
|
||||
|
||||
// PREFERENCES
|
||||
|
||||
"prefs.title" = "PHP Monitor";
|
||||
"prefs.subtitle" = "Préférences";
|
||||
"prefs.close" = "Fermer";
|
||||
|
||||
"prefs.tabs.general" = "Général";
|
||||
"prefs.tabs.appearance" = "Apparence";
|
||||
"prefs.tabs.visibility" = "Visibilité";
|
||||
"prefs.tabs.notifications" = "Notifications";
|
||||
|
||||
"prefs.global_shortcut" = "Raccourci Clavier :";
|
||||
"prefs.dynamic_icon" = "Type d'Icône :";
|
||||
"prefs.info_density" = "Densité d'Informations :";
|
||||
"prefs.services" = "Services :";
|
||||
"prefs.switcher" = "Sélecteur :";
|
||||
"prefs.php_doctor" = "PHP Doctor :";
|
||||
"prefs.integrations" = "Intégrations :";
|
||||
"prefs.updates" = "Mises-à-jour :";
|
||||
"prefs.notifications" = "Notifications :";
|
||||
"prefs.warnings" = "Avertissements :";
|
||||
"prefs.menu_contents" = "Le menu contient :";
|
||||
"prefs.startup" = "Démarrage :";
|
||||
|
||||
"prefs.auto_start_desc" = "Lancer automatiquement PHP Monitor lorsque vous vous connectez à votre Mac.";
|
||||
"prefs.auto_start_title" = "Démarrer PHP Monitor à la connexion";
|
||||
|
||||
"prefs.icon_options.php" = "Afficher l'icône PHP";
|
||||
"prefs.icon_options.elephant" = "Afficher l'icône Éléphant";
|
||||
"prefs.icon_options.none" = "Ne Pas Afficher d'icône";
|
||||
|
||||
"prefs.icon_options_desc" = "Cette option détermine l'icône qui sera affichée à côté du numéro de version de la version de PHP actuellement liée. Si l'option Icône dynamique a été désactivée, cette option n'aura aucun effet.";
|
||||
|
||||
"prefs.auto_restart_services_title" = "Redémarrer PHP-FPM automatiquement";
|
||||
"prefs.auto_restart_services_desc" = "Lorsque cette option est cochée, PHP-FPM redémarre automatiquement lorsque vous cochez ou décochez une extension. Légèrement plus lent lorsqu'il est activé, mais il applique immédiatement le changement d'extension pour tous les sites que vous servez, sans avoir besoin de redémarrer PHP-FPM manuellement.";
|
||||
|
||||
"prefs.dynamic_icon_title" = "Afficher une icône dynamique dans la barre de menu";
|
||||
"prefs.dynamic_icon_desc" = "Si vous décochez cette case, l'icône du camion sera toujours visible. Si elle est cochée, elle affichera le numéro de la version majeure de la version de PHP actuellement liée.";
|
||||
|
||||
"prefs.display_full_php_version" = "Afficher la version complète de PHP partout";
|
||||
"prefs.display_full_php_version_desc" = "Afficher la version complète au lieu de la version majeure affichée dans la barre de menu et le menu déroulant. (Cela peut s'avérer indésirable sur les petits écrans, c'est pourquoi cette option est désactivée par défaut).";
|
||||
|
||||
"prefs.auto_composer_update_title" = "Mise à jour automatique des dépendances globales";
|
||||
"prefs.auto_composer_update_desc" = "Si cette option est cochée, elle demandera automatiquement à Composer d'exécuter `composer global update` à chaque fois que vous passerez d'une version de PHP à une autre. Vous serez en mesure de voir quels changements sont effectués, ou si cela échoue.";
|
||||
|
||||
"prefs.open_protocol_title" = "Autoriser les intégrations tierces";
|
||||
"prefs.open_protocol_desc" = "Lorsque cette option est cochée, elle permet à l'interaction avec des utilitaires tiers de fonctionner (par exemple Alfred, Raycast). Si vous désactivez cette option, le PHP Monitor recevra toujours les commandes, mais n'agira pas en conséquence.";
|
||||
|
||||
"prefs.automatic_update_check_title" = "Vérifier automatiquement les mises à jour";
|
||||
"prefs.automatic_update_check_desc" = "Lorsque cette option est cochée, PHP Monitor vérifie automatiquement si une version plus récente est disponible, et vous en informe si c'est le cas.";
|
||||
|
||||
"prefs.php_doctor_suggestions_title" = "Toujours afficher les suggestions";
|
||||
"prefs.php_doctor_suggestions_desc" = "Si vous décochez cette option, aucune suggestion de PHP Doctor n'apparaîtra dans le menu de PHP Monitor. Gardez à l'esprit que PHP Doctor n'apparaîtra pas s'il n'y a pas de recommandations.";
|
||||
|
||||
"prefs.shortcut_set" = "Définir un raccourci global";
|
||||
"prefs.shortcut_listening" = "<écoute de l'appui sur le clavier>";
|
||||
"prefs.shortcut_clear" = "Éffacer";
|
||||
"prefs.shortcut_desc" = "Si une combinaison de raccourcis est configurée, vous pouvez basculer le moniteur PHP où que vous soyez en appuyant sur la combinaison de touches que vous avez choisie. (Annulez le choix d'un raccourci en appuyant sur la barre d'espacement).";
|
||||
|
||||
"prefs.notify_about_version_change_desc" = "Affiche une notification lorsque la version active de PHP change.";
|
||||
"prefs.notify_about_version_change" = "Notification du changement de version de PHP";
|
||||
|
||||
"prefs.notify_about_php_fpm_change_desc" = "Affiche une notification lorsque le processus PHP-FPM actif a redémarré suite à un changement de configuration.";
|
||||
"prefs.notify_about_php_fpm_change" = "Notifier le redémarrage de PHP-FPM";
|
||||
|
||||
"prefs.notify_about_services_desc" = "Affiche une notification lorsque l'un des services Homebrew (installés et configurés par Valet) a été redémarré ou arrêté.";
|
||||
"prefs.notify_about_services" = "Notifier l'état des services";
|
||||
|
||||
"prefs.notify_about_presets_desc" = "Affiche une notification lorsqu'un paramètre a été appliqué ou annulé avec succès.";
|
||||
"prefs.notify_about_presets" = "Notification de l'application des paramètres";
|
||||
|
||||
"prefs.notify_about_secure_status_desc" = "Affiche une notification lorsqu'un domaine a été sécurisé ou non sécurisé" ;
|
||||
"prefs.notify_about_secure_status" = "Notification de l'état sécurisé/non sécurisé";
|
||||
|
||||
"prefs.notify_about_composer_success_desc" = "Affiche une notification lorsque la configuration globale de Composer a été mise à jour avec succès" ;
|
||||
"prefs.notify_about_composer_success" = "Notifier sur les mises à jour globales composer" ;
|
||||
|
||||
"prefs.warn_about_non_standard_tld_desc" = "Si vous utilisez un TLD non standard, vous ne souhaiterez peut-être pas recevoir de notifications répétées à ce sujet" ;
|
||||
"prefs.warn_about_non_standard_tld" = "Avertir à propos d'un TLD non standard" ;
|
||||
|
||||
"prefs.display_global_version_switcher_desc" = "Si cette option est désactivée, vous ne pourrez pas modifier la version de PHP liée globalement via le menu principal.";
|
||||
"prefs.display_global_version_switcher" = "PHP Switcher";
|
||||
|
||||
"prefs.display_services_manager_desc" = "S'il est désactivé, vous ne pourrez pas voir, démarrer ou arrêter les différents services. (Si des services sont désactivés, vous ne pourrez pas facilement voir que c'est le cas).";
|
||||
"prefs.display_services_manager" = "Gestionnaire des services";
|
||||
|
||||
"prefs.display_valet_integration_desc" = "Si elle est désactivée, vous ne pourrez pas localiser le dossier principal de Valet ni ouvrir la liste des domaines.";
|
||||
"prefs.display_valet_integration" = "Intégration Valet";
|
||||
|
||||
"prefs.display_php_config_finder_desc" = "Si cette option est désactivée, vous ne pourrez pas localiser facilement vos fichiers de configuration PHP et/ou générer un dump phpinfo().";
|
||||
"prefs.display_php_config_finder" = "Chercheur de configuration PHP";
|
||||
|
||||
"prefs.display_composer_toolkit_desc" = "Si cette option est désactivée, vous ne pourrez pas invoquer Composer via le menu principal. La mise à jour automatique de Composer après avoir changé de préférence n'est pas affectée par ce changement.";
|
||||
"prefs.display_composer_toolkit" = "Boîte à Outils Composer";
|
||||
|
||||
"prefs.display_limits_widget_desc" = "Si cette option est désactivée, vous ne pourrez pas voir le widget des limites (mémoire, POST, téléchargement) dans le menu principal.";
|
||||
"prefs.display_limits_widget" = "Widget des Limites";
|
||||
|
||||
"prefs.display_extensions_desc" = "Si cette option est désactivée, vous ne pourrez pas contrôler facilement les extensions via le menu principal.";
|
||||
"prefs.display_extensions" = "Extensions";
|
||||
|
||||
"prefs.display_presets_desc" = "Si cette option est désactivée, il ne sera pas possible d'appliquer ou de revenir sur les paramètres de configuration de PHP.";
|
||||
"prefs.display_presets" = "Paramètres";
|
||||
|
||||
"prefs.display_misc_desc" = "Si vous êtes désactivé, vous ne pourrez pas accéder au menu Premiers Secours et Services.";
|
||||
"prefs.display_misc" = "Menu Premiers Secours et Services";
|
||||
|
||||
// NOTIFICATIONS
|
||||
|
||||
"notification.version_changed_title" = "PHP %@ maintenant actif";
|
||||
"notification.version_changed_desc" = "PHP Monitor est passé à PHP %@.";
|
||||
|
||||
"notification.php_fpm_restarted" = "PHP-FPM a redémarrer automatiquement";
|
||||
"notification.php_fpm_restarted_desc" = "Vous avez basculé une extension, et PHP-FPM a donc été redémarré automatiquement.";
|
||||
|
||||
"notification.services_stopped" = "Les Services Valet sont arrêtés";
|
||||
"notification.services_stopped_desc" = "Tous les services ont été arrêtés avec succès.";
|
||||
|
||||
"notification.services_restarted" = "Redémarrage des services Valet";
|
||||
"notification.services_restarted_desc" = "Tous les services ont été redémarrés avec succès.";
|
||||
|
||||
"notification.preset_applied_title" = "Paramètre appliqué";
|
||||
"notification.preset_applied_desc" = "Le paramètre '%@' a été appliqué avec succès.";
|
||||
|
||||
"notification.preset_reverted_title" = "Paramètre annulé";
|
||||
"notification.preset_reverted_desc" = "Le dernier paramètre que vous avez appliqué a été annulé. Votre configuration précédente est maintenant active.";
|
||||
|
||||
"notification.phpmon_updated.title" = "PHP Monitor a été mis à jour !";
|
||||
"notification.phpmon_updated.desc" = "Vous utilisez maintenant PHP Monitor v%@. L'équipe vous remercie !";
|
||||
"notification.phpmon_updated_dev.desc" = "PHP Monitor v%@ (build %@) est maintenant installé et actif.";
|
||||
|
||||
// Composer Update
|
||||
"alert.composer_missing.title" = "Composer introuvable!";
|
||||
"alert.composer_missing.subtitle" = "PHP Monitor n'a pas pu trouver Composer. Assurez-vous que Composer est installé et réessayez.";
|
||||
"alert.composer_missing.desc" = "PHP Monitor suppose que Composer est situé dans:
|
||||
|
||||
• `/usr/local/bin/composer`
|
||||
• `/opt/homebrew/bin/composer`
|
||||
|
||||
Assurez-vous qu'il est installé à l'un de ces endroits, ou créez un lien symbolique si Composer est installé ailleurs.";
|
||||
|
||||
"alert.composer_progress.title" = "Mise à jour des dépendances globales...";
|
||||
"alert.composer_progress.info" = "Vous pouvez voir la progression dans le terminal ci-dessous.";
|
||||
|
||||
"alert.composer_failure.title" = "Quelque chose n'a pas fonctionné !";
|
||||
"alert.composer_failure.info" = "Vos dépendances globales de Composer n'ont pas pu être mises à jour.
|
||||
Vous trouverez plus d'informations dans le message ci-dessous. Vous devrez corriger ce
|
||||
problème manuellement, en utilisant votre propre application Terminal (ceci vous montre simplement un message).";
|
||||
|
||||
"alert.composer_success.title" = "Composer a fini sa mise à jour!";
|
||||
"alert.composer_success.info" = "Les dépendances globales de votre Composer ont été mises à jour avec succès.";
|
||||
|
||||
// Composer Version
|
||||
|
||||
"alert.composer_php_isolated.desc" = "Ce site a été isolé, ce qui signifie que Valet sert PHP %@ pour ce site spécifiquement. La version globale est actuellement PHP %@.";
|
||||
"alert.composer_php_requirement.title" = "'%@' a besoin de PHP %@.";
|
||||
"alert.composer_php_requirement.unable_to_determine" = "Impossible de déterminer les versions requises PHP";
|
||||
"alert.composer_php_requirement.type.unknown" = "PHP Monitor n'a pas pu déterminer quelle version de PHP est requise pour ce domaine. La contrainte peut être déterminée si vous avez un fichier `composer.json` ou un fichier `.valetphprc` dans le dossier de votre projet.";
|
||||
"alert.composer_php_requirement.type.require" = "La version PHP requise a été déterminée en vérifiant le champ `require` dans le fichier `composer.json` lors de la dernière mise à jour de la liste des sites.";
|
||||
"alert.composer_php_requirement.type.platform" = "La version PHP requise a été déterminée en vérifiant le champ `platform` dans le fichier `composer.json` lors de la dernière mise à jour de la liste des sites.";
|
||||
"alert.composer_php_requirement.type.valetphprc" = "La version de PHP requise a été déterminée en vérifiant le fichier .valetphprc dans le dossier de votre projet.";
|
||||
"alert.composer_php_requirement.type.valetrc" = "La version de PHP requise a été déterminée en vérifiant le fichier .valetrc dans le répertoire de votre projet.";
|
||||
"alert.unable_to_determine_is_fine" = "Si vous avez un projet simple, il se peut qu'aucune version de PHP ne soit exigée. Dans ce cas, vous pouvez ignorer cet avertissement.";
|
||||
"alert.php_version_ideal" = "La version PHP actuellement active est idéale pour ce site.";
|
||||
"alert.php_version_incorrect" = "La version PHP actuellement active ne respecte pas les contraintes définies pour ce site.";
|
||||
"alert.php_suggestions" = "Il se peut qu'il existe une version différente de PHP qui soit plus proche de la contrainte.";
|
||||
|
||||
// Suggest Fix My Valet
|
||||
"alert.php_switch_failed.title" = "Le basculement vers PHP %@ semble avoir échoué.";
|
||||
"alert.php_switch_failed.info" = "PHP Monitor a détecté que PHP %@ n'est pas actif après avoir terminé sa procédure de remplacement. Vous pouvez essayer d'exécuter « Fix My Valet » et recommencer à basculer après cela. Voulez-vous essayer cette solution ?";
|
||||
"alert.php_switch_failed.desc" = "Tout d'abord, vous devriez essayer « Fix My Valet » si vous ne l'avez pas déjà fait. Si PHP Monitor reste incapable de changer la version active de PHP, il se peut que vous deviez mettre à jour Valet et les paquets Homebrew. Vous pouvez le faire en lançant `brew update && brew upgrade` ainsi qu'en mettant à jour Valet en lançant `composer global update && valet install`.";
|
||||
"alert.php_switch_failed.confirm" = "Oui, éxécute \"Fix My Valet\"";
|
||||
"alert.php_switch_failed.cancel" = "Ne Pas Éxécuter";
|
||||
|
||||
// PHP Formula Missing
|
||||
"alert.php_formula_missing.title" = "Oups ! La formule `php` doit être installée pour que Fix My Valet fonctionne...";
|
||||
"alert.php_formula_missing.info" = "Il semble que vous n'ayez pas installé la formule `php`, ce qui empêche PHP Monitor d'exécuter Fix My Valet. Veuillez l'installer en utilisant `brew install php`, redémarrez PHP Monitor et réessayez.";
|
||||
|
||||
// Fix My Valet Started
|
||||
"alert.fix_my_valet.title" = "Vous avez des problèmes ? Fix My Valet est prêt à vous aider !";
|
||||
"alert.fix_my_valet.info" = "Cela peut prendre un certain temps. Veuillez être patient.\n\nLorsque cela sera fait, tous les autres services seront interrompus et PHP %@ sera lié. Vous pourrez passer à la version de PHP de votre choix une fois cette opération terminée.\n\n(Vous recevrez une autre notification lorsque Fix My Valet sera terminé.)";
|
||||
"alert.fix_my_valet.ok" = "Continuer";
|
||||
"alert.fix_my_valet.cancel" = "Annuler";
|
||||
|
||||
// Fix My Valet Done
|
||||
"alert.fix_my_valet_done.title" = "Fix My Valet a terminé ses opérations.";
|
||||
"alert.fix_my_valet_done.subtitle" = "Tous les services appropriés ont été arrêtés et les sélectionnés redémarrés, et la dernière version de PHP devrait maintenant être active. Vous pouvez maintenant essayer de passer à une autre version de PHP.";
|
||||
"alert.fix_my_valet_done.stay" = "Rester avec PHP %@";
|
||||
"alert.fix_my_valet_done.switch_back" = "Revenir à PHP %@";
|
||||
"alert.fix_my_valet_done.desc" = "Si le chargement des sites ne fonctionne toujours pas, vous pouvez essayer d'exécuter `valet install` à nouveau, cela peut corriger un problème 502 (Bad Gateway).\n\nSi Valet est cassé et que vous ne pouvez pas exécuter `valet install`, vous pouvez avoir besoin d'exécuter `composer global update`. Veuillez consulter la FAQ sur GitHub si vous avez d'autres problèmes.";
|
||||
|
||||
// Restore Homebrew Permissions
|
||||
"alert.fix_homebrew_permissions.title" = "À propos de \"Rétablir les permissions Homebrew\"";
|
||||
"alert.fix_homebrew_permissions.subtitle" = "Cette fonctionnalité a été créée pour que vous puissiez exécuter `brew upgrade` ou `brew cleanup` sans problème de permission. (Vous serez notifié lorsque ce correctif aura été appliqué.)";
|
||||
"alert.fix_homebrew_permissions.desc" = "Cela nécessite des privilèges administrateurs, car PHP Monitor va restaurer votre accès aux fichiers et dossiers qui sont actuellement la propriété de l'utilisateur `root`, du fait que les services Valet s'exécutent en tant qu'utilisateur root.";
|
||||
"alert.fix_homebrew_permissions.ok" = "Rétablir les Permissions";
|
||||
"alert.fix_homebrew_permissions.cancel" = "Annuler";
|
||||
|
||||
"alert.fix_homebrew_permissions_done.title" = "Toutes les autorisations de fichiers et de dossiers pour les dépendances de Valet ont été rétablies.";
|
||||
"alert.fix_homebrew_permissions_done.subtitle" = "Pour cette raison, tous les services de Valet ne sont plus actifs. Vous pouvez maintenant interagir avec Homebrew, mais vos sites Valet seront indisponibles car tous les services sont désactivés.";
|
||||
"alert.fix_homebrew_permissions_done.desc" = "Lorsque vous avez terminé avec Homebrew (après avoir lancé `brew upgrade`, par exemple), vous devriez redémarrer PHP Monitor et sélectionner « Redémarrer les services Valet » Lorsque vous avez terminé avec Homebrew (après avoir lancé `brew upgrade`, par exemple), vous devriez redémarrer PHP Monitor et sélectionner ``Restart Valet Services`` si vous voulez que Valet fonctionne à nouveau. Il est toujours recommandé de redémarrer PHP Monitor à chaque fois que vous mettez à jour une version de PHP avec `brew upgrade`, sans quoi des problèmes pourraient survenir.";
|
||||
|
||||
// PHP FPM Broken
|
||||
"alert.php_fpm_broken.title" = "Votre configuration PHP-FPM ne pointe pas vers le socket Valet !";
|
||||
"alert.php_fpm_broken.info" = "PHP Monitor a déterminé qu'il y a des problèmes avec votre configuration PHP-FPM. Cela se traduira par des réponses '502 Bad Gateway' si vous visitez des sites web liés via Valet.";
|
||||
"alert.php_fpm_broken.description" = "Si cela fait longtemps, vous pouvez habituellement corriger cela en lançant `valet install`, qui met à jour votre configuration PHP-FPM.\n\nSi vous voyez ce message et que vous essayez d'exécuter une pré-version de PHP, il est possible que Valet ne supporte pas encore celle-ci.\n\nVous devrez peut-être mettre à jour votre installation de Laravel Valet vers au moins la version 3.1.11, après quoi vous devrez exécuter `valet install`. Plus d'informations ici : https://phpmon.app/prerelease-php";
|
||||
|
||||
// PHP Monitor Cannot Start
|
||||
"alert.cannot_start.title" = "PHP Monitor ne peut pas démarrer en raison d'un problème de configuration de votre système";
|
||||
"alert.cannot_start.subtitle" = "Le problème dont vous venez d'être informé empêche le PHP Monitor de fonctionner correctement.";
|
||||
"alert.cannot_start.description" = "Il se peut que vous n'ayez pas besoin de quitter PHP Monitor et de le redémarrer. Si vous avez résolu le problème (ou si vous ne vous souvenez pas du problème exact), vous pouvez cliquer sur Réessayer, ce qui permettra à PHP Monitor de refaire les vérifications de démarrage.";
|
||||
"alert.cannot_start.close" = "Quitter";
|
||||
"alert.cannot_start.retry" = "Essayer à nouveau";
|
||||
|
||||
// PHP alias issue
|
||||
"alert.php_alias_conflict.title" = "Conflit d'alias de la formule Homebrew `php` détecté";
|
||||
"alert.php_alias_conflict.info" = "PHP Monitor a détecté des alias `php` conflictuels dans votre configuration Homebrew, qui ont tous deux été détectés comme étant installés.\n\nCeci entraînera probablement l'échec de la liaison lors du changement de version de PHP, et brisera la fonctionnalité de PHP Monitor.\n\nPour plus d'informations, veuillez visiter : https://github.com/nicoverbruggen/phpmon/issues/54";
|
||||
|
||||
"alert.min_valet_version.title" = "La version installée de Valet ne correspond pas à la version minimale requise. Le PHP Monitor peut ne pas fonctionner comme prévu !";
|
||||
"alert.min_valet_version.info" = "Vous êtes en train d'exécuter Valet %@.
|
||||
|
||||
Pour une prise en charge optimale des dernières versions de PHP et un changement de version correct, il est recommandé de mettre à jour vers la version %@, qui est la configuration minimale requise pour cette version de PHP Monitor.
|
||||
|
||||
Vous pouvez mettre à jour en executant `composer global update` dans votre terminal. Une fois fait, lancez `valet install` à nouveau. Pour de meilleurs résultats, redémarrez PHP Monitor. Tant que ceci n'est pas réglé, PHP Monitor ne fonctionnera pas comme prévu.";
|
||||
|
||||
// Preset text description
|
||||
"alert.preset_description.switcher_version" = "Basculer vers PHP %@.\n\n";
|
||||
"alert.preset_description.applying_extensions" = "Les extensions suivantes seront appliquées :\n";
|
||||
"alert.preset_description.applying_config" = "Applique les valeurs de configuration suivantes :\n";
|
||||
"alert.preset_description.enabled" = "activée";
|
||||
"alert.preset_description.disabled" = "désactivée";
|
||||
"alert.preset_description.empty" = "(vide)";
|
||||
|
||||
// PHP version unavailable
|
||||
"alert.php_switch_unavailable.title" = "Version de PHP non supportée";
|
||||
"alert.php_switch_unavailable.subtitle" = "PHP Monitor ne peut pas passer à PHP %@, car il n'est peut-être pas installé ou disponible. L'application de ce paramètre a été annulée.";
|
||||
"alert.php_switch_unavailable.info" = "Assurez-vous que PHP %@ est installé et vous pouvez le sélectionner dans le menu déroulant. Les versions actuellement supportées sont PHP : %@.";
|
||||
"alert.php_switch_unavailable.ok" = "OK";
|
||||
|
||||
// Service error
|
||||
"alert.service_error.title" = "Le service '%@' signale une erreur!";
|
||||
"alert.service_error.subtitle.error_log" = "Cela signifie que le service '%@' n'est pas lancé. Cela peut empêcher Valet de fonctionner correctement. Ce service est associé à un fichier log que vous pouvez consulter.";
|
||||
"alert.service_error.subtitle.no_error_log" = "Cela signifie que le service '%@' n'est pas lancé. Cela peut empêcher Valet de fonctionner correctement. Malheureusement, il n'y a pas de fichier log associé à ce service.";
|
||||
"alert.service_error.extra" = "Vous pouvez également suivre les étapes de résolution des problèmes les plus communes. Pour en savoir plus, cliquez sur le bouton '?' dans la section services de PHP Monitor.";
|
||||
|
||||
"alert.service_error.button.show_log" = "Voir le log d'erreur";
|
||||
"alert.service_error.button.close" = "Fermer";
|
||||
|
||||
// Composer issues
|
||||
"alert.global_composer_platform_issues.title" = "Composer a détecté des problèmes dans votre plate-forme";
|
||||
"alert.global_composer_platform_issues.subtitle" = "La version de PHP que vous avez choisie est trop ancienne pour les dépendances globales de Composer que vous avez installées. Ces dépendances devront être mises à jour.";
|
||||
"alert.global_composer_platform_issues.desc" = "La façon la plus simple d'éviter ce problème à l'avenir est de basculer vers la plus ancienne version de PHP que vous avez installée et de lancer à nouveau `composer global update`. \n\nVous pouvez également choisir l'option \"Mettre à jour automatiquement les dépendances globales\" dans les préférences pour éviter ce problème.\n\nSi vous continuez à voir ce message même après avoir essayé de mettre à jour ces dépendances globales, vous pouvez consulter votre fichier de configuration globale de composer, situé à `~/.composer/composer.json`.";
|
||||
"alert.global_composer_platform_issues.buttons.update" = "Mettre à jour les dépendances globales";
|
||||
"alert.global_composer_platform_issues.buttons.quit" = "Quitter PHP Monitor";
|
||||
|
||||
// Revert
|
||||
"alert.revert_description.title" = "Revenir à la configuration précédente ?";
|
||||
"alert.revert_description.subtitle" = "PHP Monitor peut revenir à la configuration précédente active. Voici celle qui sera appliqué : \n\n%@";
|
||||
"alert.revert_description.ok" = "Revenir";
|
||||
"alert.revert_description.cancel" = "Annuler";
|
||||
|
||||
// STARTUP
|
||||
|
||||
/// 0. Architecture mismatch
|
||||
|
||||
"alert.homebrew_missing.title" = "Le PHP Monitor ne peut pas démarrer !";
|
||||
"alert.homebrew_missing.subtitle" = "Un binaire Homebrew fonctionnel n'a pas pu être trouvé à l'emplacement standard. Veuillez redémarrer l'application après avoir résolu ce problème.";
|
||||
"alert.homebrew_missing.info" = "Vous utilisez PHP Monitor avec l'architecture suivante : %@. En conséquence, un binaire Homebrew fonctionnel est attendu dans `%@`, mais n'a pas été trouvé. C'est pourquoi PHP Monitor ne peut pas fonctionner. \n\nSi vous n'avez pas encore installé Homebrew, faites-le. Si vous êtes sur Apple Silicon, assurez-vous que Homebrew et PHP Monitor utilisent la même architecture, en activant ou désactivant Rosetta si nécessaire.";
|
||||
|
||||
"alert.homebrew_missing.quit" = "Quitter";
|
||||
|
||||
/// PHP binary not found
|
||||
"startup.errors.php_binary.title" = "PHP n'est pas correctement installé";
|
||||
"startup.errors.php_binary.subtitle" = "Vous devez installer PHP via Homebrew. L'application ne fonctionnera pas correctement tant que vous n'aurez pas résolu ce problème.";
|
||||
"startup.errors.php_binary.desc" = "Généralement, l'exécution de `brew link php` dans votre Terminal résoudra ce problème.\n\nPour diagnostiquer ce qui ne va pas, vous pouvez essayer de lancer `which php` dans votre Terminal, il devrait retourner `%@`.";
|
||||
|
||||
/// PHP not found in /usr/local/opt or /opt/homebrew/opt
|
||||
"startup.errors.php_opt.title" = "PHP n'est pas correctement installé";
|
||||
"startup.errors.php_opt.subtitle" = "L'alias PHP n'a pas été trouvé dans `%@`. L'application ne fonctionnera pas correctement tant que vous n'aurez pas résolu ce problème.";
|
||||
"startup.errors.php_opt.desc" = "Si vous avez déjà installé la formule `php`, vous pouvez avoir besoin de lancer `brew install php` pour que PHP Monitor détecte cette installation.";
|
||||
|
||||
/// PHP binary is broken
|
||||
"startup.errors.dyld_library.title" = "PHP est installé, mais ne fonctionne manifestement pas.";
|
||||
"startup.errors.dyld_library.subtitle" = "Lorsque le PHP Monitor tente d'exécuter des commandes, il ne parvient pas à le faire correctement. C'est généralement un indicateur d'une installation PHP défectueuse.";
|
||||
"startup.errors.dyld_library.desc" = "Lancer `brew reinstall php && brew link php` dans votre Terminal peut résoudre ce problème, veuillez donc essayer.";
|
||||
|
||||
/// Valet is not installed
|
||||
"startup.errors.valet_executable.title" = "Laravel Valet n'est pas correctement installé";
|
||||
"startup.errors.valet_executable.subtitle" = "Vous devez installer Valet avec Composer. L'application ne fonctionnera pas correctement tant que vous n'aurez pas résolu ce problème.";
|
||||
"startup.errors.valet_executable.desc" = "Si vous n'avez pas encore installé Laravel Valet, faites-le d'abord. Si vous l'avez installé mais que vous voyez quand même ce message, essayez de lancer `which valet` dans Terminal, il devrait retourner : `%@`.";
|
||||
|
||||
/// Valet configuration file missing or broken
|
||||
"startup.errors.valet_json_invalid.title" = "Fichier de configuration de Laravel Valet invalide ou manquant";
|
||||
"startup.errors.valet_json_invalid.subtitle" = "PHP Monitor doit pouvoir lire le fichier de configuration. Il semble que le fichier soit malformé ou manquant. Veuillez vérifier qu'il existe et qu'il est correctement formaté.";
|
||||
"startup.errors.valet_json_invalid.desc" = "Vous pouvez trouver le fichier à `~/.config/valet/config.json`. Si Laravel Valet ne peut pas analyser le fichier de configuration, l'exécution de n'importe quelle commande `valet` corrigera automatiquement le fichier JSON. Essayez d'exécuter `valet --version` pour corriger automatiquement le fichier.";
|
||||
|
||||
/// Valet version not readable
|
||||
"startup.errors.valet_version_unknown.title" = "La version de votre Valet n'a pu être lue";
|
||||
"startup.errors.valet_version_unknown.subtitle" = "L'analyse de la réponse de `valet --version` a échoué. Assurez-vous que votre installation de Valet fonctionne et qu'elle est à jour.";
|
||||
"startup.errors.valet_version_unknown.desc" = "Essayez de lancer `valet --version` dans un terminal pour savoir ce qui se passe.";
|
||||
|
||||
"startup.errors.valet_not_installed.title" = "Le dossier de configuration de Valet est absent";
|
||||
"startup.errors.valet_not_installed.subtitle" = "Le répertoire requis `~/.config/valet` est manquant. Cela signifie généralement que vous avez oublié d'exécuter `valet install`.";
|
||||
"startup.errors.valet_not_installed.desc" = "En supposant que vous avez déjà installé Valet via Composer, lancez `valet install` pour terminer la configuration de Laravel Valet.
|
||||
|
||||
Si vous voyez ce message mais que vous ne savez pas pourquoi ce dossier a disparu, vous pouvez chercher à savoir pourquoi il a disparu - il ne devrait pas disparaître comme ça et cela signifie que l'installation de Valet est défectueuse.";
|
||||
|
||||
// Valet version too new or old
|
||||
"startup.errors.valet_version_not_supported.title" = "Cette version de Valet n'est pas compatible";
|
||||
"startup.errors.valet_version_not_supported.subtitle" = "Vous utilisez une version de Valet qui n'est pas supportée actuellement. PHP Monitor fonctionne actuellement avec Valet v2, v3 et v4. Afin d'éviter de causer des problèmes sur votre système, PHP Monitor ne peut pas démarrer.";
|
||||
"startup.errors.valet_version_not_supported.desc" = "Vous devez installer une version de Valet qui est compatible avec PHP Monitor, ou vous pouvez avoir besoin de mettre à jour vers une version plus récente de PHP Monitor qui peut inclure la compatibilité avec cette version de Valet (consultez les dernières notes de version pour plus d'informations).";
|
||||
|
||||
/// Brew & sudoers
|
||||
"startup.errors.sudoers_brew.title" = "Brew n'a pas été ajouté à sudoers.d";
|
||||
"startup.errors.sudoers_brew.subtitle" = "Vous devez exécuter `sudo valet trust` pour vous assurer que Valet peut démarrer et arrêter les services sans avoir à utiliser sudo à chaque fois. L'application ne fonctionnera pas correctement tant que vous n'aurez pas résolu ce problème.";
|
||||
"startup.errors.sudoers_brew.desc" = "Si vous continuez à voir cette erreur, il est possible qu'il y ait un problème de permission où PHP Monitor ne peut pas valider le fichier, ce qui peut généralement être résolu en exécutant : `sudo chmod +r /private/etc/sudoers.d/brew`";
|
||||
|
||||
/// Valet & sudoers
|
||||
"startup.errors.sudoers_valet.title" = "Valet n'a pas été ajouté à sudoers.d";
|
||||
"startup.errors.sudoers_valet.subtitle" = "Vous devez exécuter `sudo valet trust` pour vous assurer que Valet peut démarrer et arrêter les services sans avoir à utiliser sudo à chaque fois. L'application ne fonctionnera pas correctement tant que vous n'aurez pas résolu ce problème. Si vous l'avez déjà fait, exécutez à nouveau `sudo valet trust`.";
|
||||
"startup.errors.sudoers_valet.desc" = "Si vous continuez à voir cette erreur, il est possible qu'il y ait un problème de permission où PHP Monitor ne peut pas valider le fichier, ce qui peut généralement être résolu en exécutant : `sudo chmod +r /private/etc/sudoers.d/valet`";
|
||||
|
||||
/// Platform issue detected
|
||||
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor et Valet ne peuvent pas fonctionner correctement : Composer signale un problème avec votre plateforme";
|
||||
"startup.errors.global_composer_platform_issues.subtitle" = "Veuillez suivre les étapes suivantes pour éviter ce problème à l'avenir :\n\n1. Exécuter `composer global update`.\n2. Redémarrer PHP Monitor. (Il devrait fonctionner à nouveau.)\n3. Passez à la version la plus ancienne de PHP que vous avez installée.\n4. Exécutez à nouveau `composer global update`.";
|
||||
"startup.errors.global_composer_platform_issues.desc" = "Vous pouvez aller dans Préférences et cocher l'option 'Mettre à jour automatiquement les dépendances globales'. Cela mettra à jour les dépendances globales de Composer à chaque fois que vous changerez de version de PHP, ce qui n'est pas idéal si vous n'avez pas un accès constant à internet.\n\nPour savoir exactement ce qui ne va pas, essayez de lancer `valet --version`. Valet n'est actuellement pas fonctionnel avec les dépendances installées. Habituellement, cela est dû à une incompatibilité de version : c'est-à-dire que les dépendances installées correspondent à une version de PHP plus récente que la version actuellement active.";
|
||||
|
||||
/// Cannot retrieve services
|
||||
"startup.errors.services_json_error.title" = "Impossible de déterminer l'état des services";
|
||||
"startup.errors.services_json_error.subtitle" = "PHP Monitor interroge habituellement `brew` en utilisant la commande suivante pour tester si les services peuvent être récupérés : `sudo brew services info nginx --json`.\n\n Le moniteur PHP n'a pas pu interpréter cette réponse.";
|
||||
"startup.errors.services_json_error.desc" = "Cela peut arriver si votre installation Homebrew n'est pas à jour, auquel cas Homebrew ne renverra pas encore de JSON. Vous pouvez généralement corriger cela en lançant `brew update` ou `brew tap homebrew/services`. Vous pouvez aussi essayer de lancer `sudo brew services info nginx --json` dans le terminal de votre choix.";
|
||||
|
||||
/// Issue with `which` alias
|
||||
"startup.errors.which_alias_issue.title" = "Un problème de configuration a été détecté";
|
||||
"startup.errors.which_alias_issue.subtitle" = "Il semble qu'il y ait un fichier dans `/usr/local/bin/which`. Ceci est généralement mis en place par NodeJS, mais `node` n'est pas dans le PATH de `/usr/local/bin`. Pour corriger cela, continuez à lire.";
|
||||
"startup.errors.which_alias_issue.desc" = "Vous devrez faire un lien symbolique entre `node` et le répertoire `/usr/local/bin` pour vous assurer que PHP Monitor peut démarrer avec succès. Pour plus d'informations, voir : https://github.com/nicoverbruggen/phpmon/issues/174";
|
||||
|
||||
/// Laravel Herd conflicts
|
||||
"startup.errors.herd_running.title" = "Laravel Herd semble être lancé";
|
||||
"startup.errors.herd_running.subtitle" = "Il semble que Laravel Herd soit en cours d'exécution. La configuration de Valet intégrée à Herd peut entrer en conflit avec votre installation habituelle de Valet, veuillez donc quitter Herd avant de continuer. (Vous pouvez parfaitement mélanger l'utilisation de Herd et de Valet mais vous ne devez pas utiliser les deux en même temps).";
|
||||
"startup.errors.herd_running.desc" = "Vous pouvez également constater que l'alias `php` ajouté par Herd à votre $PATH peut empêcher l'alias `php` de PHP Monitor de fonctionner, alors gardez cela à l'esprit. Vous pouvez vérifier `~/.zshrc` et voir ce que Herd a ajouté à votre $PATH.";
|
||||
|
||||
// Warning about a different PHP version linked than last time
|
||||
"startup.version_mismatch.title" = "Votre version active de PHP a changé.";
|
||||
"startup.version_mismatch.subtitle" = "Depuis la dernière activation du moniteur PHP, la version PHP liée a été modifiée pour PHP %@. Souhaitez-vous revenir à PHP %@, ou souhaitez-vous continuer à utiliser la version actuelle ?";
|
||||
"startup.version_mismatch.desc" = "PHP Monitor surveille la version de PHP qui est liée globalement. La version globale peut avoir été changée à cause d'un autre programme ou Homebrew peut avoir lié une formule différente après les mises à jour.";
|
||||
"startup.version_mismatch.button_switch_back" = "Revenir à PHP %@";
|
||||
"startup.version_mismatch.button_stay" = "Continuer à utiliser PHP %@";
|
||||
|
||||
// Warning about unsupported PHP versions
|
||||
"startup.unsupported_versions_explanation.title" = "Installation(s) PHP non supportée(s) par Valet détectée(s) !";
|
||||
"startup.unsupported_versions_explanation.subtitle" = "Les versions suivantes de PHP sont installées sur votre système mais ne sont pas supportées par cette version de Valet.
|
||||
|
||||
%@
|
||||
|
||||
Valet risque de ne pas fonctionner si vous liez ces versions de PHP, c'est pourquoi PHP Monitor ne vous laissera pas passer à ces versions.";
|
||||
"startup.unsupported_versions_explanation.desc" = "Si vous avez besoin de la prise en charge de versions plus anciennes de PHP, vous devrez peut-être passer à une version plus ancienne de Valet. Sinon, il peut être judicieux de désinstaller toutes les versions obsolètes qui ne sont pas utilisées. Il se peut également que cette version de Valet soit trop ancienne. Ce message ne disparaîtra qu'après le redémarrage de PHP Monitor.";
|
||||
|
||||
// Sponsor encouragement
|
||||
"startup.sponsor_encouragement.title" = "Si PHP Monitor vous a été utile, à vous ou à votre entreprise, n'hésitez pas à laisser un \"tip\".";
|
||||
"startup.sponsor_encouragement.subtitle" = "Pour être 100% transparent : je prévois de garder PHP Monitor open source et gratuit. Votre soutien rend cette décision très facile.\n\n - (Vous ne verrez cette annonce qu'une seule fois.)";
|
||||
"startup.sponsor_encouragement.desc" = "Si vous avez déjà fait un don, c'est grâce à VOUS que l'application a pu bénéficier de toutes ces mises à jour. Dans ce cas, ceci est un message de remerciement pour vous. J'apprécie votre soutien.";
|
||||
|
||||
"startup.sponsor_encouragement.accept" = "Sponsoriser Maintenant";
|
||||
"startup.sponsor_encouragement.learn_more" = "En Apprendre Plus";
|
||||
"startup.sponsor_encouragement.skip" = "Non Merci";
|
||||
|
||||
// ERROR MESSAGES (based on AlertableError)
|
||||
|
||||
"alert.errors.homebrew_permissions.applescript_returned_nil.title" = "La restauration des permissions Homebrew a été annulée.";
|
||||
"alert.errors.homebrew_permissions.applescript_returned_nil.description" = "Le résultat du script exécuté pour ajuster les permissions est `nil`, ce qui signifie habituellement que vous n'avez pas accordé les permissions administratives à PHP Monitor.\n\nSi vous avez cliqué sur Annuler lors de l'invite d'authentification, c'est normal. Si vous vous êtes authentifié et que vous voyez toujours ce message, quelque chose a probablement échoué.";
|
||||
|
||||
"alert.key_service_not_running.title" = "En raison de problèmes avec les services Homebrew nécessaires, Valet ne fonctionne pas correctement pour le moment";
|
||||
"alert.key_service_not_running.subtitle" = "Pour que Valet fonctionne correctement, il faut qu'au moins trois services clés fonctionnent correctement.
|
||||
|
||||
PHP Monitor signale que ce n'est pas le cas. Vous pouvez essayer de résoudre ce problème en appuyant sur le bouton avec le 'X' dans le menu sous le service concerné pour (re)démarrer le service qui est actuellement inactif.";
|
||||
"alert.key_service_not_running.desc" = "Si le fait de cliquer sur le bouton situé sous le service ne fonctionne pas (c.-à-d. que la roulette apparaît mais affiche toujours un \"X\" au bout d'un certain temps), il se peut que vous deviez lancer Fix My Valet. Vous pouvez le faire via le menu First Aid > Fix My Valet.
|
||||
|
||||
Vous pouvez également utiliser `valet stop` et `valet start` dans le terminal, ce qui peut également résoudre le problème (comme alternative à Fix My Valet).
|
||||
|
||||
Pour un débogage plus approfondi, vous pouvez consulter le GitHub issue tracker, où d'autres personnes peuvent avoir eu des problèmes similaires. En tant que développeur, j'essaie de m'assurer que toutes les questions reçoivent une réponse :)";
|
||||
|
||||
"alert.key_service_has_error.title" = "En raison de problèmes avec les services Homebrew nécessaires, Valet ne fonctionne pas correctement pour le moment.";
|
||||
"alert.key_service_has_error.subtitle" = "Pour que Valet fonctionne correctement, il faut qu'au moins trois services clés fonctionnent correctement.
|
||||
|
||||
PHP Monitor signale que ce n'est pas le cas. Il semble que l'un des services concernés signale un état d'erreur, et je recommande donc de cliquer sur le 'E'.
|
||||
|
||||
PHP Monitor tentera de redémarrer le service, et s'il échoue (ce qui est probable), il proposera de localiser le fichier journal s'il existe, ce qui peut contenir des informations supplémentaires qui peuvent vous aider à déboguer le problème.";
|
||||
"alert.key_service_has_error.desc" = "Malheureusement, si un service signale une erreur, cela est souvent dû à une configuration invalide, qui peut être difficile à déboguer.
|
||||
|
||||
CONSEILS DE DÉPANNAGE
|
||||
|
||||
• Essayez de redémarrer le service et de vérifier le fichier log (s'il existe) en premier lieu. Vous pouvez demander à PHP Monitor de le faire en cliquant sur le bouton 'E'.
|
||||
|
||||
• PHP : Si vous voyez un statut d'erreur, il se peut qu'il y ait un problème avec la configuration de PHP. Assurez-vous que les fichiers .ini de l'installation Homebrew sont corrects et qu'il n'y a pas de conflit concernant les sockets.
|
||||
|
||||
• nginx : Si vous obtenez un statut d'erreur, il est probable qu'un site soit mal configuré (ce qui est généralement indiqué dans le log d'erreur). Vous voudrez probablement vérifier le dossier nginx de Valet.
|
||||
|
||||
• dnsmasq: Si vous obtenez une erreur, le fichier de configuration de dnsmasq est probablement endommagé (il se trouve généralement dans ~/.config/valet/dnsmasq.d).";
|
||||
|
||||
// CHECK FOR UPDATES
|
||||
|
||||
"updater.alerts.newer_version_available.title" = "PHP Monitor v%@ est maintenant disponible !";
|
||||
"updater.alerts.newer_version_available.subtitle" = "Il est fortement recommandé de maintenir PHP Monitor à jour, car les nouvelles versions corrigent généralement les bogues et incluent des correctifs pour prendre en charge les dernières versions de Valet et de PHP.";
|
||||
"updater.installation_source.brew" = "La méthode recommandée pour installer les mises à jour de PHP Monitor est d'appuyer simplement sur “Install Update” (Installer la mise à jour). \n\nComme vous avez utilisé Homebrew pour installer l'application, vous pouvez également effectuer la mise à jour via le terminal en exécutant `%@`, mais cela n'est pas recommandé. \n\n(Veuillez noter que l'installation via cette mise à jour intégrée supprimera PHP Monitor du répertoire Caskroom de Homebrew, afin d'éviter que des mises à jour en double ne soient téléchargées et ne causent des problèmes potentiels plus tard).";
|
||||
"updater.installation_source.direct" = "La méthode recommandée pour installer les mises à jour de PHP Monitor est de cliquer simplement sur 'Installer la mise à jour'.";
|
||||
"updater.alerts.buttons.release_notes" = "Voir les notes de mise à jour";
|
||||
|
||||
"updater.alerts.is_latest_version.title" = "PHP Monitor est à jour !";
|
||||
"updater.alerts.is_latest_version.subtitle" = "La version actuellement installée (v%@) est à jour. Il n'y a pas de version plus récente disponible.";
|
||||
|
||||
"updater.alerts.cannot_check_for_update.title" = "PHP Monitor n'a pas pu déterminer si une version plus récente est disponible.";
|
||||
"updater.alerts.cannot_check_for_update.subtitle" = "Il se peut que vous ne soyez pas connecté à l'internet, que vous bloquiez le trafic ou que GitHub soit en panne et ne vous permette pas de vérifier les mises à jour. Si vous continuez à voir ce message, vous pouvez vérifier manuellement la page des versions.";
|
||||
"updater.alerts.cannot_check_for_update.description" = "La version actuellement installée est : %@. Vous pouvez accéder à la liste des dernières versions (sur GitHub) en cliquant sur le bouton à gauche.";
|
||||
"updater.alerts.buttons.releases_on_github" = "Voir les versions";
|
||||
"updater.alerts.buttons.install" = "Installer la mise à jour";
|
||||
"updater.alerts.buttons.dismiss" = "Annuler";
|
||||
|
||||
// WARNINGS ABOUT NON-DEFAULT TLD
|
||||
|
||||
"alert.warnings.tld_issue.title" = "Vous n'utilisez pas `.test` comme TLD pour Valet.";
|
||||
"alert.warnings.tld_issue.subtitle" = "L'utilisation d'un TLD autre que celui par défaut peut ne pas fonctionner correctement et n'est pas officiellement pris en charge.";
|
||||
"alert.warnings.tld_issue.description" = "PHP Monitor restera fonctionnel, mais il pourrait y avoir des problèmes : l'application pourrait ne pas montrer correctement quels domaines ont été sécurisés. Pour des résultats optimaux, allez dans votre fichier de configuration Valet (config.json dans le répertoire Valet) et changez le TLD en `test`.";
|
||||
"alert.do_not_tell_again" = "Ne m'en Parlez Plus";
|
||||
|
||||
// WARNINGS
|
||||
|
||||
"warnings.limits_error.title" = "PHP Monitor n'a pas pu obtenir les limites.";
|
||||
"warnings.limits_error.steps" = "Essayez de lancer 'php -v' dans votre terminal.";
|
||||
|
||||
"warnings.title" = "PHP Doctor";
|
||||
"warnings.description" = "**PHP Doctor** vous proposera des améliorations de la configuration de votre système.";
|
||||
"warnings.disclaimer" = "Vous pouvez choisir de masquer toutes les recommandations dans le menu PHP Monitor des préférences, mais il est recommandé de traiter tous les points pouvant être améliorés.";
|
||||
"warnings.refresh.button" = "Scanner à nouveau";
|
||||
"warnings.refresh.button.description" = "Appuyez sur ce bouton une fois que vous avez corrigé un problème. PHP Monitor va alors réévaluer votre environnement. Si le problème est vraiment corrigé, la recommandation devrait disparaître.";
|
||||
|
||||
"warnings.helper_permissions.title" = "Les programmes d'aide du PHP Monitor ne sont pas disponibles pour le moment.";
|
||||
"warnings.helper_permissions.description" = "Le PHP Monitor est livré avec plusieurs scripts auxiliaires. L'utilisation de ces scripts vous permet d'invoquer facilement une version spécifique de PHP sans changer la version de PHP liée.";
|
||||
"warnings.helper_permissions.unavailable" = "Cependant, ces aides sont potentiellement *indisponibles* parce que PHP Monitor ne peut pas créer ou mettre à jour les liens symboliques requis.";
|
||||
"warnings.helper_permissions.symlink" = "Si vous ne souhaitez pas rendre `/usr/local/bin` accessible en écriture, vous pouvez ajouter le répertoire d'aide de PHP Monitor à votre variable `PATH` pour faire disparaître cet avertissement. (Cliquez sur “En savoir plus” pour savoir comment résoudre ce problème).";
|
||||
|
||||
"warnings.arm_compatibility.title" = "Vous exécutez PHP Monitor en utilisant Rosetta sur Apple Silicon, ce qui signifie que votre environnement PHP est également exécuté via Rosetta.";
|
||||
"warnings.arm_compatibility.description" = "Vous semblez utiliser une version compatible ARM de macOS, mais vous exécutez PHP Monitor en utilisant Rosetta. Bien que cela fonctionne correctement, il est recommandé d'utiliser la version native de Homebrew.";
|
||||
|
||||
"warnings.files_missing.title" = "Des fichiers de configuration importants sont absents de votre installation PHP.";
|
||||
"warnings.files_missing.description" = "Les fichiers de configuration clés suivants doivent exister à la suite de l'installation de PHP :
|
||||
|
||||
• %@
|
||||
|
||||
Lorsque des fichiers de ce type sont manquants, vous devriez passer à la version de PHP associée à ces fichiers : cela peut résoudre le problème. Si cela ne résout pas le problème, il est recommandé de réinstaller la (les) version(s) PHP appropriée(s) via Homebrew, ce qui devrait restaurer les fichiers de configuration manquants. Les fichiers de configuration manquants peuvent être la raison pour laquelle vous obtenez des erreurs '502 Bad Gateway', même après avoir exécuté Fix My Valet (si vous utilisez Valet).";
|
||||
|
||||
"warnings.none" = "Il n'y a pas de recommandations disponibles pour vous en ce moment. Tout est parfait !";
|
||||
|
||||
// ONBOARDING
|
||||
|
||||
"onboarding.title" = "Visite d'Accueil";
|
||||
"onboarding.welcome" = "Bienvenue sur PHP Monitor !";
|
||||
"onboarding.explore" = "Vous avez maintenant accès à l'ensemble des fonctionnalités de PHP Monitor. Vous pouvez en apprendre davantage sur certaines des fonctionnalités offertes par PHP Monitor en consultant cet écran.";
|
||||
"onboarding.explore.lite" = "Vous avez maintenant accès aux fonctionnalités les plus importantes de PHP Monitor.
|
||||
Veuillez noter que certaines fonctionnalités (grisées ci-dessous) sont actuellement indisponibles car Laravel Valet n'est pas actif.";
|
||||
"onboarding.tour.menu_bar.title" = "Le Pouvoir dans votre Barre de Menu";
|
||||
"onboarding.tour.menu_bar" = "PHP Monitor se trouve dans votre barre de menu. À partir de ce menu, vous pouvez accéder à la plupart des fonctionnalités clés de PHP Monitor, y compris le changement de la version globale de PHP, la localisation des fichiers de configuration, l'installation de différentes versions de PHP, et plus encore.";
|
||||
"onboarding.tour.faq_hint" = "**Questions?** Je vous recommande de lire le [README](https://github.com/nicoverbruggen/phpmon/blob/main/README.md) sur GitHub: il contient une FAQ complète avec divers conseils et des questions et réponses courantes.";
|
||||
"onboarding.tour.services.title" = "Gérer les services Homebrew";
|
||||
"onboarding.tour.services" = "Une fois que vous avez cliqué sur l'icône de la barre de menu, vous pouvez voir d'un coup d'œil si tous les services Homebrew sont opérationnels, en vous basant sur les coches ou les croix. Vous pouvez également cliquer sur un service pour le basculer rapidement.";
|
||||
"onboarding.tour.domains.title" = "Gérer les Domaines";
|
||||
"onboarding.tour.domains" = "En ouvrant la fenêtre Domaines via la barre de menu, vous pouvez voir quels domaines sont liés et parqués, ainsi que les proxys nginx actifs.";
|
||||
"onboarding.tour.isolation.title" = "Isoler les Domaines";
|
||||
"onboarding.tour.isolation" = "Si vous avez installé Valet 3 ou une version plus récente, vous pouvez même utiliser l'isolation de domaine en faisant un clic droit sur un domaine donné dans la fenêtre Domaines. Cela vous permet de choisir une version spécifique de PHP à utiliser pour ce domaine, et ce domaine seulement.";
|
||||
"onboarding.tour.feature_unavailable" = "Cette fonctionnalité n'est actuellement pas disponible et nécessite l'installation de Laravel Valet.";
|
||||
"onboarding.tour.once" = "Vous ne verrez la visite de bienvenue qu'une seule fois. Vous pouvez rouvrir la visite de bienvenue ultérieurement via l'icône de la barre de menu (disponible dans le menu, sous Premiers Secours et Services).";
|
||||
"onboarding.tour.close" = "Fermer la Visite d'Accueil";
|
@ -91,6 +91,7 @@
|
||||
"phpman.version.has_update" = "Versie %@ geïnstalleerd, %@ beschikbaar.";
|
||||
"phpman.version.installed" = "Versie %@ is momenteel geïnstalleerd.";
|
||||
"phpman.version.available_for_installation" = "Deze versie kan worden geïnstalleerd.";
|
||||
"phpman.version.automatic_upgrade" = "Deze versie zal automatisch geïnstalleerd worden door een upgrade.";
|
||||
"phpman.buttons.uninstall" = "Verwijderen";
|
||||
"phpman.buttons.install" = "Installeren";
|
||||
"phpman.buttons.update" = "Bijwerken";
|
||||
@ -652,6 +653,11 @@ Als u dit bericht ziet, maar verward bent waarom deze map ontbreekt, wilt u moge
|
||||
"startup.errors.which_alias_issue.subtitle" = "Het lijkt erop dat er een bestand is in `/usr/local/bin/which`. Dit wordt meestal ingesteld door NodeJS, maar `node` staat niet in de PATH in `/usr/local/bin`. Om dit op te lossen, gaat u verder met lezen.";
|
||||
"startup.errors.which_alias_issue.desc" = "U moet `node` symbolisch koppelen aan de `/usr/local/bin`-directory om ervoor te zorgen dat PHP Monitor succesvol kan starten. Voor meer informatie, zie: https://github.com/nicoverbruggen/phpmon/issues/174";
|
||||
|
||||
/// Laravel Herd conflicts
|
||||
"startup.errors.herd_running.title" = "Laravel Herd lijkt actief te zijn";
|
||||
"startup.errors.herd_running.subtitle" = "Het lijkt erop dat Laravel Herd momenteel actief is. De ingebouwde Valet-configuratie van Herd kan conflicteren met je reguliere Valet-installatie, dus sluit Herd af voordat je verdergaat. (Je kunt perfect gebruik maken van zowel Herd als reguliere Valet, maar je moet ze niet tegelijkertijd uitvoeren.)";
|
||||
"startup.errors.herd_running.desc" = "Je kan ook merken dat de `php`-alias die Herd aan je $PATH heeft toegevoegd, niet werkt met de aliases van PHP Monitor, dus hou daar rekening mee. Je kunt `~/.zshrc` bekijken om te zien wat Herd aan je $PATH heeft toegevoegd.";
|
||||
|
||||
// Warning about a different PHP version linked than last time
|
||||
"startup.version_mismatch.title" = "Uw actieve PHP-versie is gewijzigd.";
|
||||
"startup.version_mismatch.subtitle" = "Sinds PHP Monitor voor het laatst actief was, is uw gekoppelde PHP-versie gewijzigd naar PHP %@. Wilt u terugschakelen naar PHP %@, of wilt u de huidige versie blijven gebruiken?";
|
||||
|
@ -90,6 +90,7 @@
|
||||
"phpman.version.has_update" = "Versão %@ instalada, %@ disponível.";
|
||||
"phpman.version.installed" = "Versão %@ atualmente instalada.";
|
||||
"phpman.version.available_for_installation" = "Esta versão pode ser instalada.";
|
||||
"phpman.version.automatic_upgrade" = "Esta versão será instalada automaticamente ao atualizar uma versão mais antiga.";
|
||||
"phpman.buttons.uninstall" = "Desinstalar";
|
||||
"phpman.buttons.install" = "Instalar";
|
||||
"phpman.buttons.update" = "Atualizar";
|
||||
@ -652,6 +653,11 @@ Se ainda vê esta mensagem, e não percebe porque a diretoria desapareceu, conv
|
||||
"startup.errors.which_alias_issue.subtitle" = "Parece que há um ficheiro em `/usr/local/bin/which`. Isto geralmente é configurado pelo NodeJS, mas `node` não está no PATH em `/usr/local/bin`. Para corrigir isto, continue a ler.";
|
||||
"startup.errors.which_alias_issue.desc" = "Precisará vincular `node` à diretoria `/usr/local/bin` para garantir que o PHP Monitor possa iniciar com sucesso. Para mais informações, consulte: https://github.com/nicoverbruggen/phpmon/issues/174";
|
||||
|
||||
// Laravel Herd conflicts
|
||||
"startup.errors.herd_running.title" = "O Laravel Herd parece estar em execução";
|
||||
"startup.errors.herd_running.subtitle" = "Parece que o Laravel Herd está atualmente em execução. A configuração integrada do Valet do Herd pode entrar em conflito com a sua instalação regular do Valet. Por favor, encerre o Herd antes de continuar. (Você pode combinar perfeitamente o uso do Herd e do Valet regular, mas não deve executar ambos ao mesmo tempo.)";
|
||||
"startup.errors.herd_running.desc" = "Você também pode perceber que o alias `php` adicionado pelo Herd ao seu $PATH pode impedir o aliasing do PHP Monitor como `php`, então tenha isso em mente. Você pode verificar o arquivo `~/.zshrc` para ver o que o Herd adicionou ao seu $PATH.";
|
||||
|
||||
// Warning about a different PHP version linked than last time
|
||||
"startup.version_mismatch.title" = "A sua versão vinculada do PHP mudou.";
|
||||
"startup.version_mismatch.subtitle" = "Desde que o PHP Monitor esteve ativo a última vez, a sua versão do PHP vinculada foi alterada para PHP %@. Gostaria de voltar para o PHP %@ ou deseja continuar a usar a versão atual?";
|
||||
|
@ -90,6 +90,7 @@
|
||||
"phpman.version.has_update" = "Phiên bản %@ được cài đặt, Phiên bản %@ có sẵn.";
|
||||
"phpman.version.installed" = "Phiên bản %@ hiện đã được cài đặt.";
|
||||
"phpman.version.available_for_installation" = "Phiên bản này có thể được cài đặt.";
|
||||
"phpman.version.automatic_upgrade" = "Phiên bản này sẽ được cài đặt tự động bằng cách nâng cấp từ một phiên bản cũ hơn.";
|
||||
"phpman.buttons.uninstall" = "Gỡ cài đặt";
|
||||
"phpman.buttons.install" = "Cài đặt";
|
||||
"phpman.buttons.update" = "Cập nhật";
|
||||
@ -646,6 +647,11 @@ Nếu bạn nhìn thấy thông báo này nhưng bối rối vì thư mục này
|
||||
"startup.errors.which_alias_issue.subtitle" = "Dường như có một tệp trong `/usr/local/bin/which`. Điều này thường được thiết lập bởi NodeJS, nhưng `node` không có trong PATH trong `/usr/local/bin`. Để khắc phục điều này, hãy đọc tiếp.";
|
||||
"startup.errors.which_alias_issue.desc" = "Bạn sẽ cần tạo liên kết tượng trưng cho `node` vào thư mục `/usr/local/bin` để đảm bảo PHP Monitor có thể khởi động thành công. Để biết thêm thông tin, xem: https://github.com/nicoverbruggen/phpmon/issues/174";
|
||||
|
||||
/// Laravel Herd conflicts
|
||||
"startup.errors.herd_running.title" = "Có vẻ như Laravel Herd đang chạy";
|
||||
"startup.errors.herd_running.subtitle" = "Có vẻ như Laravel Herd hiện đang chạy. Cài đặt Valet tích hợp của Herd có thể xung đột với cài đặt Valet thông thường của bạn, vì vậy hãy thoát Herd trước khi tiếp tục. (Bạn có thể hoàn toàn kết hợp sử dụng Herd và Valet thông thường nhưng bạn không nên chạy cả hai cùng một lúc.)";
|
||||
"startup.errors.herd_running.desc" = "Bạn cũng có thể thấy rằng bí danh `php` mà Herd thêm vào $PATH của bạn có thể ngăn chặn việc đặt bí danh `php` cho PHP Monitor hoạt động, vì vậy hãy lưu ý điều đó. Bạn có thể kiểm tra tệp `~/.zshrc` và xem Herd đã thêm gì vào $PATH của bạn.";
|
||||
|
||||
// Warning about a different PHP version linked than last time
|
||||
"startup.version_mismatch.title" = "Phiên bản PHP đang hoạt động của bạn đã thay đổi.";
|
||||
"startup.version_mismatch.subtitle" = "Kể từ khi PHP Monitor hoạt động lần cuối, phiên bản PHP được liên kết của bạn đã được thay đổi thành PHP %@. Bạn có muốn chuyển lại sang PHP %@ không, hay bạn muốn tiếp tục sử dụng phiên bản hiện tại?";
|
||||
|
@ -27,22 +27,23 @@ final class DomainsListTest: UITestCase {
|
||||
|
||||
app.menuItems["mi_domain_list".localized].click()
|
||||
|
||||
let window = app.windows.allElementsBoundByIndex.first { element in
|
||||
element.title == "domain_list.title".localized
|
||||
}!
|
||||
let window = app.windows.element(boundBy: 0)
|
||||
XCTAssertEqual(window.title, "domain_list.title".localized)
|
||||
|
||||
let searchField = window.searchFields.firstMatch
|
||||
let searchField = window.searchFields.element(boundBy: 0)
|
||||
|
||||
searchField.click()
|
||||
searchField.typeText("non-existent thing")
|
||||
Thread.sleep(forTimeInterval: 0.2)
|
||||
XCTAssertTrue(window.tables.tableRows.count == 0)
|
||||
|
||||
searchField.clearText()
|
||||
searchField.click()
|
||||
searchField.typeText("concord")
|
||||
Thread.sleep(forTimeInterval: 0.2)
|
||||
XCTAssertTrue(window.tables.tableRows.count == 1)
|
||||
|
||||
sleep(2)
|
||||
sleep(1)
|
||||
}
|
||||
|
||||
final func test_can_tap_add_domain_button() throws {
|
||||
@ -50,9 +51,8 @@ final class DomainsListTest: UITestCase {
|
||||
|
||||
app.menuItems["mi_domain_list".localized].click()
|
||||
|
||||
let window = app.windows.allElementsBoundByIndex.first { element in
|
||||
element.title == "domain_list.title".localized
|
||||
}!
|
||||
let window = app.windows.element(boundBy: 0)
|
||||
XCTAssertEqual(window.title, "domain_list.title".localized)
|
||||
|
||||
window.buttons["Add Link"].click()
|
||||
|
||||
@ -61,6 +61,6 @@ final class DomainsListTest: UITestCase {
|
||||
assertExists(app.buttons["selection.create_proxy".localized])
|
||||
assertExists(app.buttons["selection.cancel".localized])
|
||||
|
||||
sleep(2)
|
||||
sleep(1)
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,8 @@ final class MainMenuTest: UITestCase {
|
||||
let app = launch(openMenu: true)
|
||||
app.mainMenuItem(withText: "mi_preferences".localized).click()
|
||||
|
||||
Thread.sleep(forTimeInterval: 0.5)
|
||||
|
||||
assertExists(app.buttons["General"])
|
||||
click(app.buttons["General"])
|
||||
|
||||
@ -78,16 +80,17 @@ final class MainMenuTest: UITestCase {
|
||||
// Should display loader
|
||||
assertExists(app.staticTexts["phpman.busy.title".localized], 1)
|
||||
|
||||
// After loading, should display PHP 8.2
|
||||
// After loading, should display PHP 8.2 and PHP 8.3
|
||||
assertExists(app.staticTexts["PHP 8.2"], 5)
|
||||
assertExists(app.staticTexts["PHP 8.3"])
|
||||
|
||||
// Should also display pre-release version
|
||||
assertExists(app.staticTexts["PHP 8.3"])
|
||||
assertExists(app.staticTexts["PHP 8.4"])
|
||||
assertExists(app.staticTexts["phpman.version.prerelease".localized.uppercased()])
|
||||
assertExists(app.staticTexts["phpman.version.available_for_installation".localized])
|
||||
|
||||
// But not PHP 8.4 (yet)
|
||||
assertNotExists(app.staticTexts["PHP 8.4"])
|
||||
// But not PHP 8.5 (yet)
|
||||
assertNotExists(app.staticTexts["PHP 8.5"])
|
||||
|
||||
// Also, PHP 8.2 should have an update available
|
||||
assertExists(app.staticTexts["phpman.version.has_update".localized(
|
||||
|
Reference in New Issue
Block a user