1
0
mirror of https://github.com/nicoverbruggen/phpmon.git synced 2025-08-08 04:20:07 +02:00

Compare commits

...

39 Commits
v7.0.6 ... v7.2

Author SHA1 Message Date
4827c4a44b 🚀 Version 7.2 2025-03-22 12:05:54 +01:00
201554b237 🔧 Bump version to 7.2 2025-03-22 11:33:52 +01:00
e4bf6a9655 📝 Bump build, update credits and add sponsors 2025-03-22 11:32:59 +01:00
f9ea654ffc 🔧 Tweak brew output parsing
Improved the accuracy of the brew output. Often, when multiple console
messages were returned, the progress prompt in the PHP version manager
would display the earliest found step, not the latest, thus unfortunately
misrepresenting the progress of the installation steps.

This fixes that by reversing the return order, but also extracts
relevant information from the commands, too, so that contextual info
is now included (for pouring, installing and downloading steps).

(This makes it a little bit more transparent for the end user to find
out what is taking up all this time. I wish that Homebrew was faster,
too, but there's a reason I'm not using statically compiled PHP for
this project. Either way, this is a nice QoL change.)
2025-03-22 11:15:47 +01:00
8677628850 🔧 Bump build for new EAP release 2025-03-01 12:59:09 +01:00
e09b0156df 📝 Update README 2025-03-01 12:58:36 +01:00
41a83b1d91 🔨 Update .gitignore 2025-02-28 13:20:32 +01:00
a9e97b0bc9 🌐 Add Indonesian translations
These translations were added via a locally ran LLM.
If you identify any mistakes, please get in touch!
2025-02-21 13:27:39 +01:00
e4e12799ef 🌐 Add Spanish translations
These translations were added via a locally ran LLM. I know some Spanish, but
if you identify any mistakes, please get in touch!
2025-02-20 19:54:04 +01:00
4e25fffa7d 🌐 Add missing translations 2025-02-20 19:21:25 +01:00
3e319cd50f 🚀 Version 7.1 2024-11-26 15:24:18 +01:00
595dc8c028 Add info about test failures 2024-11-26 15:22:03 +01:00
f7b1679e97 🐛 Serial dispatch queue for test FS 2024-11-26 14:17:06 +01:00
9f1761d68e Checked and updated tests 2024-11-26 13:44:08 +01:00
871480d70c 📝 Updated README.md, SECURITY.md 2024-11-26 12:56:38 +01:00
2b1c1c12f8 Add info button for PHP upgrades 2024-11-25 16:43:19 +01:00
a22346ed35 🐛 Fix issue with formulae upgrades for tap 2024-11-25 14:04:17 +01:00
e3fa34d4f9 🔨 Adjust URL for unavailable PHP (wiki) 2024-11-25 13:40:02 +01:00
3d225ea79f ✍️ Clarify text about upgrading PHP (EN only) 2024-11-22 19:09:10 +01:00
d2cd387c18 Add button that redirects to wiki 2024-11-22 18:23:28 +01:00
48bb782e33 🚧 WIP: Changes related to unavailable formulae 2024-11-22 17:42:28 +01:00
9710ffa8da 🚧 WIP: Handle temporarily unavailable formulae 2024-11-22 13:26:09 +01:00
46408f5ee5 Indicate DEV builds in PHP Version Manager 2024-11-15 16:43:59 +01:00
2c39f1db8b 🔧 Upgrade checks for Xcode 16.1 2024-11-15 16:10:25 +01:00
f20286cbd9 Notify user if startup takes too long (> 30s) 2024-11-15 16:03:44 +01:00
f1fe42e563 Updated constants for PHP 8.4 & 8.5 support
Thankfully, these changes are simple. Before releasing, I will be
testing the new build, though.

Here's what constants I changed, and why:

- Homebrew PHP formulae are now consistently sourced from the
  `shivammathur/php` tap. This should make the transition to new PHP
  releases a little bit easier, but I need to verify this works without
  issues before publishing this update.

- Bumped the PHP formulae cutoff date to Nov 30, 2025.
  At this point, PHP 8.5 should be released.

- Added support for pre-release (daily) versions of PHP 8.5.
2024-11-15 15:22:53 +01:00
94abfe4b49 🐛 Fix crash bug (oops) 2024-10-31 22:51:49 +01:00
cef19243ee 🔧 Bump build 2024-10-31 21:59:42 +01:00
b319ecab59 👌 Move cut-off date to PHP 8.4 release day 2024-10-31 21:56:13 +01:00
a47b139d92 👌 Cleanup 2024-08-31 22:14:56 +02:00
e026ecf60d ♻️ Various extension list improvements (#274)
Installing and removing extensions now scrolls to the extension afterwards, and animates this. This is done to emphasise that the operation succeeded.
2024-08-31 15:57:08 +02:00
3c0a4a6142 🌐 Updated localization 2024-08-26 15:04:37 +02:00
87ebb20284 ♻️ Use alternate cell identifier for favorite 2024-08-25 16:21:16 +02:00
d60c26c9b2 UserDefaults-backed storage for Favorites 2024-08-25 14:35:11 +02:00
5c9c51f580 Mark domain as favorite (UI only)
Please note that this functionality is currently not persistent.
As such, reloading the domain list will reset any changes you have made.
2024-08-25 13:35:27 +02:00
0c320074da ♻️ Avoid using non-Sendable Timer 2024-08-06 14:15:37 +02:00
e3ea712a99 Ensure all tests run and pass 2024-07-16 18:38:56 +02:00
4db478ca64 👌 Update copyright information 2024-07-16 18:30:56 +02:00
3064a07d69 📦 Use NVAppUpdater and NVAlert packages 2024-07-16 18:29:11 +02:00
79 changed files with 2808 additions and 899 deletions

4
.gitignore vendored
View File

@ -1,6 +1,4 @@
phpmon.xcodeproj/project.xcworkspace
phpmon.xcodeproj/xcuserdata
PHP Monitor.xcodeproj/project.xcworkspace
PHP Monitor.xcodeproj/xcuserdata
phpmon-updater/PHP Monitor Self-Updater.app/
.DS_Store

View File

@ -14,6 +14,17 @@ It also automatically runs when you try to build the project. You'll get a warni
swiftlint --fix
```
## 📦 Swift Packages
Starting from PHP Monitor 7.1, the app now uses various first-party package dependencies.
The following package dependencies are in use:
* [`NVAppUpdater`](https://github.com/nicoverbruggen/NVAppUpdater)
* [`NVAlert`](https://github.com/nicoverbruggen/NVAlert)
You may need an internet connection to download these dependencies, or you can also clone the dependencies and include them manually.
## ⚙️ Preferences
You can find the persisted configuration file in `~/Library/Preferences/com.nicoverbruggen.phpmon.plist`
@ -40,6 +51,12 @@ Once you have downloaded this repository, open `PHP Monitor.xcodeproj`, and you
If you'd like to create a production build, choose "Any Mac" as the target and select Product > Archive.
## ✅ Testing
In order to properly test everything, you will want to use the _PHP Monitor DEV_ target. There are unit and UI tests both.
You may sporadically see failures in UI tests due to the following error: `Invalid parameter not satisfying: point.x != INFINITY && point.y != INFINITY`. This seems to be an issue with Xcode that Apple may need to resolve? You can retry the tests in question and they should eventually pass.
## 🚀 Release procedure
1. Merge into `main`

View File

@ -64,11 +64,6 @@
C4068CAB27B0890D00544CD5 /* MenuBarIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4068CA927B0890D00544CD5 /* MenuBarIcons.swift */; };
C406A5F3298AD2CE00B5B85A /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = C406A5F2298AD2CE00B5B85A /* main.swift */; };
C406A5F7298AD2CF00B5B85A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C406A5F6298AD2CF00B5B85A /* Assets.xcassets */; };
C406A602298AD50D00B5B85A /* Updater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C406A601298AD50D00B5B85A /* Updater.swift */; };
C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; };
C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; };
C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; };
C4080FFB27BD956700BF2C6B /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; };
C409349D298EE8E900D25014 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C409349C298EE8E900D25014 /* AppUpdater.swift */; };
C409349E298EE8E900D25014 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C409349C298EE8E900D25014 /* AppUpdater.swift */; };
C409349F298EE8E900D25014 /* AppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = C409349C298EE8E900D25014 /* AppUpdater.swift */; };
@ -295,6 +290,10 @@
C469E700294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; };
C469E701294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; };
C469E706294CFDF700A82AB2 /* DomainsListTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E702294CFDF700A82AB2 /* DomainsListTest.swift */; };
C46DC7A42C7B55DC00F19D17 /* Favorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC7A32C7B55DC00F19D17 /* Favorites.swift */; };
C46DC7A52C7B5BC900F19D17 /* Favorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC7A32C7B55DC00F19D17 /* Favorites.swift */; };
C46DC7A62C7B5BC900F19D17 /* Favorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC7A32C7B55DC00F19D17 /* Favorites.swift */; };
C46DC7A72C7B5BCA00F19D17 /* Favorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC7A32C7B55DC00F19D17 /* Favorites.swift */; };
C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; };
C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; };
@ -305,6 +304,15 @@
C46FA9882822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */; };
C46FA9892822EFDC00D78807 /* PhpConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */; };
C46FA98C2822F08F00D78807 /* PhpConfigurationFileTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA98A2822F08F00D78807 /* PhpConfigurationFileTest.swift */; };
C47014FC2C46D31B0069AAE7 /* NVAppUpdater in Frameworks */ = {isa = PBXBuildFile; productRef = C47014FB2C46D31B0069AAE7 /* NVAppUpdater */; };
C47014FF2C46D57C0069AAE7 /* NVAlert in Frameworks */ = {isa = PBXBuildFile; productRef = C47014FE2C46D57C0069AAE7 /* NVAlert */; };
C47015022C46D6910069AAE7 /* NVAlertExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47015012C46D6910069AAE7 /* NVAlertExtension.swift */; };
C47015032C46D7F00069AAE7 /* NVAlertExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47015012C46D6910069AAE7 /* NVAlertExtension.swift */; };
C47015042C46D7F00069AAE7 /* NVAlertExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47015012C46D6910069AAE7 /* NVAlertExtension.swift */; };
C47015052C46D7F10069AAE7 /* NVAlertExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47015012C46D6910069AAE7 /* NVAlertExtension.swift */; };
C47015072C46D8180069AAE7 /* NVAlert in Frameworks */ = {isa = PBXBuildFile; productRef = C47015062C46D8180069AAE7 /* NVAlert */; };
C470150B2C46D81E0069AAE7 /* NVAlert in Frameworks */ = {isa = PBXBuildFile; productRef = C470150A2C46D81E0069AAE7 /* NVAlert */; };
C470150D2C46D83E0069AAE7 /* NVAlert in Frameworks */ = {isa = PBXBuildFile; productRef = C470150C2C46D83E0069AAE7 /* NVAlert */; };
C4709CA228524B3400088BB8 /* StatsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4709CA128524B3400088BB8 /* StatsView.swift */; };
C471E79328F9B21F0021E251 /* ActiveFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */; };
C471E79428F9B23B0021E251 /* FileSystemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */; };
@ -392,10 +400,6 @@
C471E81828F9BAE80021E251 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA23E246C358E00944F05 /* StringExtension.swift */; };
C471E81928F9BAE80021E251 /* NSMenuItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C40508B028ADAB44008FAC1F /* NSMenuItemExtension.swift */; };
C471E81A28F9BAE80021E251 /* TimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */; };
C471E81B28F9BB250021E251 /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; };
C471E81C28F9BB250021E251 /* BetterAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */; };
C471E81D28F9BB260021E251 /* BetterAlertVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */; };
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 /* ProjectTypeDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415937E27A1B54F00D2E1B7 /* ProjectTypeDetection.swift */; };
@ -720,8 +724,6 @@
C4C3643A28AE4FCE00C0770E /* StatusMenu+Items.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */; };
C4C3ED412783497000AB15D8 /* MainMenu+Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */; };
C4C3ED4327834C5200AB15D8 /* CustomPrefs.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */; };
C4C75F5A298C2D5700DFD82E /* LaunchControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C75F59298C2D5700DFD82E /* LaunchControl.swift */; };
C4C75F5C298C31C000DFD82E /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C75F5B298C31C000DFD82E /* Utility.swift */; };
C4C8900328F0E28800CE5E97 /* FileSystemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */; };
C4C8900528F0E3D100CE5E97 /* RealFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900428F0E3D100CE5E97 /* RealFileSystem.swift */; };
C4C8900728F0E3EF00CE5E97 /* ActiveFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C8900628F0E3EF00CE5E97 /* ActiveFileSystem.swift */; };
@ -946,9 +948,6 @@
C406A5F2298AD2CE00B5B85A /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
C406A5F6298AD2CF00B5B85A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
C406A5FB298AD2CF00B5B85A /* phpmon-updater.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "phpmon-updater.entitlements"; sourceTree = "<group>"; };
C406A601298AD50D00B5B85A /* Updater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Updater.swift; sourceTree = "<group>"; };
C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetterAlert.swift; sourceTree = "<group>"; };
C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BetterAlertVC.swift; sourceTree = "<group>"; };
C409349C298EE8E900D25014 /* AppUpdater.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdater.swift; sourceTree = "<group>"; };
C40934A1298EEB2C00D25014 /* CaskFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaskFile.swift; sourceTree = "<group>"; };
C40934A6298EEB8700D25014 /* phpmon-dev.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = "phpmon-dev.rb"; sourceTree = "<group>"; };
@ -1054,12 +1053,14 @@
C464ADB1275A87CA003FCD53 /* DomainListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListCellProtocol.swift; sourceTree = "<group>"; };
C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeValetProxy.swift; sourceTree = "<group>"; };
C469E702294CFDF700A82AB2 /* DomainsListTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainsListTest.swift; sourceTree = "<group>"; };
C46DC7A32C7B55DC00F19D17 /* Favorites.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Favorites.swift; sourceTree = "<group>"; };
C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = "<group>"; };
C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = "<group>"; };
C46EBC4928DB966A007ACC74 /* TestableShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShell.swift; sourceTree = "<group>"; };
C46FA23E246C358E00944F05 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
C46FA9872822EFDC00D78807 /* PhpConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigurationFile.swift; sourceTree = "<group>"; };
C46FA98A2822F08F00D78807 /* PhpConfigurationFileTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpConfigurationFileTest.swift; sourceTree = "<group>"; };
C47015012C46D6910069AAE7 /* NVAlertExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NVAlertExtension.swift; sourceTree = "<group>"; };
C4709CA128524B3400088BB8 /* StatsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatsView.swift; sourceTree = "<group>"; };
C471E79228F9B1D30021E251 /* PHP Monitor.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "PHP Monitor.xctestplan"; sourceTree = "<group>"; };
C471E7AD28F9B4940021E251 /* Feature Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Feature Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
@ -1084,6 +1085,8 @@
C4930849279F331F009C240B /* AddSiteVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddSiteVC.swift; sourceTree = "<group>"; };
C495F5AE28A42E080087F70A /* EnvironmentCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentCheck.swift; sourceTree = "<group>"; };
C4998F092617633900B2526E /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = "<group>"; };
C49DA9BC2D67AC49006F9CF4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
C49DA9BD2D67B298006F9CF4 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = id.lproj/Localizable.strings; sourceTree = "<group>"; };
C49EAA5129B12A5A00AB28FC /* Measurements.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Measurements.swift; sourceTree = "<group>"; };
C49EAA5629B1689200AB28FC /* App+BrewWatch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "App+BrewWatch.swift"; sourceTree = "<group>"; };
C4A81CA328C67101008DD9D1 /* PMTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PMTableView.swift; sourceTree = "<group>"; };
@ -1120,8 +1123,6 @@
C4C3643828AE4FCE00C0770E /* StatusMenu+Items.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusMenu+Items.swift"; sourceTree = "<group>"; };
C4C3ED402783497000AB15D8 /* MainMenu+Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Startup.swift"; sourceTree = "<group>"; };
C4C3ED4227834C5200AB15D8 /* CustomPrefs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPrefs.swift; sourceTree = "<group>"; };
C4C75F59298C2D5700DFD82E /* LaunchControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchControl.swift; sourceTree = "<group>"; };
C4C75F5B298C31C000DFD82E /* Utility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = "<group>"; };
C4C8900228F0E28800CE5E97 /* FileSystemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystemProtocol.swift; sourceTree = "<group>"; };
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>"; };
@ -1198,6 +1199,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C47014FC2C46D31B0069AAE7 /* NVAppUpdater in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1205,6 +1207,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C47014FF2C46D57C0069AAE7 /* NVAlert in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1212,6 +1215,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C470150B2C46D81E0069AAE7 /* NVAlert in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1219,6 +1223,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C470150D2C46D83E0069AAE7 /* NVAlert in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1226,6 +1231,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
C47015072C46D8180069AAE7 /* NVAlert in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1348,24 +1354,12 @@
isa = PBXGroup;
children = (
C406A5F2298AD2CE00B5B85A /* main.swift */,
C406A601298AD50D00B5B85A /* Updater.swift */,
C4C75F5B298C31C000DFD82E /* Utility.swift */,
C4C75F59298C2D5700DFD82E /* LaunchControl.swift */,
C406A5F6298AD2CF00B5B85A /* Assets.xcassets */,
C406A5FB298AD2CF00B5B85A /* phpmon-updater.entitlements */,
);
path = "phpmon-updater";
sourceTree = "<group>";
};
C4080FF827BD955900BF2C6B /* Notice */ = {
isa = PBXGroup;
children = (
C4080FF527BD8C6400BF2C6B /* BetterAlert.swift */,
C4080FF927BD956700BF2C6B /* BetterAlertVC.swift */,
);
path = Notice;
sourceTree = "<group>";
};
C40C5C9E2846A42D00E28255 /* Presets */ = {
isa = PBXGroup;
children = (
@ -1468,7 +1462,6 @@
C41E181722CB61EB0072CF09 /* Domain */ = {
isa = PBXGroup;
children = (
C4080FF827BD955900BF2C6B /* Notice */,
C4AF9F6B275445D300D44ED0 /* Integrations */,
C4B13B1D25C4915000548C3A /* App */,
C4D9ADBD27761084007277F4 /* PHP */,
@ -1789,6 +1782,7 @@
isa = PBXGroup;
children = (
C44DFA852A67090A00B98ED5 /* UI */,
C46DC7A32C7B55DC00F19D17 /* Favorites.swift */,
);
path = "Domain List";
sourceTree = "<group>";
@ -2235,6 +2229,7 @@
C44B3A4528E5C70100718CB1 /* TimeIntervalExtension.swift */,
C4E2E84928FC1E70003B070C /* DataExtension.swift */,
C4D36619291173EA006BD146 /* DictionaryExtension.swift */,
C47015012C46D6910069AAE7 /* NVAlertExtension.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -2255,6 +2250,9 @@
dependencies = (
);
name = "PHP Monitor Self-Updater";
packageProductDependencies = (
C47014FB2C46D31B0069AAE7 /* NVAppUpdater */,
);
productName = "PHP Monitor Updater";
productReference = C406A5F0298AD2CE00B5B85A /* PHP Monitor Self-Updater.app */;
productType = "com.apple.product-type.application";
@ -2275,6 +2273,7 @@
);
name = "PHP Monitor";
packageProductDependencies = (
C47014FE2C46D57C0069AAE7 /* NVAlert */,
);
productName = phpmon;
productReference = C41C1B3322B0097F00E7CF16 /* PHP Monitor.app */;
@ -2294,6 +2293,9 @@
C471E7B228F9B4940021E251 /* PBXTargetDependency */,
);
name = "Feature Tests";
packageProductDependencies = (
C470150A2C46D81E0069AAE7 /* NVAlert */,
);
productName = "Feature Tests";
productReference = C471E7AD28F9B4940021E251 /* Feature Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
@ -2312,6 +2314,9 @@
C471E7C328F9B90F0021E251 /* PBXTargetDependency */,
);
name = "UI Tests";
packageProductDependencies = (
C470150C2C46D83E0069AAE7 /* NVAlert */,
);
productName = "UI Tests";
productReference = C471E7BC28F9B90F0021E251 /* UI Tests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
@ -2331,6 +2336,7 @@
);
name = "Unit Tests";
packageProductDependencies = (
C47015062C46D8180069AAE7 /* NVAlert */,
);
productName = "phpmon-tests";
productReference = C4F7807925D7F84B000DBC97 /* Unit Tests.xctest */;
@ -2344,7 +2350,7 @@
attributes = {
BuildIndependentTargetsInParallel = YES;
LastSwiftUpdateCheck = 1420;
LastUpgradeCheck = 1530;
LastUpgradeCheck = 1620;
ORGANIZATIONNAME = "Nico Verbruggen";
TargetAttributes = {
C406A5EF298AD2CE00B5B85A = {
@ -2378,9 +2384,13 @@
Base,
fr,
"zh-Hans",
es,
id,
);
mainGroup = C41C1B2A22B0097F00E7CF16;
packageReferences = (
C47014FA2C46D31B0069AAE7 /* XCRemoteSwiftPackageReference "NVAppUpdater" */,
C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */,
);
productRefGroup = C41C1B3422B0097F00E7CF16 /* Products */;
projectDirPath = "";
@ -2508,10 +2518,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C4C75F5C298C31C000DFD82E /* Utility.swift in Sources */,
C490E3BC29BCA375006D2DE6 /* Measurements.swift in Sources */,
C406A602298AD50D00B5B85A /* Updater.swift in Sources */,
C4C75F5A298C2D5700DFD82E /* LaunchControl.swift in Sources */,
C41F3D08298AED0D0042ACBF /* System.swift in Sources */,
C406A5F3298AD2CE00B5B85A /* main.swift in Sources */,
);
@ -2552,7 +2559,6 @@
C48DDD0D29C75C9E00D032D9 /* BlockingOverlayView.swift in Sources */,
C45B91532956123A00F4EC78 /* FakeServicesManager.swift in Sources */,
C41C708D28AA7F7900E8D498 /* NoWarningsView.swift in Sources */,
C4080FF627BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
0309E6672B0D4B2F002AC007 /* BrewExtensionsObservable.swift in Sources */,
C4E0F7ED27BEBDA9007475F2 /* NSWindowExtension.swift in Sources */,
C4205A7E27F4D21800191A39 /* ValetProxy.swift in Sources */,
@ -2686,11 +2692,11 @@
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
C4FACE83288F1F9700FC478F /* OnboardingWindowController.swift in Sources */,
C4415E8D2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */,
C4080FFA27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
C43FDBE929A932B0003D85EC /* PhpConfigChecker.swift in Sources */,
C4BF56AB2949381100379603 /* FakeValetInteractor.swift in Sources */,
C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */,
C451AFF62969E40F0078E617 /* HelpButton.swift in Sources */,
C46DC7A42C7B55DC00F19D17 /* Favorites.swift in Sources */,
54D9E0B627E4F51E003B9AD9 /* HotKey.swift in Sources */,
C4AFC4AE29C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */,
C4D936C927E3EB6100BD69FE /* PhpHelper.swift in Sources */,
@ -2715,6 +2721,7 @@
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */,
C493084A279F331F009C240B /* AddSiteVC.swift in Sources */,
C4DEB7D427A5D60B00834718 /* Stats.swift in Sources */,
C47015022C46D6910069AAE7 /* NVAlertExtension.swift in Sources */,
C4E49DEA28F7643D0026AC4E /* CommandProtocol.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -2788,6 +2795,7 @@
C4E2E86628FC2F1B003B070C /* XCPMApplication.swift in Sources */,
C471E85F28F9BB650021E251 /* DomainListVC+Actions.swift in Sources */,
C4D5576629C77CC5001A44CD /* PhpVersionManagerWindowController.swift in Sources */,
C47015042C46D7F00069AAE7 /* NVAlertExtension.swift in Sources */,
C4ACE9E329F84EDD00110766 /* PhpGuard.swift in Sources */,
C471E86028F9BB650021E251 /* SelectionVC.swift in Sources */,
C471E86128F9BB650021E251 /* AddSiteVC.swift in Sources */,
@ -2855,6 +2863,7 @@
C4415E8F2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */,
C471E7D828F9BA8F0021E251 /* FileSystemProtocol.swift in Sources */,
C471E7F328F9BAC70021E251 /* PhpHelper.swift in Sources */,
C46DC7A62C7B5BC900F19D17 /* Favorites.swift in Sources */,
C471E7E728F9BAC20021E251 /* Constants.swift in Sources */,
C471E81628F9BAE80021E251 /* DateExtension.swift in Sources */,
C469E700294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */,
@ -2879,7 +2888,6 @@
C471E82A28F9BB330021E251 /* ValetListable.swift in Sources */,
031E2B6B2B1525A7007C29E1 /* BrewPhpExtension.swift in Sources */,
C471E82728F9BB310021E251 /* BrewDiagnostics.swift in Sources */,
C471E81C28F9BB250021E251 /* BetterAlert.swift in Sources */,
C471E7DB28F9BA8F0021E251 /* RealShell.swift in Sources */,
C490E3B929BCA368006D2DE6 /* App+BrewWatch.swift in Sources */,
C471E7FF28F9BAD10021E251 /* Xdebug.swift in Sources */,
@ -2896,7 +2904,6 @@
C42106682AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
C4B79EC829CA474200A483EE /* FakeCommand.swift in Sources */,
C471E7DE28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
C471E81B28F9BB250021E251 /* BetterAlertVC.swift in Sources */,
C471E82928F9BB330021E251 /* Valet.swift in Sources */,
C471E80728F9BAD40021E251 /* PhpConfigurationFile.swift in Sources */,
C471E7D528F9BA8F0021E251 /* TestableConfigurations.swift in Sources */,
@ -3004,6 +3011,7 @@
C471E8C628F9BB8F0021E251 /* PMTableView.swift in Sources */,
C471E8C728F9BB8F0021E251 /* Warning.swift in Sources */,
C471E8C828F9BB8F0021E251 /* WarningManager.swift in Sources */,
C46DC7A72C7B5BCA00F19D17 /* Favorites.swift in Sources */,
C471E8C928F9BB8F0021E251 /* PhpDoctorWindowController.swift in Sources */,
C41ADCEB2970CCC700120423 /* FSNotifier.swift in Sources */,
C471E8CA28F9BB8F0021E251 /* OnboardingWindowController.swift in Sources */,
@ -3052,6 +3060,7 @@
C456A0CE2AA6166F0080144F /* BytePhpPreference.swift in Sources */,
C4FD87A829AB9ABD0002D701 /* PhpConfigChecker.swift in Sources */,
C45B9151295608E300F4EC78 /* ValetServicesManager.swift in Sources */,
C47015032C46D7F00069AAE7 /* NVAlertExtension.swift in Sources */,
C471E8EC28F9BB8F0021E251 /* SwiftUIHelper.swift in Sources */,
C471E8EE28F9BB8F0021E251 /* HotKey.swift in Sources */,
C471E8EF28F9BB8F0021E251 /* HotKeysController.swift in Sources */,
@ -3092,7 +3101,6 @@
C4463FCF29804BCB007B93D5 /* RCFile.swift in Sources */,
C471E82C28F9BB340021E251 /* ValetListable.swift in Sources */,
C471E82828F9BB310021E251 /* BrewDiagnostics.swift in Sources */,
C471E81E28F9BB260021E251 /* BetterAlert.swift in Sources */,
C43BCD4729FBEF40001547BC /* ModifyPhpVersionCommand.swift in Sources */,
C44E985F29B23EBF0059F773 /* UpdateCheckTest.swift in Sources */,
C4513F8E2B13E2E5001AD760 /* PhpExtensionManagerWindowController.swift in Sources */,
@ -3108,7 +3116,6 @@
C471E7DD28F9BAA30021E251 /* CommandProtocol.swift in Sources */,
C471E7D128F9BA630021E251 /* RealFileSystem.swift in Sources */,
033D459B2B0D4EC600070080 /* InstallPhpExtensionCommand.swift in Sources */,
C471E81D28F9BB260021E251 /* BetterAlertVC.swift in Sources */,
C471E82B28F9BB340021E251 /* Valet.swift in Sources */,
C471E80328F9BAD40021E251 /* PhpConfigurationFile.swift in Sources */,
C471E7C928F9BA2F0021E251 /* TestableConfigurations.swift in Sources */,
@ -3165,7 +3172,6 @@
C44A874928905BB000498BC4 /* ProgressVC.swift in Sources */,
C4D9ADC0277610E1007277F4 /* PhpSwitcher.swift in Sources */,
C485707528BF454F00539B36 /* StatsView.swift in Sources */,
C4080FFB27BD956700BF2C6B /* BetterAlertVC.swift in Sources */,
C4F780CC25D80B75000DBC97 /* ActivePhpInstallation.swift in Sources */,
54D9E0BB27E4F51E003B9AD9 /* ModifierFlagsExtension.swift in Sources */,
C485707328BF454300539B36 /* OnboardingView.swift in Sources */,
@ -3213,6 +3219,7 @@
C4F780AE25D80B37000DBC97 /* PhpExtensionTest.swift in Sources */,
C456A0C72AA614BD0080144F /* PhpPreference.swift in Sources */,
C42106672AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */,
C46DC7A52C7B5BC900F19D17 /* Favorites.swift in Sources */,
C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */,
C4FC21B128391F8E00D368BB /* MainMenu+Actions.swift in Sources */,
54D9E0B927E4F51E003B9AD9 /* KeyCombo.swift in Sources */,
@ -3258,7 +3265,6 @@
C40B24F427A310830018C7D2 /* StatusMenu.swift in Sources */,
C417DC75277614690015E6EE /* Helpers.swift in Sources */,
C469E6FF294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */,
C4080FF727BD8C6400BF2C6B /* BetterAlert.swift in Sources */,
C4B97B7C275CF20A003F3378 /* App+GlobalHotkey.swift in Sources */,
5489625928313231004F647A /* CreatedFromFile.swift in Sources */,
C4513F932B13E2FB001AD760 /* PhpExtensionManagerView.swift in Sources */,
@ -3316,6 +3322,7 @@
C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */,
C4C0E8E027F88AEB002D32A9 /* FakeDomainScanner.swift in Sources */,
C4463FCD29804BCB007B93D5 /* RCFile.swift in Sources */,
C47015052C46D7F10069AAE7 /* NVAlertExtension.swift in Sources */,
C409349E298EE8E900D25014 /* AppUpdater.swift in Sources */,
C4AF9F7D275454A900D44ED0 /* ValetVersionExtractorTest.swift in Sources */,
C4B56362276AB0A500F12CCB /* VersionExtractorTest.swift in Sources */,
@ -3406,6 +3413,8 @@
C4622F572A7593CB0016F8FB /* pt-PT */,
0336CAAF2B0D0CDA009A1034 /* fr */,
C453874C2BE37FD6002B9C65 /* zh-Hans */,
C49DA9BC2D67AC49006F9CF4 /* es */,
C49DA9BD2D67B298006F9CF4 /* id */,
);
name = Localizable.strings;
sourceTree = "<group>";
@ -3432,14 +3441,14 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor Self-Updater";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023-2025 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 1.2;
MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -3467,14 +3476,14 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor Self-Updater";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023-2025 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 1.2;
MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -3502,14 +3511,14 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor Self-Updater";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023-2025 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 1.2;
MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -3537,14 +3546,14 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor Self-Updater";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023-2025 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 1.2;
MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -3685,7 +3694,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1492;
CURRENT_PROJECT_VERSION = 1535;
DEAD_CODE_STRIPPING = YES;
DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787;
@ -3698,7 +3707,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 7.0.6;
MARKETING_VERSION = 7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_MODULE_NAME = PHP_Monitor;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -3716,7 +3725,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1492;
CURRENT_PROJECT_VERSION = 1535;
DEAD_CODE_STRIPPING = YES;
DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787;
@ -3729,7 +3738,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 7.0.6;
MARKETING_VERSION = 7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_MODULE_NAME = PHP_Monitor;
PRODUCT_NAME = "$(TARGET_NAME)";
@ -3957,7 +3966,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1492;
CURRENT_PROJECT_VERSION = 1535;
DEAD_CODE_STRIPPING = YES;
DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787;
@ -3970,7 +3979,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 7.0.6;
MARKETING_VERSION = 7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
PRODUCT_MODULE_NAME = PHP_Monitor;
PRODUCT_NAME = "$(TARGET_NAME) DEV";
@ -4074,7 +4083,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1492;
CURRENT_PROJECT_VERSION = 1535;
DEAD_CODE_STRIPPING = YES;
DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787;
@ -4087,7 +4096,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 7.0.6;
MARKETING_VERSION = 7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.dev;
PRODUCT_MODULE_NAME = PHP_Monitor;
PRODUCT_NAME = "$(TARGET_NAME) DEV";
@ -4191,7 +4200,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1492;
CURRENT_PROJECT_VERSION = 1535;
DEAD_CODE_STRIPPING = YES;
DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787;
@ -4204,7 +4213,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 7.0.6;
MARKETING_VERSION = 7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
PRODUCT_MODULE_NAME = PHP_Monitor;
PRODUCT_NAME = "$(TARGET_NAME) EAP";
@ -4232,14 +4241,14 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor Self-Updater";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023-2025 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 1.2;
MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -4374,7 +4383,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1492;
CURRENT_PROJECT_VERSION = 1535;
DEAD_CODE_STRIPPING = YES;
DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787;
@ -4387,7 +4396,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 7.0.6;
MARKETING_VERSION = 7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon.eap;
PRODUCT_MODULE_NAME = PHP_Monitor;
PRODUCT_NAME = "$(TARGET_NAME) EAP";
@ -4415,14 +4424,14 @@
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = "PHP Monitor Self-Updater";
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023-2025 Nico Verbruggen. All rights reserved.";
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.4;
MARKETING_VERSION = 1.2;
MARKETING_VERSION = 1.3;
PRODUCT_BUNDLE_IDENTIFIER = "com.nicoverbruggen.phpmon-updater";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@ -4614,6 +4623,53 @@
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
C47014FA2C46D31B0069AAE7 /* XCRemoteSwiftPackageReference "NVAppUpdater" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/nicoverbruggen/NVAppUpdater";
requirement = {
branch = main;
kind = branch;
};
};
C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/nicoverbruggen/NVAlert";
requirement = {
branch = main;
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
C47014FB2C46D31B0069AAE7 /* NVAppUpdater */ = {
isa = XCSwiftPackageProductDependency;
package = C47014FA2C46D31B0069AAE7 /* XCRemoteSwiftPackageReference "NVAppUpdater" */;
productName = NVAppUpdater;
};
C47014FE2C46D57C0069AAE7 /* NVAlert */ = {
isa = XCSwiftPackageProductDependency;
package = C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */;
productName = NVAlert;
};
C47015062C46D8180069AAE7 /* NVAlert */ = {
isa = XCSwiftPackageProductDependency;
package = C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */;
productName = NVAlert;
};
C470150A2C46D81E0069AAE7 /* NVAlert */ = {
isa = XCSwiftPackageProductDependency;
package = C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */;
productName = NVAlert;
};
C470150C2C46D83E0069AAE7 /* NVAlert */ = {
isa = XCSwiftPackageProductDependency;
package = C47014FD2C46D57C0069AAE7 /* XCRemoteSwiftPackageReference "NVAlert" */;
productName = NVAlert;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = C41C1B2B22B0097F00E7CF16 /* Project object */;
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
LastUpgradeVersion = "1620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
LastUpgradeVersion = "1620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
LastUpgradeVersion = "1620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
LastUpgradeVersion = "1620"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1540"
LastUpgradeVersion = "1620"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View File

@ -22,7 +22,7 @@ You can also add new domains as links, isolate sites, manage various services, a
PHP Monitor is a universal application that runs natively on Apple Silicon **and** Intel-based Macs.
* Your user account can administer your computer (required for some functionality, e.g. certificate generation)
* macOS 12.4 or later (Monterey, Ventura and Sonoma are supported)
* macOS 12.4 or later
* Homebrew is installed in the default location (`/usr/local/homebrew` or `/opt/homebrew`)
* Homebrew `php` formula is installed
* Optional but recommended: Laravel Valet
@ -84,9 +84,13 @@ Initially, I had an Alfred workflow for this — but it has now been replaced wi
## 🐘 Why not use Laravel Herd?
If you don't need to customize your local PHP setup and just want an easy and ready-to-go environment to start coding, [Laravel Herd](https://herd.laravel.com) is probably more than sufficient for many use cases.
_**Disclaimer**: The author is not affiliated with Laravel or the Laravel team, nor Beyond Code, who maintain Laravel Herd. PHP Monitor is an independent project._
If you need more customization and flexibility I encourage you to consider PHP Monitor in combination with Laravel Valet or some other solution like Docker (with Laravel Sail, for example).
If you don't need to customize your local PHP setup and just want an easy and ready-to-go environment to start coding, [Laravel Herd](https://herd.laravel.com) is probably more than sufficient for many use cases. They also offer paid features that may be useful to you or your team.
At this point, many people enjoy using Herd. However, Herd may not be for everyone, which is why other solutions to run PHP locally exist. If you need more customization and flexibility I encourage you to consider PHP Monitor in combination with Laravel Valet.
If you want to get as close as you can to a real server environment your best bet is probably to use a Docker container. I _highly_ recommend that you try different setups, and use what you like best.
## 🤬 The app won't start?!

View File

@ -6,7 +6,7 @@ Generally speaking, only the latest version of **PHP Monitor** is supported, exc
| Version | Apple Silicon | Supported | Supported macOS | Minimum Deployment | Detected PHP Versions | Recommended Valet Version |
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
| 7.0 | ✅ 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 |
| 7.1 | ✅ Universal binary | ✅ Yes | Monterey (12.4+)<br/>Ventura (13.0+)<br/>Sonoma (14.0+)<br/>Sequoia (15.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.5 (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 youre using an
| Version | Apple Silicon | Supported | Supported macOS | Minimum Deployment | Detected PHP Versions | Minimum Required Valet Version |
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
| 7.0 | ✅ 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.2 | ✅ 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.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 |

View File

@ -1,46 +0,0 @@
//
// LaunchControl.swift
// PHP Monitor Self-Updater
//
// Created by Nico Verbruggen on 02/02/2023.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
class LaunchControl {
public static func smartRestart(priority: [String]) async {
for appPath in priority {
if FileManager.default.fileExists(atPath: appPath) {
let app = await LaunchControl.startApplication(at: appPath)
if app != nil {
return
}
}
}
}
public static func terminateApplications(bundleIds: [String]) async {
let runningApplications = NSWorkspace.shared.runningApplications
// Terminate all instances found
for id in bundleIds {
if let phpmon = runningApplications.first(where: {
(application) in return application.bundleIdentifier == id
}) {
phpmon.terminate()
}
}
}
public static func startApplication(at path: String) async -> NSRunningApplication? {
await withCheckedContinuation { continuation in
let url = NSURL(fileURLWithPath: path, isDirectory: true) as URL
let configuration = NSWorkspace.OpenConfiguration()
NSWorkspace.shared.openApplication(at: url, configuration: configuration) { phpmon, error in
continuation.resume(returning: phpmon)
}
}
}
}

View File

@ -1,162 +0,0 @@
//
// Updater.swift
// PHP Monitor Updater
//
// Created by Nico Verbruggen on 01/02/2023.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Cocoa
class Updater: NSObject, NSApplicationDelegate {
var updaterDirectory: String = ""
var manifestPath: String = ""
var manifest: ReleaseManifest! = nil
func applicationDidFinishLaunching(_ aNotification: Notification) {
Task { await self.installUpdate() }
}
func installUpdate() async {
print("PHP MONITOR SELF-UPDATER by Nico Verbruggen")
print("===========================================")
self.updaterDirectory = "~/.config/phpmon/updater"
.replacingOccurrences(of: "~", with: NSHomeDirectory())
print("Updater directory set to: \(self.updaterDirectory)")
self.manifestPath = "\(updaterDirectory)/update.json"
// Fetch the manifest on the local filesystem
let manifest = await parseManifest()!
// Download the latest file
let zipPath = await download(manifest)
// Terminate all instances of PHP Monitor first
await LaunchControl.terminateApplications(bundleIds: [
"com.nicoverbruggen.phpmon.eap",
"com.nicoverbruggen.phpmon.dev",
"com.nicoverbruggen.phpmon"
])
// Install the app based on the zip
let appPath = await extractAndInstall(zipPath: zipPath)
// Restart PHP Monitor, this will also close the updater
_ = await LaunchControl.startApplication(at: appPath)
exit(1)
}
func applicationWillTerminate(_ aNotification: Notification) {
exit(1)
}
func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool {
return false
}
private func parseManifest() async -> ReleaseManifest? {
// Read out the correct information from the manifest JSON
print("Checking manifest file at \(manifestPath)...")
do {
let manifestText = try String(contentsOfFile: manifestPath)
manifest = try JSONDecoder().decode(ReleaseManifest.self, from: manifestText.data(using: .utf8)!)
return manifest
} catch {
print("Parsing the manifest failed (or the manifest file doesn't exist)!")
await Alert.show(description: "The manifest file for a potential update was not found. Please try searching for updates again in PHP Monitor.")
}
return nil
}
private func download(_ manifest: ReleaseManifest) async -> String {
// Remove all zips
system_quiet("rm -rf \(updaterDirectory)/*.zip")
// Download the file (and follow redirects + no output on failure)
system_quiet("cd \"\(updaterDirectory)\" && curl \(manifest.url) -fLO --max-time 20")
// Identify the downloaded file
let filename = system("cd \"\(updaterDirectory)\" && ls | grep .zip")
.trimmingCharacters(in: .whitespacesAndNewlines)
// Ensure the zip exists
if filename.isEmpty {
print("The update has not been downloaded. Sadly, that means that PHP Monitor cannot not updated!")
await Alert.show(description: "The update could not be downloaded, or the file was not correctly written to disk. \n\nPlease try again. \n\n(Note that the download will time-out after 20 seconds, so for slow connections it is recommended to manually download the update.)")
}
// Calculate the checksum for the downloaded file
let checksum = system("openssl dgst -sha256 \"\(updaterDirectory)/\(filename)\" | awk '{print $NF}'")
.trimmingCharacters(in: .whitespacesAndNewlines)
// Compare the checksums
print("""
Comparing checksums...
Expected SHA256: \(manifest.sha256)
Actual SHA256: \(checksum)
""")
// Make sure the checksum matches before we do anything with the file
if checksum != manifest.sha256 {
print("The checksums failed to match. Cancelling!")
await Alert.show(description: "The downloaded update failed checksum validation. Please try again. If this issue persists, there may be an issue with the server and I do not recommend upgrading.")
}
// Return the path to the zip
return "\(updaterDirectory)/\(filename)"
}
private func extractAndInstall(zipPath: String) async -> String {
// Remove the directory that will contain the extracted update
system_quiet("rm -rf \"\(updaterDirectory)/extracted\"")
// Recreate the directory where we will unzip the .app file
system_quiet("mkdir -p \"\(updaterDirectory)/extracted\"")
// Make sure the updater directory exists
var isDirectory: ObjCBool = true
if !FileManager.default.fileExists(atPath: "\(updaterDirectory)/extracted", isDirectory: &isDirectory) {
await Alert.show(description: "The updater directory is missing. The automatic updater will quit. Make sure that ` ~/.config/phpmon/updater` is writeable.")
}
// Unzip the file
system_quiet("unzip \"\(zipPath)\" -d \"\(updaterDirectory)/extracted\"")
// Find the .app file
let app = system("ls \"\(updaterDirectory)/extracted\" | grep .app")
.trimmingCharacters(in: .whitespacesAndNewlines)
print("Finished extracting: \(updaterDirectory)/extracted/\(app)")
// Make sure the file was extracted
if app.isEmpty {
await Alert.show(description: "The downloaded file could not be extracted. The automatic updater will quit. Make sure that ` ~/.config/phpmon/updater` is writeable.")
}
// Remove the original app
print("Removing \(app) before replacing...")
system_quiet("rm -rf \"/Applications/\(app)\"")
// Move the new app in place
system_quiet("mv \"\(updaterDirectory)/extracted/\(app)\" \"/Applications/\(app)\"")
// Remove the zip
system_quiet("rm \"\(zipPath)\"")
// Remove the manifest
system_quiet("rm \"\(manifestPath)\"")
// Write a file that is only written when we upgraded successfully
system_quiet("touch \"\(updaterDirectory)/upgrade.success\"")
// Return the new location of the app
return "/Applications/\(app)"
}
}

View File

@ -1,34 +0,0 @@
//
// Utility.swift
// PHP Monitor Self-Updater
//
// Created by Nico Verbruggen on 02/02/2023.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
class Alert {
public static func show(description: String, shouldExit: Bool = true) async {
await withUnsafeContinuation { continuation in
DispatchQueue.main.async {
let alert = NSAlert()
alert.messageText = "The app could not be updated."
alert.informativeText = description
alert.addButton(withTitle: "OK")
alert.alertStyle = .critical
alert.runModal()
if shouldExit {
exit(0)
}
continuation.resume()
}
}
}
}
public struct ReleaseManifest: Codable {
let url: String
let sha256: String
}

View File

@ -7,8 +7,17 @@
//
import Cocoa
import NVAppUpdater
let app = NSApplication.shared
let delegate = Updater()
app.delegate = delegate
let delegate = SelfUpdater(
appName: "PHP Monitor",
bundleIdentifiers: [
"com.nicoverbruggen.phpmon.eap",
"com.nicoverbruggen.phpmon.dev",
"com.nicoverbruggen.phpmon"
],
selfUpdaterPath: "~/.config/phpmon/updater"
)
NSApplication.shared.delegate = delegate
_ = NSApplicationMain(CommandLine.argc, CommandLine.unsafeArgv)

View File

@ -24,13 +24,13 @@ struct Constants {
This hardcoded list will expire and will need to be modified when
the cutoff date occurs, which is when the `php` formula will
become PHP 8.4, and a new build will need to be made.
become PHP 8.5, and a new build will need to be made.
If users launch an older version of the app, then a warning
will be displayed to let them know that certain operations
will not work correctly and that they need to update their app.
*/
static let PhpFormulaeCutoffDate = "2024-11-30" // YYYY-MM-DD
static let PhpFormulaeCutoffDate = "2025-11-30" // YYYY-MM-DD
/**
* The PHP versions that are considered pre-release versions.
@ -39,6 +39,7 @@ struct Constants {
*/
static var ExperimentalPhpVersions: Set<String> {
let releaseDates = [
"8.5": Date.fromString(Self.PhpFormulaeCutoffDate),
"8.4": Date.fromString("2024-11-22")
]
@ -72,8 +73,8 @@ struct Constants {
static let DetectedPhpVersions: Set = [
"5.6",
"7.0", "7.1", "7.2", "7.3", "7.4",
"8.0", "8.1", "8.2", "8.3",
"8.4"
"8.0", "8.1", "8.2", "8.3", "8.4",
"8.5" // DEV
]
/**
@ -89,14 +90,13 @@ struct Constants {
3: // Valet v3 dropped support for v5.6
[
"7.0", "7.1", "7.2", "7.3", "7.4",
"8.0", "8.1", "8.2", "8.3",
"8.4" // dev
"8.0", "8.1", "8.2", "8.3", "8.4"
],
4: // Valet v4 dropped support for v7.0
[
"7.1", "7.2", "7.3", "7.4",
"8.0", "8.1", "8.2", "8.3",
"8.4" // dev
"8.0", "8.1", "8.2", "8.3", "8.4",
"8.5" // DEV
]
]
@ -112,6 +112,14 @@ struct Constants {
string: "https://phpmon.app/faq"
)!
static let WikiPhpUnavailable = URL(
string: "https://phpmon.app/php-unavailable"
)!
static let WikiPhpUpgrade = URL(
string: "https://phpmon.app/php-upgrade"
)!
static let DonationPayment = URL(
string: "https://phpmon.app/sponsor/now"
)!

View File

@ -45,7 +45,6 @@ func grepContains(file: String, query: String) async -> Bool {
/**
Attempts to introduce sleep for a particular duration. Use with caution.
Only intended for testing purposes.
*/
func delay(seconds: Double) async {
try! await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))

View File

@ -8,6 +8,6 @@
import Foundation
protocol AlertableError {
public protocol AlertableError {
func getErrorMessageKey() -> String
}

View File

@ -0,0 +1,23 @@
//
// NVAlertExtension.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 16/07/2024.
// Copyright © 2024 Nico Verbruggen. All rights reserved.
//
import Foundation
import NVAlert
extension NVAlert {
/**
Shows the modal for a particular error.
*/
@MainActor public static func show(for error: Error & AlertableError) {
let key = error.getErrorMessageKey()
return NVAlert().withInformation(
title: "\(key).title".localized,
subtitle: "\(key).description".localized
).withPrimary(text: "generic.ok".localized).show()
}
}

View File

@ -14,6 +14,8 @@ class PhpInstallation {
var iniFiles: [PhpConfigurationFile] = []
var isPreRelease: Bool = false
var isMissingBinary: Bool = false
var isHealthy: Bool = true
@ -59,6 +61,10 @@ class PhpInstallation {
trimNewlines: false
).trimmingCharacters(in: .whitespacesAndNewlines)
if longVersionString.contains("-dev") {
isPreRelease = true
}
// 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.
versionNumber = try! VersionNumber.parse(longVersionString)

View File

@ -8,9 +8,6 @@
import Foundation
extension Process: @unchecked Sendable {}
extension Timer: @unchecked Sendable {}
class RealShell: ShellProtocol {
/**
The launch path of the terminal in question that is used.
@ -184,25 +181,26 @@ class RealShell: ShellProtocol {
}
return try await withCheckedThrowingContinuation({ continuation in
let timer = Timer.scheduledTimer(withTimeInterval: timeout, repeats: false) { _ in
let task = Task {
try await Task.sleep(nanoseconds: timeout.nanoseconds)
// Only terminate if the process is still running
if process.isRunning {
process.terminationHandler = nil
process.terminate()
return continuation.resume(throwing: ShellError.timedOut)
continuation.resume(throwing: ShellError.timedOut)
}
}
process.terminationHandler = { [timer, output] process in
timer.invalidate()
process.terminationHandler = { [output] process in
task.cancel()
process.haltListening()
if !output.err.isEmpty {
return continuation.resume(returning: (process, .err(output.err)))
continuation.resume(returning: (process, .err(output.err)))
} else {
continuation.resume(returning: (process, .out(output.out)))
}
return continuation.resume(returning: (process, .out(output.out)))
}
process.launch()
@ -210,3 +208,9 @@ class RealShell: ShellProtocol {
})
}
}
extension TimeInterval {
var nanoseconds: UInt64 {
return UInt64(self * 1_000_000_000)
}
}

View File

@ -18,11 +18,11 @@ class TestableFileSystem: FileSystemProtocol {
self.files = files
// Ensure that each of the ~ characters are replaced with the home directory path
for key in self.files.keys where key.contains("~") {
self.files.renameKey(
fromKey: key,
toKey: key.replacingOccurrences(of: "~", with: self.homeDirectory)
)
accessQueue.sync {
for (key, value) in files {
let adjustedKey = key.contains("~") ? key.replacingOccurrences(of: "~", with: self.homeDirectory) : key
self.files[adjustedKey] = value
}
}
// Ensure that intermediate directories are created
@ -46,38 +46,49 @@ class TestableFileSystem: FileSystemProtocol {
*/
private(set) var homeDirectory = "/Users/fake"
/**
Serial dispatch queue for ensuring thread-safe access to the `files` dictionary.
*/
private let accessQueue = DispatchQueue(label: "com.testablefilesystem.accessQueue")
// MARK: - Basics
func createDirectory(_ path: String, withIntermediateDirectories: Bool) throws {
let path = path.replacingTildeWithHomeDirectory
if files[path] != nil {
throw TestableFileSystemError.alreadyExists
try accessQueue.sync {
if files[path] != nil {
throw TestableFileSystemError.alreadyExists
}
self.createIntermediateDirectories(path)
self.files[path] = .fake(.directory)
}
self.createIntermediateDirectories(path)
self.files[path] = .fake(.directory)
}
func writeAtomicallyToFile(_ path: String, content: String) throws {
let path = path.replacingTildeWithHomeDirectory
if files[path] != nil {
throw TestableFileSystemError.alreadyExists
}
try accessQueue.sync {
if files[path] != nil {
throw TestableFileSystemError.alreadyExists
}
self.files[path] = .fake(.text, content)
self.files[path] = .fake(.text, content)
}
}
func getStringFromFile(_ path: String) throws -> String {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path] else {
throw TestableFileSystemError.fileMissing
}
return try accessQueue.sync {
guard let file = files[path] else {
throw TestableFileSystemError.fileMissing
}
return file.content ?? ""
return file.content ?? ""
}
}
func getShallowContentsOfDirectory(_ path: String) throws -> [String] {
@ -88,32 +99,36 @@ class TestableFileSystem: FileSystemProtocol {
seek = "\(seek)/"
}
return self.files.keys
.filter { $0.hasPrefix(seek) }
.map { $0.replacingOccurrences(of: seek, with: "") }
.filter { !$0.contains("/") }
return accessQueue.sync {
self.files.keys
.filter { $0.hasPrefix(seek) }
.map { $0.replacingOccurrences(of: seek, with: "") }
.filter { !$0.contains("/") }
}
}
func getDestinationOfSymlink(_ path: String) throws -> String {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path] else {
throw TestableFileSystemError.fileMissing
}
return try accessQueue.sync {
guard let file = files[path] else {
throw TestableFileSystemError.fileMissing
}
if file.type != .symlink {
throw TestableFileSystemError.notSymlink
}
if file.type != .symlink {
throw TestableFileSystemError.notSymlink
}
guard let pathToSymlink = file.content else {
throw TestableFileSystemError.invalidSymlink
}
guard let pathToSymlink = file.content else {
throw TestableFileSystemError.invalidSymlink
}
if !files.keys.contains(pathToSymlink) {
throw TestableFileSystemError.invalidSymlink
}
if !files.keys.contains(pathToSymlink) {
throw TestableFileSystemError.invalidSymlink
}
return pathToSymlink
return pathToSymlink
}
}
// MARK: - Move & Delete Files
@ -122,27 +137,31 @@ class TestableFileSystem: FileSystemProtocol {
let path = path.replacingTildeWithHomeDirectory
let newPath = newPath.replacingTildeWithHomeDirectory
self.files.keys.forEach { key in
if key.hasPrefix(path) {
self.files.renameKey(
fromKey: key,
toKey: key.replacingOccurrences(of: path, with: newPath)
)
accessQueue.sync {
self.files.keys.forEach { key in
if key.hasPrefix(path) {
self.files.renameKey(
fromKey: key,
toKey: key.replacingOccurrences(of: path, with: newPath)
)
}
}
}
self.files.renameKey(fromKey: path, toKey: newPath)
self.files.renameKey(fromKey: path, toKey: newPath)
}
}
func remove(_ path: String) throws {
// Remove recursively
self.files.keys.forEach { key in
if key.hasPrefix(path) {
self.files.removeValue(forKey: key)
accessQueue.sync {
// Remove recursively
self.files.keys.forEach { key in
if key.hasPrefix(path) {
self.files.removeValue(forKey: key)
}
}
}
self.files.removeValue(forKey: path)
self.files.removeValue(forKey: path)
}
}
// MARK: Attributes
@ -150,11 +169,13 @@ class TestableFileSystem: FileSystemProtocol {
func makeExecutable(_ path: String) throws {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path] else {
throw TestableFileSystemError.fileMissing
}
try accessQueue.sync {
guard let file = files[path] else {
throw TestableFileSystemError.fileMissing
}
file.type = .binary
file.type = .binary
}
}
// MARK: - Checks
@ -162,93 +183,107 @@ class TestableFileSystem: FileSystemProtocol {
func isExecutableFile(_ path: String) -> Bool {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path.replacingTildeWithHomeDirectory] else {
return false
}
return accessQueue.sync {
guard let file = files[path.replacingTildeWithHomeDirectory] else {
return false
}
return file.type == .binary
return file.type == .binary
}
}
func isWriteableFile(_ path: String) -> Bool {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path.replacingTildeWithHomeDirectory] else {
return false
}
return accessQueue.sync {
guard let file = files[path.replacingTildeWithHomeDirectory] else {
return false
}
return !file.readOnly
return !file.readOnly
}
}
func anyExists(_ path: String) -> Bool {
let path = path.replacingTildeWithHomeDirectory
return files.keys.contains(path)
return accessQueue.sync {
files.keys.contains(path)
}
}
func fileExists(_ path: String) -> Bool {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path] else {
return false
}
return accessQueue.sync {
guard let file = files[path] else {
return false
}
return [.binary, .symlink, .text].contains(file.type)
return [.binary, .symlink, .text].contains(file.type)
}
}
func directoryExists(_ path: String) -> Bool {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path] else {
return false
}
return accessQueue.sync {
guard let file = files[path] else {
return false
}
return [.directory].contains(file.type)
return [.directory].contains(file.type)
}
}
func isSymlink(_ path: String) -> Bool {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path] else {
return false
}
return accessQueue.sync {
guard let file = files[path] else {
return false
}
return file.type == .symlink
return file.type == .symlink
}
}
func isDirectory(_ path: String) -> Bool {
let path = path.replacingTildeWithHomeDirectory
guard let file = files[path] else {
return false
}
return accessQueue.sync {
guard let file = files[path] else {
return false
}
return file.type == .directory
return file.type == .directory
}
}
public func printContents() {
for key in self.files.keys.sorted() {
print("\(key) -> \(self.files[key]!.type)")
accessQueue.sync {
for key in self.files.keys.sorted() {
print("\(key) -> \(self.files[key]!.type)")
}
}
}
private func createIntermediateDirectories(_ path: String) {
let path = path.replacingTildeWithHomeDirectory
let items = path.components(separatedBy: "/")
var preceding = ""
var directoriesToCreate: [String] = []
for item in items {
let key = preceding == "/"
? "/\(item)"
: "\(preceding)/\(item)"
if !self.files.keys.contains(key) {
self.files[key] = .fake(.directory)
}
let key = preceding == "/" ? "/\(item)" : "\(preceding)/\(item)"
directoriesToCreate.append(key)
preceding = key
}
for key in directoriesToCreate where !self.files.keys.contains(key) {
self.files[key] = .fake(.directory)
}
}
}

View File

@ -16,9 +16,9 @@
<p><b>Do you enjoy using the app? Is it helping you save time?</b> Leave a <a href="https://phpmon.app/github">star on GitHub</a>!</p>
<p><b>Having issues?</b> Consult the <a href="https://phpmon.app/faq">FAQ</a> section, I did my best to ensure everything is documented.</p>
<p><b>Want to support further development of PHP Monitor?</b> You can <a href="https://phpmon.app/sponsor">financially support</a> the continued development of this app.</p>
<p><b>Get the latest on Twitter or Mastodon.</b> Give me a <a href="https://twitter.com/nicoverbruggen">follow on Twitter</a> or <a href="https://phpc.social/@nicoverbruggen">Mastodon</a> to learn about what's brewing and when new updates drop.</p>
<p><b>Get the latest on Bluesky or Mastodon.</b> Give me a <a href="https://bsky.app/profile/nicoverbruggen.be">follow on Bluesky</a> or <a href="https://phpc.social/@nicoverbruggen">Mastodon</a> to learn about what's brewing and when new updates drop.</p>
<p><b>Special thanks</b> to all current and past <a href="https://github.com/sponsors/nicoverbruggen#sponsors"><b>sponsors</b></a> of PHP Monitor, who have helped to make further development of the app possible.</p>
<p><b>Made possible by these GitHub Sponsors</b>: @abdusfauzi, @abicons, @adrolli, @andresayej, @andyunleashed, @anzacorp, @argirisp, @AshPowell, @aurawindsurfing, @awsmug, @barrycarton, @BertvanHoekelen, @calebporzio, @caseyalee, @cgreuling, @cjcox17, @Diewy, @drfraker, @driftingly, @duellsy, @edalzell, @EYOND, @faithfm, @frankmichel, @gwleuverink, @hopkins385, @intrepidws, @jacksleight, @JacobBennett, @jasonvarga, @jeromegamez, @jimmyaldape, @jimmysawczuk, @joetannenbaum, @jolora, @joshuablum, @jpeinelt, @jreviews, @JustSteveKing, @Kajvdh, @KFoobar, @Laravel-Backpack, @leganz, @martinleveille, @mathiasonea, @matthewmnewman, @mcastillo1030, @megabubbletea, @mennen-online, @mike-healy, @mostafakram, @mpociot, @MrMicky-FR, @MrMooky, @murdercode, @nckrtl, @nhedger, @ninjaparade, @ozanuzer, @pepatel, @philbraun, @pickuse2013, @pk-informatics, @Plytas, @rderimay, @rickyjohnston, @rico, @RobertBoes, @runofthemill, @SahinU88, @sdebacker, @sdevore, @shadracnicholas, @simonhamp, @SRWieZ, @stefanbauer, @StriveMedia, @swilla, @Tailcode-Studio, @theutz, @ThomasEnssner, @tillkruss, @timothyrowan, @ttnppedr, @vincent-tarrit, @WheresMarco, @xPand4B, @xuandung38, @yeslandi89, @zackkatz, @zacksmash, @zaherg.<br/>(Some names have been omitted due to their sponsorships being private. Thank you all!)</p>
<p><b>Made possible by these GitHub Sponsors</b>: @abdusfauzi, @abicons, @adibnoh, @adrolli, @andresayej, @andyunleashed, @anzacorp, @argirisp, @ash-jc-allen, @AshPowell, @aurawindsurfing, @awsmug, @barrycarton, @BertvanHoekelen, @calebporzio, @casenxu, @caseyalee, @cgreuling, @cjcox17, @clescuyer, @codelinde, @designhammer, @Diewy, @drfraker, @driftingly, @duellsy, @e9li, @edalzell, @EYOND, @faithfm, @frankmichel, @gekich, @gpluess, @gwleuverink, @hopkins385, @incon, @intrepidws, @israaraujo, @jacksleight, @JacobBennett, @jasonvarga, @jeromegamez, @jimmyaldape, @jimmysawczuk, @joetannenbaum, @jolora, @jorisnoo, @joshuablum, @jpeinelt, @jreviews, @JustSteveKing, @Kajvdh, @KFoobar, @kholisabdullah, @Laravel-Backpack, @leganz, @lucianvacaroiu,@martinleveille, @mathiasonea, @matthewmnewman, @mcastillo1030, @megabubbletea, @megabubbleteam, @mennen-online, @mike-healy, @mostafakram, @mpociot, @MrMicky-FR, @MrMooky, @murdercode, @nckrtl, @nhedger, @ninjaparade, @ozanuzer, @pepatel, @philbraun, @pickuse2013, @pk-informatics, @Plytas, @rastitkac, @rderimay, @renecum, @richardhulbert, @richardtape, @rickyjohnston, @rico, @RobertBoes, @runofthemill, @SahinU88, @sdebacker, @sdevore, @shadracnicholas, @simonhamp, @slaFFik, @spatie, @SRWieZ, @stefanbauer, @stefanzweifel, @StriveMedia, @swilla, @Tailcode-Studio, @theutz, @ThomasEnssner, @tillkruss, @timothyrowan, @ttnppedr, @vincent-tarrit, @vintagesucks, @WheresMarco, @xPand4B, @xuandung38, @yeslandi89, @zackkatz, @zacksmash, @zaherg.<br/>(This is a historical list of sponsors, not current sponsors. Some names have been omitted due to their sponsorships being private. Thank you all!)</p>
<p><b>Localization credits:</b></br>
&dash; English, Dutch</b> by @nicoverbruggen</br>
&dash; Vietnamese</b> by @xuandung38</br>
@ -26,6 +26,8 @@
&dash; Portuguese</b> by @joseborges</br>
&dash; French</b> by @nhedger, @tplesnar</br>
&dash; Chinese</b> by @guanguans</br>
</br>
Other languages are considered experimental, and were generated via a local LLM. If you have feedback or concerns, please don't hesitate to get in touch.
</p>
<br/>
</body>

View File

@ -89,6 +89,9 @@ class App {
/** List of detected (installed) applications that PHP Monitor can work with. */
var detectedApplications: [Application] = []
/** Favorites storage, which keeps track of favorited domains. */
var favorites = Favorites.shared
/** The warning manager, responsible for keeping track of warnings. */
var warnings = WarningManager.shared

View File

@ -8,6 +8,7 @@
import Foundation
import Cocoa
import NVAlert
class AppUpdater {
var caskFile: CaskFile!
@ -72,7 +73,7 @@ class AppUpdater {
: "brew upgrade phpmon"
Task { @MainActor in
BetterAlert().withInformation(
NVAlert().withInformation(
title: "updater.alerts.newer_version_available.title"
.localized(latestVersionOnline.humanReadable),
subtitle: "updater.alerts.newer_version_available.subtitle"
@ -112,7 +113,7 @@ class AppUpdater {
public func presentNoNewerVersionAvailableAlert() {
Task { @MainActor in
BetterAlert().withInformation(
NVAlert().withInformation(
title: "updater.alerts.is_latest_version.title".localized,
subtitle: "updater.alerts.is_latest_version.subtitle".localized(App.shortVersion),
description: ""
@ -124,7 +125,7 @@ class AppUpdater {
public func presentCouldNotRetrieveUpdate() {
Task { @MainActor in
BetterAlert().withInformation(
NVAlert().withInformation(
title: "updater.alerts.cannot_check_for_update.title".localized,
subtitle: "updater.alerts.cannot_check_for_update.subtitle".localized,
description: "updater.alerts.cannot_check_for_update.description".localized(

View File

@ -515,10 +515,10 @@
</objects>
<point key="canvasLocation" x="-374" y="2267"/>
</scene>
<!--Better AlertVC-->
<!--AlertVC-->
<scene sceneID="y9E-bB-wIG">
<objects>
<viewController storyboardIdentifier="noticeVC" id="hkw-9V-NxP" customClass="BetterAlertVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
<viewController storyboardIdentifier="noticeVC" id="hkw-9V-NxP" customClass="NVAlertVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="UPH-hV-Naz">
<rect key="frame" x="0.0" y="0.0" width="500" height="212"/>
<autoresizingMask key="autoresizingMask"/>
@ -826,6 +826,13 @@ Gw
<rect key="frame" x="0.0" y="0.0" width="626" height="309"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<progressIndicator maxValue="100" displayedWhenStopped="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="ZiS-Gq-TLQ">
<rect key="frame" x="298" y="150" width="30" height="30"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="XK3-AR-Oc0"/>
<constraint firstAttribute="height" constant="30" id="lfW-dB-Eu3"/>
</constraints>
</progressIndicator>
<scrollView borderType="none" horizontalLineScroll="54" horizontalPageScroll="10" verticalLineScroll="54" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p0j-eB-I2i">
<rect key="frame" x="0.0" y="0.0" width="626" height="309"/>
<clipView key="contentView" ambiguous="YES" drawsBackground="NO" id="6IL-DW-37w">
@ -923,6 +930,50 @@ Gw
<outlet property="labelSiteName" destination="XJL-Uw-frD" id="f0t-vd-W68"/>
</connections>
</tableCellView>
<tableCellView identifier="domainListNameCellFavorited" wantsLayer="YES" id="Byb-te-u65" customClass="DomainListNameCell" customModule="PHP_Monitor" customModuleProvider="target">
<rect key="frame" x="69" y="54" width="200" height="54"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="aot-FJ-HIk">
<rect key="frame" x="33" y="26" width="145" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="my-domain-name.test" id="LHu-UF-QlC">
<font key="font" metaFont="systemSemibold" size="13"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField focusRingType="none" horizontalHuggingPriority="251" verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="GNH-l8-oki">
<rect key="frame" x="33" y="12" width="75" height="14"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="~/path/to/site" id="LNw-Ju-0Ot">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="3Wp-DX-An9">
<rect key="frame" x="5" y="4" width="20" height="47"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="Q76-fI-lkW">
<imageReference key="image" image="star.circle.fill" catalog="system" symbolScale="large"/>
</imageCell>
<color key="contentTintColor" name="AccentColor"/>
</imageView>
</subviews>
<constraints>
<constraint firstItem="3Wp-DX-An9" firstAttribute="leading" secondItem="Byb-te-u65" secondAttribute="leading" constant="5" id="CTd-ON-loK"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="aot-FJ-HIk" secondAttribute="trailing" constant="20" symbolic="YES" id="Csc-Dy-H4K"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="GNH-l8-oki" secondAttribute="trailing" constant="20" symbolic="YES" id="H10-MG-hCG"/>
<constraint firstItem="GNH-l8-oki" firstAttribute="leading" secondItem="aot-FJ-HIk" secondAttribute="leading" id="Hk0-x3-RyN"/>
<constraint firstItem="3Wp-DX-An9" firstAttribute="top" secondItem="Byb-te-u65" secondAttribute="top" constant="9" id="erH-dR-K7S"/>
<constraint firstItem="aot-FJ-HIk" firstAttribute="top" secondItem="Byb-te-u65" secondAttribute="top" constant="12" id="ktI-fg-qaX"/>
<constraint firstAttribute="bottom" secondItem="3Wp-DX-An9" secondAttribute="bottom" constant="9" id="uyc-26-gZb"/>
<constraint firstItem="aot-FJ-HIk" firstAttribute="leading" secondItem="Byb-te-u65" secondAttribute="leading" constant="35" id="vXE-jj-lLF"/>
<constraint firstItem="GNH-l8-oki" firstAttribute="top" secondItem="aot-FJ-HIk" secondAttribute="bottom" id="wSX-fR-O7a"/>
</constraints>
<connections>
<outlet property="labelPathName" destination="GNH-l8-oki" id="GC1-TA-lIk"/>
<outlet property="labelSiteName" destination="aot-FJ-HIk" id="HdZ-Rh-ua6"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn identifier="ENVIRONMENT" width="100" minWidth="100" maxWidth="150" id="hzb-XI-Out">
@ -1092,13 +1143,6 @@ Gw
<autoresizingMask key="autoresizingMask"/>
</tableHeaderView>
</scrollView>
<progressIndicator maxValue="100" displayedWhenStopped="NO" indeterminate="YES" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="ZiS-Gq-TLQ">
<rect key="frame" x="298" y="150" width="30" height="30"/>
<constraints>
<constraint firstAttribute="width" constant="30" id="XK3-AR-Oc0"/>
<constraint firstAttribute="height" constant="30" id="lfW-dB-Eu3"/>
</constraints>
</progressIndicator>
<customView translatesAutoresizingMaskIntoConstraints="NO" id="wcV-ed-8Bv">
<rect key="frame" x="113" y="5" width="400" height="300"/>
<constraints>
@ -1126,7 +1170,7 @@ Gw
</viewController>
<customObject id="HgD-aB-bQb" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="323" y="723"/>
<point key="canvasLocation" x="323" y="722.5"/>
</scene>
<!--Add ProxyVC-->
<scene sceneID="g8z-pE-RL9">
@ -1503,6 +1547,10 @@ Gw
<image name="Lock" width="30" height="30"/>
<image name="arrow.clockwise" catalog="system" width="14" height="16"/>
<image name="plus" catalog="system" width="14" height="13"/>
<image name="star.circle.fill" catalog="system" width="20" height="20"/>
<namedColor name="AccentColor">
<color red="0.0" green="0.46000000000000002" blue="0.89000000000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="IconColorGreen">
<color red="0.24699999392032623" green="0.69700002670288086" blue="0.50099998712539673" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>

View File

@ -8,6 +8,7 @@
import Foundation
import Cocoa
import NVAlert
class ValetServicesManager: ServicesManager {
override init() {
@ -131,7 +132,7 @@ class ValetServicesManager: ServicesManager {
Log.err("The service '\(named)' is now reporting an error.")
guard let errorLogPath = after.error_log_path else {
return BetterAlert().withInformation(
return NVAlert().withInformation(
title: "alert.service_error.title".localized(named),
subtitle: "alert.service_error.subtitle.no_error_log".localized(named),
description: "alert.service_error.extra".localized
@ -140,7 +141,7 @@ class ValetServicesManager: ServicesManager {
.show()
}
BetterAlert().withInformation(
NVAlert().withInformation(
title: "alert.service_error.title".localized(named),
subtitle: "alert.service_error.subtitle.error_log".localized(named),
description: "alert.service_error.extra".localized

View File

@ -7,9 +7,24 @@
import Foundation
import AppKit
import NVAlert
class Startup {
@MainActor static var startupTimer: Timer?
@MainActor func startTimeoutTimer() {
Self.startupTimer = Timer.scheduledTimer(
timeInterval: 30.0, target: self, selector: #selector(startupTimeout),
userInfo: nil, repeats: false
)
}
@MainActor static func invalidateTimeoutTimer() {
Self.startupTimer?.invalidate()
Self.startupTimer = nil
}
/**
Checks the user's environment and checks if PHP Monitor can be used properly.
This checks if PHP is installed, Valet is running, the appropriate permissions are set, and more.
@ -21,6 +36,11 @@ class Startup {
// Do the important system setup checks
Log.info("The user is running PHP Monitor with the architecture: \(App.architecture)")
// Set up a "background" timer on the main thread
Task { @MainActor in
startTimeoutTimer()
}
for group in self.groups {
if group.condition() {
Log.info("Now running \(group.checks.count) \(group.name) checks!")
@ -44,10 +64,34 @@ class Startup {
// If we get here, nothing has gone wrong. That's what we want!
initializeSwitcher()
Log.info("PHP Monitor has determined the application has successfully passed all checks.")
Log.separator(as: .info)
return true
}
/**
Displays an alert for when the application startup process takes too long.
*/
@MainActor @objc func startupTimeout() {
NVAlert()
.withInformation(
title: "startup.timeout.title".localized,
subtitle: "startup.timeout.subtitle".localized,
description: "startup.timeout.description".localized
)
.withPrimary(text: "alert.cannot_start.close".localized, action: { vc in
vc.close(with: .alertFirstButtonReturn)
exit(1)
})
.withSecondary(text: "startup.timeout.ignore".localized, action: { vc in
vc.close(with: .alertSecondButtonReturn)
})
.withTertiary(text: "", action: { _ in
NSWorkspace.shared.open(URL(string: "https://github.com/nicoverbruggen/phpmon/issues/294")!)
})
.show()
}
/**
Displays an alert for a particular check. There are two types of alerts:
- ones that require an app restart, which prompt the user to exit the app
@ -55,7 +99,7 @@ class Startup {
*/
@MainActor private func showAlert(for check: EnvironmentCheck) {
if check.requiresAppRestart {
BetterAlert()
NVAlert()
.withInformation(
title: check.titleText,
subtitle: check.subtitleText,
@ -66,7 +110,7 @@ class Startup {
}).show()
}
BetterAlert()
NVAlert()
.withInformation(
title: check.titleText,
subtitle: check.subtitleText,

View File

@ -7,6 +7,7 @@
//
import Foundation
import NVAlert
@MainActor class ComposerWindow {
private var shouldNotify: Bool! = nil
@ -109,7 +110,7 @@ import Foundation
// MARK: Alert
private func presentMissingAlert() {
BetterAlert()
NVAlert()
.withInformation(
title: "alert.composer_missing.title".localized,
subtitle: "alert.composer_missing.subtitle".localized,

View File

@ -35,10 +35,11 @@ class Brew {
/// Each formula for each PHP version that can be installed.
public static let phpVersionFormulae = [
"8.5": "shivammathur/php/php@8.5",
"8.4": "shivammathur/php/php@8.4",
"8.3": "php@8.3",
"8.2": "php@8.2",
"8.1": "php@8.1",
"8.3": "shivammathur/php/php@8.3",
"8.2": "shivammathur/php/php@8.2",
"8.1": "shivammathur/php/php@8.1",
"8.0": "shivammathur/php/php@8.0",
"7.4": "shivammathur/php/php@7.4",
"7.3": "shivammathur/php/php@7.3",

View File

@ -7,6 +7,7 @@
//
import Foundation
import NVAlert
class BrewDiagnostics {
/**
@ -183,7 +184,7 @@ class BrewDiagnostics {
*/
private static func presentAlertAboutConflict() {
Task { @MainActor in
BetterAlert()
NVAlert()
.withInformation(
title: "alert.php_alias_conflict.title".localized,
subtitle: "alert.php_alias_conflict.info".localized

View File

@ -21,11 +21,12 @@ struct BrewPhpFormula: Equatable {
/// The upgrade that is currently available, if it exists.
let upgradeVersion: String?
// TODO: A rebuild attribute could be checked, to check if a Tap update exists for a pre-release version
/// Whether this formula is a stable version of PHP.
let prerelease: Bool
/// Whether this formula's associated Homebrew file exists.
var hasFormulaFile: Bool = false
/// Whether the formula is currently installed.
var isInstalled: Bool {
return installedVersion != nil
@ -43,6 +44,7 @@ struct BrewPhpFormula: Equatable {
self.installedVersion = installedVersion
self.upgradeVersion = upgradeVersion
self.prerelease = prerelease
self.hasFormulaFile = checkFormulaFile()
}
/// Whether the formula can be upgraded.
@ -93,6 +95,21 @@ struct BrewPhpFormula: Equatable {
return isHealthy() ?? true
}
/**
Verify whether the formula file exists (sourced via `shivammathur/homebrew-php`).
If it does not exist, the formula cannot be installed.
*/
private func checkFormulaFile() -> Bool {
guard let version = shortVersion else {
return false
}
return FileSystem.fileExists(
"\(Paths.tapPath)/shivammathur/homebrew-php/Formula/php@\(version).rb"
.replacingOccurrences(of: "php@" + PhpEnvironments.brewPhpAlias, with: "php")
)
}
/**
* Determines if this PHP installation is healthy.
* Uses the cached installation health check as basis.

View File

@ -39,19 +39,25 @@ class BrewPhpFormulaeHandler: HandlesBrewPhpFormulae {
OutdatedFormulae.self,
from: rawJsonText
).formulae.filter({ formula in
formula.name.starts(with: "php")
formula.name.starts(with: "shivammathur/php/php") || formula.name.starts(with: "php")
})
}
return Brew.phpVersionFormulae.map { (version, formula) in
var fullVersion: String?
var upgradeVersion: String?
var isPrerelease: Bool = Constants.ExperimentalPhpVersions.contains(version)
if let install = PhpEnvironments.shared.cachedPhpInstallations[version] {
fullVersion = install.versionNumber.text
fullVersion = install.isPreRelease ? "\(fullVersion!)-dev" : fullVersion
upgradeVersion = outdated?.first(where: { formula in
return formula.name == install.formulaName
return formula.name.replacingOccurrences(of: "shivammathur/php/", with: "")
== install.formulaName.replacingOccurrences(of: "shivammathur/php/", with: "")
})?.current_version
isPrerelease = install.isPreRelease
}
return BrewPhpFormula(
@ -59,7 +65,7 @@ class BrewPhpFormulaeHandler: HandlesBrewPhpFormulae {
displayName: "PHP \(version)",
installedVersion: fullVersion,
upgradeVersion: upgradeVersion,
prerelease: Constants.ExperimentalPhpVersions.contains(version)
prerelease: isPrerelease
)
}.sorted { $0.displayName > $1.displayName }
}

View File

@ -16,21 +16,65 @@ protocol BrewCommand {
extension BrewCommand {
internal func reportInstallationProgress(_ text: String) -> (Double, String)? {
if text.contains("Fetching") {
// Special cases: downloading a manifest is effectively fetching metadata
if text.contains("==> Downloading") && text.contains("/manifests/") {
return (0.1, "phpman.steps.fetching".localized)
}
if text.contains("Downloading") {
return (0.25, "phpman.steps.downloading".localized)
}
if text.contains("Installing") {
return (0.60, "phpman.steps.installing".localized)
}
if text.contains("Pouring") {
return (0.80, "phpman.steps.pouring".localized)
}
if text.contains("Summary") {
// Logical progress evaluation (reverse order for accuracy)
if text.contains("==> Summary") {
return (0.90, "phpman.steps.summary".localized)
}
if text.contains("==> Pouring") {
if let subject = extractContext(from: text) {
return (0.80, "phpman.steps.pouring".localized + "\n(\(subject))")
}
return (0.80, "phpman.steps.pouring".localized)
}
if text.contains("==> Installing") {
if let subject = extractContext(from: text) {
return (0.60, "phpman.steps.installing".localized + "\n(\(subject))")
}
return (0.60, "phpman.steps.installing".localized)
}
if text.contains("==> Downloading") {
if let subject = extractContext(from: text) {
return (0.25, "phpman.steps.downloading".localized + "\n(\(subject))")
}
return (0.25, "phpman.steps.downloading".localized)
}
if text.contains("==> Fetching") {
return (0.1, "phpman.steps.fetching".localized)
}
return nil
}
internal func extractContext(from text: String) -> String? {
var pattern = #""#
if text.contains("==> Fetching") {
pattern = #"==> Fetching (\S+)"#
}
if text.contains("==> Downloading") {
pattern = #"==> Downloading (\S+)"#
}
if text.contains("==> Installing") {
pattern = #"==> Installing (\S+)"#
}
if text.contains("==> Pouring") {
pattern = #"==> Pouring (\S+)"#
}
guard let regex = try? NSRegularExpression(pattern: pattern) else {
return nil
}
let range = NSRange(text.startIndex..<text.endIndex, in: text)
if let match = regex.firstMatch(in: text, options: [], range: range) {
if let formulaRange = Range(match.range(at: 1), in: text) {
return String(text[formulaRange])
}
}
return nil
}

View File

@ -24,4 +24,6 @@ protocol ValetListable {
func getListableUrl() -> URL?
func getListableFavorited() -> Bool
}

View File

@ -14,6 +14,11 @@ class ValetProxy: ValetListable {
var target: String
var secured: Bool = false
var favorited: Bool = false
var favoriteSignature: String {
"proxy:domain:\(domain).\(tld)|target:\(target)"
}
init(domain: String, target: String, secure: Bool, tld: String) {
self.domain = domain
self.tld = tld
@ -28,6 +33,8 @@ class ValetProxy: ValetListable {
secure: false,
tld: configuration.tld
)
self.favorited = Favorites.shared.contains(domain: self.domain)
self.determineSecured()
}
@ -61,12 +68,21 @@ class ValetProxy: ValetListable {
return URL(string: "\(self.secured ? "https://" : "http://")\(self.domain).\(self.tld)")
}
func getListableFavorited() -> Bool {
return self.favorited
}
// MARK: - Interactions
func determineSecured() {
self.secured = FileSystem.fileExists("~/.config/valet/Certificates/\(self.domain).\(self.tld).key")
}
func toggleFavorite() {
self.favorited.toggle()
Favorites.shared.toggle(domain: self.favoriteSignature)
}
func toggleSecure() async throws {
try await ValetInteractor.shared.toggleSecure(proxy: self)
}

View File

@ -61,6 +61,11 @@ class ValetSite: ValetListable {
?? "???"
}
var favorited: Bool = false
var favoriteSignature: String {
"site:domain:\(name).\(tld)|path:\(absolutePath)"
}
init(
name: String,
tld: String,
@ -75,6 +80,7 @@ class ValetSite: ValetListable {
self.secured = false
if makeDeterminations {
self.favorited = Favorites.shared.contains(domain: favoriteSignature)
determineSecured()
determineIsolated()
determineComposerPhpVersion()
@ -305,12 +311,21 @@ class ValetSite: ValetListable {
return URL(string: "\(self.secured ? "https://" : "http://")\(self.name).\(Valet.shared.config.tld)")
}
func getListableFavorited() -> Bool {
return self.favorited
}
// MARK: - Interactions
func toggleSecure() async throws {
try await ValetInteractor.shared.toggleSecure(site: self)
}
func toggleFavorite() {
self.favorited.toggle()
Favorites.shared.toggle(domain: self.favoriteSignature)
}
func isolate(version: String) async throws {
try await ValetInteractor.shared.isolate(site: self, version: version)
}

View File

@ -7,6 +7,7 @@
//
import Foundation
import NVAlert
extension Valet {
@ -16,7 +17,7 @@ extension Valet {
public func notifyAboutUnsupportedTLD() {
if Valet.shared.config.tld != "test" && Preferences.isEnabled(.warnAboutNonStandardTLD) {
Task { @MainActor in
BetterAlert().withInformation(
NVAlert().withInformation(
title: "alert.warnings.tld_issue.title".localized,
subtitle: "alert.warnings.tld_issue.subtitle".localized,
description: "alert.warnings.tld_issue.description".localized
@ -33,7 +34,7 @@ extension Valet {
public func notifyAboutOutdatedValetVersion(_ version: VersionNumber) {
Task { @MainActor in
BetterAlert()
NVAlert()
.withInformation(
title: "alert.min_valet_version.title".localized,
subtitle: "alert.min_valet_version.info".localized(
@ -60,7 +61,7 @@ extension Valet {
}
Task { @MainActor in
BetterAlert()
NVAlert()
.withInformation(
title: "alert.php_fpm_broken.title".localized,
subtitle: "alert.php_fpm_broken.info".localized,

View File

@ -7,6 +7,7 @@
//
import Cocoa
import NVAlert
extension MainMenu {
@ -20,7 +21,7 @@ extension MainMenu {
@MainActor @objc func displayUnlinkedInfo() {
Task { @MainActor in
BetterAlert()
NVAlert()
.withInformation(
title: "phpman.unlinked.title".localized,
subtitle: "phpman.unlinked.desc".localized,
@ -32,7 +33,7 @@ extension MainMenu {
}
@MainActor @objc func fixHomebrewPermissions() {
if !BetterAlert()
if !NVAlert()
.withInformation(
title: "alert.fix_homebrew_permissions.title".localized,
subtitle: "alert.fix_homebrew_permissions.subtitle".localized,
@ -47,7 +48,7 @@ extension MainMenu {
asyncExecution {
try Actions.fixHomebrewPermissions()
} success: {
BetterAlert()
NVAlert()
.withInformation(
title: "alert.fix_homebrew_permissions_done.title".localized,
subtitle: "alert.fix_homebrew_permissions_done.subtitle".localized,
@ -56,7 +57,7 @@ extension MainMenu {
.withPrimary(text: "generic.ok".localized)
.show()
} failure: { error in
BetterAlert.show(for: error as! HomebrewPermissionError)
NVAlert.show(for: error as! HomebrewPermissionError)
}
}
@ -175,7 +176,7 @@ extension MainMenu {
return
}
BetterAlert().withInformation(
NVAlert().withInformation(
title: "alert.revert_description.title".localized,
subtitle: "alert.revert_description.subtitle".localized(
preset.textDescription
@ -196,7 +197,7 @@ extension MainMenu {
}
@MainActor @objc func showPresetHelp() {
BetterAlert().withInformation(
NVAlert().withInformation(
title: "preset_help_title".localized,
subtitle: "preset_help_info".localized,
description: "preset_help_desc".localized
@ -263,7 +264,7 @@ extension MainMenu {
Task { MainMenu.shared.switchToPhpVersion(version) }
} else {
Task {
BetterAlert().withInformation(
NVAlert().withInformation(
title: "alert.php_switch_unavailable.title".localized,
subtitle: "alert.php_switch_unavailable.subtitle".localized(version)
).withPrimary(

View File

@ -8,6 +8,7 @@
import Foundation
import AppKit
import NVAlert
extension MainMenu {
@ -19,7 +20,7 @@ extension MainMenu {
return
}
if !BetterAlert()
if !NVAlert()
.withInformation(
title: "alert.fix_my_valet.title".localized,
subtitle: "alert.fix_my_valet.info".localized(PhpEnvironments.brewPhpAlias)
@ -43,7 +44,7 @@ extension MainMenu {
}
@MainActor private func presentAlertForMissingFormula() {
BetterAlert()
NVAlert()
.withInformation(
title: "alert.php_formula_missing.title".localized,
subtitle: "alert.php_formula_missing.info".localized
@ -53,7 +54,7 @@ extension MainMenu {
}
@MainActor private func presentAlertForSameVersion() {
BetterAlert()
NVAlert()
.withInformation(
title: "alert.fix_my_valet_done.title".localized,
subtitle: "alert.fix_my_valet_done.subtitle".localized,
@ -64,7 +65,7 @@ extension MainMenu {
}
@MainActor private func presentAlertForDifferentVersion(version: String) {
BetterAlert()
NVAlert()
.withInformation(
title: "alert.fix_my_valet_done.title".localized,
subtitle: "alert.fix_my_valet_done.subtitle".localized,

View File

@ -7,6 +7,7 @@
//
import Cocoa
import NVAlert
extension MainMenu {
/**
@ -114,6 +115,9 @@ extension MainMenu {
// Finally!
Log.info("PHP Monitor is ready to serve!")
// Avoid showing the "startup timeout" alert
Startup.invalidateTimeoutTimer()
// Check if we upgraded from a previous version
AppUpdater.checkIfUpdateWasPerformed()
}
@ -143,7 +147,7 @@ extension MainMenu {
*/
private func onEnvironmentFail() async {
Task { @MainActor [self] in
BetterAlert()
NVAlert()
.withInformation(
title: "alert.cannot_start.title".localized,
subtitle: "alert.cannot_start.subtitle".localized,

View File

@ -7,6 +7,7 @@
//
import Foundation
import NVAlert
extension MainMenu {
@ -75,7 +76,7 @@ extension MainMenu {
}
@MainActor private func suggestFixMyValet(failed version: String) {
let outcome = BetterAlert()
let outcome = NVAlert()
.withInformation(
title: "alert.php_switch_failed.title".localized(version),
subtitle: "alert.php_switch_failed.info".localized(version),
@ -90,7 +91,7 @@ extension MainMenu {
}
@MainActor private func suggestFixMyComposer() {
BetterAlert().withInformation(
NVAlert().withInformation(
title: "alert.global_composer_platform_issues.title".localized,
subtitle: "alert.global_composer_platform_issues.subtitle".localized,
description: "alert.global_composer_platform_issues.desc".localized

View File

@ -6,6 +6,7 @@
//
import Cocoa
import NVAlert
@MainActor
class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate {
@ -120,7 +121,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
@objc func showIncompatiblePhpVersionsAlert() {
Task { @MainActor in
BetterAlert().withInformation(
NVAlert().withInformation(
title: "startup.unsupported_versions_explanation.title".localized,
subtitle: "startup.unsupported_versions_explanation.subtitle".localized(
PhpEnvironments.shared.incompatiblePhpVersions
@ -180,12 +181,12 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
@objc func openAbout() {
NSApplication.shared.activate(ignoringOtherApps: true)
NSApplication.shared.orderFrontStandardAboutPanel()
NSApplication.shared.orderFrontStandardAboutPanel(self)
}
@objc func openLiteModeInfo() {
Task { @MainActor in
BetterAlert().withInformation(
NVAlert().withInformation(
title: "lite_mode_explanation.title".localized,
subtitle: "lite_mode_explanation.subtitle".localized,
description: "lite_mode_explanation.description".localized

View File

@ -1,122 +0,0 @@
//
// Notice.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 16/02/2022.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
@MainActor
class BetterAlert {
var windowController: NSWindowController!
var noticeVC: BetterAlertVC {
return self.windowController.contentViewController as! BetterAlertVC
}
init() {
let storyboard = NSStoryboard(name: "Main", bundle: nil)
self.windowController = storyboard.instantiateController(
withIdentifier: "noticeWindow"
) as? NSWindowController
}
public static func make() -> BetterAlert {
return BetterAlert()
}
public func withPrimary(
text: String,
action: @MainActor @escaping (BetterAlertVC) -> Void = { vc in
vc.close(with: .alertFirstButtonReturn)
}
) -> Self {
self.noticeVC.buttonPrimary.title = text
self.noticeVC.actionPrimary = action
return self
}
public func withSecondary(
text: String,
action: (@MainActor (BetterAlertVC) -> Void)? = { vc in
vc.close(with: .alertSecondButtonReturn)
}
) -> Self {
self.noticeVC.buttonSecondary.title = text
self.noticeVC.actionSecondary = action
return self
}
public func withTertiary(
text: String = "",
action: (@MainActor (BetterAlertVC) -> Void)? = nil
) -> Self {
if text == "" {
self.noticeVC.buttonTertiary.bezelStyle = .helpButton
}
self.noticeVC.buttonTertiary.title = text
self.noticeVC.actionTertiary = action
return self
}
public func withInformation(
title: String,
subtitle: String,
description: String = ""
) -> Self {
self.noticeVC.labelTitle.stringValue = title
self.noticeVC.labelSubtitle.stringValue = subtitle
self.noticeVC.labelDescription.stringValue = description
// If the description is missing, handle the excess space and change the top margin
if description == "" {
self.noticeVC.labelDescription.isHidden = true
self.noticeVC.primaryButtonTopMargin.constant = 0
}
return self
}
/**
Shows the modal and returns a ModalResponse.
If you wish to simply show the alert and disregard the outcome, use `show`.
*/
@MainActor public func runModal() -> NSApplication.ModalResponse {
if !Thread.isMainThread {
fatalError("You should always present alerts on the main thread!")
}
NSApp.activate(ignoringOtherApps: true)
windowController.window?.makeKeyAndOrderFront(nil)
windowController.window?.setCenterPosition(offsetY: 70)
return NSApplication.shared.runModal(for: windowController.window!)
}
/** Shows the modal and returns true if the user pressed the primary button. */
@MainActor public func didSelectPrimary() -> Bool {
return self.runModal() == .alertFirstButtonReturn
}
/**
Shows the modal and does not return anything.
*/
@MainActor public func show() {
_ = self.runModal()
}
/**
Shows the modal for a particular error.
*/
@MainActor public static func show(for error: Error & AlertableError) {
let key = error.getErrorMessageKey()
return BetterAlert().withInformation(
title: "\(key).title".localized,
subtitle: "\(key).description".localized
).withPrimary(text: "generic.ok".localized).show()
}
}

View File

@ -1,77 +0,0 @@
//
// NoticeVC.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 16/02/2022.
// Copyright © 2023 Nico Verbruggen. All rights reserved.
//
import Foundation
import Cocoa
class BetterAlertVC: NSViewController {
// MARK: - Outlets
@IBOutlet weak var labelTitle: NSTextField!
@IBOutlet weak var labelSubtitle: NSTextField!
@IBOutlet weak var labelDescription: NSTextField!
@IBOutlet weak var buttonPrimary: NSButton!
@IBOutlet weak var buttonSecondary: NSButton!
@IBOutlet weak var buttonTertiary: NSButton!
var actionPrimary: (@MainActor (BetterAlertVC) -> Void) = { _ in }
var actionSecondary: (@MainActor (BetterAlertVC) -> Void)?
var actionTertiary: (@MainActor (BetterAlertVC) -> Void)?
@IBOutlet weak var imageView: NSImageView!
@IBOutlet weak var primaryButtonTopMargin: NSLayoutConstraint!
// MARK: - Lifecycle
override func viewWillAppear() {
imageView.image = NSApp.applicationIconImage
if actionSecondary == nil {
buttonSecondary.isHidden = true
}
if actionTertiary == nil {
buttonTertiary.isHidden = true
}
}
override func viewDidAppear() {
view.window?.makeFirstResponder(buttonPrimary)
}
deinit {
// Log.perf("deinit: \(String(describing: self)).\(#function)")
}
// MARK: Outlet Actions
@IBAction func primaryButtonAction(_ sender: Any) {
self.actionPrimary(self)
}
@IBAction func secondaryButtonAction(_ sender: Any) {
if self.actionSecondary != nil {
self.actionSecondary!(self)
} else {
self.close(with: .alertSecondButtonReturn)
}
}
@IBAction func tertiaryButtonAction(_ sender: Any) {
if self.actionTertiary != nil {
self.actionTertiary!(self)
}
}
@MainActor public func close(with code: NSApplication.ModalResponse) {
self.view.window?.close()
NSApplication.shared.stopModal(withCode: code)
}
}

View File

@ -7,6 +7,7 @@
//
import Foundation
import NVAlert
class PhpGuard {
@ -43,7 +44,7 @@ class PhpGuard {
Log.info("PHP Guard noticed a different PHP version. An alert will be displayed!")
Task { @MainActor in
BetterAlert()
NVAlert()
.withInformation(
title: "startup.version_mismatch.title".localized,
subtitle: "startup.version_mismatch.subtitle".localized(

View File

@ -28,6 +28,10 @@ class Preferences {
environmentVariables: [:]
)
if isRunningSwiftUIPreview {
return
}
Task { await loadCustomPreferences() }
}

View File

@ -8,6 +8,7 @@
import Foundation
import Cocoa
import NVAlert
class Stats {
@ -123,7 +124,7 @@ class Stats {
}
Task { @MainActor in
let donate = BetterAlert()
let donate = NVAlert()
.withInformation(
title: "startup.sponsor_encouragement.title".localized,
subtitle: "startup.sponsor_encouragement.subtitle".localized,

View File

@ -7,6 +7,7 @@
//
import Foundation
import NVAlert
struct Preset: Codable, Equatable {
let name: String
@ -139,7 +140,7 @@ struct Preset: Codable, Equatable {
return true
} else {
Task { @MainActor in
BetterAlert().withInformation(
NVAlert().withInformation(
title: "alert.php_switch_unavailable.title".localized,
subtitle: "alert.php_switch_unavailable.subtitle".localized(version!),
description: "alert.php_switch_unavailable.info".localized(

View File

@ -38,10 +38,12 @@ struct BlockingOverlayView<Content: View>: View {
.bold()
.foregroundColor(.primary)
.padding(.top, 8)
.multilineTextAlignment(.center)
Text(detailText)
.font(.system(size: 11))
.foregroundColor(.primary)
.padding(.top, -4)
.multilineTextAlignment(.center)
}.padding(60)
}
}

View File

@ -10,6 +10,11 @@ import Foundation
import SwiftUI
struct HelpButton: View {
@State var frameSize: CGFloat = 14
@State var textSize: CGFloat = 12
@State var shadowOpacity: CGFloat = 0.3
@State var shadowRadius: CGFloat = 1
var action: () -> Void
var body: some View {
@ -18,9 +23,10 @@ struct HelpButton: View {
Circle()
.strokeBorder(Color(NSColor.separatorColor), lineWidth: 0.5)
.background(Circle().foregroundColor(Color(NSColor.controlColor)).opacity(0.7))
.shadow(color: Color(NSColor.separatorColor).opacity(0.3), radius: 1)
.frame(width: 14, height: 14)
Text("?").font(.system(size: 12, weight: .medium))
.shadow(color: Color(NSColor.separatorColor)
.opacity(shadowOpacity), radius: shadowRadius)
.frame(width: frameSize, height: frameSize)
Text("?").font(.system(size: textSize, weight: .medium))
.foregroundColor(Color(NSColor.labelColor))
}
})

View File

@ -8,6 +8,7 @@
import Foundation
import SwiftUI
import NVAlert
struct ServicesView: View {
@ -81,7 +82,7 @@ struct ServicesView: View {
: "key_service_not_running"
// Show an alert with more information
BetterAlert().withInformation(
NVAlert().withInformation(
title: "alert.\(type).title".localized,
subtitle: "alert.\(type).subtitle".localized,
description: "alert.\(type).desc".localized
@ -116,7 +117,7 @@ struct ServiceView: View {
if service.status == .missing {
Button {
Task { @MainActor in
BetterAlert().withInformation(
NVAlert().withInformation(
title: "alert.warnings.service_missing.title".localized,
subtitle: "alert.warnings.service_missing.subtitle".localized,
description: "alert.warnings.service_missing.description".localized

View File

@ -40,7 +40,7 @@
<key>LSUIElement</key>
<true/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2019-2023 Nico Verbruggen. All rights reserved.</string>
<string>Copyright © 2019-2025 Nico Verbruggen. All rights reserved.</string>
<key>NSMainStoryboardFile</key>
<string>Main</string>
<key>NSPrincipalClass</key>

View File

@ -0,0 +1,38 @@
//
// Favorites.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 25/08/2024.
// Copyright © 2024 Nico Verbruggen. All rights reserved.
//
import Foundation
class Favorites {
static var shared: Favorites = Favorites()
var items: [String]
init() {
if let items = UserDefaults.standard.array(forKey: "user_favorites") as? [String] {
self.items = items
} else {
self.items = []
}
}
public func contains(domain: String) -> Bool {
return self.items.contains(domain)
}
public func toggle(domain: String) {
if let index = items.firstIndex(of: domain) {
items.remove(at: index)
} else {
items.append(domain)
}
UserDefaults.standard.setValue(items, forKey: "user_favorites")
UserDefaults.standard.synchronize()
}
}

View File

@ -10,6 +10,7 @@ import Cocoa
import AppKit
protocol DomainListCellProtocol {
static func getCellIdentifier(for domain: ValetListable) -> String
func populateCell(with site: ValetSite)
func populateCell(with proxy: ValetProxy)
}

View File

@ -10,10 +10,12 @@ import Cocoa
import AppKit
class DomainListKindCell: NSTableCellView, DomainListCellProtocol {
static let reusableName = "domainListKindCell"
@IBOutlet weak var imageViewType: NSImageView!
static func getCellIdentifier(for domain: ValetListable) -> String {
return "domainListKindCell"
}
func populateCell(with site: ValetSite) {
// If the `aliasPath` is nil, we're dealing with a parked site (otherwise: linked).
imageViewType.image = site.aliasPath == nil

View File

@ -10,11 +10,13 @@ import Cocoa
import AppKit
class DomainListNameCell: NSTableCellView, DomainListCellProtocol {
static let reusableName = "domainListNameCell"
@IBOutlet weak var labelSiteName: NSTextField!
@IBOutlet weak var labelPathName: NSTextField!
static func getCellIdentifier(for domain: ValetListable) -> String {
return domain.getListableFavorited() ? "domainListNameCellFavorited" : "domainListNameCell"
}
func populateCell(with site: ValetSite) {
labelSiteName.stringValue = "\(site.name).\(site.tld)"
labelPathName.stringValue = site.absolutePathRelative

View File

@ -11,13 +11,15 @@ import AppKit
import SwiftUI
class DomainListPhpCell: NSTableCellView, DomainListCellProtocol {
static let reusableName = "domainListPhpCell"
var site: ValetSite?
@IBOutlet weak var buttonPhpVersion: NSButton!
@IBOutlet weak var imageViewPhpVersionOK: NSImageView!
static func getCellIdentifier(for domain: ValetListable) -> String {
return "domainListPhpCell"
}
func populateCell(with site: ValetSite) {
self.site = site

View File

@ -10,10 +10,12 @@ import Cocoa
import AppKit
class DomainListTLSCell: NSTableCellView, DomainListCellProtocol {
static let reusableName = "domainListTLSCell"
@IBOutlet weak var imageViewLock: NSImageView!
static func getCellIdentifier(for domain: ValetListable) -> String {
return "domainListTLSCell"
}
func populateCell(with site: ValetSite) {
imageViewLock.contentTintColor = site.secured
? NSColor(named: "IconColorGreen")

View File

@ -10,11 +10,13 @@ import Cocoa
import AppKit
class DomainListTypeCell: NSTableCellView, DomainListCellProtocol {
static let reusableName = "domainListTypeCell"
@IBOutlet weak var labelDriver: NSTextField!
@IBOutlet weak var labelPhpVersion: NSTextField!
static func getCellIdentifier(for domain: ValetListable) -> String {
return "domainListTypeCell"
}
func populateCell(with site: ValetSite) {
labelDriver.stringValue = site.driver ?? "driver.not_detected".localized

View File

@ -8,6 +8,7 @@
import Foundation
import Cocoa
import NVAlert
extension DomainListVC {
@ -17,7 +18,7 @@ extension DomainListVC {
}
guard let url = selected.getListableUrl() else {
BetterAlert()
NVAlert()
.withInformation(
title: "domain_list.alert.invalid_folder_name".localized,
subtitle: "domain_list.alert.invalid_folder_name_desc".localized
@ -66,6 +67,14 @@ extension DomainListVC {
// MARK: - Interactions with `valet` or terminal
@objc func toggleFavorite() {
guard let selected = self.selected else {
return
}
Task { await toggleFavorite(domain: selected) }
}
@objc func toggleSecure() {
if selected is ValetSite {
Task { await toggleSecure(site: selected as! ValetSite) }
@ -93,6 +102,22 @@ extension DomainListVC {
}
}
func toggleFavorite(domain: any ValetListable) async {
waitAndExecute {
do {
if let site = domain as? ValetSite {
site.toggleFavorite()
}
if let proxy = domain as? ValetProxy {
proxy.toggleFavorite()
}
// Reload the entire table as the sorting may be affected
self.reloadTable()
}
}
}
func toggleSecure(site: ValetSite) async {
waitAndExecute {
do {
@ -249,7 +274,7 @@ extension DomainListVC {
}
private func notifyAboutUsingIsolatedPhpVersionInTerminal(version: VersionNumber) {
BetterAlert()
NVAlert()
.withInformation(
title: "domain_list.alerts_isolated_php_terminal.title".localized(version.short),
subtitle: "domain_list.alerts_isolated_php_terminal.subtitle".localized(
@ -263,7 +288,7 @@ extension DomainListVC {
}
private func notifyAboutFailedSecureStatus(command: String) {
BetterAlert()
NVAlert()
.withInformation(
title: "domain_list.alerts_status_not_changed.title".localized,
subtitle: "domain_list.alerts_status_not_changed.desc".localized(command)
@ -273,7 +298,7 @@ extension DomainListVC {
}
private func notifyAboutFailedSiteIsolation(command: String) {
BetterAlert()
NVAlert()
.withInformation(
title: "domain_list.alerts_isolation_failed.title".localized,
subtitle: "domain_list.alerts_isolation_failed.subtitle".localized,

View File

@ -65,6 +65,7 @@ extension DomainListVC {
menu.addItem(HeaderView.asMenuItem(text: "domain_list.actions".localized))
addToggleFavorite(to: menu, favorited: site.favorited)
addToggleSecure(to: menu, secured: site.secured)
addUnlink(to: menu, with: site)
@ -172,6 +173,16 @@ extension DomainListVC {
)
}
private func addToggleFavorite(to menu: NSMenu, favorited: Bool) {
menu.addItem(
withTitle: favorited
? "domain_list.unfavorite".localized
: "domain_list.favorite".localized,
action: #selector(toggleFavorite),
keyEquivalent: ""
)
}
private func addMenuItemsForExtensions(to menu: NSMenu, for extensions: [PhpExtension], version: String) {
var items: [NSMenuItem] = [
NSMenuItem(title: "domain_list.applies_to".localized(version))
@ -200,6 +211,7 @@ extension DomainListVC {
let menu = NSMenu()
addOpenProxyInBrowser(to: menu)
addSeparator(to: menu)
addToggleFavorite(to: menu, favorited: proxy.favorited)
addToggleSecure(to: menu, secured: proxy.secured)
addRemoveProxy(to: menu)
return menu

View File

@ -221,7 +221,9 @@ class DomainListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource
default: break
}
self.domains = descriptor.ascending ? sorted.reversed() : sorted
sorted = descriptor.ascending ? sorted.reversed() : sorted
self.domains = sorted.sorted { $0.getListableFavorited() && !$1.getListableFavorited() }
}
func addedNewSite(name: String, secureAfterLinking: Bool) async {
@ -261,16 +263,17 @@ class DomainListVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource
}
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
let mapping: [String: String] = [
"TLS": DomainListTLSCell.reusableName,
"DOMAIN": DomainListNameCell.reusableName,
"ENVIRONMENT": DomainListPhpCell.reusableName,
"KIND": DomainListKindCell.reusableName,
"TYPE": DomainListTypeCell.reusableName
let mapping: [String: DomainListCellProtocol.Type] = [
"TLS": DomainListTLSCell.self,
"DOMAIN": DomainListNameCell.self,
"ENVIRONMENT": DomainListPhpCell.self,
"KIND": DomainListKindCell.self,
"TYPE": DomainListTypeCell.self
]
let columnName = tableColumn!.identifier.rawValue
let identifier = NSUserInterfaceItemIdentifier(rawValue: mapping[columnName]!)
guard let cellType = mapping[columnName] else { return nil }
let identifier = NSUserInterfaceItemIdentifier(rawValue: cellType.getCellIdentifier(for: domains[row]))
guard let userCell = tableView.makeView(withIdentifier: identifier, owner: self)
as? DomainListCellProtocol else { return nil }

View File

@ -112,5 +112,4 @@ struct ByteLimitView: View {
#Preview("Config Manager") {
ConfigManagerView()
.frame(width: 600, height: .infinity)
.previewDisplayName("Config Manager")
}

View File

@ -27,13 +27,14 @@ extension PhpExtensionManagerView {
)
}
public func install(_ ext: BrewPhpExtension) {
public func install(_ ext: BrewPhpExtension, onCompletion: @escaping () -> Void = {}) {
Task {
await self.runCommand(InstallPhpExtensionCommand(install: [ext]))
onCompletion()
}
}
public func confirmUninstall(_ ext: BrewPhpExtension) {
public func confirmUninstall(_ ext: BrewPhpExtension, onCompletion: @escaping () -> Void = {}) {
Alert.confirm(
onWindow: App.shared.phpExtensionManagerWindowController!.window!,
messageText: "phpextman.warnings.removal.title".localized(ext.name),
@ -45,6 +46,7 @@ extension PhpExtensionManagerView {
onFirstButtonPressed: {
Task {
await self.runCommand(RemovePhpExtensionCommand(remove: ext))
onCompletion()
}
}
)

View File

@ -12,7 +12,9 @@ import SwiftUI
struct PhpExtensionManagerView: View {
@ObservedObject var manager: BrewExtensionsObservable
@ObservedObject var status: BusyStatus
@State var searchText: String
@State private var highlightedExtension: String?
init() {
self.searchText = ""
@ -22,11 +24,22 @@ struct PhpExtensionManagerView: View {
self.status.busy = false
}
var availablePhpVersions: [String] {
if isRunningSwiftUIPreview {
return [manager.phpVersion]
}
return PhpEnvironments.shared.availablePhpVersions
}
var filteredExtensions: [BrewPhpExtension] {
guard !searchText.isEmpty else {
return manager.extensions
return manager.extensions.sorted { $0.isInstalled && !$1.isInstalled }
}
return manager.extensions.filter { $0.name.contains(searchText) }
return manager.extensions
.filter { $0.name.contains(searchText) }
.sorted { $0.isInstalled && !$1.isInstalled }
}
var body: some View {
@ -48,14 +61,19 @@ struct PhpExtensionManagerView: View {
title: self.status.title,
text: self.status.description
) {
List(Array(self.filteredExtensions.enumerated()), id: \.1.name) { (_, ext) in
listContent(for: ext)
.padding(.vertical, 8)
.padding(.horizontal, 8)
ScrollViewReader { proxy in
List(Array(self.filteredExtensions.enumerated()), id: \.1.name) { (_, ext) in
listContent(for: ext, proxy: proxy)
}
.edgesIgnoringSafeArea(.top)
.listStyle(PlainListStyle())
.searchable(text: $searchText)
.onChange(of: manager.phpVersion, perform: { _ in
if let ext = self.filteredExtensions.first {
proxy.scrollTo(ext.name)
}
})
}
.edgesIgnoringSafeArea(.top)
.listStyle(PlainListStyle())
.searchable(text: $searchText)
}
}
.frame(minWidth: 600, minHeight: 600)
@ -76,9 +94,8 @@ struct PhpExtensionManagerView: View {
// MARK: View Variables
private var phpVersionPicker: some View {
Picker("",
selection: $manager.phpVersion) {
ForEach(PhpEnvironments.shared.availablePhpVersions, id: \.self) {
Picker("", selection: $manager.phpVersion) {
ForEach(self.availablePhpVersions, id: \.self) {
Text("PHP \($0)")
.tag($0)
.font(.system(size: 12))
@ -147,17 +164,16 @@ struct PhpExtensionManagerView: View {
}
}
private func listContent(for ext: BrewPhpExtension) -> some View {
private func listContent(for ext: BrewPhpExtension, proxy: ScrollViewProxy) -> some View {
HStack(alignment: .center, spacing: 7.0) {
VStack(alignment: .center, spacing: 0) {
HStack {
HStack {
Image(systemName: ext.isInstalled || ext.hasAlternativeInstall
? "puzzlepiece.extension.fill"
: "puzzlepiece.extension")
.resizable()
.frame(width: 24, height: 20)
.foregroundColor(ext.hasAlternativeInstall ? Color.gray : Color.blue)
? "puzzlepiece.extension.fill" : "puzzlepiece.extension")
.resizable()
.frame(width: 24, height: 20)
.foregroundColor(ext.hasAlternativeInstall ? Color.gray : Color.blue)
}.frame(width: 36, height: 24)
VStack(alignment: .leading, spacing: 5) {
@ -184,19 +200,41 @@ struct PhpExtensionManagerView: View {
HStack {
if ext.isInstalled {
Button("phpman.buttons.uninstall".localizedForSwiftUI, role: .destructive) {
self.confirmUninstall(ext)
}.disabled(ext.firstDependent(in: self.manager.extensions) != nil)
self.confirmUninstall(ext, onCompletion: {
scrollAndAnimate(ext, proxy)
})
}
.disabled(ext.firstDependent(in: self.manager.extensions) != nil)
} else {
Button("phpman.buttons.install".localizedForSwiftUI) {
self.install(ext)
self.install(ext, onCompletion: {
scrollAndAnimate(ext, proxy)
})
}.disabled(ext.hasAlternativeInstall)
}
}
}
.padding(.vertical, 8)
.padding(.horizontal, 8)
.background(highlightedExtension == ext.name ? Color.accentColor.opacity(0.3) : Color.clear)
.cornerRadius(8)
.animation(.easeInOut(duration: 0.5), value: highlightedExtension)
}
private func scrollAndAnimate(_ ext: BrewPhpExtension, _ proxy: ScrollViewProxy) {
withAnimation {
highlightedExtension = ext.name
proxy.scrollTo(ext.name, anchor: .top)
}
DispatchQueue.main.asyncAfter(deadline: .now() + 1.5) {
withAnimation {
highlightedExtension = nil
}
}
}
}
#Preview {
PhpExtensionManagerView()
.frame(width: 600, height: 600)
PhpExtensionManagerView().frame(width: 600, height: 600)
}

View File

@ -9,6 +9,7 @@
import Foundation
import SwiftUI
// swiftlint:disable type_body_length
struct PhpVersionManagerView: View {
@ObservedObject var formulae: BrewFormulaeObservable
@ObservedObject var status: BusyStatus
@ -192,6 +193,7 @@ struct PhpVersionManagerView: View {
.buttonStyle(.automatic)
.controlSize(.large)
}
.accessibilityIdentifier("RefreshButton")
.focusable(false)
.disabled(self.status.busy)
@ -231,14 +233,18 @@ struct PhpVersionManagerView: View {
}
}
if formula.isInstalled {
if formula.hasUpgradedFormulaAlias {
HelpButton(frameSize: 18, textSize: 14, shadowOpacity: 1, shadowRadius: 2, action: {
NSWorkspace.shared.open(Constants.Urls.WikiPhpUpgrade)
})
} else if formula.isInstalled {
Button("phpman.buttons.uninstall".localizedForSwiftUI, role: .destructive) {
Task { await self.confirmUninstall(formula) }
}
} else {
Button("phpman.buttons.install".localizedForSwiftUI) {
Task { await self.install(formula) }
}.disabled(formula.hasUpgradedFormulaAlias)
}.disabled(formula.hasUpgradedFormulaAlias || !formula.hasFormulaFile)
}
}
}
@ -268,6 +274,8 @@ struct PhpVersionManagerView: View {
Text("phpman.version.installed".localized(formula.installedVersion!))
.font(.system(size: 11))
.foregroundColor(.gray)
} else if !formula.hasFormulaFile {
unavailableFormula()
} else {
Text("phpman.version.available_for_installation".localizedForSwiftUI)
.font(.system(size: 11))
@ -291,7 +299,19 @@ struct PhpVersionManagerView: View {
.foregroundColor(formula.iconColor)
.padding(.horizontal, 5)
}
private func unavailableFormula() -> some View {
HStack(spacing: 5) {
Text("phpman.version.unavailable".localizedForSwiftUI)
.font(.system(size: 11))
.foregroundColor(.gray)
HelpButton(action: {
NSWorkspace.shared.open(Constants.Urls.WikiPhpUnavailable)
})
}
}
}
// swiftlint:enable type_body_length
#Preview {
PhpVersionManagerView(

View File

@ -45,7 +45,7 @@ extension NSEvent.ModifierFlags {
}
}
extension NSEvent.ModifierFlags: CustomStringConvertible {
extension NSEvent.ModifierFlags: @retroactive CustomStringConvertible {
public var description: String {
var output = ""

View File

@ -122,8 +122,10 @@ und PHP Monitor neu starten, damit die Erweiterungen sichtbar werden. Wenn das P
"phpman.version.broken" = "Diese Version scheint defekt zu sein, Sie können versuchen, sie zu reparieren.";
"phpman.version.has_update" = "Version %@ installiert, %@ verfügbar.";
"phpman.version.installed" = "Version %@ ist derzeit installiert.";
"phpman.version.unavailable" = "Diese Version ist vorübergehend nicht verfügbar.";
"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.version.automatic_upgrade" = "Diese Version wird automatisch installiert, indem eine ältere Version aktualisiert wird.
(Sowohl diese neue Version als auch die alte Version werden nach dem Upgrade verfügbar sein.)";
"phpman.buttons.uninstall" = "Deinstallieren";
"phpman.buttons.install" = "Installieren";
"phpman.buttons.update" = "Aktualisieren";
@ -301,6 +303,8 @@ Möglicherweise werden Sie während des Deinstallationsvorgangs nach Ihrem Passw
"domain_list.always_use_php" = "Immer PHP %@ verwenden";
"domain_list.isolation_unavailable" = "Isolierung wird nicht unterstützt (in Valet 2)";
"domain_list.favorite" = "Als Favorit markieren";
"domain_list.unfavorite" = "Aus den Favoriten entfernen";
"domain_list.actions" = "Aktionen";
"domain_list.unlink" = "Ordner-Link aufheben";
"domain_list.secure" = "Domain sichern";
@ -616,7 +620,7 @@ Sie können dies tun, indem Sie `composer global update` in Ihrem Terminal ausf
// STARTUP
/// 0. Architecture mismatch
// 0. Architecture mismatch
"alert.homebrew_missing.title" = "PHP Monitor kann nicht starten!";
"alert.homebrew_missing.subtitle" = "Eine funktionierende Homebrew-Binärdatei konnte nicht am üblichen Ort gefunden werden. Bitte starten Sie die Anwendung neu, nachdem Sie dieses Problem behoben haben.";
@ -624,32 +628,32 @@ Sie können dies tun, indem Sie `composer global update` in Ihrem Terminal ausf
"alert.homebrew_missing.quit" = "Schließen";
/// PHP binary not found
// PHP binary not found
"startup.errors.php_binary.title" = "PHP ist nicht korrekt installiert";
"startup.errors.php_binary.subtitle" = "Sie müssen PHP über Homebrew installieren. Die App wird nicht richtig funktionieren, bis Sie dieses Problem behoben haben.";
"startup.errors.php_binary.desc" = "Normalerweise wird dieses Problem durch das Ausführen von `brew link php` in Ihrem Terminal gelöst.\n\n Um herauszufinden, was falsch ist, können Sie versuchen, `which php` in Ihrem Terminal auszuführen, es sollte `%@` zurückgeben.";
/// PHP not found in /usr/local/opt or /opt/homebrew/opt
// PHP not found in /usr/local/opt or /opt/homebrew/opt
"startup.errors.php_opt.title" = "PHP ist nicht korrekt installiert";
"startup.errors.php_opt.subtitle" = "Der PHP-Alias wurde in `%@` nicht gefunden. Die Anwendung wird nicht korrekt funktionieren, bis Sie dieses Problem behoben haben.";
"startup.errors.php_opt.desc" = "Wenn Sie bereits die `php` Formel installiert haben, müssen Sie eventuell `brew install php` ausführen, damit PHP Monitor diese Installation erkennt.";
/// PHP binary is broken
// PHP binary is broken
"startup.errors.dyld_library.title" = "PHP ist installiert, scheint aber defekt zu sein";
"startup.errors.dyld_library.subtitle" = "Wenn PHP Monitor versucht, Befehle auszuführen, gelingt es ihm nicht richtig. Dies ist normalerweise ein Hinweis auf eine fehlerhafte PHP-Installation.";
"startup.errors.dyld_library.desc" = "Das Ausführen von `brew reinstall php && brew link php` in Ihrem Terminal kann dieses Problem lösen, also versuchen Sie es bitte.";
/// Valet is not installed
// Valet is not installed
"startup.errors.valet_executable.title" = "Laravel Valet ist nicht korrekt installiert";
"startup.errors.valet_executable.subtitle" = "Sie müssen Valet mit Composer installieren. Die App wird nicht richtig funktionieren, bis Sie dieses Problem behoben haben.";
"startup.errors.valet_executable.desc" = "Wenn Sie Laravel Valet noch nicht installiert haben, tun Sie dies bitte zuerst. Wenn Sie es installiert haben, aber trotzdem diese Meldung sehen, dann versuchen Sie, `which valet` im Terminal auszuführen, es sollte zurückgegeben werden: `%@`.";
/// Valet configuration file missing or broken
// Valet configuration file missing or broken
"startup.errors.valet_json_invalid.title" = "Laravel Valet-Konfigurationsdatei ungültig oder fehlt";
"startup.errors.valet_json_invalid.subtitle" = "PHP Monitor muss in der Lage sein, die Konfigurationsdatei zu lesen. Es scheint, dass die Datei falsch formatiert ist oder fehlt. Bitte überprüfen Sie, ob sie existiert und korrekt formatiert ist.";
"startup.errors.valet_json_invalid.desc" = "Sie finden die Datei unter `~/.config/valet/config.json`. Wenn Laravel Valet die Konfigurationsdatei nicht parsen kann, wird die JSON-Datei durch die Ausführung eines beliebigen `valet`-Befehls normalerweise automatisch korrigiert. Versuchen Sie, `valet --version` auszuführen, um die Datei automatisch zu korrigieren.";
/// Valet version not readable
// Valet version not readable
"startup.errors.valet_version_unknown.title" = "Ihre Valet-Version konnte nicht gelesen werden";
"startup.errors.valet_version_unknown.subtitle" = "Das Auslesen der Ausgabe von `valet --version` ist fehlgeschlagen. Stellen Sie sicher, dass Ihre Valet-Installation funktioniert und aktuell ist.";
"startup.errors.valet_version_unknown.desc" = "Versuchen Sie, `valet --version` in einem Terminal auszuführen, um herauszufinden, was los ist.";
@ -665,27 +669,27 @@ Wenn Sie diese Meldung sehen, aber nicht wissen, warum dieser Ordner verschwunde
"startup.errors.valet_version_not_supported.subtitle" = "Sie verwenden eine Version von Valet, die derzeit nicht unterstützt wird. PHP Monitor funktioniert derzeit mit Valet v2, v3 und v4. Um Probleme auf Ihrem System zu vermeiden, kann PHP Monitor nicht gestartet werden.";
"startup.errors.valet_version_not_supported.desc" = "Sie müssen eine Version von Valet installieren, die mit PHP Monitor kompatibel ist, oder Sie müssen ein Upgrade auf eine neuere Version von PHP Monitor durchführen, die möglicherweise die Kompatibilität mit dieser Version von Valet beinhaltet (weitere Informationen finden Sie in den aktuellen Release Notes).";
/// Brew & sudoers
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew wurde nicht zu sudoers.d hinzugefügt";
"startup.errors.sudoers_brew.subtitle" = "Sie müssen `sudo valet trust` ausführen, um sicherzustellen, dass Valet Dienste starten und stoppen kann, ohne jedes Mal sudo verwenden zu müssen. Die Anwendung wird nicht richtig funktionieren, bis Sie dieses Problem behoben haben.";
"startup.errors.sudoers_brew.desc" = "Wenn Sie diesen Fehler immer wieder sehen, kann es sein, dass PHP Monitor die Datei nicht validieren kann. Dies lässt sich in der Regel wie folgt beheben: `sudo chmod +r /private/etc/sudoers.d/brew`.";
/// Valet & sudoers
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Valet wurde nicht zu sudoers.d hinzugefügt";
"startup.errors.sudoers_valet.subtitle" = "Sie müssen `sudo valet trust` ausführen, um sicherzustellen, dass Valet Dienste starten und stoppen kann, ohne jedes Mal sudo verwenden zu müssen. Die Anwendung wird nicht richtig funktionieren, bis Sie dieses Problem behoben haben. Wenn Sie dies bereits getan haben, führen Sie bitte `sudo valet trust` erneut aus.";
"startup.errors.sudoers_valet.desc" = "Wenn Sie diesen Fehler immer wieder sehen, kann es sein, dass PHP Monitor die Datei nicht validieren kann. Dies lässt sich in der Regel wie folgt beheben: `sudo chmod +r /private/etc/sudoers.d/valet`.";
/// Platform issue detected
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor und Valet funktionieren nicht richtig: Composer meldet ein Problem mit Ihrer Plattform";
"startup.errors.global_composer_platform_issues.subtitle" = "Bitte befolgen Sie die folgenden empfohlenen Schritte, um dieses Problem in Zukunft zu vermeiden:\n\n1. Führen Sie `composer global update` aus.\n2. Starten Sie PHP Monitor neu. (Es sollte wieder funktionieren.)\n3. Wechseln Sie zur ältesten PHP-Version, die Sie installiert haben.\n4. Führen Sie `composer global update` erneut aus.";
"startup.errors.global_composer_platform_issues.desc" = "Sie können in den Einstellungen die Option \"Globale Abhängigkeiten automatisch aktualisieren\" aktivieren. Dadurch werden Ihre globalen Composer-Abhängigkeiten bei jeder Änderung der PHP-Version aktualisiert, was nicht ideal ist, wenn Sie nicht ständig Zugang zum Internet haben. Valet funktioniert derzeit nicht mit den installierten Abhängigkeiten. Normalerweise wird dies durch eine Versionsabweichung verursacht: d.h. installierte Abhängigkeiten für eine neuere Version von PHP als die derzeit aktive Version.";
/// Cannot retrieve services
// Cannot retrieve services
"startup.errors.services_json_error.title" = "Status der Dienste kann nicht ermittelt werden";
"startup.errors.services_json_error.subtitle" = "PHP Monitor fragt normalerweise `brew` mit dem folgenden Befehl ab, um zu testen, ob die Dienste abgerufen werden können: `sudo brew services info nginx --json`.\nPHP Monitor konnte diese Antwort nicht interpretieren.";
"startup.errors.services_json_error.desc" = "Dies kann passieren, wenn Ihre Homebrew-Installation veraltet ist. In diesem Fall gibt Homebrew noch kein JSON zurück. Sie können dies normalerweise beheben, indem Sie `brew update` oder `brew tap homebrew/services` ausführen. Sie können auch versuchen, `sudo brew services info nginx --json` in einem Terminal Ihrer Wahl auszuführen.";
/// Issue with `which` alias
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "Es wurde ein Konfigurationsproblem festgestellt";
"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";
@ -833,3 +837,14 @@ Bitte beachten Sie, dass einige Funktionen (unten ausgegraut) derzeit nicht verf
"alert.language_changed.title" = "Sie sollten PHP Monitor neu starten!";
"alert.language_changed.subtitle" = "Sie haben soeben die Anzeigesprache von PHP Monitor geändert. Das Menü wird sofort die korrekte Sprache verwenden, aber Sie müssen die App möglicherweise neu starten, damit alle Texte in der App Ihre neue Sprachwahl widerspiegeln.";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "Ignorieren";
"startup.timeout.title" = "PHP Monitor benötigt zu lange zum Initialisieren!";
"startup.timeout.subtitle" = "Falls PHP Monitor länger als 30 Sekunden beschäftigt bleibt, könnte es ein Problem mit deiner Homebrew-Konfiguration geben.";
"startup.timeout.description" = "Manchmal können Dinge aufgrund von Dateiberechtigungsproblemen fehlschlagen. Du kannst versuchen, `brew doctor` und `brew cleanup` zu verwenden, um dies zu beheben.
Es wird empfohlen, PHP Monitor anschließend neu zu starten. Erfahre mehr über dieses Problem unter: https://github.com/nicoverbruggen/phpmon/issues/294.
Falls PHP Monitor inzwischen initialisiert wurde oder du etwas länger warten möchtest, kannst du auf 'Ignorieren' klicken und PHP Monitor wie gewohnt verwenden. In jedem Fall solltest du der Ursache auf den Grund gehen, da dieser Vorgang nicht so lange dauern sollte.";

View File

@ -120,7 +120,7 @@
"phpextman.list.status.external" = "This extension is already installed via another source, and cannot be managed.";
"phpextman.list.status.installable" = "This extension can be installed.";
"phpextman.list.status.dependent" = "You cannot uninstall this before uninstalling %@.";
"phpextman.list.status.can_manage" = "This extension is installed and can be managed by PHP Monitor.";
"phpextman.list.status.can_manage" = "This extension is installed and managed by PHP Monitor.";
"phpextman.errors.not_found.title" = "Uh oh. No extensions discovered!";
"phpextman.errors.not_found.desc" = "This is not supposed to happen. You may need to run the following command in your terminal:
@ -138,7 +138,9 @@ and restart PHP Monitor for extensions to become visible. If the problem persist
"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.version.unavailable" = "This version is temporarily unavailable.";
"phpman.version.automatic_upgrade" = "This version will be automatically installed by upgrading an older version.
(Both this new version and the old one will be available after upgrading.)";
"phpman.buttons.uninstall" = "Uninstall";
"phpman.buttons.install" = "Install";
"phpman.buttons.update" = "Update";
@ -199,11 +201,11 @@ You may be asked for your password during the uninstallation process if file per
"phpman.operations.updating" = "Installing updates...";
"phpman.operations.installing" = "Installing %@...";
"phpman.steps.fetching" = "Fetching...";
"phpman.steps.fetching" = "Fetching some package metadata...";
"phpman.steps.downloading" = "Downloading package data...";
"phpman.steps.installing" = "Installing some package data...";
"phpman.steps.pouring" = "Pouring... This can take a while...";
"phpman.steps.summary" = "Some package has finished installing...";
"phpman.steps.summary" = "Please wait a moment...";
"phpman.services.loading" = "Loading...";
"phpman.services.not_installed" = "A key service is not installed.";
@ -330,6 +332,8 @@ You may be asked for your password during the uninstallation process if file per
"domain_list.always_use_php" = "Always use PHP %@";
"domain_list.isolation_unavailable" = "Isolation Not Supported (in Valet 2)";
"domain_list.favorite" = "Favorite Domain";
"domain_list.unfavorite" = "Unfavorite Domain";
"domain_list.actions" = "Actions";
"domain_list.unlink" = "Unlink Directory";
"domain_list.secure" = "Secure Domain";
@ -645,7 +649,7 @@ You can do this by running `composer global update` in your terminal. After that
// STARTUP
/// 0. Architecture mismatch
// 0. Architecture mismatch
"alert.homebrew_missing.title" = "PHP Monitor cannot start!";
"alert.homebrew_missing.subtitle" = "A working Homebrew binary could not be found in the usual location. Please restart the app after fixing this issue.";
@ -653,32 +657,32 @@ You can do this by running `composer global update` in your terminal. After that
"alert.homebrew_missing.quit" = "Quit";
/// PHP binary not found
// PHP binary not found
"startup.errors.php_binary.title" = "PHP is not correctly installed";
"startup.errors.php_binary.subtitle" = "You must install PHP via Homebrew. The app will not work correctly until you resolve this issue.";
"startup.errors.php_binary.desc" = "Usually running `brew link php` in your Terminal will resolve this issue.\n\nTo diagnose what is wrong, you can try running `which php` in your Terminal, it should return `%@`.";
/// PHP not found in /usr/local/opt or /opt/homebrew/opt
// PHP not found in /usr/local/opt or /opt/homebrew/opt
"startup.errors.php_opt.title" = "PHP is not correctly installed";
"startup.errors.php_opt.subtitle" = "The PHP alias was not found in `%@`. The app will not work correctly until you resolve this issue.";
"startup.errors.php_opt.desc" = "If you already have the `php` formula installed, you may need to run `brew install php` in order for PHP Monitor to detect this installation.";
/// PHP binary is broken
// PHP binary is broken
"startup.errors.dyld_library.title" = "PHP is installed, but appears to be broken";
"startup.errors.dyld_library.subtitle" = "When PHP Monitor is attempting to run commands, it is failing to do so correctly. This is usually an indicator of a broken PHP installation.";
"startup.errors.dyld_library.desc" = "Running `brew reinstall php && brew link php` in your Terminal may resolve this issue, so please give that a try.";
/// Valet is not installed
// Valet is not installed
"startup.errors.valet_executable.title" = "Laravel Valet is not correctly installed";
"startup.errors.valet_executable.subtitle" = "You must install Valet with Composer. The app will not work correctly until you resolve this issue.";
"startup.errors.valet_executable.desc" = "If you haven't installed Laravel Valet yet, please do so first. If you have it installed but are seeing this message anyway, then try running `which valet` in Terminal, it should return: `%@`.";
/// Valet configuration file missing or broken
// Valet configuration file missing or broken
"startup.errors.valet_json_invalid.title" = "Laravel Valet configuration file invalid or missing";
"startup.errors.valet_json_invalid.subtitle" = "PHP Monitor needs to be able to read the configuration file. It appears the file is malformed or missing. Please check that it exists and is formatted correctly.";
"startup.errors.valet_json_invalid.desc" = "You can find the file at `~/.config/valet/config.json`. If Laravel Valet cannot parse the configuration file, running any `valet` command will usually automatically fix the JSON file. Try running `valet --version` to automatically fix the file.";
/// Valet version not readable
// Valet version not readable
"startup.errors.valet_version_unknown.title" = "Your Valet version could not be read";
"startup.errors.valet_version_unknown.subtitle" = "Parsing the output of `valet --version` failed. Make sure your Valet installation works and is up-to-date.";
"startup.errors.valet_version_unknown.desc" = "Try running `valet --version` in a terminal to find out what's going on.";
@ -694,32 +698,32 @@ If you are seeing this message but are confused why this folder has gone missing
"startup.errors.valet_version_not_supported.subtitle" = "You are running a version of Valet that is currently not supported. PHP Monitor currently works with Valet v2, v3 and v4. In order to avoid causing issues on your system, PHP Monitor cannot start.";
"startup.errors.valet_version_not_supported.desc" = "You must install a version of Valet that is compatible with PHP Monitor, or you may need to upgrade to a newer version of PHP Monitor which may include compatibility for this version of Valet (consult the latest release notes for more info).";
/// Brew & sudoers
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew has not been added to sudoers.d";
"startup.errors.sudoers_brew.subtitle" = "You must run `sudo valet trust` to ensure Valet can start and stop services without having to use sudo every time. The app will not work correctly until you resolve this issue.";
"startup.errors.sudoers_brew.desc" = "If you keep seeing this error, it is possible that there is a permission issue where PHP Monitor cannot validate the file, which can usually be resolved by running: `sudo chmod +r /private/etc/sudoers.d/brew`";
/// Valet & sudoers
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Valet has not been added to sudoers.d";
"startup.errors.sudoers_valet.subtitle" = "You must run `sudo valet trust` to ensure Valet can start and stop services without having to use sudo every time. The app will not work correctly until you resolve this issue. If you did this before, please run `sudo valet trust` again.";
"startup.errors.sudoers_valet.desc" = "If you keep seeing this error, it is possible that there is a permission issue where PHP Monitor cannot validate the file, which can usually be resolved by running: `sudo chmod +r /private/etc/sudoers.d/valet`";
/// Platform issue detected
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor and Valet cannot work correctly: Composer is reporting an issue with your platform";
"startup.errors.global_composer_platform_issues.subtitle" = "Please follow these recommended steps to avoid seeing this issue in the future:\n\n1. Run `composer global update`.\n2. Restart PHP Monitor. (It should work again.)\n3. Switch to the oldest PHP version you have installed.\n4. Run `composer global update` again.";
"startup.errors.global_composer_platform_issues.desc" = "You can go to Preferences and check the 'Automatically update global dependencies' option. This will update your global Composer dependencies whenever you change PHP versions, so this may not be ideal if you may not have constant access to the internet.\n\nTo find out exactly what's going wrong, try running `valet --version`. Valet is currently not functional with the installed dependencies. Usually this is caused by a version mismatch: i.e. installed dependencies for a newer version of PHP than the version that is currently active.";
/// Cannot retrieve services
// Cannot retrieve services
"startup.errors.services_json_error.title" = "Cannot determine services status";
"startup.errors.services_json_error.subtitle" = "PHP Monitor usually queries `brew` using the following command to test if the services can be retrieved: `sudo brew services info nginx --json`.\n\nPHP Monitor could not interpret this response.";
"startup.errors.services_json_error.desc" = "This can happen if your Homebrew installation is out of date, in which case Homebrew won't return JSON yet. You can usually fix this by running `brew update` or `brew tap homebrew/services`. You can also try running `sudo brew services info nginx --json` in your terminal of choice.";
/// Issue with `which` alias
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "A configuration issue was detected";
"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
// 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.";
@ -749,7 +753,7 @@ Valet might break if you link these PHP versions so PHP Monitor won't let you sw
"startup.sponsor_encouragement.learn_more" = "Learn More";
"startup.sponsor_encouragement.skip" = "No Thanks";
// ERROR MESSAGES (based on AlertableError)
// ERROR MESSAGES
"alert.errors.homebrew_permissions.applescript_returned_nil.title" = "Restore Homebrew Permissions has been cancelled.";
"alert.errors.homebrew_permissions.applescript_returned_nil.description" = "The outcome of the script that is executed to adjust the permissions returned nil, which usually means that you did not grant administrative permissions to PHP Monitor.\n\nIf you clicked on Cancel during the authentication prompt, this is normal. If you did actually authenticate and you are still seeing this message, something probably went wrong.";
@ -862,3 +866,14 @@ Please note that some features (greyed out below) are currently unavailable beca
"alert.language_changed.title" = "You must restart PHP Monitor!";
"alert.language_changed.subtitle" = "You just changed the display language of PHP Monitor. The menu will immediately use the correct language, but you may need to restart the app for all text throughout the app to reflect your new language choice.";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "Ignore";
"startup.timeout.title" = "PHP Monitor is taking too long to initialize!";
"startup.timeout.subtitle" = "If PHP Monitor remains busy for longer than 30 seconds, there may be something wrong with your Homebrew setup.";
"startup.timeout.description" = "Sometimes, due to various file permission issues, things may break. You can try using `brew doctor` and `brew cleanup` to fix this.
It is recommended to restart PHP Monitor afterwards. Learn more about this issue at: https://github.com/nicoverbruggen/phpmon/issues/294.
If PHP Monitor has finished initializing anyway or you want to wait a bit longer, feel free to click 'Ignore' and use PHP Monitor as usual. Either way, you may want to investigate, because this isn't supposed to take this long.";

View File

@ -0,0 +1,853 @@
// MENU ITEMS (MI)
"mi_busy" = "PHP Monitor está ocupado...";
"mi_unsure" = "No estamos seguros de qué versión de PHP estás ejecutando.";
"mi_php_version" = "Versión global: PHP";
"mi_php_switch" = "Cambiar a PHP";
"mi_php_unsupported" = "Algunas versiones instaladas de PHP no se muestran.";
"mi_php_broken_1" = "¡Uy! Parece que tu instalación de PHP está rota...";
"mi_php_broken_2" = "Intenta ejecutar `php -v` en tu terminal.";
"mi_php_broken_3" = "También podrías intentar cambiar a otra versión.";
"mi_php_broken_4" = "Ejecutar `brew reinstall php` (o para la versión equivalente) podría ayudar.";
"mi_no_php_linked" = "¡No hay ninguna versión de PHP vinculada!";
"mi_fix_php_link" = "Arreglar automáticamente...";
"mi_no_php_linked_explain" = "¿Qué es esto?";
"mi_php_version_manager" = "Gestionar instalaciones de PHP...";
"mi_php_ext_manager" = "Gestionar extensiones de PHP...";
"mi_php_config_manager" = "Editor de configuración de PHP...";
"mi_manage_limits" = "Gestionar límites...";
"mi_diagnostics" = "Diagnósticos";
"mi_active_services" = "Servicios activos";
"mi_restart_php_fpm" = "Reiniciar servicio: php";
"mi_restart_nginx" = "Reiniciar servicio: nginx";
"mi_restart_dnsmasq" = "Reiniciar servicio: dnsmasq";
"mi_manage_services" = "Gestionar servicios";
"mi_restart_valet_services" = "Reiniciar servicios de Valet";
"mi_stop_valet_services" = "Detener servicios de Valet";
"mi_fix_my_valet" = "Arreglar mi Valet...";
"mi_fix_my_valet_tooltip" = "¿Algo anda mal con tu instalación de Valet? ¡Prueba las correcciones automáticas de PHP Monitor que te ayudarán a estar funcionando en poco tiempo!";
"mi_fix_brew_permissions" = "Restaurar permisos de Homebrew...";
"mi_fix_brew_permissions_tooltip" = "¿Tienes problemas de permisos al ejecutar `brew upgrade`? ¡PHP Monitor al rescate!";
"mi_php_refresh" = "Actualizar información";
"mi_configuration" = "Configuración de PHP";
"mi_limits" = "Configuración de límites";
"mi_memory_limit" = "Memory Limit";
"mi_post_max_size" = "Max POST";
"mi_upload_max_filesize" = "Max Upload";
"mi_manual_actions" = "Acciones manuales";
"mi_services" = "Servicios";
"mi_other" = "Primeros auxilios y servicios";
"mi_first_aid" = "Primeros auxilios";
"mi_xdebug_mode" = "Gestionar Xdebug";
"mi_composer" = "Composer";
"mi_valet_config" = "Localizar carpeta de Valet (.config/valet)";
"mi_php_config" = "Localizar archivo de configuración PHP (php.ini)";
"mi_phpmon_config" = "Localizar carpeta de PHP Monitor (.config/phpmon)";
"mi_global_composer" = "Localizar archivo global de Composer (.composer)";
"mi_phpinfo" = "Mostrar configuración actual (phpinfo)";
"mi_update_global_composer" = "Actualizar dependencias globales de Composer...";
"mi_detected_extensions" = "Extensiones detectadas";
"mi_no_extensions_detected" = "No se detectaron extensiones adicionales.";
"mi_php_doctor" = "PHP Doctor";
"mi_fa_php_doctor" = "Abrir PHP Doctor...";
"mi_recommendations_count" = "¡%i problema(s) detectado(s)!";
"mi_view_recommendations" = "Ver recomendaciones...";
"mi_valet" = "Laravel Valet";
"mi_domain_list" = "Ver lista de dominios...";
"mi_preferences" = "Preferencias...";
"mi_donate" = "Donar...";
"mi_check_for_updates" = "Buscar actualizaciones...";
"mi_lite_mode" = "Acerca del modo independiente...";
"mi_quit" = "Salir de PHP Monitor";
"mi_about" = "Acerca de PHP Monitor";
"mi_presets_title" = "Ajustes preestablecidos";
"mi_apply_presets_title" = "Aplicar ajustes preestablecidos";
"mi_revert_to_prev_config" = "Volver a la configuración anterior...";
"mi_profiles_loaded" = "%i perfiles cargados desde el archivo de configuración";
"mi_no_presets" = "No hay ajustes preestablecidos disponibles.";
"mi_set_up_presets" = "Aprende más sobre los ajustes preestablecidos...";
"mi_view_onboarding" = "Abrir tour de bienvenida...";
"mi_xdebug_available_modes" = "Modos disponibles";
"mi_xdebug_actions" = "Acciones";
"mi_xdebug_disable_all" = "Desactivar todos los modos";
"mm_actions" = "Acciones";
// CONFMAN
"confman.title" = "Editor de configuración de PHP";
"confman.description" = "Esta función te permite personalizar la configuración de tu instalación de PHP fácilmente.\nTen en cuenta que cualquier cambio que hagas se aplica inmediata y automáticamente.";
"confman.byte_limit.unlimited" = "Permitir uso ilimitado";
"php_ini.memory_limit.title" = "Memory Limit";
"php_ini.memory_limit.description" = "Esto establece la cantidad máxima de memoria en bytes que un script puede asignar. Esto ayuda a evitar que los scripts mal escritos consuman toda la memoria disponible en un servidor.";
"php_ini.post_max_size.title" = "POST Max Size";
"php_ini.post_max_size.description" = "Establece el tamaño máximo permitido de datos POST. Esta configuración también afecta la carga de archivos. Para cargar archivos grandes, este valor debe ser mayor que Upload Max Size. En general, Memory Limit debe ser mayor que POST Max Size.";
"php_ini.file_uploads.title" = "File Uploads";
"php_ini.file_uploads.description" = "Activa o desactiva completamente la carga de archivos. Se recomienda mantener esto activado.";
"php_ini.upload_max_filesize.title" = "Upload Max Size";
"php_ini.upload_max_filesize.description" = "El tamaño máximo de un archivo cargado. POST Max Size debe ser mayor que este valor.";
// PHPEXTMAN
"phpextman.window.title" = "Extensiones";
"phpextman.description" = "**PHP Extension Manager** te permite gestionar diferentes extensiones de PHP con un simple clic. Como se usa Homebrew, las extensiones no necesitarán ser compiladas al momento usando `pecl`.";
"phpextman.disclaimer" = "Algunas extensiones pueden requerir que se instalen otras dependencias, pero en general, instalar extensiones debería ser mucho más rápido que instalar versiones de PHP.";
"phpextman.warnings.removal.title" = "¿Desinstalar la extensión `%@`?";
"phpextman.warnings.removal.desc" = "Se eliminará la extensión y su archivo de configuración único. La funcionalidad de la extensión ya no estará disponible para esta instalación de PHP. ¿Estás seguro?
(Si la extensión está habilitada usando un nombre de archivo no estándar, no se eliminará. Así que si no quieres que se elimine el archivo .ini, es mejor simplemente renombrarlo a algo diferente. En ese caso, la extensión solo se deshabilitará como parte del proceso de limpieza.)";
"phpextman.warnings.removal.button" = "Desinstalar";
"phpextman.list.showing_count" = "Actualmente mostrando %@ extensiones para:";
"phpextman.list.depends_on" = "Depende de:";
"phpextman.list.status.external" = "Esta extensión ya está instalada a través de otra fuente y no se puede gestionar.";
"phpextman.list.status.installable" = "Esta extensión puede ser instalada.";
"phpextman.list.status.dependent" = "No puedes desinstalar esto antes de desinstalar %@.";
"phpextman.list.status.can_manage" = "Esta extensión está instalada y gestionada por PHP Monitor.";
"phpextman.errors.not_found.title" = "¡Ups! ¡No se descubrieron extensiones!";
"phpextman.errors.not_found.desc" = "Esto no debería suceder. Es posible que necesites ejecutar el siguiente comando en tu terminal:
`brew tap shivammathur/extensions`
y reiniciar PHP Monitor para que las extensiones sean visibles. Si el problema persiste después de ejecutar el comando y reiniciar PHP Monitor, considera abrir un issue en GitHub.";
// PHPMAN
"phpman.busy.title" = "¡Buscando actualizaciones!";
"phpman.busy.description.outdated" = "Comprobando si alguna versión de PHP está desactualizada...";
"phpman.version.broken" = "Esta versión parece estar rota, puedes intentar repararla.";
"phpman.version.has_update" = "Versión %@ instalada, %@ disponible.";
"phpman.version.installed" = "La versión %@ está actualmente instalada.";
"phpman.version.available_for_installation" = "Esta versión puede ser instalada.";
"phpman.version.unavailable" = "Esta versión está temporalmente no disponible.";
"phpman.version.automatic_upgrade" = "Esta versión se instalará automáticamente al actualizar una versión anterior.
(Tanto esta nueva versión como la antigua estarán disponibles después de la actualización.)";
"phpman.buttons.uninstall" = "Desinstalar";
"phpman.buttons.install" = "Instalar";
"phpman.buttons.update" = "Actualizar";
"phpman.buttons.repair" = "Reparar";
"phpman.version.prerelease" = "Versión preliminar";
"phpman.steps.installing" = "Instalando %@";
"phpman.steps.removing" = "Eliminando %@";
"phpman.steps.reloading" = "Recargando versiones de PHP...";
"phpman.steps.preparing" = "PHP Monitor está preparando Homebrew...";
"phpman.steps.wait" = "Por favor espera...";
"phpman.steps.completed" = "¡Operación completada!";
"phpman.steps.success" = "La operación se ha completado con éxito.";
"phpman.steps.failure" = "El comando no se ejecutó correctamente.";
"phpman.title" = "Gestor de versiones de PHP";
"phpman.description" = "**PHP Version Manager** te permite instalar, actualizar y eliminar diferentes versiones de PHP a través de Homebrew sin necesidad de ejecutar los comandos en la terminal tú mismo.";
"phpman.disclaimer" = "Ten en cuenta que instalar o actualizar versiones de PHP puede causar que otros paquetes de Homebrew también se actualicen. La mayoría de los pasos de instalación suelen llevar algo de tiempo, así que ten paciencia mientras Homebrew hace su trabajo.";
"phpman.refresh.button" = "Buscar actualizaciones";
"phpman.refresh.button.description" = "Puedes presionar el botón de actualizar para comprobar si hay actualizaciones disponibles para las versiones instaladas de PHP.";
"phpman.has_updates.description" = "**Hay una o más actualizaciones disponibles.** PHP Monitor siempre instalará o actualizará las versiones de PHP en conjunto, por lo que siempre actualizarás todas las instalaciones a la vez.";
"phpman.has_updates.button" = "Actualizar todo";
"phpman.warnings.outdated.title" = "Esta versión de PHP Monitor está desactualizada";
"phpman.warnings.outdated.desc" = "Es muy probable que las fórmulas de Homebrew hayan cambiado desde que se creó esta versión de PHP Monitor. Te recomiendo encarecidamente actualizar la aplicación antes de usar el gestor de versiones para instalar, eliminar o actualizar versiones de PHP.";
"phpman.warnings.unsupported.title" = "Tu versión de Homebrew puede causar problemas";
"phpman.warnings.unsupported.desc" = "No se ha desactivado ninguna funcionalidad, pero algunos comandos pueden no funcionar como se espera. Actualmente estás ejecutando Homebrew %@.
Actualmente, Homebrew 4 es la única versión compatible con el Gestor de versiones de PHP. Si estás ejecutando una versión más nueva de Homebrew, es posible que desees comprobar si hay una versión más nueva de PHP Monitor disponible.";
"phpman.warnings.removal.title" = "¿Estás seguro de que quieres desinstalar %@?";
"phpman.warnings.removal.desc" = "Ten en cuenta que los archivos de configuración no se eliminarán, por lo que debería ser fácil reinstalar más tarde si es necesario.
Es posible que se te pida tu contraseña durante el proceso de desinstalación si los permisos de archivo no permiten una eliminación simple.";
"phpman.warnings.removal.button" = "Desinstalar";
"phpman.failures.install.title" = "¡La instalación falló!";
"phpman.failures.install.desc" = "Desafortunadamente, la operación devolvió un código de error por alguna razón. Es posible que las fórmulas se hayan instalado o actualizado correctamente. Lamentablemente, no puedo hacer mucho al respecto. Por favor, revisa los últimos mensajes de Homebrew aquí para más información sobre lo que sucedió:
%@";
"phpman.action_prevented_busy.title" = "PHP Monitor está actualmente ocupado.";
"phpman.action_prevented_busy.desc" = "PHP Monitor está actualmente haciendo algo como cambiar entre versiones de PHP. Para asegurar que tu sistema no se rompa, necesitarás esperar hasta que PHP Monitor esté listo antes de intentar esto de nuevo.";
"phpman.uninstall_prevented.title" = "No puedes desinstalar la versión activa actual de PHP a través de PHP Monitor.";
"phpman.uninstall_prevented.desc" = "Para prevenir problemas con PHP Monitor y más fallos, no es posible desinstalar la versión actualmente vinculada de PHP a través de esta interfaz. Puedes cambiar de versión e intentarlo de nuevo, o desinstalar esta versión manualmente a través de la terminal.\n\nTen en cuenta que PHP Monitor puede fallar si desinstalas la versión de PHP actualmente vinculada.";
"phpman.failures.uninstall.title" = "¡La desinstalación falló!";
"phpman.failures.uninstall.desc" = "Desafortunadamente, la desinstalación automática falló. Puedes intentar ejecutar este comando manualmente: `%@` y descubrir qué sale mal. Recuerda reiniciar PHP Monitor (o presionar el botón de actualizar) cuando esto esté hecho.";
"phpman.unlinked.title" = "Ninguna de las versiones de PHP instaladas en tu sistema está actualmente vinculada.";
"phpman.unlinked.desc" = "Es probable que aún tengas alguna versión de PHP instalada, pero actualmente ninguna versión de PHP está vinculada.";
"phpman.unlinked.detail" = "Sin ninguna versión de PHP vinculada, el binario `php` no es accesible en tu sistema y no puedes ejecutar ningún script PHP sin ser explícitamente parte del PATH. Puedes hacer que PHP Monitor resuelva automáticamente este problema (elige Arreglar automáticamente en el menú principal), o arreglarlo tú mismo ejecutando `brew link php --force`.";
"phpman.operations.repairing" = "Reparando instalaciones...";
"phpman.operations.updating" = "Instalando actualizaciones...";
"phpman.operations.installing" = "Instalando %@...";
"phpman.steps.fetching" = "Obteniendo...";
"phpman.steps.downloading" = "Descargando datos del paquete...";
"phpman.steps.installing" = "Instalando algunos datos del paquete...";
"phpman.steps.pouring" = "Vertiendo... Esto puede llevar un tiempo...";
"phpman.steps.summary" = "Algún paquete ha terminado de instalarse...";
"phpman.services.loading" = "Cargando...";
"phpman.services.not_installed" = "Un servicio clave no está instalado.";
"phpman.services.error" = "Un servicio clave está reportando un estado de error.";
"phpman.services.inactive" = "Un servicio clave no está ejecutándose.";
"phpman.services.all_ok" = "Todos los servicios de Valet están OK.";
// LITE MODE
"lite_mode_explanation.title" = "Actualmente estás ejecutando PHP Monitor en modo independiente.";
"lite_mode_explanation.subtitle" = "PHP Monitor tiene características adicionales que están disponibles si eres usuario de Laravel Valet. En este momento, PHP Monitor no pudo detectar una instalación activa de Valet en tu sistema, por lo que esas características no están disponibles.";
"lite_mode_explanation.description" = "Para más información, te recomiendo consultar el README (accesible en GitHub) que explicará los pasos necesarios para instalar Valet y hacer que PHP Monitor funcione correctamente con él instalado. Necesitarás reiniciar PHP Monitor después de instalar Laravel Valet antes de que salga del modo independiente.";
// GENERIC
"generic.ok" = "Aceptar";
"generic.cancel" = "Cancelar";
"generic.retry" = "Reintentar";
"generic.notice" = "Aviso";
// PRESET LOADING
"preset_help_title" = "Trabajar con ajustes preestablecidos de configuración";
"preset_help_info" = "Puedes configurar ajustes preestablecidos en el archivo config.json, ubicado en ~/.config/phpmon/config.json. Estos ajustes pueden aplicar una selección de valores de configuración todos a la vez. Esta es una característica poderosa, pero actualmente necesita ser configurada manualmente.";
"preset_help_desc" = "Después de reiniciar PHP Monitor, se cargarán todos los ajustes preestablecidos encontrados en el archivo. Si no aparecen ajustes preestablecidos, probablemente el archivo no se pudo analizar correctamente.\n\nPuedes hacer clic en el signo de interrogación en esta alerta para ir a las preguntas frecuentes en GitHub, donde puedes encontrar más información sobre esta característica, incluyendo un archivo de ejemplo.";
// MENU ITEMS (if window is open)
"mm_add_folder_as_link" = "Agregar carpeta como enlace...";
"mm_reload_domain_list" = "Recargar lista de dominios";
"mm_find_in_domain_list" = "Buscar en lista de dominios";
// SITE LIST
"domain_list.title" = "Dominios";
"domain_list.subtitle" = "";
"domain_list.domains_empty.title" = "No hay dominios disponibles.";
"domain_list.domains_empty.desc" = "No se encontraron dominios para esta búsqueda o aún no has vinculado ningún dominio.";
"domain_list.domains_empty.button" = "Agregar dominio...";
"domain_list.tooltips.isolated" = "Este dominio está aislado y usando PHP %@ en lugar del PHP vinculado globalmente.";
"domain_list.tooltips.checkmark" = "Este dominio se está sirviendo con una versión de PHP que es compatible con este requisito (PHP %@). Haz clic en la versión de PHP junto a esta marca de verificación para obtener más información sobre cómo se determinó este requisito.";
"domain_list.alerts_isolation_failed.title" = "¡Ups! No se aplicó el aislamiento del sitio";
"domain_list.alerts_isolation_failed.subtitle" = "Algo salió mal al intentar cambiar el estado de aislamiento para este sitio. Si este es tu sitio predeterminado pero no está vinculado, te recomiendo vincular manualmente el sitio antes de configurar el aislamiento.";
"domain_list.alerts_isolation_failed.desc" = "Para descubrir qué sale mal, puedes intentar ejecutar el comando en tu terminal manualmente: %@";
"domain_list.alerts_status_not_changed.title" = "¡Ups! No se cambió el estado SSL";
"domain_list.alerts_status_not_changed.desc" = "Algo salió mal. Intenta ejecutar el comando en tu terminal manualmente: %@";
"domain_list.alerts_status_changed.title" = "Estado SSL cambiado";
"domain_list.alerts_status_changed.desc" = "El dominio '%@' ahora está %@.";
"domain_list.alerts_status_secure" = "seguro";
"domain_list.alerts_status_unsecure" = "no seguro";
"domain_list.confirm_unlink" = "¿Estás seguro de que quieres desvincular '%@'?";
"domain_list.confirm_unlink_desc" = "No se eliminarán archivos. Siempre puedes vincular la carpeta de nuevo haciendo clic en el botón + y seleccionando la carpeta original.";
"site_link.close" = "Cerrar";
"site_link.switch_to_php" = "Cambiar a PHP %@";
"site_link.isolate_php" = "Aislar PHP %@";
"domain_list.confirm_unproxy" = "¿Estás seguro de que quieres eliminar el proxy '%@'?";
"domain_list.confirm_unproxy_desc" = "Siempre puedes crear el proxy de nuevo haciendo clic en el botón +.";
"domain_list.columns.secure" = "TLS";
"domain_list.columns.domain" = "Dominio";
"domain_list.columns.active" = "Activo";
"domain_list.columns.kind" = "Tipo";
"domain_list.columns.project_type" = "Tipo de proyecto";
"domain_list.extensions" = "Alternar extensiones";
"domain_list.applies_to" = "Se aplica a PHP %@";
// CHOOSE WHAT TO ADD
"selection.title" = "¿Qué tipo de dominio te gustaría configurar?";
"selection.description" = "Los enlaces se usan para servir proyectos directamente. Si tienes una carpeta de Laravel, Symfony, WordPress, etc. con código, querrás crear un enlace y elegir la carpeta donde vive tu código.\n\nSi necesitas un proxy, puedes hacer proxy de, por ejemplo, un contenedor a un nombre de dominio particular. Esto puede ser útil en combinación con Docker, por ejemplo.";
"selection.create_link" = "Crear un enlace";
"selection.create_proxy" = "Crear un proxy";
"selection.cancel" = "Cancelar";
// ADD PROXY TO DOMAINS LIST
"domain_list.add.set_up_proxy" = "Configurar un proxy";
"domain_list.add.proxy_subject" = "Sujeto del proxy (debe incluir protocolo y puerto)";
"domain_list.add.domain_name" = "Nombre de dominio";
"domain_list.add.create_proxy" = "Crear proxy";
"domain_list.add.proxy_available" = "%@ será proxy y estará disponible vía: %@://%@.%@";
"domain_list.add.proxy_https_warning" = "%@ será proxy y estará disponible vía: %@://%@.%@.
(!) IMPORTANTE: Este proxy puede no funcionar hasta que agregues manualmente `proxy_ssl_verify off;` al archivo de configuración de nginx para este dominio. Se recomienda usar un dominio no seguro como sujeto del proxy.";
// ADD SITE TO DOMAINS LIST
"domain_list.add.link_folder" = "Vincular una carpeta";
"domain_list.add.domain_name_placeholder" = "Ingresa un nombre de dominio aquí";
"domain_list.add.secure_after_creation" = "Asegurar %@.%@ después de la creación";
"domain_list.add.secure_description" = "Asegurar un dominio requiere privilegios administrativos.\nEs posible que se te solicite tu contraseña o Touch ID.";
"domain_list.add.create_link" = "Crear enlace";
"domain_list.add.cancel" = "Cancelar";
"domain_list.add.folder_available" = "Este sitio estará disponible vía la siguiente URL: %@://%@.%@";
"domain_list.add.empty_fields" = "Uno o más campos están vacíos. Por favor, completa todos los campos requeridos.";
"domain_list.add.errors.empty" = "Debes ingresar un nombre de dominio.";
"domain_list.add.errors.empty_proxy" = "Debes ingresar lo que será proxy.";
"domain_list.add.errors.subject_invalid" = "El sujeto que has ingresado no es válido.\nDebes incluir el protocolo y puerto.";
"domain_list.add.errors.already_exists" = "Ya existe un enlace con ese nombre.";
// ADD SITE ERROR: FOLDER MISSING SINCE SELECTION
"domain_list.alert.folder_missing.desc" = "La carpeta que elegiste ya no parece existir. ¿Quieres cancelar la adición de esta carpeta? Si moviste la carpeta, siempre puedes volver a ponerla y intentar de nuevo.";
"domain_list.alert.folder_missing.title" = "¡Carpeta faltante!";
"domain_list.alert.folder_missing.cancel" = "Cancelar enlace";
"domain_list.alert.folder_missing.return" = "Aceptar";
"domain_list.add.modal_description" = "Primero, selecciona qué carpeta te gustaría vincular.";
// SITE LIST ACTIONS
"domain_list.isolate" = "Cambiar versión de PHP";
"domain_list.site_isolation" = "Aislamiento del sitio";
"domain_list.remove_isolation" = "Eliminar aislamiento";
"domain_list.always_use_php" = "Usar siempre PHP %@";
"domain_list.isolation_unavailable" = "Aislamiento no compatible (en Valet 2)";
"domain_list.favorite" = "Marcar como favorito";
"domain_list.unfavorite" = "Desmarcar como favorito";
"domain_list.actions" = "Acciones";
"domain_list.unlink" = "Desvincular directorio";
"domain_list.secure" = "Asegurar dominio";
"domain_list.unsecure" = "Desasegurar dominio";
"domain_list.open_in" = "Abrir con %@";
"domain_list.open_in_finder" = "Abrir en Finder";
"domain_list.open_in_browser" = "Abrir en navegador";
"domain_list.open_in_terminal" = "Abrir en Terminal";
"domain_list.detected_apps" = "Aplicaciones detectadas";
"domain_list.system_apps" = "Aplicaciones del sistema";
"domain_list.unproxy" = "Eliminar proxy";
"domain_list.use_in_terminal" = "Abrir PHP %@ en Terminal";
"domain_list.alerts_isolated_php_terminal.title" = "¡Puedes usar PHP %@ en una terminal específica!";
"domain_list.alerts_isolated_php_terminal.subtitle" = "Lamentablemente, PHP Monitor no puede abrir una terminal por ti (y escribir los comandos apropiados). Tendrás que ejecutar manualmente el script auxiliar para usar esta versión específica de PHP. Para hacer esto, puedes escribir lo siguiente en una terminal de tu elección:
. pm%@
Esto ejecutará el script auxiliar generado por PHP Monitor y habilitará el uso de PHP %@ para esa terminal específica.
Esto no tiene efecto en otras terminales, solo para la sesión particular de terminal en la que lo estás usando. (es decir, si tienes múltiples pestañas en tu aplicación de terminal, otras pestañas y ventanas no se ven afectadas.)";
"domain_list.alerts_isolated_php_terminal.desc" = "Si esto no funciona, es posible que desees verificar PHP Doctor a través del menú de Primeros auxilios aquí en PHP Monitor. También puedes encontrar más información sobre esta característica en GitHub (en la wiki del repositorio de PHP Monitor). Esta alerta se incluye para mejorar la visibilidad de esta característica.";
"domain_list.warning.spaces" = "¡Advertencia! Este sitio tiene un espacio en su carpeta.\nEl sitio no será accesible a través del navegador.";
"domain_list.alert.invalid_folder_name" = "Nombre de carpeta inválido";
"domain_list.alert.invalid_folder_name_desc" = "Esta carpeta no se pudo resolver a una URL válida. Esto generalmente sucede porque hay un espacio en el nombre de la carpeta. Por favor, renombra la carpeta, recarga la lista de sitios e intenta de nuevo.";
"domain_list.columns.tls" = "TLS";
"domain_list.columns.domain" = "Dominio";
"domain_list.columns.php" = "PHP";
"domain_list.columns.type" = "Tipo";
"domain_list.columns.kind" = "Tipo";
// DRIVERS
"driver.not_detected" = "Otro";
// PRESET
"preset.extension" = "%i extensión";
"preset.extensions" = "%i extensiones";
"preset.preference" = "%i preferencia";
"preset.preferences" = "%i preferencias";
// EDITORS
"editors.alert.try_again" = "Intentar de nuevo";
"editors.alert.cancel" = "Cancelar";
// PREFERENCES
"prefs.title" = "PHP Monitor";
"prefs.subtitle" = "Preferencias";
"prefs.close" = "Cerrar";
"prefs.tabs.general" = "General";
"prefs.tabs.appearance" = "Apariencia";
"prefs.tabs.visibility" = "Visibilidad";
"prefs.tabs.notifications" = "Notificaciones";
"prefs.global_shortcut" = "Atajo global:";
"prefs.dynamic_icon" = "Icono dinámico:";
"prefs.dynamic_icon" = "Tipo de icono:";
"prefs.info_density" = "Densidad de información:";
"prefs.services" = "Servicios:";
"prefs.switcher" = "Selector:";
"prefs.php_doctor" = "PHP Doctor:";
"prefs.integrations" = "Integraciones:";
"prefs.updates" = "Actualizaciones:";
"prefs.notifications" = "Notificaciones:";
"prefs.warnings" = "Advertencias:";
"prefs.menu_contents" = "Funciones en el menú:";
"prefs.startup" = "Inicio:";
"prefs.auto_start_desc" = "Inicia PHP Monitor automáticamente cuando inicias sesión en tu Mac.";
"prefs.auto_start_title" = "Iniciar PHP Monitor al iniciar sesión";
"prefs.icon_options.php" = "Mostrar icono de PHP";
"prefs.icon_options.elephant" = "Mostrar icono del elefante";
"prefs.icon_options.none" = "No mostrar icono";
"prefs.icon_options_desc" = "Esta opción determina qué icono se mostrará junto al número de versión de PHP actualmente vinculado. Si la opción de Icono dinámico está desactivada, esto no tendrá efecto.";
"prefs.auto_restart_services_title" = "Reiniciar PHP-FPM automáticamente";
"prefs.auto_restart_services_desc" = "Cuando está marcado, reiniciará automáticamente PHP-FPM al activar o desactivar una extensión. Es un poco más lento cuando está activado, pero aplica el cambio de extensión inmediatamente para todos los sitios que estés sirviendo, sin necesidad de reiniciar PHP-FPM manualmente.";
"prefs.dynamic_icon_title" = "Mostrar icono dinámico en la barra de menú";
"prefs.dynamic_icon_desc" = "Si desmarcas esta casilla, el icono del camión siempre será visible. Si está marcada, mostrará el número de versión principal de la versión de PHP actualmente vinculada.";
"prefs.display_full_php_version" = "Mostrar versión completa de PHP en todas partes";
"prefs.display_full_php_version_desc" = "Muestra la versión completa en lugar de la versión principal en la barra de menú y el menú desplegable. (Esto puede ser indeseable en pantallas más pequeñas, por lo que está desactivado por defecto.)";
"prefs.auto_composer_update_title" = "Actualizar dependencias globales automáticamente";
"prefs.auto_composer_update_desc" = "Cuando está marcado, pedirá automáticamente a Composer que ejecute `composer global update` cada vez que cambies entre diferentes versiones de PHP. Podrás ver qué cambios se están realizando, o si esto falla.";
"prefs.open_protocol_title" = "Permitir integraciones de terceros";
"prefs.open_protocol_desc" = "Cuando está marcado, permitirá que funcione la interacción con utilidades de terceros (por ejemplo, Alfred, Raycast). Si lo desactivas, PHP Monitor seguirá recibiendo los comandos, pero no actuará sobre ellos.";
"prefs.automatic_update_check_title" = "Buscar actualizaciones automáticamente";
"prefs.automatic_update_check_desc" = "Cuando está marcado, PHP Monitor verificará automáticamente si hay una versión más nueva disponible y te notificará si ese es el caso.";
"prefs.php_doctor_suggestions_title" = "Mostrar sugerencias siempre";
"prefs.php_doctor_suggestions_desc" = "Si desmarcas este elemento, no aparecerán sugerencias de PHP Doctor en el menú de PHP Monitor. Ten en cuenta que PHP Doctor no aparecerá si no hay recomendaciones.";
"prefs.shortcut_set" = "Establecer atajo global";
"prefs.shortcut_listening" = "<esperando pulsación de teclas>";
"prefs.shortcut_clear" = "Borrar";
"prefs.shortcut_desc" = "Si se configura una combinación de teclas, puedes alternar PHP Monitor donde sea presionando la combinación de teclas que elegiste. (Cancela la elección de un atajo presionando la barra espaciadora.)";
"prefs.notify_about_version_change_desc" = "Muestra una notificación cada vez que cambia la versión activa de PHP.";
"prefs.notify_about_version_change" = "Notificar sobre cambio de versión de PHP";
"prefs.notify_about_php_fpm_change_desc" = "Muestra una notificación cada vez que el proceso PHP-FPM activo se reinicia debido a un cambio de configuración.";
"prefs.notify_about_php_fpm_change" = "Notificar sobre reinicio de PHP-FPM";
"prefs.notify_about_services_desc" = "Muestra una notificación cada vez que cualquiera de los servicios de Homebrew (instalados y configurados por Valet) se han reiniciado o detenido.";
"prefs.notify_about_services" = "Notificar sobre estado de servicios";
"prefs.notify_about_presets_desc" = "Muestra una notificación cada vez que se aplica o revierte correctamente un preset.";
"prefs.notify_about_presets" = "Notificar sobre presets aplicados";
"prefs.notify_about_secure_status_desc" = "Muestra una notificación cuando un dominio ha sido asegurado o desasegurado.";
"prefs.notify_about_secure_status" = "Notificar sobre estado seguro/inseguro";
"prefs.notify_about_composer_success_desc" = "Muestra una notificación cuando la configuración global de Composer se actualizó correctamente.";
"prefs.notify_about_composer_success" = "Notificar sobre actualización global de composer";
"prefs.warn_about_non_standard_tld_desc" = "Si usas un TLD no estándar, es posible que no desees recibir notificaciones repetidas sobre esto.";
"prefs.warn_about_non_standard_tld" = "Advertir sobre TLD no estándar";
"prefs.display_global_version_switcher_desc" = "Si está desactivado, no podrás cambiar la versión de PHP vinculada globalmente a través del menú principal.";
"prefs.display_global_version_switcher" = "Selector de PHP";
"prefs.display_services_manager_desc" = "Si está desactivado, no podrás ver, iniciar o detener servicios individuales. (Si hay servicios deshabilitados, no podrás ver fácilmente que este es el caso.)";
"prefs.display_services_manager" = "Gestor de servicios";
"prefs.display_valet_integration_desc" = "Si está desactivado, no podrás localizar la carpeta principal de Valet ni abrir la lista de dominios.";
"prefs.display_valet_integration" = "Integración con Valet";
"prefs.display_php_config_finder_desc" = "Si está desactivado, no podrás localizar fácilmente tus archivos de configuración de PHP y/o generar un volcado phpinfo().";
"prefs.display_php_config_finder" = "Buscador de configuración PHP";
"prefs.display_composer_toolkit_desc" = "Si está desactivado, no podrás invocar Composer a través del menú principal. La actualización automática de Composer después de cambiar la preferencia no se ve afectada por este cambio.";
"prefs.display_composer_toolkit" = "Herramientas de Composer";
"prefs.display_limits_widget_desc" = "Si está desactivado, no podrás ver el widget de límites (memoria, POST, carga) en el menú principal.";
"prefs.display_limits_widget" = "Widget de límites";
"prefs.display_extensions_desc" = "Si está desactivado, no podrás activar/desactivar extensiones fácilmente a través del menú principal.";
"prefs.display_extensions" = "Extensiones";
"prefs.display_presets_desc" = "Si está desactivado, no podrás aplicar o revertir presets de configuración PHP.";
"prefs.display_presets" = "Presets";
"prefs.display_misc_desc" = "Si está desactivado, no podrás acceder al menú de Primeros auxilios y Servicios.";
"prefs.display_misc" = "Menú de Primeros auxilios y Servicios";
// NOTIFICATIONS
"notification.version_changed_title" = "PHP %@ ahora activo";
"notification.version_changed_desc" = "PHP Monitor ha cambiado a PHP %@.";
"notification.php_fpm_restarted" = "PHP-FPM reiniciado automáticamente";
"notification.php_fpm_restarted_desc" = "Has activado/desactivado una extensión, por lo que PHP-FPM se reinició automáticamente.";
"notification.services_stopped" = "Servicios de Valet detenidos";
"notification.services_stopped_desc" = "Todos los servicios se han detenido correctamente.";
"notification.services_restarted" = "Servicios de Valet reiniciados";
"notification.services_restarted_desc" = "Todos los servicios se han reiniciado correctamente.";
"notification.preset_applied_title" = "Preset aplicado";
"notification.preset_applied_desc" = "El preset '%@' se ha aplicado correctamente.";
"notification.preset_reverted_title" = "Preset revertido";
"notification.preset_reverted_desc" = "El último preset que aplicaste ha sido deshecho. Tu configuración anterior está ahora activa.";
"notification.phpmon_updated.title" = "¡PHP Monitor se ha actualizado!";
"notification.phpmon_updated.desc" = "Ahora estás ejecutando PHP Monitor v%@. ¡Gracias por mantenerte actualizado!";
"notification.phpmon_updated_dev.desc" = "PHP Monitor v%@ (compilación %@) está ahora instalado y activo.";
// Composer Update
"alert.composer_missing.title" = "¡No se encontró Composer!";
"alert.composer_missing.subtitle" = "PHP Monitor no pudo encontrar Composer. Asegúrate de que Composer esté instalado e inténtalo de nuevo.";
"alert.composer_missing.desc" = "PHP Monitor asume que Composer está ubicado en:
• `/usr/local/bin/composer`
• `/opt/homebrew/bin/composer`
Asegúrate de tenerlo instalado en una de estas ubicaciones, o crea un enlace simbólico si tienes Composer instalado en otro lugar.";
"alert.composer_progress.title" = "Actualizando dependencias globales...";
"alert.composer_progress.info" = "Puedes ver el progreso en la salida del terminal más abajo.";
"alert.composer_failure.title" = "¡Algo salió mal!";
"alert.composer_failure.info" = "Tus dependencias globales de Composer no se pudieron actualizar.
Puedes encontrar más información en la salida del terminal más abajo. Tendrás que arreglar este
problema manualmente, usando tu propia aplicación Terminal (esto solo te muestra la salida).";
"alert.composer_success.title" = "¡Composer ha terminado de actualizar!";
"alert.composer_success.info" = "Tus dependencias globales de Composer se han actualizado correctamente.";
// Composer Version
"alert.composer_php_isolated.desc" = "Este sitio ha sido aislado, lo que significa que Valet sirve PHP %@ específicamente para este sitio. La versión global es actualmente PHP %@.";
"alert.composer_php_requirement.title" = "'%@' requiere PHP %@.";
"alert.composer_php_requirement.unable_to_determine" = "No se puede determinar el requisito de PHP";
"alert.composer_php_requirement.type.unknown" = "PHP Monitor no pudo determinar qué versión de PHP se requiere para este dominio. La restricción puede determinarse si tienes un archivo `composer.json` o `.valetphprc` en el directorio de tu proyecto.";
"alert.composer_php_requirement.type.require" = "Este requisito de versión de PHP se determinó verificando el campo `require` en el archivo `composer.json` cuando se actualizó por última vez la lista de sitios.";
"alert.composer_php_requirement.type.platform" = "Este requisito de versión de PHP se determinó verificando el campo `platform` en el archivo `composer.json` cuando se actualizó por última vez la lista de sitios.";
"alert.composer_php_requirement.type.valetphprc" = "Este requisito de versión de PHP se determinó verificando el archivo .valetphprc en el directorio de tu proyecto.";
"alert.composer_php_requirement.type.valetrc" = "Este requisito de versión de PHP se determinó verificando el archivo .valetrc en el directorio de tu proyecto.";
"alert.unable_to_determine_is_fine" = "Si tienes un proyecto simple, es posible que no haya una versión de PHP específica establecida como requisito. En ese caso, puedes ignorar esta advertencia.";
"alert.php_version_ideal" = "La versión de PHP actualmente activa es ideal para este sitio.";
"alert.php_version_incorrect" = "La versión de PHP actualmente activa no coincide con la restricción requerida para este sitio.";
"alert.php_suggestions" = "Puede haber una versión diferente de PHP que esté más cerca de la restricción.";
// Suggest Fix My Valet
"alert.php_switch_failed.title" = "Parece que ha fallado el cambio a PHP %@.";
"alert.php_switch_failed.info" = "PHP Monitor ha detectado que PHP %@ no está activo después de completar el procedimiento de cambio. Puedes intentar ejecutar \"Fix My Valet\" y cambiar de nuevo después. ¿Quieres intentar esta solución?";
"alert.php_switch_failed.desc" = "Primero, deberías probar \"Fix My Valet\" si aún no lo has intentado. Si PHP Monitor sigue sin poder cambiar la versión activa de PHP incluso después de eso, es posible que necesites actualizar Valet y los paquetes de Homebrew en tu sistema. Puedes hacer esto ejecutando `brew update && brew upgrade` y también actualizar Valet ejecutando `composer global update && valet install`.";
"alert.php_switch_failed.confirm" = "Sí, ejecutar \"Fix My Valet\"";
"alert.php_switch_failed.cancel" = "No ejecutar";
// PHP Formula Missing
"alert.php_formula_missing.title" = "¡Ups! La fórmula `php` debe estar instalada para Fix My Valet...";
"alert.php_formula_missing.info" = "Parece que no tienes la fórmula `php` instalada, lo que impide que PHP Monitor ejecute Fix My Valet. Por favor, instálala usando `brew install php`, reinicia PHP Monitor e inténtalo de nuevo.";
// Fix My Valet Started
"alert.fix_my_valet.title" = "¿Problemas? ¡Fix My Valet está listo para comenzar!";
"alert.fix_my_valet.info" = "Esto puede llevar un tiempo. Por favor, ten paciencia.\n\nCuando termine, todos los otros servicios se detendrán y PHP %@ será enlazado. Podrás cambiar a la versión de PHP deseada una vez que esta operación haya terminado.\n\n(Recibirás otra alerta cuando Fix My Valet haya terminado.)";
"alert.fix_my_valet.ok" = "Continuar";
"alert.fix_my_valet.cancel" = "Cancelar";
// Fix My Valet Done
"alert.fix_my_valet_done.title" = "Fix My Valet ha completado sus operaciones.";
"alert.fix_my_valet_done.subtitle" = "Todos los servicios apropiados han sido detenidos y los correctos reiniciados, y la última versión de PHP debería estar activa ahora. Ahora puedes intentar cambiar a otra versión de PHP.";
"alert.fix_my_valet_done.stay" = "Mantener PHP %@";
"alert.fix_my_valet_done.switch_back" = "Volver a PHP %@";
"alert.fix_my_valet_done.desc" = "Si los sitios siguen sin funcionar, puedes intentar ejecutar `valet install` de nuevo, esto puede solucionar un error 502 (Bad Gateway).\n\nSi Valet está roto y no puedes ejecutar `valet install`, puede que necesites ejecutar `composer global update`. Por favor, consulta las FAQ en GitHub si tienes más problemas.";
// Restore Homebrew Permissions
"alert.fix_homebrew_permissions.title" = "Acerca de \"Restaurar Permisos de Homebrew\"";
"alert.fix_homebrew_permissions.subtitle" = "Esta función fue creada para que puedas ejecutar `brew upgrade` o `brew cleanup` sin problemas de permisos.\n\n(Se te notificará cuando se haya aplicado esta corrección.)";
"alert.fix_homebrew_permissions.desc" = "Esto requerirá privilegios administrativos, ya que PHP Monitor restaurará tu propiedad de los archivos y carpetas que actualmente son propiedad del usuario `root`, debido a que los servicios de Valet se ejecutan como root.";
"alert.fix_homebrew_permissions.ok" = "Restaurar Permisos";
"alert.fix_homebrew_permissions.cancel" = "Cancelar";
"alert.fix_homebrew_permissions_done.title" = "Se han restaurado todos los permisos de archivos y carpetas para las dependencias de Valet.";
"alert.fix_homebrew_permissions_done.subtitle" = "Debido a esto, todos los servicios de Valet ya no están ejecutándose. Ahora puedes interactuar con Homebrew, pero tus sitios de Valet no estarán disponibles ya que todos los servicios están deshabilitados.";
"alert.fix_homebrew_permissions_done.desc" = "Cuando hayas terminado con Homebrew (después de ejecutar `brew upgrade`, por ejemplo) deberías reiniciar PHP Monitor y seleccionar \"Reiniciar Servicios de Valet\" si quieres que Valet funcione de nuevo. Siempre se recomienda reiniciar PHP Monitor cuando actualices versiones de PHP con `brew upgrade`, o las cosas podrían romperse.";
// PHP FPM Broken
"alert.php_fpm_broken.title" = "¡Tu configuración de PHP-FPM no está apuntando al socket de Valet!";
"alert.php_fpm_broken.info" = "PHP Monitor ha determinado que hay problemas con tu configuración de PHP-FPM. Esto resultará en respuestas '502 Bad Gateway' si visitas sitios web enlazados a través de Valet.";
"alert.php_fpm_broken.description" = "Si ha pasado un tiempo, normalmente puedes arreglar esto ejecutando `valet install`, que actualiza tu configuración de PHP-FPM.\n\nSi estás viendo este mensaje y estás intentando ejecutar una versión preliminar de PHP, es posible que Valet aún no soporte esta versión preliminar de PHP.\n\nPuede que necesites actualizar tu instalación de Laravel Valet a por lo menos v3.1.11, después deberías ejecutar `valet install`. Más información aquí: https://phpmon.app/prerelease-php";
// PHP Monitor Cannot Start
"alert.cannot_start.title" = "PHP Monitor no puede iniciarse debido a un problema con la configuración de tu sistema";
"alert.cannot_start.subtitle" = "El problema del que acabas de ser notificado está impidiendo que PHP Monitor funcione correctamente.";
"alert.cannot_start.description" = "Puede que no necesites cerrar PHP Monitor y reiniciarlo. Si has solucionado el problema (o no recuerdas cuál era el problema exacto) puedes hacer clic en Reintentar, lo que hará que PHP Monitor vuelva a realizar las comprobaciones de inicio.";
"alert.cannot_start.close" = "Cerrar";
"alert.cannot_start.retry" = "Reintentar";
// PHP alias issue
"alert.php_alias_conflict.title" = "Detectado conflicto de alias de fórmula `php` de Homebrew";
"alert.php_alias_conflict.info" = "PHP Monitor ha detectado alias `php` conflictivos en tu configuración de Homebrew, ambos detectados como instalados.\n\nEsto probablemente resultará en fallos de enlace al cambiar versiones de PHP y romperá la funcionalidad de PHP Monitor.\n\nPara más información, por favor visita: https://github.com/nicoverbruggen/phpmon/issues/54";
"alert.min_valet_version.title" = "La versión instalada de Valet no cumple con el requisito mínimo de versión. ¡PHP Monitor puede no funcionar como se espera!";
"alert.min_valet_version.info" = "Actualmente estás ejecutando Valet %@.\n\nPara un soporte óptimo de las últimas versiones de PHP y un cambio de versión adecuado, se recomienda que actualices a la versión %@, que es el requisito mínimo para esta versión de PHP Monitor.\n\nPuedes hacer esto ejecutando `composer global update` en tu terminal. Después de eso, ejecuta `valet install` de nuevo. Para mejores resultados, reinicia PHP Monitor después de eso. Hasta que esto se resuelva, PHP Monitor puede no comportarse como se espera.";
// Preset text description
"alert.preset_description.switcher_version" = "Cambia a PHP %@.\n\n";
"alert.preset_description.applying_extensions" = "Aplica las siguientes extensiones:\n";
"alert.preset_description.applying_config" = "Aplica los siguientes valores de configuración:\n";
"alert.preset_description.enabled" = "habilitado";
"alert.preset_description.disabled" = "deshabilitado";
"alert.preset_description.empty" = "(vacío)";
// PHP version unavailable
"alert.php_switch_unavailable.title" = "Versión de PHP no compatible";
"alert.php_switch_unavailable.subtitle" = "PHP Monitor no puede cambiar a PHP %@, ya que es posible que no esté instalado o disponible. Se ha cancelado la aplicación de este preset.";
"alert.php_switch_unavailable.info" = "Asegúrate de que PHP %@ esté instalado y puedas cambiar a él en el menú desplegable. Las versiones actualmente compatibles incluyen PHP: %@.";
"alert.php_switch_unavailable.ok" = "Aceptar";
// Service error
"alert.service_error.title" = "¡El servicio '%@' está reportando un error!";
"alert.service_error.subtitle.error_log" = "Esto significa que el servicio '%@' no está funcionando. Esto puede impedir que Valet funcione correctamente. Sin embargo, este servicio tiene un archivo de registro asociado que puedes revisar.";
"alert.service_error.subtitle.no_error_log" = "Esto significa que el servicio '%@' no está funcionando. Esto puede impedir que Valet funcione correctamente. Desafortunadamente, no hay un archivo de registro asociado para este servicio.";
"alert.service_error.extra" = "También puedes seguir los pasos comunes de solución de problemas. Para saber más, presiona el botón '?' en la sección de servicios en PHP Monitor.";
"alert.service_error.button.show_log" = "Ver registro de errores";
"alert.service_error.button.close" = "Cerrar";
// Composer issues
"alert.global_composer_platform_issues.title" = "Composer detectó problemas en tu plataforma";
"alert.global_composer_platform_issues.subtitle" = "La versión de PHP a la que cambiaste es demasiado antigua para las dependencias globales de Composer que tienes instaladas. Estas dependencias necesitarán ser actualizadas.";
"alert.global_composer_platform_issues.desc" = "La forma más fácil de evitar que este problema ocurra en el futuro es cambiar a la versión más antigua de PHP que tengas instalada y ejecutar `composer global update` nuevamente. \n\nAlternativamente, puedes elegir la opción 'Actualizar automáticamente las dependencias globales' en Preferencias para evitar este problema también.\n\nSi sigues viendo este mensaje incluso después de intentar actualizar esas dependencias globales, es posible que desees revisar tu archivo de configuración global de composer, ubicado en `~/.composer/composer.json`.";
"alert.global_composer_platform_issues.buttons.update" = "Actualizar dependencias globales";
"alert.global_composer_platform_issues.buttons.quit" = "Salir de PHP Monitor";
// Revert
"alert.revert_description.title" = "¿Revertir configuración?";
"alert.revert_description.subtitle" = "PHP Monitor puede revertir a la configuración anterior que estaba activa. Esto es lo que se aplicará: \n\n%@";
"alert.revert_description.ok" = "Revertir";
"alert.revert_description.cancel" = "Cancelar";
// STARTUP
// 0. Architecture mismatch
"alert.homebrew_missing.title" = "¡PHP Monitor no puede iniciarse!";
"alert.homebrew_missing.subtitle" = "No se pudo encontrar un binario funcional de Homebrew en la ubicación habitual. Por favor, reinicia la aplicación después de solucionar este problema.";
"alert.homebrew_missing.info" = "Estás ejecutando PHP Monitor con la siguiente arquitectura: %@. Como resultado, se espera un binario funcional de Homebrew en `%@`, pero no se encontró. Por esto PHP Monitor no puede funcionar.\n\nSi aún no has instalado Homebrew, por favor hazlo. Si estás en Apple Silicon, asegúrate de que Homebrew y PHP Monitor usen la misma arquitectura, habilitando o deshabilitando Rosetta según sea necesario.";
"alert.homebrew_missing.quit" = "Salir";
// PHP binary not found
"startup.errors.php_binary.title" = "PHP no está instalado correctamente";
"startup.errors.php_binary.subtitle" = "Debes instalar PHP a través de Homebrew. La aplicación no funcionará correctamente hasta que resuelvas este problema.";
"startup.errors.php_binary.desc" = "Normalmente, ejecutar `brew link php` en tu Terminal resolverá este problema.\n\nPara diagnosticar qué está mal, puedes intentar ejecutar `which php` en tu Terminal, debería devolver `%@`.";
// PHP not found in /usr/local/opt or /opt/homebrew/opt
"startup.errors.php_opt.title" = "PHP no está instalado correctamente";
"startup.errors.php_opt.subtitle" = "No se encontró el alias de PHP en `%@`. La aplicación no funcionará correctamente hasta que resuelvas este problema.";
"startup.errors.php_opt.desc" = "Si ya tienes la fórmula `php` instalada, es posible que necesites ejecutar `brew install php` para que PHP Monitor detecte esta instalación.";
// PHP binary is broken
"startup.errors.dyld_library.title" = "PHP está instalado, pero parece estar dañado";
"startup.errors.dyld_library.subtitle" = "Cuando PHP Monitor intenta ejecutar comandos, no lo está haciendo correctamente. Esto suele ser un indicador de una instalación de PHP dañada.";
"startup.errors.dyld_library.desc" = "Ejecutar `brew reinstall php && brew link php` en tu Terminal puede resolver este problema, así que por favor inténtalo.";
// Valet is not installed
"startup.errors.valet_executable.title" = "Laravel Valet no está instalado correctamente";
"startup.errors.valet_executable.subtitle" = "Debes instalar Valet con Composer. La aplicación no funcionará correctamente hasta que resuelvas este problema.";
"startup.errors.valet_executable.desc" = "Si aún no has instalado Laravel Valet, por favor hazlo primero. Si lo tienes instalado pero sigues viendo este mensaje, intenta ejecutar `which valet` en Terminal, debería devolver: `%@`.";
// Valet configuration file missing or broken
"startup.errors.valet_json_invalid.title" = "Archivo de configuración de Laravel Valet inválido o faltante";
"startup.errors.valet_json_invalid.subtitle" = "PHP Monitor necesita poder leer el archivo de configuración. Parece que el archivo está mal formado o falta. Por favor, verifica que existe y está formateado correctamente.";
"startup.errors.valet_json_invalid.desc" = "Puedes encontrar el archivo en `~/.config/valet/config.json`. Si Laravel Valet no puede analizar el archivo de configuración, ejecutar cualquier comando `valet` generalmente arreglará automáticamente el archivo JSON. Intenta ejecutar `valet --version` para arreglar automáticamente el archivo.";
// Valet version not readable
"startup.errors.valet_version_unknown.title" = "No se pudo leer tu versión de Valet";
"startup.errors.valet_version_unknown.subtitle" = "Falló el análisis de la salida de `valet --version`. Asegúrate de que tu instalación de Valet funcione y esté actualizada.";
"startup.errors.valet_version_unknown.desc" = "Intenta ejecutar `valet --version` en una terminal para averiguar qué está pasando.";
"startup.errors.valet_not_installed.title" = "Tu directorio de configuración de Valet está faltando";
"startup.errors.valet_not_installed.subtitle" = "El directorio requerido `~/.config/valet` está faltando. Esto generalmente significa que olvidaste ejecutar `valet install`.";
"startup.errors.valet_not_installed.desc" = "Asumiendo que ya instalaste Valet a través de Composer, por favor ejecuta `valet install` para terminar de configurar Laravel Valet.
Si estás viendo este mensaje pero estás confundido por qué esta carpeta ha desaparecido, entonces quizás quieras investigar por qué se fue—no debería simplemente desaparecer y significa que tu instalación de Valet está dañada.";
// Valet version too new or old
"startup.errors.valet_version_not_supported.title" = "Esta versión de Valet no es compatible";
"startup.errors.valet_version_not_supported.subtitle" = "Estás usando una versión de Valet que actualmente no es compatible. PHP Monitor funciona con Valet v2, v3 y v4. Para evitar problemas en tu sistema, PHP Monitor no puede iniciarse.";
"startup.errors.valet_version_not_supported.desc" = "Debes instalar una versión de Valet compatible con PHP Monitor o actualizar a una versión más reciente de PHP Monitor que pueda ser compatible con esta versión de Valet (consulta las notas de la última versión para más información).";
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew no ha sido agregado a sudoers.d";
"startup.errors.sudoers_brew.subtitle" = "Debes ejecutar `sudo valet trust` para asegurarte de que Valet pueda iniciar y detener servicios sin necesidad de usar sudo cada vez. La app no funcionará correctamente hasta que resuelvas este problema.";
"startup.errors.sudoers_brew.desc" = "Si sigues viendo este error, es posible que haya un problema de permisos que impide que PHP Monitor valide el archivo. Normalmente, esto se soluciona ejecutando: `sudo chmod +r /private/etc/sudoers.d/brew`";
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Valet no ha sido agregado a sudoers.d";
"startup.errors.sudoers_valet.subtitle" = "Debes ejecutar `sudo valet trust` para asegurarte de que Valet pueda iniciar y detener servicios sin necesidad de usar sudo cada vez. La app no funcionará correctamente hasta que resuelvas este problema. Si ya lo hiciste antes, prueba ejecutando `sudo valet trust` de nuevo.";
"startup.errors.sudoers_valet.desc" = "Si sigues viendo este error, es posible que haya un problema de permisos que impide que PHP Monitor valide el archivo. Normalmente, esto se soluciona ejecutando: `sudo chmod +r /private/etc/sudoers.d/valet`";
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor y Valet no pueden funcionar correctamente: Composer informa un problema con tu plataforma";
"startup.errors.global_composer_platform_issues.subtitle" = "Sigue estos pasos recomendados para evitar este problema en el futuro:\n\n1. Ejecuta `composer global update`.\n2. Reinicia PHP Monitor. (Debería volver a funcionar).\n3. Cambia a la versión más antigua de PHP que tengas instalada.\n4. Ejecuta `composer global update` de nuevo.";
"startup.errors.global_composer_platform_issues.desc" = "Puedes ir a Preferencias y marcar la opción 'Actualizar dependencias globales automáticamente'. Esto actualizará tus dependencias globales de Composer cada vez que cambies de versión de PHP, aunque puede que no sea ideal si no tienes acceso constante a internet.\n\nPara saber exactamente qué está fallando, prueba ejecutando `valet --version`. Valet no es funcional con las dependencias instaladas. Normalmente, esto ocurre debido a una incompatibilidad de versiones, es decir, que las dependencias instaladas son para una versión más reciente de PHP que la que está activa actualmente.";
// Cannot retrieve services
"startup.errors.services_json_error.title" = "No se puede determinar el estado de los servicios";
"startup.errors.services_json_error.subtitle" = "PHP Monitor suele consultar `brew` con el siguiente comando para verificar si los servicios pueden recuperarse: `sudo brew services info nginx --json`.\n\nPHP Monitor no pudo interpretar esta respuesta.";
"startup.errors.services_json_error.desc" = "Esto puede ocurrir si tu instalación de Homebrew está desactualizada y aún no devuelve JSON. Normalmente, puedes solucionar esto ejecutando `brew update` o `brew tap homebrew/services`. También puedes intentar ejecutar `sudo brew services info nginx --json` en tu terminal preferida.";
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "Se ha detectado un problema de configuración";
"startup.errors.which_alias_issue.subtitle" = "Parece que hay un archivo en `/usr/local/bin/which`. Esto suele ser configurado por NodeJS, pero `node` no está en el PATH en `/usr/local/bin`. Para solucionarlo, sigue leyendo.";
"startup.errors.which_alias_issue.desc" = "Debes crear un symlink de `node` en el directorio `/usr/local/bin` para asegurarte de que PHP Monitor pueda iniciarse correctamente. Para más información, consulta: https://github.com/nicoverbruggen/phpmon/issues/174";
// Laravel Herd conflicts
"startup.errors.herd_running.title" = "Laravel Herd parece estar en ejecución";
"startup.errors.herd_running.subtitle" = "Parece que Laravel Herd está en ejecución. La configuración integrada de Valet en Herd puede entrar en conflicto con tu instalación regular de Valet, por lo que debes cerrar Herd antes de continuar. (Puedes usar Herd y Valet juntos, pero no deberían ejecutarse al mismo tiempo).";
"startup.errors.herd_running.desc" = "También es posible que el alias `php` agregado por Herd a tu $PATH impida que el alias de `php` de PHP Monitor funcione correctamente, así que tenlo en cuenta. Puedes revisar `~/.zshrc` para ver qué ha agregado Herd a tu $PATH.";
// Warning about a different PHP version linked than last time
"startup.version_mismatch.title" = "Tu versión activa de PHP ha cambiado.";
"startup.version_mismatch.subtitle" = "Desde la última vez que usaste PHP Monitor, la versión de PHP vinculada ha cambiado a PHP %@. ¿Quieres volver a PHP %@ o prefieres seguir usando la versión actual?";
"startup.version_mismatch.desc" = "PHP Monitor lleva un registro de qué versión de PHP está vinculada globalmente. La versión global puede haber cambiado debido a otro programa o porque Homebrew vinculó una fórmula diferente después de una actualización.";
"startup.version_mismatch.button_switch_back" = "Volver a PHP %@";
"startup.version_mismatch.button_stay" = "Seguir usando PHP %@";
// Valet version too new or old
"startup.errors.valet_version_not_supported.title" = "Esta versión de Valet no está soportada";
"startup.errors.valet_version_not_supported.subtitle" = "Está ejecutando una versión de Valet que actualmente no se respalda. PHP Monitor funciona correctamente con Valet v2, v3 y v4. En orden a evitar problemas en su sistema, PHP Monitor no puede iniciar.";
"startup.errors.valet_version_not_supported.desc" = "Debe instalar una versión compatible de Valet o podría necesitar actualizar a una versión más nueva de PHP Monitor que podría incluir compatibilidad para esta versión de Valet (consulte los últimos anuncios de lanzamiento para más información).";
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew no ha sido agregado a sudoers.d";
"startup.errors.sudoers_brew.subtitle" = "Debe ejecutar `sudo valet trust` para asegurarse de que Valet pueda iniciar y detener servicios sin utilizar `sudo` cada vez. La aplicación funcionará incorrectamente hasta que resuelva este problema.";
"startup.errors.sudoers_brew.desc" = "Si sigue viendo este error, es posible que haya un problema de permisos donde PHP Monitor no puede validar el archivo, lo cual generalmente se puede resolver ejecutando: `sudo chmod +r /private/etc/sudoers.d/brew`";
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Valet no ha sido agregado a sudoers.d";
"startup.errors.sudoers_valet.subtitle" = "Debe ejecutar `sudo valet trust` para asegurarse de que Valet pueda iniciar y detener servicios sin utilizar `sudo` cada vez. La aplicación funcionará incorrectamente hasta que resuelva este problema. Si lo hizo antes, por favor ejecute `sudo valet trust` otra vez.";
"startup.errors.sudoers_valet.desc" = "Si sigue viendo este error, es posible que haya un problema de permisos donde PHP Monitor no puede validar el archivo, lo cual generalmente se puede resolver ejecutando: `sudo chmod +r /private/etc/sudoers.d/valet`";
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor y Valet no pueden funcionar correctamente: Composer informa de un problema con su plataforma";
"startup.errors.global_composer_platform_issues.subtitle" = "Por favor, siga estos pasos recomendados para evitar ver este error en el futuro:\n\n1. Ejecute `composer global update`.\n2. Reinicie PHP Monitor. (Debería funcionar de nuevo.)\n3. Cambie a la versión más antigua de PHP que tenga instalada.\n4. Ejecute `composer global update` de nuevo.";
"startup.errors.global_composer_platform_issues.desc" = "Usted puede ir a Preferencias e indicar la opción 'Actualizar automáticamente las dependencias globales' de Composer. Esto actualizará las dependencias globales de Composer cada vez que cambie a una nueva versión de PHP, por lo que esto no es ideal si no tiene acceso constante a Internet.\n\nPara obtener información sobre qué está saliendo mal, pruebe ejecutando `valet --version`. Valet actualmente no es funcional con las dependencias instaladas. Por lo general, este problema se debe a un desacuerdo de versión: es decir, las dependencias instaladas para una versión más nueva de PHP que la versión actual en uso.";
// Cannot retrieve services
"startup.errors.services_json_error.title" = "No se puede determinar el estado de los servicios";
"startup.errors.services_json_error.subtitle" = "A menudo, PHP Monitor consulta `brew` utilizando el siguiente comando para verificar si los servicios pueden ser recuperados: `sudo brew services info nginx --json`.\n\nPHP Monitor no pudo interpretar esta respuesta.";
"startup.errors.services_json_error.desc" = "Este problema puede ocurrir si su instalación de Homebrew está desactualizada, en cuyo caso Homebrew no devolverá JSON aún. Generalmente se puede solucionar ejecutando `brew update` o `brew tap homebrew/services`. También puede probar ejecutando `sudo brew services info nginx --json` en la terminal de su elección.";
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "Se detectó un problema de configuración";
"startup.errors.which_alias_issue.subtitle" = "Aparece que hay un archivo en `/usr/local/bin/which`. Normalmente, esto se establece por NodeJS, pero `node` no está en el PATH en `/usr/local/bin`. Para solucionar este problema, necesita seguir las instrucciones a continuación.";
"startup.errors.which_alias_issue.desc" = "Tendrá que crear un enlace simbólico (ln) para `node` en la carpeta `/usr/local/bin` para asegurarse de que PHP Monitor pueda iniciar correctamente. Para obtener más información, consulte: https://github.com/nicoverbruggen/phpmon/issues/174";
// Laravel Herd conflicts
"startup.errors.herd_running.title" = "Se ejecuta Laravel Herd";
"startup.errors.herd_running.subtitle" = "Aparece que está corriendo Laravel Herd. El establecimiento integrado de Valet en Herd puede conflictuar con su instalación normal de Valet, por lo tanto, debes detener Herd antes de continuar. (Usted puede usar perfectamente ambas funciones de Herd y la instalación normal de Valet, pero no deben ejecutar ambos al mismo tiempo.)";
"startup.errors.herd_running.desc" = "También es posible que el `php` que adije Laravel Herd a su $PATH impida que el enlace `php` del PHP Monitor funcione correctamente, por lo que tenga en cuenta eso. Puede verificar las instrucciones en `~/.zshrc` y ver qué ha agregado a su $PATH.";
// Warning about a different PHP version linked than last time
"startup.version_mismatch.title" = "Su versión de PHP actualizada se ha cambiado.";
"startup.version_mismatch.subtitle" = "Desde que PHP Monitor fue la última vez en funcionar, su versión vinculada de PHP ha cambiado a PHP %@. ¿Desea cambiar a PHP %@ o desea conservar la versión actual?";
"startup.version_mismatch.desc" = "PHP Monitor registra cuál es la versión de PHP que está vinculada globalmente. La versión global puede haber sido cambiada debido a algún otro programa o Homebrew haya vinculado una otra fórmula después de las actualizaciones.";
"startup.version_mismatch.button_switch_back" = "Volver a PHP %@";
"startup.version_mismatch.button_stay" = "Conservar PHP %@";
// WARNINGS ABOUT NON-DEFAULT TLD
"alert.warnings.tld_issue.title" = "No estás utilizando `.test` como el TLD para Valet.";
"alert.warnings.tld_issue.subtitle" = "Utilizar un TLD diferente puede no funcionar correctamente y no está oficialmente soportado.";
"alert.warnings.tld_issue.description" = "PHP Monitor seguirá siendo funcional, pero hay posibles problemas: la aplicación podría no mostrar correctamente cuáles dominios han sido protegidos. Para obtener resultados óptimos, vaya a su archivo de configuración de Valet (config.json en la carpeta de Valet) y cambie el TLD de nuevo al `test`.";
"alert.do_not_tell_again" = "No digas más";
// WARNINGS
"warnings.limits_error.title" = "PHP Monitor no pudo obtener límites.";
"warnings.limits_error.steps" = "Pruebe ejecutando `php -v` en su terminal.";
"warnings.title" = "Doctor de PHP";
"warnings.description" = "**Doctor de PHP** sugerirá mejoras para su configuración de sistema activa.";
"warnings.disclaimer" = "Usted puede elegir ocultar todas las recomendaciones del menú de PHP Monitor en Preferencias, pero se recomienda que trate todos los items de acciónables.";
"warnings.refresh.button" = "Escanear de nuevo";
"warnings.refresh.button.description" = "Presione este botón después de haber solucionado un problema. Esto causará que PHP Monitor evalúe de nuevo su entorno. Si realmente ha sido arreglado, la recomendación debería desaparecer.";
"warnings.helper_permissions.title" = "Los ayudantes del PHP Monitor no están disponibles actualmente.";
"warnings.helper_permissions.description" = "El PHP Monitor viene con varios scripts ayudantes. Usando estos scripts le permite invocar una versión específica de PHP sin cambiar la versión enlazada de PHP.";
"warnings.helper_permissions.unavailable" = "Sin embargo, estos ayudantes son potencialmente *no disponibles* porque PHP Monitor no puede crear o actualizar las enlaces simbólicos por defecto.";
"warnings.helper_permissions.symlink" = "Si usted no desea hacer `/usr/local/bin` escritura, puede agregar el directorio de ayuda del helper de PHP a su variable PATH para que este aviso se elimine. (Haga clic en ”Más información” para aprender cómo solucionar este problema.)";
"warnings.arm_compatibility.title" = "Está corriendo PHP Monitor utilizando Rosetta en la placa de Apple Silicon, lo cual significa que su entorno de PHP también está ejecutándose mediante Rosetta.";
"warnings.arm_compatibility.description" = "Usted parece estar corriendo una versión compatible con ARM de macOS, pero actualmente está ejecutando PHP Monitor usando Rosetta. Aunque esto funcionará correctamente, se recomienda utilizar la versión nativa de Homebrew.";
"warnings.files_missing.title" = "Su instalación de PHP falta archivos de configuración importantes.";
"warnings.files_missing.description" = "Los siguientes archivos de configuración clave deben existir después de instalar PHP:
• %@
Cuando esos archivos están faltantes, se recomienda cambiar a la versión de PHP asociada con esos archivos: esto puede resolver el problema. Si no arregla el problema, se recomienda reinicializar nuevamente las versiones de PHP asociadas con Homebrew, lo que debería restaurar los archivos de configuración que están faltantes. Los archivos de configuración faltantes pueden ser la razón por la cual usted recibe errores '502 Bad Gateway', incluso después de ejecutar \"Arreglar Mi Valet\" (si utiliza Valet).";
"warnings.none" = "No hay recomendaciones disponibles para ti en este momento. Usted está bien!";
// ONBOARDING
"onboarding.title" = "Gira de Bienvenida";
"onboarding.welcome" = "¡Bienvenido a PHP Monitor!";
"onboarding.explore" = "Ahora tiene acceso al completo conjunto de funcionalidades del PHP Monitor. Puede obtener más información sobre algunas de las características que ofrece el PHP Monitor en esta pantalla.";
"onboarding.explore.lite" = "Ahora tiene acceso a todas las funciones clave del PHP Monitor.
Nota: Algunas funciones (en gris en la pantalla siguiente) actualmente no están disponibles porque Laravel Valet no está activo.";
"onboarding.tour.menu_bar.title" = "Poder En Tu Barra De Menús";
"onboarding.tour.menu_bar" = "PHP Monitor vive en tu barra de menús. Desde este menú, usted puede acceder a la mayoría de las funciones clave del PHP Monitor, incluyendo cambiar la versión de PHP enlazada globalmente, localizar archivos de configuración, instalar diferentes versiones de PHP, entre otras.";
"onboarding.tour.faq_hint" = "**Preguntas?** Le recomendamos que revise el [README](https://github.com/nicoverbruggen/phpmon/blob/main/README.md) en GitHub: contiene una FAQ completa con diversas sugerencias y preguntas y respuestas comunes.";
"onboarding.tour.services.title" = "Administrar Servicios de Homebrew";
"onboarding.tour.services" = "Una vez que haga clic en el ícono de la barra de menús, usted puede ver a simple vista si todos los servicios de Homebrew están funcionando o no. También puede hacer clic en un servicio para deshabilitarlo rápidamente.";
"onboarding.tour.domains.title" = "Administrar Dominios";
"onboarding.tour.domains" = "Al abrir la ventana de dominios a través del ícono de la barra de menús, usted puede ver cuáles dominios están enlazados y estacionados, así como los proxies de nginx activos.";
"onboarding.tour.isolation.title" = "Aislamiento de Dominios";
"onboarding.tour.isolation" = "Si usted tiene Valet 3 o más reciente instalado, también puede utilizar aislamiento de dominio haciendo clic derecho en un dominio específico en la ventana de dominios. Esto le permite seleccionar una versión específica de PHP para ese dominio y solo ese dominio.";
"onboarding.tour.feature_unavailable" = "Esta función está actualmente inavailability e requiere Laravel Valet instalado.";
"onboarding.tour.once" = "Usted verá esta Gira Únicamente Una Vez. Puede reabrir la Gira de Bienvenida más tarde a través del ícono de la barra de menús (disponible en el menú, bajo Primera Aida & Servicios).";
"onboarding.tour.close" = "Cierre Tour";
// LANGUAGE CHOICE
"prefs.language" = "Idioma:";
"prefs.language_options_desc" = "Seleccione un idioma diferente para usar con PHP Monitor. Para aplicar totalmente este cambio, debe reiniciar la aplicación.";
"alert.language_changed.title" = "Debe reiniciar el PHP Monitor!";
"alert.language_changed.subtitle" = "Usted acaba de cambiar el idioma de visualización del PHP Monitor. La barra de menús lo utilizará correctamente de inmediato, pero tal vez necesite reiniciar la aplicación para que todos los textos a través del app se reflejen su nuevo idioma elegido.";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "Ignorar";
"startup.timeout.title" = "PHP Monitor tarda demasiado en iniciar!";
"startup.timeout.subtitle" = "Si PHP Monitor sigue ocupado por más de 30 segundos, tal vez haya algo mal con su configuración de Homebrew.";
"startup.timeout.description" = "A veces, debido a diversas problemas con las permisos de archivos, pueden fallar. Puede intentar usar `brew doctor` y `brew cleanup` para solucionar este problema.
Se recomienda reiniciar PHP Monitor después de esto. Aprenda más sobre este problema aquí: https://github.com/nicoverbruggen/phpmon/issues/294.
Si PHP Monitor ya ha finalizado su iniciación o desea esperar un poco más, no dude en hacer clic en \"Ignorar\" y usar PHP Monitor como de costumbre. En cualquier caso, tal vez desee investigar, porque esto no está supuestamente tardando tanto.";
```

View File

@ -138,8 +138,10 @@ et redémarrer PHP Monitor pour que les extensions deviennent visibles. Si le pr
"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.unavailable" = "Cette version est temporairement indisponible.";
"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.version.automatic_upgrade" = "Cette version sera automatiquement installée lors de la mise à niveau d'une ancienne version.
(Cette nouvelle version et l'ancienne seront toutes deux disponibles après la mise à niveau.)";
"phpman.buttons.uninstall" = "Désinstaller";
"phpman.buttons.install" = "Installer";
"phpman.buttons.update" = "Mettre à jour";
@ -317,6 +319,8 @@ Il se peut que vous deviez saisir votre mot de passe pendant le processus de dé
"domain_list.always_use_php" = "Tojours utiliser PHP %@";
"domain_list.isolation_unavailable" = "Isolement non pris en charge (dans Valet 2)";
"domain_list.favorite" = "Marquer comme favori";
"domain_list.unfavorite" = "Démarquer des favoris";
"domain_list.actions" = "Actions";
"domain_list.unlink" = "Supprimer le Lien vers le Dossier";
"domain_list.secure" = "Sécuriser le Domaine";
@ -629,7 +633,7 @@ Vous pouvez mettre à jour en executant `composer global update` dans votre term
// STARTUP
/// 0. Architecture mismatch
// 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.";
@ -637,32 +641,32 @@ Vous pouvez mettre à jour en executant `composer global update` dans votre term
"alert.homebrew_missing.quit" = "Quitter";
/// PHP binary not found
// 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
// 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
// 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
// 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
// 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
// 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.";
@ -678,32 +682,32 @@ Si vous voyez ce message mais que vous ne savez pas pourquoi ce dossier a dispar
"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
// 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
// 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
// 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
// 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
// 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
// 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.";
@ -846,3 +850,14 @@ Veuillez noter que certaines fonctionnalités (grisées ci-dessous) sont actuell
"alert.language_changed.title" = "Vous devriez redémarrer PHP Monitor !";
"alert.language_changed.subtitle" = "Vous venez de changer la langue d'affichage de PHP Monitor. Le menu utilisera immédiatement la bonne langue, mais vous devrez peut-être redémarrer l'application pour que tout le texte dans l'application reflète votre nouveau choix de langue.";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "Ignorer";
"startup.timeout.title" = "PHP Monitor met trop de temps à s'initialiser !";
"startup.timeout.subtitle" = "Si PHP Monitor reste occupé pendant plus de 30 secondes, il peut y avoir un problème avec votre configuration Homebrew.";
"startup.timeout.description" = "Parfois, en raison de problèmes de permissions de fichiers, certaines choses peuvent mal fonctionner. Vous pouvez essayer d'utiliser `brew doctor` et `brew cleanup` pour corriger cela.
Il est recommandé de redémarrer PHP Monitor ensuite. En savoir plus sur ce problème ici : https://github.com/nicoverbruggen/phpmon/issues/294.
Si PHP Monitor s'est finalement initialisé ou si vous souhaitez patienter un peu plus longtemps, vous pouvez cliquer sur 'Ignorer' et utiliser PHP Monitor normalement. Quoi qu'il en soit, il serait bon d'enquêter, car cela ne devrait pas prendre autant de temps.";

View File

@ -0,0 +1,840 @@
// MENU ITEMS (MI)
"mi_busy" = "PHP Monitor sedang sibuk...";
"mi_unsure" = "Kami tidak yakin tentang versi PHP yang Anda jalankan.";
"mi_php_version" = "Versi Global: PHP";
"mi_php_switch" = "Ganti ke PHP";
"mi_php_unsupported" = "Beberapa versi PHP yang terpasang tidak ditampilkan.";
"mi_php_broken_1" = "Ouch! Tentu saja, instalasi PHP Anda bermasalah...";
"mi_php_broken_2" = "Coba jalankan `php -v` di terminal Anda.";
"mi_php_broken_3" = "Anda mungkin ingin mencoba memilih versi lainnya.";
"mi_php_broken_4" = "Memastikan `brew reinstall php` (atau untuk versi yang sama) mungkin akan membantu.";
"mi_no_php_linked" = "Tidak ada versi PHP terhubung!";
"mi_fix_php_link" = "Sunting Otomatis...";
"mi_no_php_linked_explain" = "Apa Itu?";
"mi_php_version_manager" = "Manajer Versi PHP...";
"mi_php_ext_manager" = "Manajer Ekstensi PHP...";
"mi_php_config_manager" = "Pengelola Konfigurasi PHP...";
"mi_manage_limits" = "Manajemen Batasan...";
"mi_diagnostics" = "Penyakit";
"mi_active_services" = "Jasa yang Aktif";
"mi_restart_php_fpm" = "Buat Lagi: php";
"mi_restart_nginx" = "Buat Lagi: nginx";
"mi_restart_dnsmasq" = "Buat Lagi: dnsmasq";
"mi_manage_services" = "Manajemen Jasa";
"mi_restart_valet_services" = "Buat Lagi Layanan Valet";
"mi_stop_valet_services" = "Stop Layanan Valet";
"mi_fix_my_valet" = "Sunting My Valet...";
"mi_fix_my_valet_tooltip" = "Ada masalah dengan instalasi Anda Valet? PHP Monitor akan membantu Anda mengatur ulang dan kembalinya ke operasi dalam waktu singkat!";
"mi_fix_brew_permissions" = "Kembalikan Izin Homebrew...";
"mi_fix_brew_permissions_tooltip" = "Sudahkah Anda membutuhkan izin ketika menjalankan `brew upgrade`? PHP Monitor akan membantu mengatasi masalah izin tersebut.";
"mi_php_refresh" = "Refresh Information";
"mi_configuration" = "Konfigurasi PHP";
"mi_limits" = "Batasan Konfigurasi";
"mi_memory_limit" = "Batas Memori";
"mi_post_max_size" = "Max POST";
"mi_upload_max_filesize" = "Max Upload";
"mi_manual_actions" = "Tindakan Tangan Pertama";
"mi_services" = "Jasa";
"mi_other" = "Pertolongan & Jasa";
"mi_first_aid" = "Pertolongan";
"mi_xdebug_mode" = "Manajer Mode Xdebug";
"mi_composer" = "Composer";
"mi_valet_config" = "Temukan Folder Valet (.config/valet)";
"mi_php_config" = "Temukan File Konfigurasi PHP (php.ini)";
"mi_phpmon_config" = "Temukan Folder PHP Monitor (.config/phpmon)";
"mi_global_composer" = "Temukan File Composer Global (.composer)";
"mi_phpinfo" = "Tampilkan Konfigurasi Saat Ini (phpinfo)";
"mi_update_global_composer" = "Perbarui Dependent Composer Global...";
"mi_detected_extensions" = "Ekstensi yang Didektksi";
"mi_no_extensions_detected" = "Tidak ada ekstensi tambahan yang didekati.";
"mi_php_doctor" = "Dokter PHP";
"mi_fa_php_doctor" = "Buka Dokter PHP...";
"mi_recommendations_count" = "%i Pertanyaan Ditemukan!";
"mi_view_recommendations" = "Lihat Rekomendasi...";
"mi_valet" = "Valet Laravel";
"mi_domain_list" = "Lihat Daftar Domain...";
"mi_preferences" = "Pengaturan...";
"mi_donate" = "Donasi...";
"mi_check_for_updates" = "Cek Perbarui...";
"mi_lite_mode" = "Tentang Mode Standalone...";
"mi_quit" = "Selesai PHP Monitor";
"mi_about" = "Tentang PHP Monitor";
"mi_presets_title" = "Preset Konfigurasi";
"mi_apply_presets_title" = "Aplikasi Preset Konfigurasi";
"mi_revert_to_prev_config" = "Kembalikan ke Konfigurasi Sebelumnya...";
"mi_profiles_loaded" = "%i profile di-load dari file konfigurasi";
"mi_no_presets" = "Tidak ada preset yang tersedia.";
"mi_set_up_presets" = "Pelajari lebih lanjut tentang preset...";
"mi_view_onboarding" = "Buka Tour Pendahuluan...";
"mi_xdebug_available_modes" = "Mode Tersedia";
"mi_xdebug_actions" = "Aksi";
"mi_xdebug_disable_all" = "Tutup Semua Mode";
// CONFMAN
"confman.title" = "Pengaturan PHP Editor";
"confman.description" = "Fitur ini memungkinkan Anda mengatur pengkonfigurasi PHP dengan mudah.\nPerhatian: apapun perubahan yang Anda buat segera dan otomatis dijalankan.";
"confman.byte_limit.unlimited" = "Biar tidak ada batas";
"php_ini.memory_limit.title" = "Maksimum Batasan Memori";
"php_ini.memory_limit.description" = "Ini menetapkan jumlah maksimum memori dalam byte yang sebuah skrip boleh gunakan. Ini membantu mencegah skrip buruk yang menghabiskan semua memori tersedia pada server.";
"php_ini.post_max_size.title" = "Maksimum Ukuran POST";
"php_ini.post_max_size.description" = "Menetapkan batasan ukuran data post yang diizinkan. Ini juga mempengaruhi pengunggahan berkas besar. Untuk mengunggah berkas besar, nilai ini harus lebih besar dari Upload Max Size. Secara umum, Batasan Memori Maksimum harus lebih besar daripada Maksimum Ukuran POST.";
"php_ini.file_uploads.title" = "Unggahan Berkas";
"php_ini.file_uploads.description" = "Kembalikan atau tidakkan pengunggahan berkas secara keseluruhan. Dia direkomendasikan untuk tetap diaktifkan.";
"php_ini.upload_max_filesize.title" = "Batasan Ukuran Pengunggahan Berkas";
"php_ini.upload_max_filesize.description" = "Ukuran maksimum dari berkas yang dapat diunggah. Maksimum Ukuran POST harus lebih besar daripada ini.";
// PHPEXTMAN
"phpextman.window.title" = "Ekseni";
"phpextman.description" = "**Pengelola Eksen PHP** memungkinkan Anda mengelola berbagai ekstensi PHP dengan klik tombol sederhana. Karena Homebrew digunakan, ekstensi tidak perlu dicompile secara langsung menggunakan `pecl`.";
"phpextman.disclaimer" = "Secara umum, beberapa ekstensi mungkin membutuhkan penginstalan lain untuk diinstal, tetapi umumnya, menginstal ekstensi harus lebih cepat daripada menginstal versi PHP.";
"phpextman.warnings.removal.title" = "Hapus ekstensi `%@`?";
"phpextman.warnings.removal.desc" = "Ekseni dan file konfigurasi unik akan dihapus. Fungsionalitasnya tidak tersedia lagi untuk pengaturan PHP ini. Anda yakin?
( Jika ekstensi diaktifkan menggunakan nama yang tidak standar, ia tidak akan dihapus. Oleh karena itu, jika Anda tidak ingin file .ini dihapus, terbaik adalah menggandakan namanya ke sesuatu. Dalam kasus tersebut, ekstensi hanya akan diaktifkan kembali sebagai bagian dari proses pembersihan.)";
"phpextman.warnings.removal.button" = "Hapus";
"phpextman.list.showing_count" = "Saat ini menunjukkan %@ ekstensi untuk:";
"phpextman.list.depends_on" = "Tergantung pada:";
"phpextman.list.status.external" = "Ini ekstensi sudah diinstal menggunakan sumber lain, dan tidak dapat dikendalikan.";
"phpextman.list.status.installable" = "Ini bisa diinstal.";
"phpextman.list.status.dependent" = "Anda tidak bisa menghapusnya sebelum menghapus %@.";
"phpextman.list.status.can_manage" = "Ekseni ini diinstal dan dikendalikan oleh PHP Monitor.";
"phpextman.errors.not_found.title" = "Oh-oh. Tiada ekstensi yang ditemukan!";
"phpextman.errors.not_found.desc" = "Tidak seharusnya terjadi. Anda mungkin membutuhkan perintah berikut di terminal Anda:
`brew tap shivammathur/extensions`
dan mulai kembali PHP Monitor untuk ekstensi menjadi visible. Jika masalah tetap ada setelah menjalankan perintah dan mengeklik mulai kembali PHP Monitor, silakan buka isu di GitHub.";
```
// PHPMAN
"phpman.busy.title" = "Mendapatkan update!";
"phpman.busy.description.outdated" = "Mereka memeriksa apakah versi PHP yang diinstalasi adalah versi lama...";
"phpman.version.broken" = "Versi ini tampaknya rusak, Anda dapat mencoba pemulihan.";
"phpman.version.has_update" = "Versi %@ terpasang, tersedia untuk %@.";
"phpman.version.installed" = "Versi %@ saat ini terpasang.";
"phpman.version.available_for_installation" = "Anda dapat menginstal versi ini.";
"phpman.version.unavailable" = "Versi ini tidak tersedia secara sementara.";
"phpman.version.automatic_upgrade" = "Versi ini akan diatur otomatis oleh memperbarui versi yang lebih lama. (Kedua versi baru dan lama tersebut akan tersedia setelah memperbarui.)";
"phpman.buttons.uninstall" = "Uninstall";
"phpman.buttons.install" = "Install";
"phpman.buttons.update" = "Update";
"phpman.buttons.repair" = "Pemulihan";
"phpman.version.prerelease" = "Pre-release";
"phpman.steps.installing" = "Menginstal %@";
"phpman.steps.removing" = "Menghapus %@";
"phpman.steps.reloading" = "Memuat kembali versi PHP... Mereka mengumpulkan semua versi PHP...";
"phpman.steps.preparing" = "PHP Monitor sedang mempersiapkan Homebrew...";
"phpman.steps.wait" = "Silakan menunggu...";
"phpman.steps.completed" = "Proses selesai!";
"phpman.steps.success" = "Operasi berhasil dilakukan.";
"phpman.steps.failure" = "Perintah gagal dijalankan dengan benar.";
"phpman.title" = "Pengelola Versi PHP";
"phpman.description" = "**Pengelola Versi PHP** memungkinkan Anda menginstal, memperbarui dan menghapus variasi versi PHP melalui Homebrew tanpa perlu menjalankan perintah di terminal secara manual.";
"phpman.disclaimer" = "Perhatian, instalasi atau pembaruan versi PHP mungkin akan menyebabkan upgrade paket Homebrew yang lain. Sebagian besar langkah penginstalan biasanya membutuhkan waktu, jadi silakan menunggu sementara Homebrew melakukannya.";
"phpman.refresh.button" = "Cari Perbarui";
"phpman.refresh.button.description" = "Anda dapat tekan tombol refresh untuk memeriksa apakah ada perbaruan tersedia pada variasi PHP yang terpasang.";
"phpman.has_updates.description" = "**Ada satu atau lebih perbaruan yang tersedia.** Pengelola Versi PHP akan selalu menginstal atau memperbaruhi variasi PHP secara otomatis, jadi Anda akan selalu mengupgrade semua instalasi sekaligus.";
"phpman.has_updates.button" = "Upgrade All";
"phpman.warnings.outdated.title" = "Versi PHP Monitor ini adalah versi yang tidak terbaru";
"phpman.warnings.outdated.desc" = "Dengan sangat mungkin, formulae Homebrew telah berubah sejak versi PHP Monitor ini dibuat. Saya sangat merekomendasikan Anda memperbarui aplikasi ini sebelum menggunakan Pengelola Versi PHP untuk menginstal, menghapus atau memperbarui variasi versi PHP.";
"phpman.warnings.unsupported.title" = "Versi Homebrew Anda mungkin menyebabkan masalah";
"phpman.warnings.unsupported.desc" = "Tidak ada fungsi yang di-disabled, tetapi beberapa perintah mungkin tidak berfungsi seakan-akan dengan benar. Anda saat ini menjalankan Homebrew %@.
Saat ini, versi Homebrew 4 adalah versi yang hanya didukung oleh Pengelola Versi PHP. Jika Anda sedang menjalankan versi Homebrew yang lebih baru, mungkin Anda ingin memeriksa apakah ada versi pengelolaan PHP yang tersedia.";
"phpman.warnings.removal.title" = "Anda yakin ingin menghapus %@?";
"phpman.warnings.removal.desc" = "Diperhatikan, konfigurasi tidak dihapus, jadi seharusnya mudah untuk menginstal kembali jika diperlukan.
Anda mungkin akan diminta kata sandi selama proses penghapusan apabila izin akses file tidak memungkinkan pemindahan yang sederhana.";
"phpman.warnings.removal.button" = "Uninstall";
"phpman.failures.install.title" = "Instalasi gagal!";
"phpman.failures.install.desc" = "Sayangnya, operasinya kembali dengan kode error untuk alasan yang tidak jelas. Mungkin Anda akan menemukan bahwa formulae sudah benar-benar diinstal atau diperbarui. Sayangnya, saya tidak dapat banyak tentang ini. Silakan cek pesan terakhir dari Homebrew disini untuk lebih informasi mengapa hal itu terjadi:
%@";
"phpman.action_prevented_busy.title" = "Pengelola Versi PHP sedang sibuk.";
"phpman.action_prevented_busy.desc" = "Pengelola Versi PHP sedang melakukan sesuatu seperti memilih antara variasi PHP. Untuk menghindari kerusakan pada sistem Anda, Anda harus menunggu hingga Pengelola Versi PHP siap sebelum mencoba lagi.";
"phpman.uninstall_prevented.title" = "Anda tidak dapat menghapus versi aktif dari PHP menggunakan antarmuka ini.";
"phpman.uninstall_prevented.desc" = "Dengan sengaja, instalasi versi aktif dari PHP tidak mungkin dihapus menggunakan antarmuka ini. Anda dapat memilih versi dan mencobanya kembali atau menghapuskannya secara manual melalui terminal.\n\nPeringatan, Pengelola Versi PHP mungkin akan gagal jika Anda menghapus versi yang di-linkkan.";
"phpman.failures.uninstall.title" = "Gagal menghapus!";
"phpman.failures.uninstall.desc" = "Sayangnya, uninstallasi otomatis gagal. Anda dapat mencoba menjalankan perintah ini secara manual: `%@` dan temukan apa yang salah. Ingat untuk restart Pengelola Versi PHP (atau tekan tombol refresh) setelah itu.";
"phpman.unlinked.title" = "Tidak ada variasi dari PHP yang terpasang pada sistem Anda saat ini";
"phpman.unlinked.desc" = "Anda mungkin masih memiliki beberapa versi dari PHP yang sedang diinstal, tetapi saat ini tidak ada variasi PHP yang di-link.";
"phpman.unlinked.detail" = "Tanpa versi PHP yang di-link, ikon `php` bukan tersedia pada sistem Anda dan Anda tidak dapat menjalankan script PHP tanpa secara eksplisit menjadi bagian dari PATH. Anda mungkin ingin memperbarui masalah ini (pilih 'Pemulihan Otomatis' dalam menu utama), atau seharusnya mengatasi sendiri dengan menjalankan `brew link php --force`.";
"phpman.operations.repairing" = "Mengatur ulang instalasi...";
"phpman.operations.updating" = "Instal perbaruan...";
"phpman.operations.installing" = "Instal %@...";
"phpman.steps.fetching" = "Mendapatkan...";
"phpman.steps.downloading" = "Memuat data paket...";
"phpman.steps.installing" = "Menginstal beberapa data paket...";
"phpman.steps.pouring" = "Mengganti... Ini mungkin memakan waktu cukup lama...";
"phpman.steps.summary" = "Paket tersebut telah selesai diinstal...";
"phpman.services.loading" = "Memuat...";
"phpman.services.not_installed" = "Pelayanan kunci tidak terpasang.";
"phpman.services.error" = "Pelayanan kunci melaporkan sebuah keadaan gagal.";
"phpman.services.inactive" = "Pelayanan kunci tidak berjalan.";
"phpman.services.all_ok" = "Semua layanan Valet baik.";
// LITE MODE
"lite_mode_explanation.title" = "Andalah sedang menjalankan PHP Monitor dalam Mode Standalone.";
"lite_mode_explanation.subtitle" = "PHP Monitor memiliki fitur tambahan yang tersedia jika Anda menggunakan Laravel Valet. Saat ini, PHP Monitor tidak bisa mendeteksi instalasi aktif Valet pada sistem Anda, maka fitur-fiturnya tidak dapat digunakan.";
"lite_mode_explanation.description" = "Untuk lebih banyak informasi, saya merekomendasikan untuk memeriksa README ( tersedia di GitHub) yang akan menjelaskan langkah-langkah apa yang harus anda lakukan untuk menginstal Valet dan membuat PHP Monitor bekerja dengan benar saat Valet terpasang. Anda perlu menutup PHP Monitor sebelum fitur-fitur tersebut dapat digunakan kembali.";
"lite_mode_explanation.description" = "Setelah dijalankan kembali, semua preset yang ada dalam file config.json akan dijalankan.";
// GENERIC
"generic.ok" = "OK";
"generic.cancel" = "Batal";
"generic.retry" = "Ulangi";
"generic.notice" = "Peringatan";
// PRESET LOADING
"preset_help_title" = "Bekerja dengan Preset Konfigurasi";
"preset_help_info" = "Anda dapat mengatur preset konfigurasi dalam file config.json, yang berada di ~/.config/phpmon/config.json. Preset ini dapat memilih beberapa nilai pengaturan secara bersamaan. Fitur ini sangat kuat, tetapi saat ini harus diatur manual.";
"preset_help_desc" = "Setelah dijalankan kembali, semua preset yang ada dalam file akan dijalankan. Jika tidak ada preset yang muncul, kemungkinan file tersebut dapat diterima dengan baik.";
// MENU ITEMS (if window is open)
"mm_add_folder_as_link" = "Tambahkan Folder sebagai Link...";
"mm_reload_domain_list" = "Ulangi Daftar Domains";
"mm_find_in_domain_list" = "Carilah di Daftar Domains";
// SITE LIST
"domain_list.title" = "Domains";
"domain_list.subtitle" = "";
"domain_list.domains_empty.title" = "Tidak ada domain yang tersedia.";
"domain_list.domains_empty.desc" = "Tidak ada domain yang ditemukan untuk pencarian ini atau Anda belum menautkan sebarang domain.";
"domain_list.domains_empty.button" = "Tambahkan domain...";
"domain_list.tooltips.isolated" = "Domain ini diisolasi dan menggunakan PHP %@ daripada PHP yang terhubung secara global.";
"domain_list.tooltips.checkmark" = "Domain ini disajikan dengan versi PHP yang kompatibel dengan persyaratan (PHP %@). Klik pada versi PHP di sebelah pemberat cek untuk mendapatkan informasi lebih lanjut.";
"domain_list.alerts_isolation_failed.title" = "Oops! Isolasi Gagal";
"domain_list.alerts_isolation_failed.subtitle" = "Ada masalah saat mengubah status isolasi untuk domain ini. Jika ini adalah domain default tetapi tidak terhubung, saya merekomendasikan anda menautkan domain sebelum mengatur isolasi.";
"domain_list.alerts_isolation_failed.desc" = "Untuk mendapatkan informasi apa yang salah, cobalah menjalankan perintah di terminal Anda manual: %@";
"domain_list.alerts_status_not_changed.title" = "Oops! Status SSL Tidak Diganti";
"domain_list.alerts_status_not_changed.desc" = "Ada masalah. Cobalah menjalankan perintah dalam terminal Anda manual: %@";
"domain_list.alerts_status_changed.title" = "Status SSL Diganti";
"domain_list.alerts_status_changed.desc" = "Domain '%@' sekarang adalah %@.";
"domain_list.alerts_status_secure" = "Aman";
"domain_list.alerts_status_unsecure" = "Tidak Aman";
"domain_list.confirm_unlink" = "Anda yakin ingin melepaskan '%@'?";
"domain_list.confirm_unlink_desc" = "Tidak ada file yang akan dihapus. Anda dapat selalu menautkan folder lagi dengan memilih folder asli dan memilih "+" dan mengatur folder tersebut.";
"site_link.close" = "Tutup";
"site_link.switch_to_php" = "Pindahkan ke PHP %@";
"site_link.isolate_php" = "Isolasi PHP %@";
"domain_list.confirm_unproxy" = "Anda yakin ingin melepaskan proxy '%@'?";
"domain_list.confirm_unproxy_desc" = "Anda dapat selalu mengimpor proxy lagi dengan memilih "+" dan menambahkan proxy yang sama.";
"domain_list.columns.secure" = "TLS";
"domain_list.columns.domain" = "Domain";
"domain_list.columns.active" = "Aktif";
"domain_list.columns.kind" = "Jenis";
"domain_list.columns.project_type" = "Tipe Proyek";
"domain_list.extensions" = "Pengaturan Tambahan";
"domain_list.applies_to" = "Berlaku untuk PHP %@";
// CHOOSE WHAT TO ADD
"selection.title" = "Apakah Anda ingin menetapkan jenis domain?";
"selection.description" = "Link digunakan untuk secara langsung menyajikan proyek. Jika Anda memiliki folder Laravel, Symfony, WordPress dsb dengan kode, Anda akan perlu menciptakan link dan memilih folder di mana kode Anda hidup.\n\nJika Anda membutuhkan proxy, Anda dapat mengimpor misalnya container ke nama domain tertentu. Ini bisa berguna dalam kombinasi dengan Docker, misalnya.";
"selection.create_link" = "Buat Link";
"selection.create_proxy" = "Buat Proxy";
"selection.cancel" = "Batalkan";
// ADD PROXY TO DOMAINS LIST
"domain_list.add.set_up_proxy" = "Tetapkan Proxy";
"domain_list.add.proxy_subject" = "Subject Proxy (harus mencakup protokol dan port)";
"domain_list.add.domain_name" = "Nama Domain";
"domain_list.add.create_proxy" = "Buat Proxy";
"domain_list.add.proxy_available" = "%@ akan diimpor dan tersedia melalui: %@://%@.%@";
"domain_list.add.proxy_https_warning" = "%@ akan diimpor dan tersedia melalui: %@://%@.%@.
(!) Penting! Anda perlu menambahkan `proxy_ssl_verify off;` ke config nginx untuk domain ini. Dianjurkan untuk menggunakan domain yang tidak aman sebagai subject proxy.";
// ADD SITE TO DOMAINS LIST
"domain_list.add.link_folder" = "Link Folder";
"domain_list.add.domain_name_placeholder" = "Masukkan nama domain disini";
"domain_list.add.secure_after_creation" = "Securing %@.%@ setelah dibuat";
"domain_list.add.secure_description" = "Mengamankan sebuah domain memerlukan akses administratif.\nAnda mungkin akan diminta untuk masuk kata sandi atau Touch ID.";
"domain_list.add.create_link" = "Create Link";
"domain_list.add.cancel" = "Cancel";
"domain_list.add.folder_available" = "This site will be available via the following URL: %@://%@.%@";
"domain_list.add.empty_fields" = "One or more fields are empty. Please fill all required fields.";
"domain_list.add.errors.empty" = "Anda wajib masukkan nama domain.";
"domain_list.add.errors.empty_proxy" = "Anda wajib memasukkan apa yang akan diproksi.";
"domain_list.add.errors.subject_invalid" = "Topik yang Anda masukkan tidak valid.\nAnda harus mencukupi protokol dan port.";
"domain_list.add.errors.already_exists" = "Terdapat tautan dengan nama tersebut sudah ada.";
// ADD SITE ERROR: FOLDER MISSING SINCE SELECTION
"domain_list.alert.folder_missing.desc" = "Folder yang Anda pilih tidak terlihat lagi. Apakah Anda ingin membatalkan menautkan folder ini? Jika Anda pindah folder, Anda masih bisa menempatkan kembali dan cobalah lagi.";
"domain_list.alert.folder_missing.title" = "Folder Missing!";
"domain_list.alert.folder_missing.cancel" = "Cancel Link";
"domain_list.alert.folder_missing.return" = "OK";
"domain_list.add.modal_description" = "Terlebih dahulu, pilih folder mana yang Anda ingin tautkan.";
// SITE LIST ACTIONS
"domain_list.isolate" = "Ganti Versi PHP";
"domain_list.site_isolation" = "Isolasi Situs";
"domain_list.remove_isolation" = "Hapus Isolasi";
"domain_list.always_use_php" = "Sedang Gunakan PHP %@";
"domain_list.isolation_unavailable" = "Isolasi Tidak Dibutuhkan (di Valet 2)";
"domain_list.favorite" = "Domain Favorit";
"domain_list.unfavorite" = "Batalkan Domain sebagai Favorit";
"domain_list.actions" = "Aksi";
"domain_list.unlink" = "Hapus Tautan";
"domain_list.secure" = "Amankan Domain";
"domain_list.unsecure" = "Batalkan Amankan Domain";
"domain_list.open_in" = "Buka dengan %@";
"domain_list.open_in_finder" = "Buka di Finder";
"domain_list.open_in_browser" = "Buka di Browser";
"domain_list.open_in_terminal" = "Buka di Terminal";
"domain_list.detected_apps" = "Aplikasi yang Ditemukan";
"domain_list.system_apps" = "Aplikasi Sistem";
"domain_list.unproxy" = "Hapus Proksi";
"domain_list.use_in_terminal" = "Buka PHP %@ di Terminal";
"domain_list.alerts_isolated_php_terminal.title" = "Anda dapat menggunakan PHP %@ di terminal spesifik!";
"domain_list.alerts_isolated_php_terminal.subtitle" = "Sayangnya, PHP Monitor tidak bisa membuka terminal untuk Anda (dan mengetik perintah yang tepat). Anda harus memanfaatkan skrip bantuan secara manual untuk menggunakan versi PHP spesifik tersebut. Untuk ini, Anda dapat mengcopy dan paste berikut ke terminal pilihan Anda:
. pm%@
Ini akan memuat skrip bantuan seperti dihasilkan oleh PHP Monitor dan memungkinkan penggunaan PHP %@ pada terminal spesifik yang digunakan. Ini tidak memiliki dampak pada terminal lainnya, hanya untuk sesi terminal yang sedang dipakai (misalnya jika Anda punya beberapa tab di aplikasi terminal, tab & jendela lainnya tidak terpengaruh.).";
"domain_list.alerts_isolated_php_terminal.desc" = "Jika ini belum berjalan, mungkin Anda ingin memeriksa PHP Doctor melalui menu Pertolongan Cemas di sini di PHP Monitor. Informasi lebih lanjut tentang fitur ini juga tersedia pada GitHub (di wiki pada repositori PHP Monitor). Pemberitahuan ini dimuat untuk meningkatkan visibilitas fitur tersebut.";
"domain_list.warning.spaces" = "Peringatan! Domain Anda memiliki ruang kosong dalam folder.\nDomain tidak bisa diakses melalui browser.";
"domain_list.alert.invalid_folder_name" = "Nama Folder Invalid";
"domain_list.alert.invalid_folder_name_desc" = "Folder ini tidak dapat diidentifikasi sebagai URL yang valid. Ini umumnya karena ada ruang di dalam nama folder. Silakan rename folder, reload daftar domain, dan cobalah lagi.";
"domain_list.columns.tls" = "TLS";
"domain_list.columns.domain" = "Domain";
"domain_list.columns.php" = "PHP";
"domain_list.columns.type" = "Tipe";
"domain_list.columns.kind" = "Jenis";
// DRIVERS
"driver.not_detected" = "Lainnya";
// PRESET
"preset.extension" = "%i ekstensi";
"preset.extensions" = "%i ekstensi";
"preset.preference" = "%i preferensi";
"preset.preferences" = "%i preferensi";
// EDITORS
"editors.alert.try_again" = "Coba Lagi";
"editors.alert.cancel" = "Batal";
// PREFERENCES
"prefs.title" = "Pilihul Monitor PHP";
"prefs.subtitle" = "Pilihan";
"prefs.close" = "Tutup";
"prefs.tabs.general" = "Umum";
"prefs.tabs.appearance" = "Penampilan";
"prefs.tabs.visibility" = "Kepercayaan";
"prefs.tabs.notifications" = "Pemberitahuan";
"prefs.global_shortcut" = "Ketika Pilihan Shortcut Global:";
"prefs.dynamic_icon" = "Icon Dinamis:";
"prefs.dynamic_icon" = "Jenis Icon:";
"prefs.info_density" = "Densitas Informasi:";
"prefs.services" = "Jasa:";
"prefs.switcher" = "Switcher:";
"prefs.php_doctor" = "Dokter PHP:";
"prefs.integrations" = "Integrasi:";
"prefs.updates" = "Pengembangan:";
"prefs.notifications" = "Pemberitahuan:";
"prefs.warnings" = "Peringatan:";
"prefs.menu_contents" = "Fasilitas dalam Menu:";
"prefs.startup" = "Pemulihan:";
"prefs.auto_start_desc" = "Automatically starts PHP Monitor when you log into your Mac.";
"prefs.auto_start_title" = "Mulai Pilihul Monitor PHP pada masuk";
"prefs.icon_options.php" = "Tampilkan Icon PHP";
"prefs.icon_options.elephant" = "Tampilkan Icon Gajah";
"prefs.icon_options.none" = "Tidak Tampilkan Icon";
"prefs.icon_options_desc" = "Pilihan ini menentukan apa icon yang akan ditunjukkan di samping nomor versi aktif dari PHP yang sedang terhubung. Jika opsi Dynamic Icon telah dihapus, tidak ada efeknya.";
"prefs.auto_restart_services_title" = "Auto-restart PHP-FPM";
"prefs.auto_restart_services_desc" = "Jika Anda mengecek ini, aplikasi akan secara otomatis restart PHP-FPM ketika Anda mengecek atau mematikan ekstensi. Sedikit lambat saat diaktifkan, tetapi hal ini akan mengaplikasikan perubahan ekstensi untuk semua situs yang sedang Anda layani, tidak perlu mengrestart PHP-FPM secara manual.";
"prefs.dynamic_icon_title" = "Tampilkan icon dinamis dalam menu bar";
"prefs.dynamic_icon_desc" = "Jika Anda menonaktifkan kotak centang ini, ikon truck akan selalu ada. Jika diaktifkan, ia akan menunjukkan nomor versi mayor dari PHP yang sedang terhubung.";
"prefs.display_full_php_version" = "Tampilkan versi PHP penuh di mana saja";
"prefs.display_full_php_version_desc" = "Tampilkan versi seluruhnya daripada versi mayor yang ditampilkan dalam menu bar dan dropdown menu. (Ini mungkin tidak menguntungkan pada layar kecil, jadi ini diaktifkan oleh default.)";
"prefs.auto_composer_update_title" = "Automatically update global dependencies";
"prefs.auto_composer_update_desc" = "Jika Anda mengecek ini, PHP Monitor akan secara otomatis meminta Composer untuk menjalankan `composer global update` saat Anda berganti antara versi PHP berbeda. Anda dapat melihat perubahan apa pun, atau apabila ini gagal.";
"prefs.open_protocol_title" = "Allow third-party integrations";
"prefs.open_protocol_desc" = "Jika Anda mengecek ini, hal ini akan memungkinkan interaksi dengan utility ketiga bekerja (mis. Alfred, Raycast). Jika diaktifkan, PHP Monitor tetap menerima perintah, tetapi tidak akan terlibat dalamnya.";
"prefs.automatic_update_check_title" = "Automatically check for updates";
"prefs.automatic_update_check_desc" = "Jika Anda mengecek ini, PHP Monitor akan secara otomatis mencari versi yang lebih baru tersedia dan memberitahu Anda jika hal itu ada.";
"prefs.php_doctor_suggestions_title" = "Always show suggestions";
"prefs.php_doctor_suggestions_desc" = "Jika Anda menonaktifkan item ini, tidak ada saran dari PHP Doctor akan ditampilkan dalam menu PHP Monitor. Ingat bahwa PHP Doctor tidak akan muncul jika tidak ada rekomendasi.";
"prefs.shortcut_set" = "Set global shortcut";
"prefs.shortcut_listening" = "<menunggu teks>";
"prefs.shortcut_clear" = "Hapus";
"prefs.shortcut_desc" = "Jika kombinasi tombol panah Anda terpasang, Anda dapat mengeklik PHP Monitor di mana saja dengan menggunakan kombinasi teks yang Anda pilih. (Batalkan memilih opsi shortcut dengan menekan tombol ruang.)";
"prefs.notify_about_version_change_desc" = "Menampilkan pemberitahuan ketika versi PHP aktif berubah.";
"prefs.notify_about_version_change" = "Pemberitahuan tentang perubahan versi PHP";
"prefs.notify_about_php_fpm_change_desc" = "Menampilkan pemberitahuan ketika proses PHP-FPM telah diulangi karena perubahan konfigurasi";
"prefs.notify_about_php_fpm_change" = "Pemberitahuan tentang ulang PHP-FPM";
"prefs.notify_about_services_desc" = "Menampilkan pemberitahuan ketika layanan Homebrew (terpasang dan konfigurasinya oleh Valet) telah diulangi atau dihentikan.";
"prefs.notify_about_services" = "Pemberitahau tentang status jasa";
"prefs.notify_about_presets_desc" = "Menampilkan pemberitahuan ketika preset berhasil diterapkan atau dikembalikan";
"prefs.notify_about_presets" = "Pemberitahau tentang preset yang diterapkan";
"prefs.notify_about_secure_status_desc" = "Menampilkan pemberitahuan saat domain telah dienkripsi atau tidak terenkripsi.";
"prefs.notify_about_secure_status" = "Pemberitahau tentang status yang dienkripsi/tidak dienkripsi";
"prefs.notify_about_composer_success_desc" = "Menampilkan pemberitahuan ketika konfigurasi Composer global berhasil diupdate.";
"prefs.notify_about_composer_success" = "Pemberitahau tentang update composer global";
"prefs.warn_about_non_standard_tld_desc" = "Jika Anda menggunakan TLD yang tidak standar, mungkin Anda tidak ingin mendapatkan notifikasi yang repetitif ini.";
"prefs.warn_about_non_standard_tld" = "Peringatan tentang TLD yang tidak standar";
"prefs.display_global_version_switcher_desc" = "Jika dihapus, Anda tidak dapat mengubah versi PHP global melalui menu utama.";
"prefs.display_global_version_switcher" = "PHP Switcher";
"prefs.display_services_manager_desc" = "Jika dihapus, Anda tidak dapat melihat, memulai atau mematikan layanan individu. (Jika ada layanan yang dihapus, Anda tidak mudah untuk mengetahui bahwa ini adalah kasusnya.)";
"prefs.display_services_manager" = "Manager Layanan";
"prefs.display_valet_integration_desc" = "Jika dihapus, Anda tidak dapat melihat folder Utama Valet atau daftar domain.";
"prefs.display_valet_integration" = "Integrasi Valet";
"prefs.display_php_config_finder_desc" = "Jika dihapus, Anda tidak dapat dengan mudah mencari file konfigurasi PHP dan/atau menghasilkan dump phpinfo().";
"prefs.display_php_config_finder" = "Pencarian Konfigurasi PHP";
"prefs.display_composer_toolkit_desc" = "Jika dihapus, Anda tidak dapat memanggil Composer melalui menu utama. Perubahan Composer otomatis setelah berganti pilihan tetap tidak dipengaruhi oleh perubahan ini.";
"prefs.display_composer_toolkit" = "Tool Komposer";
"prefs.display_limits_widget_desc" = "Jika dihapus, Anda tidak dapat melihat widget batas (memori, POST, upload) dalam menu utama.";
"prefs.display_limits_widget" = "Widget Batas";
"prefs.display_extensions_desc" = "Jika dihapus, Anda tidak dapat dengan mudah mengeklik ekstensi menggunakan menu utama.";
"prefs.display_extensions" = "Ekstensi";
"prefs.display_presets_desc" = "Jika dihapus, Anda tidak dapat mengaplikasikan atau membalikkan preset konfigurasi PHP.";
"prefs.display_presets" = "Preset";
"prefs.display_misc_desc" = "Jika dihapus, Anda tidak dapat dengan mudah mengakses menu Pertolongan Pertama & Layanan.";
"prefs.display_misc" = "Menu Pertolongan Pertama & Layanan";
// Composer Update
"alert.composer_missing.title" = "Composer tidak ditemukan!";
"alert.composer_missing.subtitle" = "PHP Monitor tidak dapat menemukan Composer. Periksa jika Composer telah terpasang dan coba lagi.";
"alert.composer_missing.desc" = "PHP Monitor mempelajari bahwa Composer berlokasi di salah satu dari:
• `/usr/local/bin/composer`
• `/opt/homebrew/bin/composer`
Perhatikan apakah Anda memiliki Composer yang terpasang di lokasi ini, atau buat symlink jika Anda memiliki Composer yang terpasang di tempat lain.";
"alert.composer_progress.title" = "Mengupdate dependencies global...";
"alert.composer_progress.info" = "Anda bisa melihat kemajuan pada output terminal di bawah ini.";
"alert.composer_failure.title" = "Terjadi masalah!";
"alert.composer_failure.info" = "Dependensi Composer global Anda tidak dapat diperbarui.
Anda bisa menemukan informasi lebih lanjut pada output terminal di bawah ini. Anda harus memperbaiki masalah ini sendiri, menggunakan terminal pribadi Anda (ini hanya menunjukkan output).";
"alert.composer_success.title" = "Composer berhasil mengupdate!";
"alert.composer_success.info" = "Dependensi Composer global Anda telah diperbarui dengan sukses.";
// Composer Version
"alert.composer_php_isolated.desc" = "Halaman ini telah diisolasi, yang berarti bahwa Valet memasarkan PHP %@ untuk halaman ini khusus. Versi PHP yang global saat ini adalah %@.";
"alert.composer_php_requirement.title" = "'%@' membutuhkan PHP %@.";
"alert.composer_php_requirement.unable_to_determine" = "Tidak dapat menentukan versi PHP yang diperlukan";
"alert.composer_php_requirement.type.unknown" = "PHP Monitor tidak dapat menentukan versi PHP yang diinginkan untuk domain ini. Ketentuan mungkin dapat dipahami jika Anda memiliki `composer.json` atau `.valetphprc` file di direktori proyek Anda.";
"alert.composer_php_requirement.type.require" = "Versi PHP yang diperlukan ini telah ditentukan dengan memeriksa field `require` dalam `composer.json` file ketika daftar situs terakhir diperbarui.";
"alert.composer_php_requirement.type.platform" = "Versi PHP yang diperlukan ini telah ditentukan dengan memeriksa field `platform` dalam `composer.json` file ketika daftar situs terakhir diperbarui.";
"alert.composer_php_requirement.type.valetphprc" = "Versi PHP yang diperlukan ini telah ditentukan dengan memeriksa `.valetphprc` file di direktori proyek Anda.";
"alert.composer_php_requirement.type.valetrc" = "Versi PHP yang diperlukan ini telah ditentukan dengan memeriksa `.valetrc` file di direktori proyek Anda.";
"alert.unable_to_determine_is_fine" = "Jika Anda memiliki proyek yang sederhana, mungkin tidak ada versi PHP yang disebutkan sebagai ketentuan. Dalam hal ini, Anda boleh melewatkan peringatan ini.";
"alert.php_version_ideal" = "Versi PHP aktif saat ini adalah ideal untuk situs ini.";
"alert.php_version_incorrect" = "Versi PHP aktif saat ini tidak sesuai dengan ketentuan yang telah disetujui untuk halaman ini.";
"alert.php_suggestions" = "Mungkin ada versi PHP lainnya yang dekat dengan ketentuan.";
// Suggest Fix My Valet
"alert.php_switch_failed.title" = "Ganti ke PHP %@ tampaknya gagal.";
"alert.php_switch_failed.info" = "PHP Monitor telah memperoleh peringatan bahwa PHP %@ tidak aktif setelah menyelesaikan prosedur pindah. Anda bisa mencoba menjalankan \"Fix My Valet\" dan ganti kembali setelah itu. Apakah Anda ingin mencobanya solusi ini?";
"alert.php_switch_failed.desc" = "Pertama, Anda harus mencoba \"Fix My Valet\" jika belum mencobanya. Jika PHP Monitor tetap tidak mampu untuk menggantikan versi aktif PHP bahkan setelah itu, Anda mungkin perlu mengupdate Valet dan paket Homebrew di sistem Anda. Anda bisa melakukannya dengan menjalankan `brew update && brew upgrade` serta mengupgrade Valet dengan menjalankan `composer global update && valet install`.";
"alert.php_switch_failed.confirm" = "Ya, jalankan \"Fix My Valet\"";
"alert.php_switch_failed.cancel" = "Tidak Run";
// PHP Formula Missing
"alert.php_formula_missing.title" = "Oops! The `php` formula harus diinstal untuk Fix My Valet...";
"alert.php_formula_missing.info" = "Terlihat bahwa Anda tidak memiliki `php` formula yang telah diinstall, yang mencegah PHP Monitor dari menjalankan Fix My Valet. Silakan install dengan menjalankan `brew install php`, restart PHP Monitor dan coba lagi.";
// Fix My Valet Started
"alert.fix_my_valet.title" = "Saya punya masalah? Fix My Valet siap dimulai!";
"alert.fix_my_valet.info" = "Ini memakan waktu. Silahkan sabar.\n\nKetika ini selesai, semua jasa lainnya akan dihentikan dan PHP %@ akan terkaitkan. Anda dapat menggantung versi PHP yang diinginkan setelah operasi ini telah selesai.\n\n(Anda akan mendapatkan notifikasi lagi saat Fix My Valet selesai.)";
"alert.fix_my_valet.ok" = "Terus";
"alert.fix_my_valet.cancel" = "Dibatalkan";
// Fix My Valet Done
"alert.fix_my_valet_done.title" = "Fix My Valet telah selesai menjalankan operasinya.";
"alert.fix_my_valet_done.subtitle" = "Semua jasa yang berpengaruh telah dihentikan dan diperjalankan kembali, dan versi terbaru dari PHP seharusnya saat ini aktif. Anda bisa mencoba menggantung ke versi PHP lainnya.";
"alert.fix_my_valet_done.stay" = "Sisanya pada PHP %@";
"alert.fix_my_valet_done.switch_back" = "Kembalikan ke PHP %@";
"alert.fix_my_valet_done.desc" = "Jika mengunjungi situs masih tidak berfungsi, Anda mungkin perlu menjalankan `valet install` kembali, ini bisa mengatasi issue 502 (Bad Gateway).\n\nJika Valet rusak dan Anda tidak dapat menjalankan `valet install`, Anda mungkin perlu menjalankan `composer global update`. Silakan periksa FAQ di GitHub jika Anda memiliki masalah lanjutan.";
// Restore Homebrew Permissions
"alert.fix_homebrew_permissions.title" = "Tentang \"Restore Homebrew Permissions\"";
"alert.fix_homebrew_permissions.subtitle" = "Fitur ini diciptakan agar Anda dapat menjalankan `brew upgrade` atau `brew cleanup` tanpa masalah izin.";
"alert.fix_homebrew_permissions.desc" = "Ini membutuhkan kekuatan penuh, karena PHP Monitor akan mengatur kembali kepemilikan file dan folder yang sekarang dimiliki oleh pengguna `root`, karena jasa Valet berjalan sebagai user `root`.";
"alert.fix_homebrew_permissions.ok" = "Restore Permissions";
"alert.fix_homebrew_permissions.cancel" = "Cancel";
"alert.fix_homebrew_permissions_done.title" = "Semua izin file dan folder untuk dependensi Valet telah dikembalikan.";
"alert.fix_homebrew_permissions_done.subtitle" = "Karena itu, semua jasa dari Valet saat ini tidak berjalan. Anda dapat menginteraksi dengan Homebrew, tetapi situs Anda Valet sedang tidak tersedia karena semua jasa dihentikan.";
"alert.fix_homebrew_permissions_done.desc" = "Jika Anda selesai dengan Homebrew (setelah menjalankan `brew upgrade`, misalnya) Anda harus restart PHP Monitor dan pilih \"Restart Valet Services\" jika Anda ingin Valet bekerja lagi. Selalu direkomendasikan untuk restart PHP Monitor saat Anda mengupgrade versi PHP menggunakan `brew upgrade`, atau hal-hal mungkin akan gagal.";
// PHP FPM Broken
"alert.php_fpm_broken.title" = "Konfigurasi PHP-FPM Anda tidak mengarah ke socket Valet!";
"alert.php_fpm_broken.info" = "PHP Monitor telah menemukan masalah pada konfigurasi PHP-FPM Anda. Ini akan menyebabkan respons '502 Bad Gateway' jika Anda mengunjungi situs yang terhubung melalui Valet.";
"alert.php_fpm_broken.description" = "Jika sudah beberapa waktu, Anda biasanya dapat memperbaiki hal ini dengan menjalankan `valet install`, yang memperbarui konfigurasi PHP-FPM Anda.\n\nJika Anda lihat pesan ini dan Anda sedang mencoba versi pre-release PHP, mungkin Valet tidak mendukung ini versi pre-release PHP ini.\n\nAnda mungkin perlu mengupdate instalasi Laravel Valet ke setidaknya v3.1.11, sesudah itu Anda harus menjalankan `valet install`. Informasi lebih lanjut disini: https://phpmon.app/prerelease-php";
// PHP Monitor Cannot Start
"alert.cannot_start.title" = "PHP Monitor tidak dapat dimulai akibat masalah konfigurasi sistem";
"alert.cannot_start.subtitle" = "Masalah yang Anda diberi tahu sebelumnya tidak dapat membuat PHP Monitor berfungsi dengan benar.";
"alert.cannot_start.description" = "Anda mungkin tidak harus menghentikan PHP Monitor dan mulai ulang. Jika masalah telah diatasi (atau Anda tidak ingat apa yang isinya) Anda bisa menekan Retri, yang akan memungkinkan PHP Monitor mencoba kembali periksa awal.";
"alert.cannot_start.close" = "Selesai";
"alert.cannot_start.retry" = "Coba Ulang";
// PHP alias issue
"alert.php_alias_conflict.title" = "Konflik alias `php` dalam formula Homebrew terdeteksi";
"alert.php_alias_conflict.info" = "PHP Monitor telah mendeteksi konflik alias `php` di pengaturan Homebrew Anda, yang kedua di antaranya telah diidentifikasi sebagai terpasang.\n\nIni akan mungkin menyebabkan tautan linking yang gagal ketika Anda mengganti versi PHP, dan akan memperparah fungsi PHP Monitor.";
"alert.php_alias_conflict.info" = "Konflik alias `php` dalam formula Homebrew terdeteksi";
"alert.php_alias_conflict.info" = "Konflik alias `php` dalam formula Homebrew terdeteksi";
"alert.min_valet_version.title" = "Versi Valet yang diinstal tidak memenuhi syarat minimum. PHP Monitor mungkin tidak berfungsi sebagaimana diharapkan!";
"alert.min_valet_version.info" = "Anda sedang menggunakan Valet %@.
Untuk dukungan terbaik terhadap versi terakhir dari PHP dan fungsi berpindah PHP yang benar, disarankan untuk memperbarui ke versi %@, yang merupakan syarat paling rendah dari PHP Monitor ini.
Anda dapat melakukan ini dengan menjalankan `composer global update` di terminal Anda. Sesudah itu, jalankan lagi `valet install`. Untuk hasil terbaik, restart PHP Monitor sesudah itu. Hingga hal ini diselesaikan, PHP Monitor mungkin tidak berfungsi sebagaimana yang direncanakan.";
// Preset text description
"alert.preset_description.switcher_version" = "Pindahkan ke PHP %@.\n\n";
"alert.preset_description.applying_extensions" = "Mengaplikasikan ekstensi berikut:\n";
"alert.preset_description.applying_config" = "Mengaplikasikan nilai konfigurasi berikut:\n";
"alert.preset_description.enabled" = "dibuka";
"alert.preset_description.disabled" = "ditutup";
"alert.preset_description.empty" = "(kosong)";
// PHP version unavailable
"alert.php_switch_unavailable.title" = "Versi PHP yang tidak tersedia";
"alert.php_switch_unavailable.subtitle" = "PHP Monitor tidak dapat pindah ke PHP %@, karena mungkin tidak terpasang atau tersedia. Menerapkan preset ini telah dibatalkan.";
"alert.php_switch_unavailable.info" = "Pastikan PHP %@ terpasang dan Anda dapat menggantungnya dalam dropdown. Saat ini versi yang didukung adalah PHP: %@.";
"alert.php_switch_unavailable.ok" = "OK";
// Service error
"alert.service_error.title" = "Service '%@' mengadukan masalah!";
"alert.service_error.subtitle.error_log" = "Ini berarti service '%@' tidak sedang berjalan. Ini mungkin akan memperparah kerja Valet. File log yang terkait ini mungkin Anda ingin dilihat, namun";
"alert.service_error.subtitle.no_error_log" = "Ini berarti service '%@' tidak sedang berjalan. Ini mungkin akan memperparah kerja Valet. Tidak ada file log terkait untuk ini.";
"alert.service_error.extra" = "Anda juga boleh mengikuti langkah penelitian biasa. Untuk mendapatkan lebih banyak informasi, tekan tombol '?' dalam bagian layanan dalam PHP Monitor.";
"alert.service_error.button.show_log" = "Lihat Log Error";
"alert.service_error.button.close" = "Selesai";
// Composer issues
"alert.global_composer_platform_issues.title" = "Composer menemukan masalah di platform Anda";
"alert.global_composer_platform_issues.subtitle" = "Versi PHP yang Anda pilih adalah terlalu lama untuk dependensi global Composer Anda yang terpasang. Ini akan memerlukan perbarui.";
"alert.global_composer_platform_issues.desc" = "Cara termudah untuk menghindari masalah ini di masa depan adalah dengan pindah ke versi PHP tertua yang Anda miliki dan menjalankan `composer global update` lagi. \n\nAlternatifnya, Anda bisa memilih 'Automatically update global dependencies' dalam Preferences untuk mencegah masalah seperti ini juga.\n\nJika Anda terus melihat pesan ini setelah mencoba perbarui dependensi global tersebut, mungkin Anda ingin melihat konfigurasi composer global Anda yang terletak di `~/.composer/composer.json`.";
"alert.global_composer_platform_issues.buttons.update" = "Update Dependensi Global";
"alert.global_composer_platform_issues.buttons.quit" = "Selesai PHP Monitor";
// Revert
"alert.revert_description.title" = "Revert Konfigurasi?";
"alert.revert_description.subtitle" = "PHP Monitor dapat mengembalikan konfigurasi yang sebelumnya aktif. Ini adalah apa yang akan diaplikasikan: \n\n%@";
"alert.revert_description.ok" = "Revert";
"alert.revert_description.cancel" = "Batal";
// STARTUP
// 0. Architecture mismatch
"alert.homebrew_missing.title" = "PHP Monitor tidak dapat dimulai!";
"alert.homebrew_missing.subtitle" = "Binary Homebrew bekerja yang tidak ditemukan dapat dilihat di tempat yang biasa. Silakan mulai aplikasi setelah masalah ini diselesaikan.";
"alert.homebrew_missing.info" = "Anda sedang menjalankan PHP Monitor dengan arsitektur berikut: %@. Sebagai hasilnya, sebuah binary Homebrew bekerja diperlukan di tempat-tempat yang umum, yaitu `%@`, tetapi tidak ditemukan. Ini adalah sebabnya mengapa PHP Monitor tidak dapat berfungsi.\n\nJika Anda belum menginstal Homebrew, silakan melakukan hal itu. Jika Anda menggunakan prosesor Apple Silicon, pastikan bahwa Homebrew dan PHP Monitor yang Anda gunakan memiliki arsitektur yang sama, dengan memungkinkan atau menonaktifkan Rosetta sesuai kebutuhan.";
"alert.homebrew_missing.quit" = "Keluar";
// PHP binary not found
"startup.errors.php_binary.title" = "PHP tidak terpasang dengan benar";
"startup.errors.php_binary.subtitle" = "Anda harus menginstal PHP via Homebrew. Aplikasi ini tidak akan berfungsi dengan benar sampai Anda menyelesaikan masalah ini.";
"startup.errors.php_binary.desc" = "Umumnya, menjalankan `brew link php` di Terminal Anda akan memecahkan masalah ini.\n\nUntuk meng diagnosis apa yang salah, Anda dapat mencoba menjalankan `which php` dalam Terminal, ia harus memberikan `%@.`.";
// PHP not found in /usr/local/opt or /opt/homebrew/opt
"startup.errors.php_opt.title" = "PHP tidak terpasang dengan benar";
"startup.errors.php_opt.subtitle" = "Alias PHP tidak ditemukan di `%@`. Aplikasi ini tidak akan berfungsi dengan benar sampai Anda menyelesaikan masalah ini.";
"startup.errors.php_opt.desc" = "Jika Anda sudah memiliki formula `php` yang terpasang, Anda mungkin harus menjalankan `brew install php` agar PHP Monitor dapat mendeteksi pengaturan instalasi ini.";
// PHP binary is broken
"startup.errors.dyld_library.title" = "PHP terpasang namun tampaknya patah";
"startup.errors.dyld_library.subtitle" = "Kemungkinan untuk menjalankan perintah dengan baik oleh PHP Monitor sedang gagal. Ini adalah tanda dari instalasi PHP yang patah.";
"startup.errors.dyld_library.desc" = "Jika Anda ingin memperbaiki masalah ini, silakan jalankan `brew reinstall php && brew link php` dalam Terminal Anda.";
// Valet is not installed
"startup.errors.valet_executable.title" = "Laravel Valet tidak terpasang dengan benar";
"startup.errors.valet_executable.subtitle" = "Anda harus menginstal Valet menggunakan Composer. Aplikasi ini tidak akan berfungsi dengan benar sampai Anda menyelesaikan masalah ini.";
"startup.errors.valet_executable.desc" = "Jika Anda belum menginstall Laravel Valet, silakan melakukan hal itu terlebih dahulu. Jika Anda sudah memiliki instalasinya tapi melihat pesan ini, maka coba jalankan `which valet` di Terminal, ia harus memberikan: `%@.`.";
// Valet configuration file missing or broken
"startup.errors.valet_json_invalid.title" = "File konfigurasi Laravel Valet tidak benar atau hilang";
"startup.errors.valet_json_invalid.subtitle" = "PHP Monitor membutuhkan cara untuk membaca file konfigurasi. Terdapat indikasi bahwa file ini cacat atau hilang. Silakan periksa apakah ia ada dan dikelola dengan baik.";
"startup.errors.valet_json_invalid.desc" = "File tersebut dapat di temukan di `~/.config/valet/config.json`. Jika Laravel Valet tidak mampu membaca file konfigurasi, menjalankan setiap `valet` komandan akan biasanya otomatis memperbaiki file JSON ini. Coba jalankan `valet --version` untuk memperbaiki file ini.";
// Valet version not readable
"startup.errors.valet_version_unknown.title" = "Versi Laravel Valet tidak dapat dibaca";
"startup.errors.valet_version_unknown.subtitle" = "Penginterpretasi output dari `valet --version` gagal. Pastikan instalasi Anda valet berfungsi dan terupdate.";
"startup.errors.valet_version_unknown.desc" = "Coba jalankan `valet --version` di terminal untuk mengetahui apa yang sedang terjadi.";
"startup.errors.valet_not_installed.title" = "Direktori konfigurasi Valet Anda hilang";
"startup.errors.valet_not_installed.subtitle" = "Direktori yang diperlukan `~/.config/valet` hilang. Ini biasanya berarti Anda lupa menjalankan `valet install`.";
"startup.errors.valet_not_installed.desc" = "Asumsi Anda sudah menginstal Valet menggunakan Composer, silakan jalankan `valet install` untuk menyelesaikan pengaturan Laravel Valet.
Jika Anda melihat pesan ini tapi terpikirkan mengapa folder ini hilang, maka mungkin Anda ingin memeriksa alasannya, karena folder ini tidak harus menghilang dan berarti instalasi Valet Anda patah.";
// Valet version too new or old
"startup.errors.valet_version_not_supported.title" = "Versi Valet yang tidak didukung";
"startup.errors.valet_version_not_supported.subtitle" = "Anda sedang menggunakan versi Valet yang saat ini tidak didukung. PHP Monitor saat ini bisa digunakan dengan Valet v2, v3 dan v4. Dalam rangka mencegah terjadinya masalah pada sistem Anda, PHP Monitor tidak dapat dijalankan.";
"startup.errors.valet_version_not_supported.desc" = "Untuk menghindari masalah yang timbul akibat penggunaan versi Valet yang tidak kompatibel dengan PHP Monitor, silakan instal ulang versi Valet yang kompatibel dengan PHP Monitor (silakan lihat catatan rilis terbaru untuk lebih jelasnya).";
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew belum ditambahkan ke sudoers.d";
"startup.errors.sudoers_brew.subtitle" = "Anda harus menjalankan `valet trust` menggunakan perintah `sudo` untuk membuat Valet dapat dijalankan dan dihentikan tanpa harus menggunakan `sudo` setiap kali. PHP Monitor tidak akan berfungsi dengan baik hingga masalah ini diselesaikan.";
"startup.errors.sudoers_brew.desc" = "Jika Anda terus melihat pesan kesalahan ini, mungkin terdapat masalah izin di mana PHP Monitor tidak dapat validasi file. Masalah ini umumnya dapat diatasi dengan menjalankan `sudo chmod +r /private/etc/sudoers.d/brew`";
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Brew belum ditambahkan ke sudoers.d";
"startup.errors.sudoers_valet.subtitle" = "Anda harus menjalankan `valet trust` menggunakan perintah `sudo` untuk membuat Valet dapat dijalankan dan dihentikan tanpa harus menggunakan `sudo` setiap kali. Jika Anda telah menambahkan Brew ke sudoers.d sebelumnya, silakan jalankannya lagi: `valet trust`.";
"startup.errors.sudoers_valet.desc" = "Jika Anda terus melihat pesan kesalahan ini, mungkin terdapat masalah izin di mana PHP Monitor tidak dapat validasi file. Masalah ini umumnya dapat diatasi dengan menjalankan: `sudo chmod +r /private/etc/sudoers.d/valet`";
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor dan Valet tidak bisa bekerja secara normal: Composer melaporkan masalah tentang platform Anda";
"startup.errors.global_composer_platform_issues.subtitle" = "Silakan ikuti langkah-langkah yang direkomendasikan untuk mencegah terjadinya masalah di masa depan:\n\n1. Jalankan `composer global update`.\n2. Tutup dan jalankan kembali PHP Monitor (PHP Monitor akan bekerja lagi).\n3. Pergilah ke versi PHP tertua yang Anda miliki.\n4. Jalankan `composer global update` sekali lagi.";
"startup.errors.global_composer_platform_issues.desc" = "Anda bisa memilih opsi 'Automatically update global dependencies' pada Preferences. Ini akan memperbarui ketergantungan Composer global saat Anda mengubah versi PHP, jadi hal ini mungkin tidak cocok jika Anda tidak selalu memiliki akses ke internet.\n\nUntuk mengetahui apa yang salah, cobalah menjalankan `valet --version`. Saat ini Valet bukanlah fitur yang bisa digunakan dengan ketergantungan Composer yang terpasang. Umumnya masalah ini disebabkan oleh perbedaan versi: yaitu, ketergantungan instalasi untuk versi PHP yang lebih baru daripada versi PHP yang saat ini aktif.";
// Cannot retrieve services
"startup.errors.services_json_error.title" = "Gagal memeriksa status jasa";
"startup.errors.services_json_error.subtitle" = "Biasanya, PHP Monitor mengirimkan perintah berikut untuk menguji apakah layanan dapat diperiksa: `sudo brew services info nginx --json`.\n\nPHP Monitor tidak dapat memahami balasan ini.";
"startup.errors.services_json_error.desc" = "Ini bisa terjadi jika instalasi Homebrew Anda tidak terupdate, sehingga Homebrew tidak akan mengembalikan JSON lagi. Masalah ini umumnya dapat diatasi dengan menjalankan `brew update` atau `brew tap homebrew/services`. Anda juga bisa mencoba menjalankan `sudo brew services info nginx --json` pada terminal yang dimainkan pilihannya.";
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "Masalah yang diidentifikasi";
"startup.errors.which_alias_issue.subtitle" = "Terlihat bahwa ada file yang terdapat dalam `/usr/local/bin/which`. Ini biasanya diset oleh NodeJS, namun `node` tidak terdaftar dalam PATH di `/usr/local/bin`. Agar PHP Monitor dapat dijalankan dengan baik, Anda perlu membuat tautan (symlink) `node` ke folder `/usr/local/bin`.";
"startup.errors.which_alias_issue.desc" = "Untuk lebih jelasnya, silakan baca: https://github.com/nicoverbruggen/phpmon/issues/174";
// Laravel Herd conflicts
"startup.errors.herd_running.title" = "Laravel Herd sedang berjalan";
"startup.errors.herd_running.subtitle" = "Pertemuan terlihat bahwa Laravel Herd saat ini telah dijalankan. Konfigurasi Valet yang sudah dibuat oleh Herd mungkin bertabrakan dengan pengaturan Valet Anda secara normal, jadi sebaiknya tutup Herd sebelum melanjutkan. (Anda boleh menggunakan Herd dan Valet secara bersamaan tetapi Anda harus tidak mengjalankannya pada waktu yang sama.)";
"startup.errors.herd_running.desc" = "Pada gilirannya, Anda mungkin akan menemukan bahwa `php` alias dari Herd yang terdaftar dalam $PATH mungkin akan mencegah `php` alias dari PHP Monitor bekerja, jadi ingatilah. Anda bisa mencari tautan `~/.zshrc` dan lihat apa yang telah ditambahkan ke $PATH oleh Herd.";
// Warning about a different PHP version linked than last time
"startup.version_mismatch.title" = "Versi PHP yang aktif berbeda";
"startup.version_mismatch.subtitle" = "Sejak saat PHP Monitor terakhir dijalankan, versi PHP yang terdaftar telah berganti ke PHP %@. Apakah Anda ingin kembali ke PHP %@ atau tetap menggunakan versi yang sedang digunakan sekarang?";
"startup.version_mismatch.desc" = "PHP Monitor mengingat versi PHP yang saat ini terdaftar sebagai versi yang terpasang secara global. Versi global mungkin telah diubah karena beberapa program lainnya atau Homebrew telah menautkan versi formula setelah pembaruan.";
"startup.version_mismatch.button_switch_back" = "Kembalikan ke PHP %@";
"startup.version_mismatch.button_stay" = "Tetap menggunakan PHP %@",
// Warning about unsupported PHP versions
"startup.unsupported_versions_explanation.title" = "Versi PHP yang tidak didukung terdeteksi!";
"startup.unsupported_versions_explanation.subtitle" = "Versi PHP berikut ini telah terpasang pada sistem Anda tetapi tidak didukung oleh versi Valet saat ini.
%@
Valet mungkin akan patah jika Anda menggabungkan antara beberapa versi PHP yang tidak didukung.";
"startup.unsupported_versions_explanation.desc" = "Jika Anda membutuhkan dukungan untuk versi PHP yang lebih lama, Anda mungkin perlu turunkan ke sebuah versi Valet yang lebih tua. Jika tidak, mungkin merupakan ide yang baik untuk menghapus versi PHP yang belum digunakan yang tidak di gunakan. Ini juga bisa jadi hal yang tidak tepat dari versi Valet ini. Pesan ini hanya akan hilang setelah Anda restart PHP Monitor.";
// Sponsor encouragement
"startup.sponsor_encouragement.title" = "Jika PHP Monitor telah berguna bagi Anda atau perusahaan Anda, silakan beri tips";
"startup.sponsor_encouragement.subtitle" = "Agar 100% transparan: Saya rencana untuk tetap membuka sumber code dari PHP Monitor dan gratis. Bantuan Anda memudahkan untuk mengambil keputusan ini.\n\n(Anda hanya akan melihat prompt ini sekali.)";
"startup.sponsor_encouragement.desc" = "Jika Anda sudah menyumbang sebelumnya, maka ini adalah pesan terima kasih kepada Anda. Saya mengapresiasi dukungan Anda.";
"startup.sponsor_encouragement.accept" = "Berikan Bantuan";
"startup.sponsor_encouragement.learn_more" = "Mau Tahu Lebih Lanjut";
"startup.sponsor_encouragement.skip" = "Tidak Terlalu"
// ERROR MESSAGES
"alert.errors.homebrew_permissions.applescript_returned_nil.title" = "Restore Homebrew Permissions gagal dijalankan.";
"alert.errors.homebrew_permissions.applescript_returned_nil.description" = "Kebenaran dari skrip yang diperkenalkan untuk mengatur izin kembali adalah nil, yang biasanya berarti Anda tidak memberikan izin administratif kepada PHP Monitor.\n\nJika Anda menekan Batal pada tanda permintaan verifikasi, ini biasa. Jika Anda benar-benar melakukan pengautentikan dan Anda masih melihat pesan ini, mungkin ada masalah.";
"alert.key_service_not_running.title" = "Karena masalah dengan layanan Homebrew yang diperlukan, Valet saat ini tidak bekerja dengan benar";
"alert.key_service_not_running.subtitle" = "Untuk Valet untuk berfungsi dengan baik, setidaknya tiga layanan kunci harus dapat berjalan dengan benar.
PHP Monitor melaporkan bahwa hal ini bukanlah kasus. Anda bisa mencoba menekan tombol dengan huruf 'X' di menu di bawah layanan yang terjejas untuk (kembali) memulai layanan yang sedang tidak aktif.";
"alert.key_service_not_running.desc" = "Jika menekan tombol di bawah layanan tidak bekerja (yaitu, spinner muncul tapi tetap menjadi 'X' setelah beberapa waktu), Anda mungkin perlu menggunakan First Aid > Fix My Valet. Anda bisa melakukannya dengan menggunakan menu yang ada atau gunakan `valet stop` dan `valet start` di terminal, yang kemungkinan juga akan memperbaiki masalah (sebagai alternatif untuk First Aid > Fix My Valet).
Untuk debugging lebih lanjut, Anda mungkin ingin memeriksa halaman issue tracker GitHub, dimana mungkin telah ada masalah serupa. Sebagai pengembang, saya mencoba pastikan setiap pertanyaan diterjawab :)";
"alert.key_service_has_error.title" = "Karena masalah dengan layanan Homebrew yang diperlukan, Valet saat ini tidak bekerja dengan benar";
"alert.key_service_has_error.subtitle" = "Untuk Valet untuk berfungsi dengan baik, setidaknya tiga layanan kunci harus dapat berjalan dengan benar.
PHP Monitor melaporkan bahwa hal ini bukanlah kasus. Terdapat kesalahan pada layanan yang terjejas, maka saya sarankan menekan 'E'.";
"alert.key_service_has_error.desc" = "Saya tidak yakin apakah jika sebuah layanan memberitahukan ada kesalahan, masalah seringkali disebabkan oleh konfigurasi state yang tidak valid, yang mungkin sulit di debugging.
TIPS PERBAIKAN KOMMON
• Coba restart layanan dan periksa log file (jika ada) terlebih dahulu. Anda bisa menggunakan PHP Monitor untuk melakukan ini dengan menekan tombol 'E'.";
// CHECK FOR UPDATES
"updater.alerts.newer_version_available.title" = "PHP Monitor v%@ saat ini tersedia!";
"updater.alerts.newer_version_available.subtitle" = "Menggunakan versi terbaru PHP Monitor sangat di-rekomendasikan, karena versi baru sering kali menyelesaikan masalah dan memperbaiki pembaruan untuk mendukung versi terbaru dari Valet dan PHP.";
"updater.installation_source.brew" = "Metode yang direkomendasikan untuk mengunduh perbarui PHP Monitor adalah dengan menekan 'Install Update'.\n\nSejak Anda menggunakan Homebrew untuk instal aplikasi, Anda juga bisa mengupgrade melalui terminal dengan menjalankan `%@', tapi ini tidak di-rekomendasikan.\n\n(Silakan catat bahwa mengimpor melalui updater built-in ini akan menghapus PHP Monitor dari direktori Caskroom Homebrew, untuk mencegah unduhan duplicate yang disebabkan dan menyebabkan masalah potensial nanti.)";
"updater.installation_source.direct" = "Metode yang direkomendasikan untuk mengunduh perbarui PHP Monitor adalah dengan menekan 'Install Update'.";
"updater.alerts.buttons.release_notes" = "Lihat Catatan Rilis";
"updater.alerts.is_latest_version.title" = "Versi terbaru dari PHP Monitor telah diinstal!";
"updater.alerts.is_latest_version.subtitle" = "Versi yang sedang dipakai (v%@) sudah terupdate.\nTidak ada versi yang lebih baru tersedia.";
"updater.alerts.cannot_check_for_update.title" = "PHP Monitor tidak dapat mengetahui apakah ada versi yang lebih baru.";
"updater.alerts.cannot_check_for_update.subtitle" = "Mungkin Anda tidak terhubung ke internet, sedang menutup arus atau GitHub tidak memungkinkan untuk memeriksa perbaruan. Jika Anda tetap melihat pesan ini, Anda mungkin ingin memeriksanya manual.";
"updater.alerts.cannot_check_for_update.description" = "Versi yang sedang dipakai adalah: %@. Anda bisa pergi ke daftar versi terbaru (pada GitHub) dengan menekan tombol di sebelah kanan.";
"updater.alerts.buttons.releases_on_github" = "Lihat Rilis";
"updater.alerts.buttons.install" = "Unduh Perbarui";
"updater.alerts.buttons.dismiss" = "Tutup";
// WARNINGS ABOUT NON-DEFAULT TLD
"alert.warnings.tld_issue.title" = "Anda tidak menggunakan `.test` sebagai TLD untuk Valet.";
"alert.warnings.tld_issue.subtitle" = "Memakai TLD yang bukan default mungkin tidak berfungsi dengan baik dan belum diijinkan secara resmi.";
"alert.warnings.tld_issue.description" = "PHP Monitor tetap bisa berjalan, tapi mungkin akan ada masalah: aplikasi mungkin tidak tepat menunjukkan domain mana saja yang telah dilindungi. Untuk hasil optimal, pergi ke konfigurasi Valet Anda (config.json di direktori Valet) dan ganti kembali TLD menjadi `test`.";
"alert.do_not_tell_again" = "Tidak Kembali lagi";
// WARNINGS
"warnings.limits_error.title" = "PHP Monitor tidak dapat mengumpulkan batasan.";
"warnings.limits_error.steps" = "Coba jalankan 'php -v' di terminal Anda.";
"warnings.title" = "Dokter PHP";
"warnings.description" = "**Dokter PHP** akan merekomendasikan perbaikan untuk konfigurasi sistem yang aktif Anda.";
"warnings.disclaimer" = "Anda mungkin memilih untuk menutup semua saran dari menu PHP Monitor di Preferences, tetapi direkomendasikan Anda menghadapi semua item tindakan yang dapat diambil.";
"warnings.refresh.button" = "Scan Lagi";
"warnings.refresh.button.description" = "Tekan tombol ini setelah Anda selesai memperbaiki masalah. Ini akan menyebabkan PHP Monitor untuk mengulang evaluasinya terhadap lingkungan Anda. Jika benar-benar diperbaiki, rekomendasi harus hilang.";
"warnings.helper_permissions.title" = "Pompa bantuan PHP Monitor saat ini tidak tersedia.";
"warnings.helper_permissions.description" = "PHP Monitor datang dengan berbagai skrip bantu. Menggunakan skrip ini memungkinkan Anda untuk mengeksekusi versi spesifik dari PHP tanpa mengganti versi yang terhubung.";
"warnings.helper_permissions.unavailable" = "Namun, bantuan ini mungkin *tidak tersedia* karena PHP Monitor tidak bisa menciptakan atau mengupdate tautan yang diperlukan.";
"warnings.helper_permissions.symlink" = "Jika Anda tidak ingin membuat `/usr/local/bin` sebagai tulisan biasa, Anda bisa menambahkan direktori bantuan helper PHP Monitor ke variabel `PATH`. (Klik 'Lihat lebih lanjut' untuk mengenali cara untuk memperbaiki masalah.)";
"warnings.arm_compatibility.title" = "Anda sedang menggunakan PHP Monitor menggunakan Rosetta pada Apple Silicon, yang berarti lingkungan PHP Anda juga melakukannya melalui Rosetta.";
"warnings.arm_compatibility.description" = "Anda tampaknya sedang menjalankan versi kompatible ARM dari macOS, tetapi Anda saat ini menjalankannya menggunakan Rosetta. Ini akan bekerja dengan benar, tetapi direkomendasikan untuk menggunakannya versi yang sesuai dengan sistem yang asli Homebrew.";
"warnings.files_missing.title" = "Instalasi PHP Anda sedang missing key file konfigurasi.";
"warnings.files_missing.description" = "Berikut ini beberapa config file yang harus ada setelah menginstal PHP:
• %@
Ketika file seperti ini hilang, Anda mungkin ingin menyingkirkan versi PHP yang terhubung: hal tersebut mungkin akan memperbaiki masalah. Jika ini tidak mengatasi masalah, direkomendasikan untuk reinstall versi PHP spesifik via Homebrew kembali, yang seharusnya akan memulihkan config file yang hilang. File konfigurasi yang hilang mungkin menjadi alasan mengapa Anda mendapatkan '502 Bad Gateway' errors, bahkan setelah menggunakan First Aid > Fix My Valet (jika Anda sedang menggunakan Valet).";
"warnings.none" = "Tidak ada saran yang tersedia untuk Anda saat ini. Anda berada dalam kondisi baik!";
// ONBOARDING
"onboarding.title" = "Selamat Datang";
"onboarding.welcome" = "Selamat datang ke PHP Monitor!";
"onboarding.explore" = "Setelah ini, Anda telah memiliki akses penuh ke berbagai fungsi dari PHP Monitor. Anda dapat belajar lebih lanjut tentang beberapa fitur yang ditawarkan oleh PHP Monitor di halaman ini.";
"onboarding.explore.lite" = "Anda sekarang memiliki akses ke fitur terpenting dari PHP Monitor.
Perhatian: Beberapa fitur (dipaparkan dengan abu-abu di bawah) saat ini tidak tersedia karena Laravel Valet belum diaktifkan.";
"onboarding.tour.menu_bar.title" = "Daya Tidur di Menu Bar";
"onboarding.tour.menu_bar" = "PHP Monitor hidup di menu bar Anda. Dari menu ini, Anda dapat mengakses sebagian besar fungsi kunci dari PHP Monitor, termasuk mengganti versi PHP yang terhubung secara global, lokasi file konfigurasi, menginstal versi PHP berbeda dan lebih lanjut.";
"onboarding.tour.faq_hint" = "**Soalan?** Saya sarankan untuk anda tahu tentang [README](https://github.com/nicoverbruggen/phpmon/blob/main/README.md): ia memuatkan FAQ lengkap dengan beberapa tips yang sering dijumpai dan jawapan soalan-soalan biasa.";
"onboarding.tour.services.title" = "Kendalikan Servis Homebrew";
"onboarding.tour.services" = "Setelah Anda klik menu bar, Anda dapat melihat secara cepat berdasarkan penanda atau tanda jijik jika semua servis Homebrew berjalan dengan normal. Anda juga dapat mengklik pada servis untuk segera menyalakan dan mematikan";
"onboarding.tour.domains.title" = "Kendalikan Domains";
"onboarding.tour.domains" = "Melalui menu bar, Anda dapat melihat domain mana yang terhubung dan parkir, serta proxy nginx yang aktif.";
"onboarding.tour.isolation.title" = "Isolasi Domains";
"onboarding.tour.isolation" = "Jika Anda memiliki Valet 3 atau lebih baru diinstal, Anda juga bisa menggunakan isolasi domain dengan memilih pada domino di dalam jendela Domain. Ini mengizinkan Anda untuk memilih versi PHP yang spesifik untuk domain ini dan hanya ini.";
"onboarding.tour.feature_unavailable" = "Fitur ini saat ini tidak tersedia dan memerlukan Laravel Valet terpasang.";
"onboarding.tour.once" = "Anda akan melihat tur selamat datang hanya sekali. Anda dapat membukanya kembali dengan mengeklik icon menu bar (dapat diakses dalam menu, bawah Pertolongan & Servis).";
"onboarding.tour.close" = "Tutup Tur";
// LANGUAGE CHOICE
"prefs.language" = "Bahasa:";
"prefs.language_options_desc" = "Pilih bahasa yang berbeda untuk digunakan dengan PHP Monitor. Untuk penuh, Anda perlu mengeksekusi ulang aplikasi.";
"alert.language_changed.title" = "Anda harus restart PHP Monitor!";
"alert.language_changed.subtitle" = "Anda baru-baru ini mengubah bahasa penampilan dari PHP Monitor. Menu akan segera menggunakan bahasa yang benar, tapi mungkin Anda memerlukan mengeksekusi ulang aplikasi untuk semua teks melalui aplikasi untuk terlihat bahasa yang baru pilih.";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "Biarkan tidak diabaikan";
"startup.timeout.title" = "PHP Monitor membutuhkan waktu yang lama untuk dimulai!";
"startup.timeout.subtitle" = "Jika PHP Monitor tetap sibuk selama lebih dari 30 detik, mungkin ada masalah dengan pengaturan Homebrew Anda.";
"startup.timeout.description" = "kadang-kadang, disebabkan oleh berbagai isu izin file, hal itu dapat rusak. Anda bisa mencoba menggunakan `brew doctor` dan `brew cleanup` untuk memperbaiki ini.
Dianjurkan untuk merestart PHP Monitor setelahnya. Beli tahu lebih lanjut tentang masalah ini di: https://github.com/nicoverbruggen/phpmon/issues/294.
Jika PHP Monitor telah selesai dimulai atau Anda ingin menunggu sebentar lagi, tidak perlu khawatir dan klik 'Biarkan tidak diabaikan' dan gunakan PHP Monitor secara khusus. Tentu saja, cara yang satu pun mungkin perlu untuk dicek, karena ini bukanlah waktu yang dibutuhkan ini.";

View File

@ -123,8 +123,10 @@ en PHP Monitor herstarten om de extensies zichtbaar te maken. Als het probleem z
"phpman.version.broken" = "Deze versie lijkt kapot te zijn, u kan proberen herstellen.";
"phpman.version.has_update" = "Versie %@ geïnstalleerd, %@ beschikbaar.";
"phpman.version.installed" = "Versie %@ is momenteel geïnstalleerd.";
"phpman.version.unavailable" = "Deze versie is tijdelijk niet beschikbaar.";
"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.version.automatic_upgrade" = "Deze versie wordt automatisch geïnstalleerd door een oudere versie te upgraden.
(Zowel deze nieuwe versie als de oude versie zullen beschikbaar zijn na de upgrade.)";
"phpman.buttons.uninstall" = "Verwijderen";
"phpman.buttons.install" = "Installeren";
"phpman.buttons.update" = "Bijwerken";
@ -302,6 +304,8 @@ Tijdens het verwijderingsproces kan u worden gevraagd om uw wachtwoord indien de
"domain_list.always_use_php" = "Altijd PHP %@ gebruiken";
"domain_list.isolation_unavailable" = "Isolatie wordt niet ondersteund (in Valet 2)";
"domain_list.favorite" = "Markeren als favoriet";
"domain_list.unfavorite" = "Verwijderen uit favorieten";
"domain_list.actions" = "Acties";
"domain_list.unlink" = "Link verwijderen";
"domain_list.secure" = "Domein beveiligen";
@ -617,38 +621,38 @@ U kunt dit doen door `composer global update` uit te voeren in uw terminal. Voer
// STARTUP
/// Architecture mismatch
// Architecture mismatch
"alert.homebrew_missing.title" = "PHP Monitor kan niet starten!";
"alert.homebrew_missing.subtitle" = "Er kon geen werkende Homebrew-binair worden gevonden op de gebruikelijke locatie. Start de app opnieuw nadat u dit probleem hebt verholpen.";
"alert.homebrew_missing.info" = "U gebruikt PHP Monitor met de volgende architectuur: %@. Hierdoor wordt verwacht dat er een werkende Homebrew binary gevonden wordt in `%@`, maar deze is niet gevonden. Daarom kan PHP Monitor niet werken.\n\nAls u Homebrew nog niet hebt geïnstalleerd, doe dit dan nu. Als u gebruikmaakt van Apple Silicon, zorg er dan voor dat uw Homebrew en PHP Monitor dezelfde architectuur gebruiken door Rosetta in of uit te schakelen waar nodig.";
"alert.homebrew_missing.quit" = "Afsluiten";
/// PHP binary not found
// PHP binary not found
"startup.errors.php_binary.title" = "PHP is niet correct geïnstalleerd";
"startup.errors.php_binary.subtitle" = "U moet PHP installeren via Homebrew. De app werkt niet correct totdat u dit probleem oplost.";
"startup.errors.php_binary.desc" = "Meestal lost u dit probleem op door `brew link php` uit te voeren in uw Terminal.\n\nOm te achterhalen wat er mis is, kunt u proberen `which php` uit te voeren in uw Terminal. Het zou `%@` moeten retourneren.";
/// PHP not found in /usr/local/opt or /opt/homebrew/opt
// PHP not found in /usr/local/opt or /opt/homebrew/opt
"startup.errors.php_opt.title" = "PHP is niet correct geïnstalleerd";
"startup.errors.php_opt.subtitle" = "De PHP-alias is niet gevonden in `%@`. De app werkt niet correct totdat u dit probleem oplost.";
"startup.errors.php_opt.desc" = "Als u de `php` formule al hebt geïnstalleerd, moet u mogelijk `brew install php` uitvoeren zodat PHP Monitor deze installatie kan detecteren.";
/// PHP binary is broken
// PHP binary is broken
"startup.errors.dyld_library.title" = "PHP is geïnstalleerd, maar lijkt defect te zijn";
"startup.errors.dyld_library.subtitle" = "Bij het uitvoeren van opdrachten slaagt PHP Monitor er niet in om dit correct te doen. Dit is meestal een indicatie van een defecte PHP-installatie.";
"startup.errors.dyld_library.desc" = "Het opnieuw installeren van PHP met `brew reinstall php && brew link php` in uw Terminal kan dit probleem verhelpen, dus probeer dat eens.";
/// Valet is not installed
// Valet is not installed
"startup.errors.valet_executable.title" = "Laravel Valet is niet correct geïnstalleerd";
"startup.errors.valet_executable.subtitle" = "U moet Valet installeren met Composer. De app werkt niet correct totdat u dit probleem oplost.";
"startup.errors.valet_executable.desc" = "Als u Laravel Valet nog niet hebt geïnstalleerd, doe dit dan eerst. Als u het al hebt geïnstalleerd maar toch dit bericht ziet, probeer dan `which valet` uit te voeren in Terminal. Het zou `%@` moeten retourneren.";
/// Valet configuration file missing or broken
// Valet configuration file missing or broken
"startup.errors.valet_json_invalid.title" = "Laravel Valet configuratiebestand ongeldig of ontbreekt";
"startup.errors.valet_json_invalid.subtitle" = "PHP Monitor moet in staat zijn om het configuratiebestand te lezen. Het lijkt erop dat het bestand onjuist is opgemaakt of ontbreekt. Controleer of het bestaat en correct is opgemaakt.";
"startup.errors.valet_json_invalid.desc" = "U kunt het bestand vinden op `~/.config/valet/config.json`. Als Laravel Valet het configuratiebestand niet kan parsen, zal het uitvoeren van een `valet`-opdracht meestal automatisch het JSON-bestand herstellen. Probeer `valet --version` uit te voeren om het bestand automatisch te herstellen.";
/// Valet version not readable
// Valet version not readable
"startup.errors.valet_version_unknown.title" = "Kan uw Valet-versie niet lezen";
"startup.errors.valet_version_unknown.subtitle" = "Het parsen van de uitvoer van `valet --version` is mislukt. Zorg ervoor dat uw Valet-installatie werkt en up-to-date is.";
"startup.errors.valet_version_unknown.desc" = "Probeer `valet --version` uit te voeren in een terminal om erachter te komen wat er aan de hand is.";
@ -664,32 +668,32 @@ Als u dit bericht ziet, maar verward bent waarom deze map ontbreekt, wilt u moge
"startup.errors.valet_version_not_supported.subtitle" = "U gebruikt een versie van Valet die momenteel niet wordt ondersteund. PHP Monitor werkt momenteel met Valet v2, v3 en v4. Om problemen op uw systeem te voorkomen, kan PHP Monitor niet starten.";
"startup.errors.valet_version_not_supported.desc" = "U moet een versie van Valet installeren die compatibel is met PHP Monitor, of u moet mogelijk upgraden naar een nieuwere versie van PHP Monitor die compatibiliteit biedt met deze versie van Valet (raadpleeg de nieuwste release-opmerkingen voor meer informatie).";
/// Brew & sudoers
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew is niet toegevoegd aan sudoers.d";
"startup.errors.sudoers_brew.subtitle" = "U moet `sudo valet trust` uitvoeren om ervoor te zorgen dat Valet services kan starten en stoppen zonder telkens sudo te hoeven gebruiken. De app werkt niet correct totdat u dit probleem oplost.";
"startup.errors.sudoers_brew.desc" = "Als u deze fout blijft zien, is het mogelijk dat er een machtigingsprobleem is waarbij PHP Monitor het bestand niet kan valideren. Dit kan meestal worden opgelost door `sudo chmod +r /private/etc/sudoers.d/brew` uit te voeren";
/// Valet & sudoers
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Valet is niet toegevoegd aan sudoers.d";
"startup.errors.sudoers_valet.subtitle" = "U moet `sudo valet trust` uitvoeren om ervoor te zorgen dat Valet services kan starten en stoppen zonder telkens sudo te hoeven gebruiken. De app werkt niet correct totdat u dit probleem oplost. Als u dit al eerder hebt gedaan, voer dan `sudo valet trust` opnieuw uit.";
"startup.errors.sudoers_valet.desc" = "Als u deze fout blijft zien, is het mogelijk dat er een machtigingsprobleem is waarbij PHP Monitor het bestand niet kan valideren. Dit kan meestal worden opgelost door `sudo chmod +r /private/etc/sudoers.d/valet` uit te voeren";
/// Platform issue detected
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor en Valet kunnen niet correct werken: Composer meldt een probleem met uw platform";
"startup.errors.global_composer_platform_issues.subtitle" = "Volg deze aanbevolen stappen om dit probleem in de toekomst te voorkomen:\n\n1. Voer `composer global update` uit.\n2. Start PHP Monitor opnieuw op. (Het zou weer moeten werken.)\n3. Schakel over naar de oudste geïnstalleerde versie van PHP.\n4. Voer opnieuw `composer global update` uit.";
"startup.errors.global_composer_platform_issues.desc" = "U kunt naar Voorkeuren gaan en de optie 'Automatisch globale afhankelijkheden bijwerken' controleren. Hiermee worden uw globale Composer-afhankelijkheden bijgewerkt wanneer u PHP-versies wijzigt, dus dit is mogelijk niet ideaal als u mogelijk geen constante toegang tot internet heeft.\n\nOm erachter te komen wat er precies misgaat, probeer `valet --version` uit te voeren. Valet is momenteel niet functioneel met de geïnstalleerde afhankelijkheden. Dit wordt meestal veroorzaakt door een versieverschil: bijvoorbeeld geïnstalleerde afhankelijkheden voor een nieuwere versie van PHP dan de momenteel actieve versie.";
/// Cannot retrieve services
// Cannot retrieve services
"startup.errors.services_json_error.title" = "Kan de status van services niet bepalen";
"startup.errors.services_json_error.subtitle" = "PHP Monitor maakt meestal gebruik van de volgende opdracht om `brew` te raadplegen en te controleren of de services kunnen worden opgehaald: `sudo brew services info nginx --json`.\n\nPHP Monitor kon deze reactie niet interpreteren.";
"startup.errors.services_json_error.desc" = "Dit kan gebeuren als uw Homebrew-installatie verouderd is, waardoor Homebrew nog geen JSON retourneert. U kunt dit meestal oplossen door `brew update` of `brew tap homebrew/services` uit te voeren. U kunt ook proberen `sudo brew services info nginx --json` uit te voeren in uw terminal naar keuze.";
/// Issue with `which` alias
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "Er is een configuratieprobleem gedetecteerd";
"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
// 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.";
@ -832,3 +836,14 @@ Houd er rekening mee dat sommige functies (hieronder grijs weergegeven) momentee
"alert.language_changed.title" = "U moet PHP Monitor herstarten!";
"alert.language_changed.subtitle" = "U heeft zojuist de weergavetaal van PHP Monitor gewijzigd. Het menu zal onmiddellijk de juiste taal gebruiken, maar u moet mogelijk de app herstarten om overal de nieuwe taal te zien.";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "Negeren";
"startup.timeout.title" = "PHP Monitor doet er te lang over om te initialiseren!";
"startup.timeout.subtitle" = "Als PHP Monitor langer dan 30 seconden bezig blijft, kan er iets mis zijn met je Homebrew-installatie.";
"startup.timeout.description" = "Soms kunnen dingen misgaan door problemen met bestandstoestemmingen. Je kunt proberen `brew doctor` en `brew cleanup` te gebruiken om dit te verhelpen.
Het wordt aanbevolen om daarna PHP Monitor opnieuw te starten. Lees meer over dit probleem op: https://github.com/nicoverbruggen/phpmon/issues/294.
Als PHP Monitor toch is geïnitialiseerd of als je nog even wilt wachten, klik dan op 'Negeren' en gebruik PHP Monitor zoals gewoonlijk. Hoe dan ook, het is verstandig om dit te onderzoeken, want dit zou niet zo lang moeten duren.";

View File

@ -122,8 +122,10 @@ e reiniciar o PHP Monitor para que as extensões se tornem visíveis. Se o probl
"phpman.version.broken" = "Esta versão parece estar danificada, você pode tentar repara-la.";
"phpman.version.has_update" = "Versão %@ instalada, %@ disponível.";
"phpman.version.installed" = "Versão %@ atualmente instalada.";
"phpman.version.unavailable" = "Esta versão está temporariamente indisponível.";
"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.version.automatic_upgrade" = "Esta versão será instalada automaticamente ao atualizar a partir de uma versão mais antiga.
(Tanto esta nova versão como a versão antiga estarão disponíveis após a atualização.)";
"phpman.buttons.uninstall" = "Desinstalar";
"phpman.buttons.install" = "Instalar";
"phpman.buttons.update" = "Atualizar";
@ -302,6 +304,8 @@ Poderá ser-lhe solicitada a sua palavra-passe durante o processo de desinstala
"domain_list.always_use_php" = "Usar sempre PHP %@";
"domain_list.isolation_unavailable" = "Isolamento não suportado (no Laravel Valet 2)";
"domain_list.favorite" = "Marcar como favorito";
"domain_list.unfavorite" = "Desmarcar do favoritado";
"domain_list.actions" = "Ações";
"domain_list.unlink" = "Desvincular diretoria";
"domain_list.secure" = "Domínio seguro";
@ -616,7 +620,7 @@ Pode faze-lo executando `composer global update` no seu Terminal. Depois disso,
// STARTUP
/// 0. Architecture mismatch
// 0. Architecture mismatch
"alert.homebrew_missing.title" = "PHP Monitor não pode iniciar!";
"alert.homebrew_missing.subtitle" = "Não foi encontrado um executável do Homebrew da diretoria por defeito. Reinicie a aplicação depois de corrigir o problema.";
@ -624,32 +628,32 @@ Pode faze-lo executando `composer global update` no seu Terminal. Depois disso,
"alert.homebrew_missing.quit" = "Sair";
/// PHP binary not found
// PHP binary not found
"startup.errors.php_binary.title" = "O PHP não está instalado corretamente";
"startup.errors.php_binary.subtitle" = "Deve instalar o PHP através do Homebrew. Esta aplicação não funcionará corretamente até que resolva este problema.";
"startup.errors.php_binary.desc" = "Normalmente, executar `brew link php` no seu Terminal resolve este problema.\n\nPara diagnosticar o que está errado, pode tentar executar `which php` no seu Terminal, que deverá mostrar `%@`.";
/// PHP not found in /usr/local/opt or /opt/homebrew/opt
// PHP not found in /usr/local/opt or /opt/homebrew/opt
"startup.errors.php_opt.title" = "O PHP não está instalado corretamente";
"startup.errors.php_opt.subtitle" = "O alias do PHP não foi encontrado em `%@`. Esta aplicação não funcionará corretamente até que resolva este problema.";
"startup.errors.php_opt.desc" = "Se já possui a fórmula `php` instalada, pode ser necessário executar `brew install php` para que o PHP Monitor detecte a instalação.";
/// PHP binary is broken
// PHP binary is broken
"startup.errors.dyld_library.title" = "O PHP está instalado, mas parece estar incorretamente instalado";
"startup.errors.dyld_library.subtitle" = "Quando o PHP Monitor tenta executar comandos, falha. Isto geralmente é um indicador de uma instalação do PHP incorretamente instalado.";
"startup.errors.dyld_library.desc" = "Executar `brew reinstall php && brew link php` no seu Terminal pode resolver este problema, pelo que deve tentar executar este comando.";
/// Valet is not installed
// Valet is not installed
"startup.errors.valet_executable.title" = "Laravel Valet não está instalado corretamente";
"startup.errors.valet_executable.subtitle" = "Deve instalar o Laravel Valet com o Composer. Esta aplicação não funcionará corretamente até que resolva este problema.";
"startup.errors.valet_executable.desc" = "Se ainda não instalou o Laravel Valet, faça-o agora. Se já instalou, tente executar `which valet` no seu Terminal, que deverá mostrar: `%@`.";
/// Valet configuration file missing or broken
// Valet configuration file missing or broken
"startup.errors.valet_json_invalid.title" = "ficheiro de configuração Laravel Valet inválido ou inexistente";
"startup.errors.valet_json_invalid.subtitle" = "O PHP Monitor precisa de ler o ficheiro de configuração. Parece que o ficheiro está malformado ou inexistente. Por favor, verifique se o ficheiro existe e se está formatado corretamente.";
"startup.errors.valet_json_invalid.desc" = "Pode encontrar o ficheiro em `~/.config/valet/config.json`. Se o Laravel Valet não puder analisar o ficheiro de configuração, execute um comando `valet` qualquer que geralmente corrigirá automaticamente o ficheiro JSON. Tente executar `valet --version` para corrigir automaticamente o ficheiro.";
/// Valet version not readable
// Valet version not readable
"startup.errors.valet_version_unknown.title" = "A versão Laravel Valet não pôde ser obtida";
"startup.errors.valet_version_unknown.subtitle" = "A análise do output de `valet --version` falhou. Certifique-se de que a instalação do Laravel Valet funciona e está atualizada.";
"startup.errors.valet_version_unknown.desc" = "Tente executar `valet --version` no seu Terminal para descobrir o motivo do problema.";
@ -665,27 +669,27 @@ Se ainda vê esta mensagem, e não percebe porque a diretoria desapareceu, conv
"startup.errors.valet_version_not_supported.subtitle" = "Está a executar uma versão do Laravel Valet que não é compatível de momento. O PHP Monitor atualmente funciona apenas com Laravel Valet v2, v3 e v4. Para evitar problemas no seu sistema, o PHP Monitor não pode ser iniciado.";
"startup.errors.valet_version_not_supported.desc" = "Deve instalar uma versão do Laravel Valet que seja compatível com o PHP Monitor, ou pode ser necessário atualizar para uma versão mais recente do PHP Monitor que pode incluir compatibilidade para esta versão do Laravel Valet (consulte as notas de versão mais recentes para obter mais informações).";
/// Brew & sudoers
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew não foi adicionado a sudoers.d";
"startup.errors.sudoers_brew.subtitle" = "Deve executar `sudo valet trust` no seu Terminal para garantir que o Laravel Valet pode iniciar e parar os serviços sem ter que usar sempre o sudo. Esta aplicação não funcionará corretamente até que resolva este problema.";
"startup.errors.sudoers_brew.desc" = "Se continuar a ver este erro, é possível que haja um problema de permissão em que o PHP Monitor não pode validar o ficheiro, o que normalmente pode ser resolvido executando no seu Terminal: `sudo chmod +r /private/etc/sudoers.d/brew`";
/// Valet & sudoers
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Laravel Valet não foi adicionado a sudoers.d";
"startup.errors.sudoers_valet.subtitle" = "Você deve executar `sudo valet trust` para garantir que o Laravel Valet possa iniciar e parar os serviços sem ter que usar o sudo todas as vezes. Esta aplicação não funcionará corretamente até que você resolva este problema. Mesmo que já tenha feito isto antes, experimente executar novamente no seu Terminal `sudo valet trust`.";
"startup.errors.sudoers_valet.desc" = "Se continuar a ver este erro, é possível que haja um problema de permissão em que o PHP Monitor não pode validar o ficheiro, que normalmente pode ser resolvido executando no seu Terminal: `sudo chmod +r /private/etc/sudoers.d/valet`";
/// Platform issue detected
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "O PHP Monitor e o Laravel Valet não funcionam corretamente: o Composer reporta um problema com sua plataforma";
"startup.errors.global_composer_platform_issues.subtitle" = "Siga estes passos recomendados para evitar este problema de futuro:\n\n1. Execute a `atualização global do compositor`.\n2. Reinicie o PHP Monitor. (Deve funcionar novamente.)\n3. Mude para a versão mais antiga do PHP que instalou.\n4. Execute a `atualização global do compositor` novamente.";
"startup.errors.global_composer_platform_issues.desc" = "Pode ir a Preferências e marcar a opção 'Atualizar dependências globais automaticamente'. Isto atualizará as suas dependências globais do Composer sempre que alterar versões do PHP, portanto, no entanto, pode não ser a solução ideal se não tiver acesso à Internet.\n\nPara descobrir exatamente o que está errado, tente executar no seu Terminal `valet --version`. O Laravel Valet não está a funcionar com as dependências instaladas. Normalmente, isso é provocado por uma incompatibilidade de versão: ou seja, dependências instaladas para uma versão mais recente do PHP do que a versão que está vinculada no momento.";
/// Cannot retrieve services
// Cannot retrieve services
"startup.errors.services_json_error.title" = "Não é possível determinar o status dos serviços";
"startup.errors.services_json_error.subtitle" = "O PHP Monitor geralmente usar o `brew` usando o seguinte comando para testar se os serviços podem ser recuperados: `sudo brew services info nginx --json`.\n\nO PHP Monitor não pôde interpretar a resposta do `brew`.";
"startup.errors.services_json_error.desc" = "Isto pode acontecer se a instalação do Homebrew estiver desatualizada, e o Homebrew ainda não retornar JSON. Geralmente, pode corrigir isto executando no seu Terminal `brew update` ou `brew tap homebrew/services`. Também pode tentar executar no seu Terminal `sudo brew services info nginx --json`.";
/// Issue with `which` alias
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "Foi detectado um problema de configuração";
"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";
@ -830,3 +834,14 @@ Tenha em conta que algumas funcionalidades (esmaecidos abaixo) estão indisponí
"alert.language_changed.title" = "Deve reiniciar o PHP Monitor!";
"alert.language_changed.subtitle" = "Acabou de mudar o idioma de exibição do PHP Monitor. O menu usará imediatamente a língua correta, mas pode ser necessário reiniciar a aplicação para que todo o texto na aplicação reflita a sua nova escolha de idioma.";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "Ignorar";
"startup.timeout.title" = "O PHP Monitor está a demorar demasiado tempo a inicializar!";
"startup.timeout.subtitle" = "Se o PHP Monitor continuar ocupado por mais de 30 segundos, poderá haver um problema com a sua configuração do Homebrew.";
"startup.timeout.description" = "Por vezes, devido a problemas com permissões de ficheiros, as coisas podem correr mal. Pode tentar utilizar `brew doctor` e `brew cleanup` para resolver a situação.
Recomenda-se reiniciar o PHP Monitor depois disso. Saiba mais sobre este problema em: https://github.com/nicoverbruggen/phpmon/issues/294.
Se o PHP Monitor já tiver inicializado ou se quiser esperar um pouco mais, pode clicar em 'Ignorar' e continuar a usar o PHP Monitor normalmente. De qualquer forma, é aconselhável investigar, pois isto não deveria demorar tanto tempo.";

View File

@ -122,8 +122,10 @@ và khởi động lại PHP Monitor để các tiện ích mở rộng trở n
"phpman.version.broken" = "Phiên bản này có vẻ đã bị hỏng, bạn có thể thử sửa chữa.";
"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.unavailable" = "Phiên bản này tạm thời không khả dụng.";
"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.version.automatic_upgrade" = "Phiên bản này sẽ được cài đặt tự động khi nâng cấp từ phiên bản cũ hơn.
(Cả phiên bản mới này và phiên bản cũ đều sẽ có sẵn sau khi nâng cấp.)";
"phpman.buttons.uninstall" = "Gỡ cài đặt";
"phpman.buttons.install" = "Cài đặt";
"phpman.buttons.update" = "Cập nhật";
@ -292,6 +294,8 @@ Bạn có thể được yêu cầu nhập mật khẩu của mình trong quá t
"domain_list.always_use_php" = "Luôn sử dụng PHP %@";
"domain_list.isolation_unavailable" = "Không hỗ trợ cô lập (trong Valet 2)";
"domain_list.favorite" = "Điểm yêu thích";
"domain_list.unfavorite" = "Bỏ khỏi điểm yêu thích";
"domain_list.actions" = "Hành động";
"domain_list.unlink" = "Hủy liên kết Thư mục";
"domain_list.secure" = "Bảo mật Tên miền";
@ -609,7 +613,7 @@ Bạn có thể làm điều này bằng cách chạy `composer global update` t
// STARTUP
/// 0. Architecture mismatch
// 0. Architecture mismatch
"alert.homebrew_missing.title" = "PHP Monitor không thể khởi động!";
"alert.homebrew_missing.subtitle" = "Không tìm thấy binary Homebrew hoạt động ở vị trí thông thường. Vui lòng khởi động lại ứng dụng sau khi khắc phục vấn đề này.";
@ -617,32 +621,32 @@ Bạn có thể làm điều này bằng cách chạy `composer global update` t
"alert.homebrew_missing.quit" = "Thoát";
/// PHP binary not found
// PHP binary not found
"startup.errors.php_binary.title" = "PHP chưa được cài đặt đúng cách";
"startup.errors.php_binary.subtitle" = "Bạn phải cài đặt PHP qua Homebrew. Ứng dụng sẽ không hoạt động chính xác cho đến khi bạn giải quyết vấn đề này.";
"startup.errors.php_binary.desc" = "Thường thì chạy `brew link php` trong Terminal của bạn sẽ giải quyết vấn đề này.\n\nĐể chẩn đoán lỗi, bạn có thể thử chạy `which php` trong Terminal của bạn, nó sẽ trả về `%@`.";
/// PHP not found in /usr/local/opt or /opt/homebrew/opt
// PHP not found in /usr/local/opt or /opt/homebrew/opt
"startup.errors.php_opt.title" = "PHP chưa được cài đặt đúng cách";
"startup.errors.php_opt.subtitle" = "Bí danh PHP không được tìm thấy ở `%@`. Ứng dụng sẽ không hoạt động chính xác cho đến khi bạn giải quyết vấn đề này.";
"startup.errors.php_opt.desc" = "Nếu bạn đã cài đặt công thức `php`, bạn có thể cần chạy `brew install php` để PHP Monitor nhận ra cài đặt này.";
/// PHP binary is broken
// PHP binary is broken
"startup.errors.dyld_library.title" = "PHP đã được cài đặt, nhưng có vẻ bị lỗi";
"startup.errors.dyld_library.subtitle" = "Khi PHP Monitor cố gắng chạy các lệnh, nó không thể chạy chúng chính xác. Điều này thường là một dấu hiệu của một cài đặt PHP bị lỗi.";
"startup.errors.dyld_library.desc" = "Chạy `brew reinstall php && brew link php` trong Terminal của bạn có thể giải quyết vấn đề này, vì vậy hãy thử điều đó.";
/// Valet is not installed
// Valet is not installed
"startup.errors.valet_executable.title" = "Laravel Valet chưa được cài đặt đúng cách";
"startup.errors.valet_executable.subtitle" = "Bạn phải cài đặt Valet với Composer. Ứng dụng sẽ không hoạt động chính xác cho đến khi bạn giải quyết vấn đề này.";
"startup.errors.valet_executable.desc" = "Nếu bạn chưa cài đặt Laravel Valet, hãy cài đặt trước. Nếu bạn đã cài đặt, nhưng vẫn nhìn thấy thông báo này, thì hãy thử chạy `which valet` trong Terminal, nó sẽ trả về: `%@`.";
/// Valet configuration file missing or broken
// Valet configuration file missing or broken
"startup.errors.valet_json_invalid.title" = "Tệp cấu hình Laravel Valet không hợp lệ hoặc bị thiếu";
"startup.errors.valet_json_invalid.subtitle" = "PHP Monitor cần có thể đọc tệp cấu hình. Dường như tệp đã bị lỗi hoặc bị thiếu. Vui lòng kiểm tra xem nó tồn tại và được định dạng đúng.";
"startup.errors.valet_json_invalid.desc" = "Bạn có thể tìm thấy tệp tại `~/.config/valet/config.json`. Nếu Laravel Valet không thể phân tích cú pháp tệp cấu hình, chạy bất kỳ lệnh `valet` nào thường sẽ tự động sửa tệp JSON. Thử chạy `valet -- version` để tự động sửa file.";
/// Valet version not readable
// Valet version not readable
"startup.errors.valet_version_unknown.title" = "Phiên bản Valet của bạn không thể đọc được";
"startup.errors.valet_version_unknown.subtitle" = "Phân tích kết quả của `valet --version` đã thất bại. Hãy đảm bảo cài đặt Valet của bạn hoạt động và được cập nhật.";
"startup.errors.valet_version_unknown.desc" = "Thử chạy `valet --version` trong terminal để tìm hiểu điều gì đang xảy ra.";
@ -658,32 +662,32 @@ 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.valet_version_not_supported.subtitle" = "Bạn đang chạy một phiên bản của Valet hiện không được hỗ trợ. PHP Monitor hiện tại hoạt động với Valet v2, v3 và v4. Để tránh gây ra sự cố trên hệ thống của bạn, PHP Monitor không thể khởi động.";
"startup.errors.valet_version_not_supported.desc" = "Bạn phải cài đặt một phiên bản của Valet tương thích với PHP Monitor, hoặc bạn có thể cần nâng cấp lên phiên bản mới hơn của PHP Monitor có thể bao gồm tính năng tương thích cho phiên bản này của Valet (xem thông tin chi tiết về các bản phát hành mới nhất để biết thêm thông tin).";
/// Brew & sudoers
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew chưa được thêm vào sudoers.d";
"startup.errors.sudoers_brew.subtitle" = "Bạn phải chạy lệnh `sudo valet trust` để đảm bảo Valet có thể bắt đầu và dừng dịch vụ mà không cần phải sử dụng sudo mỗi lần. Ứng dụng sẽ không hoạt động chính xác cho đến khi bạn giải quyết vấn đề này.";
"startup.errors.sudoers_brew.desc" = "Nếu bạn tiếp tục nhìn thấy lỗi này, có thể có vấn đề về quyền truy cập mà PHP Monitor không thể xác minh tệp, điều này thường có thể giải quyết bằng cách chạy: `sudo chmod +r /private/etc/sudoers.d/brew`";
/// Valet & sudoers
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Valet chưa được thêm vào sudoers.d";
"startup.errors.sudoers_valet.subtitle" = "Bạn phải chạy lệnh `sudo valet trust` để đảm bảo Valet có thể bắt đầu và dừng dịch vụ mà không cần phải sử dụng sudo mỗi lần. Ứng dụng sẽ không hoạt động chính xác cho đến khi bạn giải quyết vấn đề này. Nếu bạn đã làm điều này trước đó, hãy chạy lại lệnh `sudo valet trust`.";
"startup.errors.sudoers_valet.desc" = "Nếu bạn tiếp tục nhìn thấy lỗi này, có thể có vấn đề về quyền truy cập mà PHP Monitor không thể xác minh tệp, điều này thường có thể giải quyết bằng cách chạy: `sudo chmod +r /private/etc/sudoers.d/valet`";
/// Platform issue detected
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor và Valet không thể hoạt động chính xác: Composer báo cáo vấn đề với nền tảng của bạn";
"startup.errors.global_composer_platform_issues.subtitle" = "Vui lòng làm theo những bước khuyến nghị sau để tránh gặp vấn đề này trong tương lai:\n\n1. Chạy lệnh `composer global update`.\n2. Khởi động lại PHP Monitor. (Nó sẽ hoạt động lại).\n3. Chuyển sang phiên bản PHP cũ nhất mà bạn đã cài đặt.\n4. Chạy lại lệnh `composer global update`.";
"startup.errors.global_composer_platform_issues.desc" = "Bạn có thể vào Tùy chọn và kiểm tra tùy chọn 'Tự động cập nhật các phụ thuộc toàn cầu'. Điều này sẽ cập nhật các phụ thuộc Composer toàn cầu của bạn mỗi khi bạn thay đổi phiên bản PHP, vì vậy điều này có thể không lý tưởng nếu bạn không có quyền truy cập internet liên tục.\n\nĐể biết chính xác điều gì đang sai, hãy thử chạy `valet --version`. Hiện tại, Valet không hoạt động với các phụ thuộc đã cài đặt. Thông thường điều này được gây ra bởi sự không phù hợp của phiên bản: ví dụ như các phụ thuộc đã cài đặt cho một phiên bản PHP mới hơn phiên bản hiện tại đang hoạt động.";
/// Cannot retrieve services
// Cannot retrieve services
"startup.errors.services_json_error.title" = "Không thể xác định trạng thái dịch vụ";
"startup.errors.services_json_error.subtitle" = "PHP Monitor thường sử dụng lệnh sau để kiểm tra liệu các dịch vụ có thể được truy xuất hay không: `sudo brew services info nginx --json`.\n\nPHP Monitor không thể giải thích được câu trả lời này.";
"startup.errors.services_json_error.desc" = "Điều này có thể xảy ra nếu cài đặt Homebrew của bạn đã lỗi thời, trong trường hợp đó Homebrew sẽ không trở lại JSON. Bạn có thể khắc phục điều này bằng cách chạy `brew update` hoặc `brew tap homebrew/services`. Bạn cũng có thể thử chạy `sudo brew services info nginx --json` trong bất kỳ terminal nào bạn muốn.";
/// Issue with `which` alias
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "Phát hiện vấn đề cấu hình";
"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
// 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.";
@ -826,3 +830,14 @@ Vui lòng lưu ý rằng một số tính năng (xám bên dưới) hiện khôn
"alert.language_changed.title" = "Bạn nên khởi động lại PHP Monitor!";
"alert.language_changed.subtitle" = "Bạn vừa thay đổi ngôn ngữ hiển thị của PHP Monitor. Menu sẽ ngay lập tức sử dụng ngôn ngữ đúng, nhưng bạn có thể cần phải khởi động lại ứng dụng để toàn bộ văn bản trong ứng dụng phản ánh sự lựa chọn ngôn ngữ mới của bạn.";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "Bỏ qua";
"startup.timeout.title" = "PHP Monitor đang mất quá nhiều thời gian để khởi tạo!";
"startup.timeout.subtitle" = "Nếu PHP Monitor vẫn bận hơn 30 giây, có thể có vấn đề với thiết lập Homebrew của bạn.";
"startup.timeout.description" = "Đôi khi, do các vấn đề về quyền tệp, mọi thứ có thể bị lỗi. Bạn có thể thử sử dụng `brew doctor` và `brew cleanup` để khắc phục.
Bạn nên khởi động lại PHP Monitor sau đó. Tìm hiểu thêm về vấn đề này tại: https://github.com/nicoverbruggen/phpmon/issues/294.
Nếu PHP Monitor đã hoàn tất khởi tạo hoặc bạn muốn chờ thêm một chút, hãy nhấn 'Bỏ qua' và sử dụng PHP Monitor như bình thường. Dù thế nào, bạn cũng nên kiểm tra vì quá trình này không nên mất quá nhiều thời gian.";

View File

@ -1,4 +1,4 @@
// 菜单项(MI)
// MENU ITEMS (MI)
"mi_busy" = "PHP Monitor 正忙着...";
"mi_unsure" = "我们不确定您正在运行的 PHP 版本";
@ -137,8 +137,10 @@
"phpman.version.broken" = "此版本似乎已损坏,您可以尝试修复";
"phpman.version.has_update" = "已安装 %@ 版本,%@ 可用";
"phpman.version.installed" = "当前已安装 %@ 版本";
"phpman.version.unavailable" = "此版本暂时不可用。";
"phpman.version.available_for_installation" = "此版本可以安装";
"phpman.version.automatic_upgrade" = "此版本将通过升级旧版本自动安装";
"phpman.version.automatic_upgrade" = "此版本将升级旧版本自动安装
(升级后,新旧两个版本都将可用。)";
"phpman.buttons.uninstall" = "卸载";
"phpman.buttons.install" = "安装";
"phpman.buttons.update" = "更新";
@ -211,32 +213,32 @@
"phpman.services.inactive" = "关键服务未运行";
"phpman.services.all_ok" = "所有 Valet 服务均正常";
// 精简模式
// LITE MODE
"lite_mode_explanation.title" = "您当前正以独立模式运行 PHP Monitor";
"lite_mode_explanation.subtitle" = "PHP Monitor 有一些附加功能,如果你恰好是 Laravel Valet 的用户就可以使用这些功能。目前PHP Monitor 无法检测到您的系统中正在安装 Valet因此这些功能不可用。";
"lite_mode_explanation.description" = "如需了解更多信息,我建议查看 README(可在 GitHub 上获取),其中将解释安装 Valet 所需的步骤,以及如何使 PHP Monitor 在安装 Valet 后正常运行。安装 Laravel Valet 后,需要重启 PHP Monitor它才会脱离独立模式";
// 通用
// GENERIC
"generic.ok" = "确定";
"generic.cancel" = "取消";
"generic.retry" = "重试";
"generic.notice" = "通知";
// 加载预设
// PRESET LOADING
"preset_help_title" = "使用配置预设";
"preset_help_info" = "您可以在 config.json 文件中设置配置预设,该文件位于 ~/.config/phpmon/config.json。这些预设可以一次性应用选定的配置值。这是一项强大的功能但目前需要手动设置";
"preset_help_desc" = "重启 PHP Monitor 后,将加载文件中找到的所有预设。如果没有预设出现,则可能是文件无法正确解析。\n\n您可以点击此提示中的问号转到 GitHub 上的 FAQ在那里您可以找到有关此功能的更多信息包括一个示例文件。";
// 菜单项(如果窗口已打开)
// MENU ITEMS (if window is open)
"mm_add_folder_as_link" = "将文件夹添加为链接...";
"mm_reload_domain_list" = "重新载入域名列表";
"mm_find_in_domain_list" = "在域名列表中搜索";
// 站点列表
// SITE LIST
"domain_list.title" = "域名";
"domain_list.subtitle" = "";
@ -278,7 +280,7 @@
"domain_list.extensions" = "切换扩展";
"domain_list.applies_to" = "适用于 PHP %@";
// 选择要添加的内容
// CHOOSE WHAT TO ADD
"selection.title" = "您想设置什么样的域名?";
"selection.description" = "链接用于直接为项目提供服务。如果你有一个包含代码的 Laravel、Symfony、WordPress 等文件夹,你需要创建一个链接,并选择代码所在的文件夹。\n\n如果需要代理可以将容器等代理到特定域名。 例如,这在与 Docker 结合使用时非常有用。";
@ -286,7 +288,7 @@
"selection.create_proxy" = "创建代理";
"selection.cancel" = "取消";
// 将代理添加到域名列表
// ADD PROXY TO DOMAINS LIST
"domain_list.add.set_up_proxy" = "设置代理";
"domain_list.add.proxy_subject" = "代理主机(必须包括协议和端口)";
@ -297,7 +299,7 @@
(!)重要提示:在该域名的 nginx 配置文件中手动添加 `proxy_ssl_verify off;` 之前,该代理可能无法工作。建议使用不安全的域名作为代理主体。";
// 将站点添加到域名列表
// ADD SITE TO DOMAINS LIST
"domain_list.add.link_folder" = "链接文件夹";
"domain_list.add.domain_name_placeholder" = "在此输入域名";
@ -313,7 +315,7 @@
"domain_list.add.errors.subject_invalid" = "您输入的主题无效";
"domain_list.add.errors.already_exists" = "该名称的链接已经存在";
// 添加站点错误:选择后文件夹丢失
// ADD SITE ERROR: FOLDER MISSING SINCE SELECTION
"domain_list.alert.folder_missing.desc" = "您选择的文件夹似乎已不存在。您要取消添加此文件夹吗?如果您移动了文件夹,可以将其放回去再试一次。";
"domain_list.alert.folder_missing.title" = "文件夹丢失!";
@ -322,7 +324,7 @@
"domain_list.add.modal_description" = "首先,选择要链接的文件夹";
// 站点列表操作
// SITE LIST ACTIONS
"domain_list.isolate" = "切换 PHP 版本";
"domain_list.site_isolation" = "站点隔离";
@ -330,6 +332,8 @@
"domain_list.always_use_php" = "始终使用 PHP %@";
"domain_list.isolation_unavailable" = "不支持隔离(在 Valet 2 中)";
"domain_list.favorite" = "添加到收藏";
"domain_list.unfavorite" = "从收藏中移除";
"domain_list.actions" = "操作";
"domain_list.unlink" = "取消链接目录";
"domain_list.secure" = "安全域名";
@ -365,23 +369,23 @@ pm%@
"domain_list.columns.type" = "类型";
"domain_list.columns.kind" = "种类";
// 驱动程序
// DRIVERS
"driver.not_detected" = "其他";
// 预设
// PRESET
"preset.extension" = "%i 扩展";
"preset.extensions" = "%i 扩展";
"preset.preference" = "%i 偏好";
"preset.preferences" = "%i 偏好";
// 编辑器
// EDITORS
"editors.alert.try_again" = "再试一次";
"editors.alert.cancel" = "取消";
// 预设
// PREFERENCES
"prefs.title" = "PHP Monitor";
"prefs.subtitle" = "首选项";
@ -489,7 +493,7 @@ pm%@
"prefs.display_misc_desc" = "如果禁用,将无法访问急救与服务菜单";
"prefs.display_misc" = "急救与服务菜单";
// 通知
// NOTIFICATIONS
"notification.version_changed_title" = "PHP %@ 已激活";
"notification.version_changed_desc" = "PHP Monitor 已切换到 PHP %@";
@ -513,7 +517,7 @@ pm%@
"notification.phpmon_updated.desc" = "您现在运行的是 PHP Monitor v%@。感谢您保持更新!";
"notification.phpmon_updated_dev.desc" = "PHP Monitor v%@ (build %@)已安装并激活";
// 组件更新
// Composer Update
"alert.composer_missing.title" = "未找到 Composer";
"alert.composer_missing.subtitle" = "PHP Monitor 无法找到 Composer。请确保已安装 Composer 并重试。";
"alert.composer_missing.desc" = "PHP Monitor 假定 Composer 位于以下任一位置:
@ -534,7 +538,7 @@ pm%@
"alert.composer_success.title" = "Composer 已完成更新!";
"alert.composer_success.info" = "您的全局 Composer 依赖项已成功更新";
// Composer 版本
// Composer Version
"alert.composer_php_isolated.desc" = "该站点已被隔离,这意味着 Valet 将专门为该站点提供 PHP %@。全局版本目前为 PHP %@。";
"alert.composer_php_requirement.title" = "`%@` 需要 PHP %@";
@ -549,31 +553,31 @@ pm%@
"alert.php_version_incorrect" = "当前活动的 PHP 版本与此站点所需的约束设置不匹配";
"alert.php_suggestions" = "可能有其他更接近约束条件的 PHP 版本";
// 建议修复我的 Valet 工具
// Suggest Fix My Valet
"alert.php_switch_failed.title" = "切换到 PHP %@ 似乎失败了";
"alert.php_switch_failed.info" = "PHP Monitor 检测到 PHP %@ 在完成切换程序后没有激活。您可以尝试运行 `Fix My Valet` 并在运行后重新切换。您想试试这个修复方法吗?";
"alert.php_switch_failed.desc" = "首先,如果您还没有尝试过 `Fix My Valet`,您应该试试。如果在此之后 PHP Monitor 仍然无法更改活动的 PHP 版本,则可能需要升级 Valet 和系统中的 Homebrew 软件包。您可以通过运行 `brew update && brew upgrade` 和运行 `composer global update && valet install` 来升级 Valet";
"alert.php_switch_failed.confirm" = "是的,运行 `Fix My Valet`";
"alert.php_switch_failed.cancel" = "不运行";
// PHP Formula 丢失
// PHP Formula Missing
"alert.php_formula_missing.title" = "哎呀Fix My Valet 必须安装 `php` Formula...";
"alert.php_formula_missing.info" = "看来您没有安装 `php` Formula导致 PHP Monitor 无法运行 Fix My Valet。请使用 `brew install php` 安装,重启 PHP Monitor 并重试。";
// Fix My Valet 启动
// Fix My Valet Started
"alert.fix_my_valet.title" = "有问题Fix My Valet 已准备就绪!";
"alert.fix_my_valet.info" = "这可能需要一段时间。请耐心等待。\n\n完成后所有其他服务都将停止PHP %@ 将被链接。一旦这项操作完成,您就可以切换到所需的 PHP 版本了。\n\n(一旦 Fix My Valet 服务完成,您将收到另一条提醒。)";
"alert.fix_my_valet.ok" = "继续";
"alert.fix_my_valet.cancel" = "中止";
// 修复我的 Valet 操作完成
// Fix My Valet Done
"alert.fix_my_valet_done.title" = "Fix My Valet 已完成操作";
"alert.fix_my_valet_done.subtitle" = "已停止所有相应的服务并重新启动了正确的服务,最新版本的 PHP 现在应该处于活动状态。您现在可以尝试切换到另一个版本的 PHP。";
"alert.fix_my_valet_done.stay" = "停留在 PHP %@";
"alert.fix_my_valet_done.switch_back" = "切换回 PHP %@";
"alert.fix_my_valet_done.desc" = "如果访问网站仍然无法正常工作,您可以尝试再次运行 `valet install`,这可以修复 502 问题(网关错误)。如果 Valet 已损坏且无法运行 `valet install`,您可能需要运行 `composer global update`。如果您遇到其他问题,请查阅 GitHub 上的 FAQ";
// 恢复 Homebrew 权限
// Restore Homebrew Permissions
"alert.fix_homebrew_permissions.title" = "关于 `恢复Homebrew权限`";
"alert.fix_homebrew_permissions.subtitle" = "创建此功能是为了让您可以在没有权限问题的情况下运行 `brew upgrade` 或 `brew cleanup`。\n\n(应用此修复后,您将收到通知。)";
"alert.fix_homebrew_permissions.desc" = "这将需要管理权限,因为由于 Valet 服务以根用户身份运行PHP Monitor 将恢复您对当前由 `root` 用户拥有的文件和文件夹的所有权";
@ -584,19 +588,19 @@ pm%@
"alert.fix_homebrew_permissions_done.subtitle" = "因此Valet 的所有服务目前都不再运行。您现在可以与 Homebrew 互动,但您的 Valet 站点将无法使用,因为所有服务都已禁用。";
"alert.fix_homebrew_permissions_done.desc" = "当您完成 Homebrew 的操作后(例如在运行 `brew upgrade` 之后),如果您希望 Valet 重新运行,您应该重启 PHP Monitor 并选择 `Restart Valet Services`。建议每次使用 `brew upgrade` 升级 PHP 版本时都重启 PHP Monitor否则可能会出错";
// PHP FPM 已损坏
// PHP FPM Broken
"alert.php_fpm_broken.title" = "您的 PHP-FPM 配置没有指向 Valet 套接字!";
"alert.php_fpm_broken.info" = "PHP Monitor 已确定您的 PHP-FPM 配置存在问题。如果您访问通过 Valet 链接的网站,这将导致 `502 Bad Gateway` 响应";
"alert.php_fpm_broken.description" = "如果已经有一段时间了,你通常可以通过运行 `valet install` 来解决这个问题,它可以更新你的 PHP-FPM 配置.\n\n如果你看到这个消息而你正在尝试运行一个预发布版本的 PHP有可能是 Valet 还不支持这个预发布版本的 PHP.\n\n你可能需要将你安装的 Laravel Valet 升级到至少 v3.1.11,之后你应该运行 `valet install`。更多信息请点击https://phpmon.app/prerelease-php";
// PHP Monitor 无法启动
// PHP Monitor Cannot Start
"alert.cannot_start.title" = "由于您的系统配置问题PHP Monitor 无法启动";
"alert.cannot_start.subtitle" = "刚才通知您的问题导致 PHP Monitor 无法正常运行";
"alert.cannot_start.description" = "您可能不需要退出 PHP Monitor 并重新启动它。如果您已解决问题(或不记得具体问题是什么)可以点击重试PHP Monitor 将重试启动检查";
"alert.cannot_start.close" = "退出";
"alert.cannot_start.retry" = "重试";
// PHP 别名问题
// PHP alias issue
"alert.php_alias_conflict.title" = "检测到 Homebrew 的 `php` Formula 别名冲突";
"alert.php_alias_conflict.info" = "PHP Monitor 在您的 Homebrew 设置中检测到了相互冲突的 `php` 别名,这两个别名都已被检测到安装";
@ -607,7 +611,7 @@ pm%@
在终端运行 `composer global update` 即可。然后,再次运行 `valet install`。为获得最佳效果,请重新启动 PHP Monitor。在此问题解决之前PHP Monitor 可能无法正常运行。";
// 预设文本描述
// Preset text description
"alert.preset_description.switcher_version" = "切换到 PHP %@.\n\n";
"alert.preset_description.applying_extensions" = "应用以下扩展:\n";
"alert.preset_description.applying_config" = "应用以下配置值:\n";
@ -615,13 +619,13 @@ pm%@
"alert.preset_description.disabled" = "禁用";
"alert.preset_description.empty" = "(空)";
// PHP 版本不可用
// PHP version unavailable
"alert.php_switch_unavailable.title" = "不支持的 PHP 版本";
"alert.php_switch_unavailable.subtitle" = "PHP Monitor 无法切换到 PHP %@,因为它可能未安装或不可用。已取消应用此预设。";
"alert.php_switch_unavailable.info" = "请确保已安装 PHP %@,并可在下拉菜单中切换到它。目前支持的版本包括 PHP %@.";
"alert.php_switch_unavailable.ok" = "确定";
// 服务错误
// Service error
"alert.service_error.title" = "服务 `%@` 报告错误!";
"alert.service_error.subtitle.error_log" = "这意味着服务 `%@` 没有运行。这可能导致 Valet 无法正常工作。不过,该服务有一个相关的日志文件,您可能需要检查一下。";
"alert.service_error.subtitle.no_error_log" = "这意味着服务 `%@` 没有运行。这可能会妨碍 Valet 正常工作。不幸的是,该服务没有相关日志文件。";
@ -630,22 +634,22 @@ pm%@
"alert.service_error.button.show_log" = "查看错误日志";
"alert.service_error.button.close" = "关闭";
// Composer 问题
// Composer issues
"alert.global_composer_platform_issues.title" = "Composer 检测到您的平台存在问题";
"alert.global_composer_platform_issues.subtitle" = "您切换到的 PHP 版本对于您安装的全局 Composer 依赖项来说太旧。这些依赖项需要更新。";
"alert.global_composer_platform_issues.desc" = "防止将来发生此问题的最简单方法是切换到已安装的最旧 PHP 版本,并再次运行 `composer global update`。\另外,你也可以在偏好设置中选择 `自动更新全局依赖` 选项来避免这个问题。如果你在尝试更新全局依赖之后仍然看到这个消息,你可能需要查看一下你的全局 composer 配置文件,它位于 `~/.composer/composer.json`";
"alert.global_composer_platform_issues.buttons.update" = "更新全局依赖";
"alert.global_composer_platform_issues.buttons.quit" = "退出 PHP Monitor";
// 还原
// Revert
"alert.revert_description.title" = "还原配置?";
"alert.revert_description.subtitle" = "PHP Monitor 可以还原到之前激活的配置。以下是将应用的配置: \n\n%@";
"alert.revert_description.ok" = "恢复";
"alert.revert_description.cancel" = "取消";
// 启动
// STARTUP
/// 0. 架构不匹配
// 0. Architecture mismatch
"alert.homebrew_missing.title" = "PHP Monitor 无法启动!";
"alert.homebrew_missing.subtitle" = "无法在常规位置找到可用的 Homebrew 二进制文件。请在修复此问题后重新启动应用程序。";
@ -653,32 +657,32 @@ pm%@
"alert.homebrew_missing.quit" = "退出";
/// 未找到 PHP 二进制文件
// PHP binary not found
"startup.errors.php_binary.title" = "PHP 未正确安装";
"startup.errors.php_binary.subtitle" = "您必须通过 Homebrew 安装 PHP。在解决此问题之前应用程序将无法正常运行";
"startup.errors.php_binary.desc" = "通常在终端运行 `brew link php` 可以解决这个问题";
/// 在 /usr/local/opt /opt/homebrew/opt 中找不到 PHP
// PHP not found in /usr/local/opt or /opt/homebrew/opt
"startup.errors.php_opt.title" = "PHP 未正确安装";
"startup.errors.php_opt.subtitle" = "在 `%@` 中找不到 PHP 别名。在您解决此问题之前,应用程序将无法正常运行";
"startup.errors.php_opt.desc" = "如果您已经安装了 `php` Formula则可能需要运行 `brew install php` 才能使 PHP Monitor 检测到该安装";
/// PHP 二进制文件已损坏
// PHP binary is broken
"startup.errors.dyld_library.title" = "PHP 已安装,但似乎已损坏";
"startup.errors.dyld_library.subtitle" = "PHP Monitor 尝试运行命令时,未能正确执行。这通常表明 PHP 安装已损坏";
"startup.errors.dyld_library.desc" = "在终端运行 `brew reinstall php && brew link php` 可能会解决此问题,因此请尝试一下";
/// Valet 未安装
// Valet is not installed
"startup.errors.valet_executable.title" = "Laravel Valet 未正确安装";
"startup.errors.valet_executable.subtitle" = "您必须使用 Composer 安装 Valet。在解决此问题之前应用程序将无法正常运行。";
"startup.errors.valet_executable.desc" = "如果您尚未安装 Laravel Valet请先安装。如果你已经安装但还是看到了这条信息那么请尝试在终端运行 `which valet`,它应该会返回:`%@`.";
/// valet 配置文件丢失或损坏
// Valet configuration file missing or broken
"startup.errors.valet_json_invalid.title" = "Laravel Valet 配置文件无效或丢失";
"startup.errors.valet_json_invalid.subtitle" = "PHP Monitor 需要能够读取配置文件。文件似乎畸形或丢失。请检查该文件是否存在,格式是否正确。";
"startup.errors.valet_json_invalid.desc" = "您可以在 `~/.config/valet/config.json` 找到该文件。如果 Laravel Valet 无法解析配置文件,运行 `valet` 命令通常会自动修复 JSON 文件。尝试运行 `valet --version` 来自动修复文件";
/// Valet 版本不可读
// Valet version not readable
"startup.errors.valet_version_unknown.title" = "无法读取您的 Valet 版本";
"startup.errors.valet_version_unknown.subtitle" = "解析 `valet --version` 输出失败。请确保您的 Valet 安装正常运行且为最新版本。";
"startup.errors.valet_version_unknown.desc" = "尝试在终端中运行 `valet --version` 以找出问题所在";
@ -689,49 +693,49 @@ pm%@
如果你看到此消息,但不明白为什么这个文件夹不见了,那么你可能想调查一下它消失的原因--它不应该就这样消失,这意味着你的 Valet 安装被破坏了。";
// Valet 版本太新或太旧
// Valet version too new or old
"startup.errors.valet_version_not_supported.title" = "不支持此 Valet 版本";
"startup.errors.valet_version_not_supported.subtitle" = "您运行的 Valet 版本目前不受支持。PHP Monitor 目前适用于 Valet v2、v3 和 v4。为了避免给您的系统带来问题PHP Monitor 无法启动";
"startup.errors.valet_version_not_supported.desc" = "您必须安装与 PHP Monitor 兼容的 Valet 版本,或者您可能需要升级到较新版本的 PHP Monitor该版本可能包含对该 Valet 版本的兼容性(更多信息请查阅最新发布说明)";
/// Brew sudoers
// Brew & sudoers
"startup.errors.sudoers_brew.title" = "Brew 没有被添加到 sudoers.d";
"startup.errors.sudoers_brew.subtitle" = "您必须运行 `sudo valet trust` 以确保 Valet 可以启动和停止服务,而无需每次都使用 sudo。在您解决此问题之前应用程序将无法正常工作。";
"startup.errors.sudoers_brew.desc" = "如果您一直看到此错误则可能存在权限问题PHP Monitor 无法验证该文件,通常可通过运行:`sudo chmod +r /private/etc/sudoers.d/brew` 解决该问题";
/// 验证和 sudoers
// Valet & sudoers
"startup.errors.sudoers_valet.title" = "Valet 尚未添加到 sudoers.d";
"startup.errors.sudoers_valet.subtitle" = "您必须运行 `sudo valet trust` 以确保 Valet 可以启动和停止服务,而无需每次都使用 sudo。在您解决此问题之前应用程序将无法正常运行。如果您之前执行过此操作请再次运行 `sudo valet trust`。";
"startup.errors.sudoers_valet.desc" = "如果一直看到此错误则可能存在权限问题PHP Monitor 无法验证文件,通常可通过运行:`sudo chmod +r /private/etc/sudoers.d/valet` 解决";
/// 检测到平台问题
// Platform issue detected
"startup.errors.global_composer_platform_issues.title" = "PHP Monitor 和 Valet 无法正常工作Composer 报告您的平台存在问题";
"startup.errors.global_composer_platform_issues.subtitle" = "请按照以下建议步骤操作,以避免将来出现此问题:\n\n1. 运行 `composer global update`.\n2. 重新启动 PHP Monitor。(它应该可以重新工作。)\n3. 切换到已安装的最早的 PHP 版本。再次运行 `composer global update`";
"startup.errors.global_composer_platform_issues.desc" = "您可以进入首选项并选中 `自动更新全局依赖` 选项。这将在您更改 PHP 版本时更新您的全局 Composer 依赖项,因此,如果您不能持续访问互联网,这可能不是最理想的选择。要找出确切的问题所在,请尝试运行 `valet --version`。Valet 目前无法使用已安装的依赖项。通常这是由于版本不匹配造成的:即安装的 PHP 依赖版本比当前激活的版本要新";
/// 无法检索服务
// Cannot retrieve services
"startup.errors.services_json_error.title" = "无法确定服务状态";
"startup.errors.services_json_error.subtitle" = "PHP Monitor 通常使用以下命令查询 `brew` 以测试是否可以检索服务:`sudo brew services info nginx --json`.\n\nPHP Monitor 无法解释此响应。";
"startup.errors.services_json_error.desc" = "如果您的 Homebrew 安装过时可能会出现这种情况在这种情况下Homebrew 还不会返回 JSON。通常可以通过运行 `brew update` 或 `brew tap homebrew/services` 来解决这个问题。你也可以尝试在终端运行 `sudo brew services info nginx --json`";
/// `which` 别名的问题
// Issue with `which` alias
"startup.errors.which_alias_issue.title" = "检测到配置问题";
"startup.errors.which_alias_issue.subtitle" = "`/usr/local/bin/which` 中似乎有一个文件。这通常是由 NodeJS 设置的,但 `/usr/local/bin` 的 PATH 中没有 `node`。要解决这个问题,请继续阅读";
"startup.errors.which_alias_issue.desc" = "您需要将 `node` 链接到 `/usr/local/bin` 目录,以确保 PHP Monitor 能够成功启动。更多信息请参见https://github.com/nicoverbruggen/phpmon/issues/174";
/// Laravel Herd 冲突
// Laravel Herd conflicts
"startup.errors.herd_running.title" = "Laravel Herd 似乎正在运行";
"startup.errors.herd_running.subtitle" = "Laravel Herd 似乎正在运行。Herd 的内置 Valet 设置可能与您的常规 Valet 安装冲突,因此请在继续之前退出 Herd。(你完全可以混合使用 Herd 和常规 Valet但不应同时运行两者)";
"startup.errors.herd_running.desc" = "你可能还会发现Herd 添加到 $PATH 的 `php` 别名可能会阻止 PHP Monitor 的 `php` 别名生效,所以请记住这一点。您可以查看 `~/.zshrc` 并了解 Herd 在您的 $PATH 中添加了什么。";
// 关于链接的 PHP 版本与上次不同的警告
// Warning about a different PHP version linked than last time
"startup.version_mismatch.title" = "您的活动 PHP 版本已更改";
"startup.version_mismatch.subtitle" = "自 PHP Monitor 上次激活以来,您链接的 PHP 版本已更改为 PHP %@。您想切换回 PHP %@,还是继续使用当前版本?";
"startup.version_mismatch.desc" = "PHP Monitor 会跟踪全局链接的 PHP 版本。全局版本可能由于其他程序或 Homebrew 升级后链接了不同的 Formula 而发生变化";
"startup.version_mismatch.button_switch_back" = "切换回 PHP %@";
"startup.version_mismatch.button_stay" = "继续使用 PHP %@";
// 关于不支持的 PHP 版本的警告
// Warning about unsupported PHP versions
"startup.unsupported_versions_explanation.title" = "检测到 Valet 不支持的 PHP 安装!";
"startup.unsupported_versions_explanation.subtitle" = "您的系统中安装了以下 PHP 版本,但该版本的 Valet 不支持这些版本。
@ -740,7 +744,7 @@ pm%@
如果链接这些 PHP 版本Valet 可能会崩溃,因此 PHP Monitor 不会让您切换到这些版本。";
"startup.unsupported_versions_explanation.desc" = " 如果您需要旧版本的 PHP 支持,您可能需要降级到旧版本的 Valet。否则最好卸载任何不使用的过时版本。也可能是 Valet 的版本太旧。只有在重启 PHP Monitor 后,此消息才会被删除。";
// 赞助鼓励
// Sponsor encouragement
"startup.sponsor_encouragement.title" = "如果 PHP Monitor 对您或贵公司有用,请考虑留下小费";
"startup.sponsor_encouragement.subtitle" = "100%透明:我计划保持 PHP Monitor 的开源和免费。您的支持使这一决定变得非常容易。";
"startup.sponsor_encouragement.desc" = "如果您已经捐赠,那么您就是应用程序能够获得所有这些更新的原因。在这种情况下,这是给您的感谢信息。感谢您的支持。";
@ -749,7 +753,7 @@ pm%@
"startup.sponsor_encouragement.learn_more" = "了解更多信息";
"startup.sponsor_encouragement.skip" = "不,谢谢";
// 错误消息(基于 AlertableError)
// ERROR MESSAGES
"alert.errors.homebrew_permissions.applescript_returned_nil.title" = "恢复 Homebrew 权限已被取消。";
"alert.errors.homebrew_permissions.applescript_returned_nil.description" = "为调整权限而执行的脚本的结果返回为零,这通常意味着您没有授予 PHP Monitor 管理权限。如果您确实进行了身份验证,但仍看到此消息,则可能出了问题。";
@ -782,7 +786,7 @@ PHP Monitor 将尝试重新启动服务,如果失败(很有可能),它将提
· dnsmasq如果出现错误状态可能是 dnsmasq 配置文件损坏(通常位于 ~/.config/valet/dnsmasq.d)";
// 检查更新
// CHECK FOR UPDATES
"updater.alerts.newer_version_available.title" = "PHP Monitor v%@ 现已可用!";
"updater.alerts.newer_version_available.subtitle" = "强烈建议将 PHP Monitor 保持更新,因为新版本通常会修复漏洞并包含支持最新版本 Valet 和 PHP 的修正";
@ -800,14 +804,14 @@ PHP Monitor 将尝试重新启动服务,如果失败(很有可能),它将提
"updater.alerts.buttons.install" = "安装更新";
"updater.alerts.buttons.dismiss" = "解除";
// 关于非默认 TLD 的警告
// WARNINGS ABOUT NON-DEFAULT TLD
"alert.warnings.tld_issue.title" = "您没有使用 `.test` 作为 Valet 的顶级域名";
"alert.warnings.tld_issue.subtitle" = "使用非默认顶级域名可能无法正常工作,并且不受官方支持";
"alert.warnings.tld_issue.description" = "PHP Monitor 仍将正常运行,但可能会出现一些问题:应用程序可能无法正确显示哪些域名已被安全保护。为获得最佳效果,请转到 Valet 配置文件(Valet 目录中的 config.json)并将 TLD 改回 `test`。";
"alert.do_not_tell_again" = "不要再告诉我";
// 警告
// WARNINGS
"warnings.limits_error.title" = "PHP Monitor 无法检索限制";
"warnings.limits_error.steps" = "尝试在终端运行 `php -v`";
@ -835,7 +839,7 @@ PHP Monitor 将尝试重新启动服务,如果失败(很有可能),它将提
"warnings.none" = "现在没有可用的建议。您可以放心使用!";
// 开机
// ONBOARDING
"onboarding.title" = "Welcome Tour";
"onboarding.welcome" = "欢迎来到 PHP Monitor!";
@ -855,7 +859,7 @@ PHP Monitor 将尝试重新启动服务,如果失败(很有可能),它将提
"onboarding.tour.once" = "您只能看到一次 Welcome Tour。您可以稍后通过菜单栏图标(可在 `急救与服务` 下的菜单中找到)重新打开 Welcome Tour。";
"onboarding.tour.close" = "关闭 Tour";
// 语言选择
// LANGUAGE CHOICE
"prefs.language" = "语言:";
"prefs.language_options_desc" = "选择不同的语言与 PHP Monitor 一起使用。要完全应用此更改,必须重新启动应用程序";
@ -863,3 +867,13 @@ PHP Monitor 将尝试重新启动服务,如果失败(很有可能),它将提
"alert.language_changed.title" = "您必须重新启动 PHP Monitor";
"alert.language_changed.subtitle" = "您刚刚更改了 PHP Monitor 的显示语言。菜单将立即使用正确的语言,但您可能需要重新启动应用程序,以使整个应用程序中的所有文本都应用您的新语言选择";
// STARTUP TIMEOUT
"startup.timeout.ignore" = "忽略";
"startup.timeout.title" = "PHP Monitor 初始化时间过长!";
"startup.timeout.subtitle" = "如果 PHP Monitor 持续忙碌超过 30 秒,可能是您的 Homebrew 配置存在问题。";
"startup.timeout.description" = "有时候,由于文件权限问题,可能会导致程序无法正常运行。您可以尝试使用 `brew doctor` 和 `brew cleanup` 来修复问题。
建议随后重新启动 PHP Monitor。了解更多信息请访问https://github.com/nicoverbruggen/phpmon/issues/294。
如果 PHP Monitor 现在已经初始化完成,或者您愿意再等一会儿,可以点击“忽略”并照常使用 PHP Monitor。不过仍然建议检查问题因为初始化不应该花费这么长时间。";

View File

@ -35,6 +35,19 @@ class TestableConfigurations {
"loopback": "127.0.0.1"
}
"""),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php.rb" : .fake(.text),
// "/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@8.5.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@8.4.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@8.3.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@8.2.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@8.1.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@8.0.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@7.4.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@7.3.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@7.2.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@7.1.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@7.0.rb" : .fake(.text),
"/opt/homebrew/Library/Taps/shivammathur/homebrew-php/Formula/php@5.6.rb" : .fake(.text)
],
shellOutput: [
"/opt/homebrew/bin/brew --version"

View File

@ -85,22 +85,27 @@ final class MainMenuTest: UITestCase {
final func test_can_open_php_version_manager() throws {
let app = launch(openMenu: true)
app.mainMenuItem(withText: "mi_php_version_manager".localized).click()
// Should display loader
assertExists(app.staticTexts["phpman.busy.title".localized], 1)
// After loading, should display PHP 8.2 and PHP 8.3
// After loading, should display PHP 8.2, PHP 8.3, PHP 8.4
assertExists(app.staticTexts["PHP 8.2"], 5)
assertExists(app.staticTexts["PHP 8.3"])
assertExists(app.staticTexts["PHP 8.4"])
// Should also display pre-release version
assertExists(app.staticTexts["PHP 8.4"])
assertExists(app.staticTexts["PHP 8.5"])
assertExists(app.staticTexts["phpman.version.prerelease".localized.uppercased()])
assertExists(app.staticTexts["phpman.version.available_for_installation".localized])
// But not PHP 8.5 (yet)
assertNotExists(app.staticTexts["PHP 8.5"])
// The pre-release version should be unavailable
assertExists(app.staticTexts["phpman.version.unavailable".localized])
// But not PHP 8.6 (yet)
assertNotExists(app.staticTexts["PHP 8.6"])
// Also, PHP 8.2 should have an update available
assertExists(app.staticTexts["phpman.version.has_update".localized(

View File

@ -51,7 +51,7 @@ final class UpdateCheckTest: UITestCase {
let app = launch(openMenu: false, with: configuration)
// Expect to see the content of the appropriate alert box
assertExists(app.staticTexts["updater.alerts.newer_version_available.title".localized("99.0.0 (9999)")], 2)
assertExists(app.staticTexts["updater.alerts.newer_version_available.title".localized("99.0.0 (9999)")], 3.0)
assertExists(app.buttons["updater.alerts.buttons.install".localized])
assertExists(app.buttons["updater.alerts.buttons.dismiss".localized])
}