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

Compare commits

...

16 Commits

Author SHA1 Message Date
00cc6711a1 🚀 Version 5.6.6 2022-12-10 13:04:16 +01:00
209244e162 🔧 Bump build 2022-12-09 18:27:19 +01:00
e48d8ed98b 👌 Add warning about https proxy subjects 2022-12-09 18:26:56 +01:00
834f76e5a1 📝 Updated README about PHP compatibility 2022-12-09 18:08:05 +01:00
7e48893247 📝 Update README 2022-12-09 18:04:05 +01:00
e29ca9e1ad 🚀 Version 5.6.5 2022-11-27 14:37:15 +01:00
40e05d9445 🔧 Bump build 2022-11-27 14:04:15 +01:00
3ebf51b319 👌 Fix threading issue with Composer update (#212) 2022-11-27 14:03:46 +01:00
4b8ad911f1 Add support for nginx-full (#211) 2022-11-21 18:10:33 +01:00
efd902b4f3 🚀 Version 5.6.4 2022-11-18 18:39:00 +01:00
918e272da7 🔧 Bump build 2022-11-18 18:37:31 +01:00
272a9182d3 🔥 Remove reference to LatestStablePhpVersion 2022-11-18 18:37:20 +01:00
63f85aff91 🐛 Fix issue when using services quick toggle 2022-11-18 18:32:38 +01:00
581c2d1974 📝 Update supported PHP versions in README 2022-11-07 20:45:58 +01:00
4deef64537 📝 Update SECURITY.md 2022-11-02 21:08:57 +01:00
bedabaa3bb 👌 PHP 8.2 release, PHP 8.3-dev support 2022-11-02 21:06:36 +01:00
16 changed files with 150 additions and 70 deletions

View File

@ -244,6 +244,8 @@
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; }; C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; }; C4CE3BBB27B324230086CA49 /* MainMenu+Switcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */; };
C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; }; C4CE3BBC27B324250086CA49 /* ComposerWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */; };
C4D27F24292BDF630081B38F /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D27F23292BDF630081B38F /* Homebrew.swift */; };
C4D27F25292BDF630081B38F /* Homebrew.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D27F23292BDF630081B38F /* Homebrew.swift */; };
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; }; C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; }; C4D5CFCB27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */; };
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; }; C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
@ -462,6 +464,7 @@
C4CDA892288F1A71007CE25F /* Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = "<group>"; }; C4CDA892288F1A71007CE25F /* Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keys.swift; sourceTree = "<group>"; };
C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Switcher.swift"; sourceTree = "<group>"; }; C4CE3BB727B31F2E0086CA49 /* MainMenu+Switcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MainMenu+Switcher.swift"; sourceTree = "<group>"; };
C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerWindow.swift; sourceTree = "<group>"; }; C4CE3BB927B31F670086CA49 /* ComposerWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerWindow.swift; sourceTree = "<group>"; };
C4D27F23292BDF630081B38F /* Homebrew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Homebrew.swift; sourceTree = "<group>"; };
C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationFile.swift; sourceTree = "<group>"; }; C4D5CFC927E0F9CD00035329 /* NginxConfigurationFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NginxConfigurationFile.swift; sourceTree = "<group>"; };
C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; }; C4D8016522B1584700C6DA1B /* Startup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Startup.swift; sourceTree = "<group>"; };
C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; }; C4D89BC52783C99400A02B68 /* ComposerJson.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerJson.swift; sourceTree = "<group>"; };
@ -644,6 +647,7 @@
C4C1019A27C65C6F001FACC2 /* Process.swift */, C4C1019A27C65C6F001FACC2 /* Process.swift */,
C40C7F2F27722E8D00DDDCDC /* Logger.swift */, C40C7F2F27722E8D00DDDCDC /* Logger.swift */,
C417DC73277614690015E6EE /* Helpers.swift */, C417DC73277614690015E6EE /* Helpers.swift */,
C4D27F23292BDF630081B38F /* Homebrew.swift */,
); );
path = Core; path = Core;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1413,6 +1417,7 @@
C476FF9822B0DD830098105B /* Alert.swift in Sources */, C476FF9822B0DD830098105B /* Alert.swift in Sources */,
C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */, C474B00624C0E98C00066A22 /* LocalNotification.swift in Sources */,
C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */, C4D5CFCA27E0F9CD00035329 /* NginxConfigurationFile.swift in Sources */,
C4D27F24292BDF630081B38F /* Homebrew.swift in Sources */,
C485707028BF452300539B36 /* WarningsWindowController.swift in Sources */, C485707028BF452300539B36 /* WarningsWindowController.swift in Sources */,
C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */, C4CE3BBA27B31F670086CA49 /* ComposerWindow.swift in Sources */,
C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */, C4D9ADC8277611A0007277F4 /* InternalSwitcher.swift in Sources */,
@ -1555,6 +1560,7 @@
C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */, C4F30B0B278E203C00755FCE /* MainMenu+Startup.swift in Sources */,
C485707C28BF459500539B36 /* NoWarningsView.swift in Sources */, C485707C28BF459500539B36 /* NoWarningsView.swift in Sources */,
C4F5FBCD28218CB8001065C5 /* Xdebug.swift in Sources */, C4F5FBCD28218CB8001065C5 /* Xdebug.swift in Sources */,
C4D27F25292BDF630081B38F /* Homebrew.swift in Sources */,
C40B24F227A310770018C7D2 /* Events.swift in Sources */, C40B24F227A310770018C7D2 /* Events.swift in Sources */,
C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */, C4F30B0A278E1A1A00755FCE /* ComposerJson.swift in Sources */,
C4C0E8E027F88AEB002D32A9 /* FakeSiteScanner.swift in Sources */, C4C0E8E027F88AEB002D32A9 /* FakeSiteScanner.swift in Sources */,
@ -1741,7 +1747,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 980; CURRENT_PROJECT_VERSION = 992;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEBUG = YES; DEBUG = YES;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
@ -1752,7 +1758,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.6.3; MARKETING_VERSION = 5.6.6;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@ -1769,7 +1775,7 @@
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES; COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 980; CURRENT_PROJECT_VERSION = 992;
DEAD_CODE_STRIPPING = YES; DEAD_CODE_STRIPPING = YES;
DEBUG = NO; DEBUG = NO;
DEVELOPMENT_TEAM = 8M54J5J787; DEVELOPMENT_TEAM = 8M54J5J787;
@ -1780,7 +1786,7 @@
"@executable_path/../Frameworks", "@executable_path/../Frameworks",
); );
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 5.6.3; MARKETING_VERSION = 5.6.6;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon; PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

View File

@ -80,19 +80,50 @@ If you're still having issues, here's a few common questions & answers, as well
<summary><strong>Which versions of PHP are supported?</strong></summary> <summary><strong>Which versions of PHP are supported?</strong></summary>
<ul> <ul>
<li>PHP 5.6 (only if you are running Valet 2)</li> <li>PHP 5.6 (backport + only if you are running Valet 2)</li>
<li>PHP 7.0</li> <li>PHP 7.0 (backport)</li>
<li>PHP 7.1</li> <li>PHP 7.1 (backport)</li>
<li>PHP 7.2</li> <li>PHP 7.2 (backport)</li>
<li>PHP 7.3</li> <li>PHP 7.3 (backport)</li>
<li>PHP 7.4</li> <li>PHP 7.4 (backport)</li>
<li>PHP 8.0</li> <li>PHP 8.0 (official support)</li>
<li>PHP 8.1</li> <li>PHP 8.1 (official support)</li>
<li>PHP 8.2 (experimental)</li> <li>PHP 8.2 (latest version)</li>
<li>PHP 8.3-dev (experimental)</li>
</ul> </ul>
For more details, consult the [constants file](https://github.com/nicoverbruggen/phpmon/blob/main/phpmon/Common/Core/Constants.swift#L16) file to see which versions are supported. For more details, consult the [constants file](https://github.com/nicoverbruggen/phpmon/blob/main/phpmon/Common/Core/Constants.swift#L16) file to see which versions are supported.
Backports are available via [this tap](https://github.com/shivammathur/homebrew-php). For more information about those backports, please see the next FAQ entry.
</details>
<details>
<summary><strong>How do I install additional versions of PHP, including legacy versions?</strong></summary>
Assuming you have installed the `php` formula, the latest stable version of PHP is installed. At the time of writing, this is PHP 8.2.
You can install other supported versions of PHP out of the box, so `php@8.0` and `php@8.1` at the time of writing.
If you wish to install older (officially unsupported) versions of PHP for local use, you can do so by using [Shivam Mathur's tap](https://github.com/shivammathur/homebrew-php):
```sh
brew tap shivammathur/php
```
You may find that this tap is already in use: if you've used Valet before, it automatically uses this tap for legacy versions of PHP.
You can then install those older versions:
```sh
brew install php@7.0
brew install php@7.1
...
```
**Always make sure to restart PHP Monitor after installing or upgrading PHP versions!**
> *Note*: Using this tap may cause [temporary alias conflicts](https://github.com/nicoverbruggen/phpmon/issues/54#issuecomment-979789724) while the core tap alias and the tap's alias refer to a different version of PHP, but this is generally speaking a minor inconvenience, since this normally only applies when a new PHP version releases.
</details> </details>
<details> <details>

View File

@ -6,9 +6,7 @@ Generally speaking, only the latest version of **PHP Monitor** is supported, exc
| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Recommended Valet Version | | Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Recommended Valet Version |
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ---- | ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
| 5.x | ✅ Universal binary | ✅ Yes | Big Sur (11.0)<br/>Monterey (12.0)<br/>Ventura (13.0)* | macOS 11+ | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x) | 3.0 recommended<br/> 2.16.2 minimum | | 5.x | ✅ Universal binary | ✅ Yes | Big Sur (11.0)<br/>Monterey (12.0)<br/>Ventura (13.0) | macOS 11+ | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x) | 3.0 recommended<br/> 2.16.2 minimum |
_(*) macOS Ventura (13.0) is not officially supported until it officially releases._
## Legacy versions ## Legacy versions

View File

@ -13,37 +13,35 @@ class Actions {
// MARK: - Services // MARK: - Services
public static func restartPhpFpm() { public static func restartPhpFpm() {
brew("services restart \(PhpEnv.phpInstall.formula)", sudo: true) brew("services restart \(Homebrew.Formulae.php)", sudo: true)
} }
public static func restartNginx() { public static func restartNginx() {
brew("services restart nginx", sudo: true) brew("services restart \(Homebrew.Formulae.nginx)", sudo: true)
} }
public static func restartDnsMasq() { public static func restartDnsMasq() {
brew("services restart dnsmasq", sudo: true) brew("services restart \(Homebrew.Formulae.dnsmasq)", sudo: true)
} }
public static func stopValetServices() { public static func stopValetServices() {
brew("services stop \(PhpEnv.phpInstall.formula)", sudo: true) brew("services stop \(Homebrew.Formulae.php)", sudo: true)
brew("services stop nginx", sudo: true) brew("services stop \(Homebrew.Formulae.nginx)", sudo: true)
brew("services stop dnsmasq", sudo: true) brew("services stop \(Homebrew.Formulae.dnsmasq)", sudo: true)
} }
public static func fixHomebrewPermissions() throws { public static func fixHomebrewPermissions() throws {
var servicesCommands = [ var servicesCommands = [
"\(Paths.brew) services stop nginx", "\(Paths.brew) services stop \(Homebrew.Formulae.nginx)",
"\(Paths.brew) services stop dnsmasq" "\(Paths.brew) services stop \(Homebrew.Formulae.dnsmasq)"
] ]
var cellarCommands = [ var cellarCommands = [
"chown -R \(Paths.whoami):admin \(Paths.cellarPath)/nginx", "chown -R \(Paths.whoami):admin \(Paths.cellarPath)/\(Homebrew.Formulae.nginx)",
"chown -R \(Paths.whoami):admin \(Paths.cellarPath)/dnsmasq" "chown -R \(Paths.whoami):admin \(Paths.cellarPath)/\(Homebrew.Formulae.dnsmasq)"
] ]
PhpEnv.shared.availablePhpVersions.forEach { version in PhpEnv.shared.availablePhpVersions.forEach { version in
let formula = version == PhpEnv.brewPhpVersion let formula = version == PhpEnv.brewPhpVersion ? "php" : "php@\(version)"
? "php"
: "php@\(version)"
servicesCommands.append("\(Paths.brew) services stop \(formula)") servicesCommands.append("\(Paths.brew) services stop \(formula)")
cellarCommands.append("chown -R \(Paths.whoami):admin \(Paths.cellarPath)/\(formula)") cellarCommands.append("chown -R \(Paths.whoami):admin \(Paths.cellarPath)/\(formula)")
} }
@ -145,9 +143,9 @@ class Actions {
*/ */
public static func fixMyValet(completed: @escaping () -> Void) { public static func fixMyValet(completed: @escaping () -> Void) {
InternalSwitcher().performSwitch(to: PhpEnv.brewPhpVersion, completion: { InternalSwitcher().performSwitch(to: PhpEnv.brewPhpVersion, completion: {
brew("services restart dnsmasq", sudo: true) brew("services restart \(Homebrew.Formulae.dnsmasq)", sudo: true)
brew("services restart php", sudo: true) brew("services restart \(Homebrew.Formulae.php)", sudo: true)
brew("services restart nginx", sudo: true) brew("services restart \(Homebrew.Formulae.nginx)", sudo: true)
completed() completed()
}) })
} }

View File

@ -9,12 +9,6 @@ import Cocoa
struct Constants { struct Constants {
/**
* The latest PHP version that is considered to be stable at the time of release.
* This version number is currently not used (only as a default fallback).
*/
static let LatestStablePhpVersion = "8.1"
/** /**
The minimum version of Valet that is recommended. The minimum version of Valet that is recommended.
If the installed version is older, a notification will be shown If the installed version is older, a notification will be shown
@ -42,13 +36,14 @@ struct Constants {
"7.4", "7.4",
"8.0", "8.0",
"8.1", "8.1",
"8.2",
// ==================== // ====================
// EXPERIMENTAL SUPPORT // EXPERIMENTAL SUPPORT
// ==================== // ====================
// Every release that supports the next release will always support the next // Every release that supports the next release will always support the next
// dev release. In this case, that means that the version below is detected. // dev release. In this case, that means that the version below is detected.
"8.2" "8.3"
] ]
struct Urls { struct Urls {

View File

@ -0,0 +1,25 @@
//
// Homebrew.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 21/11/2022.
// Copyright © 2022 Nico Verbruggen. All rights reserved.
//
import Foundation
class Homebrew {
struct Formulae {
static var php: String {
return PhpEnv.phpInstall.formula
}
static var nginx: String {
return HomebrewDiagnostics.usesNginxFullFormula ? "nginx-full" : "nginx"
}
static var dnsmasq: String {
return "dnsmasq"
}
}
}

View File

@ -46,7 +46,7 @@ class InternalSwitcher: PhpSwitcher {
} }
Log.info("Restarting nginx, just to be sure!") Log.info("Restarting nginx, just to be sure!")
brew("services restart nginx", sudo: true) brew("services restart \(Homebrew.Formulae.nginx)", sudo: true)
Log.info("The new version(s) have been linked!") Log.info("The new version(s) have been linked!")
completion() completion()

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES"> <document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21507"/>
<capability name="Image references" minToolsVersion="12.0"/> <capability name="Image references" minToolsVersion="12.0"/>
<capability name="Named colors" minToolsVersion="9.0"/> <capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Search Toolbar Item" minToolsVersion="12.0" minSystemVersion="11.0"/> <capability name="Search Toolbar Item" minToolsVersion="12.0" minSystemVersion="11.0"/>
@ -1112,17 +1112,17 @@ Gw
<objects> <objects>
<viewController storyboardIdentifier="newProxyLink" id="dwh-CF-6iv" customClass="AddProxyVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController"> <viewController storyboardIdentifier="newProxyLink" id="dwh-CF-6iv" customClass="AddProxyVC" customModule="PHP_Monitor" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="U5U-QR-YXS"> <view key="view" id="U5U-QR-YXS">
<rect key="frame" x="0.0" y="0.0" width="480" height="286"/> <rect key="frame" x="0.0" y="0.0" width="540" height="286"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="kkd-UV-SnA"> <box boxType="custom" borderWidth="0.0" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="kkd-UV-SnA">
<rect key="frame" x="0.0" y="0.0" width="480" height="286"/> <rect key="frame" x="0.0" y="0.0" width="540" height="286"/>
<view key="contentView" id="IXW-35-8NJ"> <view key="contentView" id="IXW-35-8NJ">
<rect key="frame" x="0.0" y="0.0" width="480" height="286"/> <rect key="frame" x="0.0" y="0.0" width="540" height="286"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QCK-Z9-w7g"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="QCK-Z9-w7g">
<rect key="frame" x="20" y="196" width="440" height="21"/> <rect key="frame" x="20" y="196" width="500" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="http://127.0.0.1:80" placeholderString="http://127.0.0.1:80" drawsBackground="YES" id="muS-8M-KSy"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" title="http://127.0.0.1:80" placeholderString="http://127.0.0.1:80" drawsBackground="YES" id="muS-8M-KSy">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -1149,7 +1149,7 @@ Gw
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNw-oQ-bnb"> <textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SNw-oQ-bnb">
<rect key="frame" x="20" y="147" width="440" height="21"/> <rect key="frame" x="20" y="147" width="500" height="21"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter a domain name here." drawsBackground="YES" id="gTQ-Y2-Y9w"> <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="Enter a domain name here." drawsBackground="YES" id="gTQ-Y2-Y9w">
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -1176,7 +1176,7 @@ Gw
<color key="fillColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/> <color key="fillColor" name="windowBackgroundColor" catalog="System" colorSpace="catalog"/>
</box> </box>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4Vi-cN-ude"> <button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4Vi-cN-ude">
<rect key="frame" x="317" y="13" width="150" height="32"/> <rect key="frame" x="377" y="13" width="150" height="32"/>
<buttonCell key="cell" type="push" title="[i18n] Create Proxy" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="H2Z-c5-5Vk"> <buttonCell key="cell" type="push" title="[i18n] Create Proxy" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="H2Z-c5-5Vk">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/> <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/> <font key="font" metaFont="system"/>
@ -1205,7 +1205,10 @@ Gw
</connections> </connections>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSZ-x8-Pqi"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="JSZ-x8-Pqi">
<rect key="frame" x="18" y="128" width="444" height="14"/> <rect key="frame" x="18" y="128" width="504" height="14"/>
<constraints>
<constraint firstAttribute="width" relation="lessThanOrEqual" constant="500" id="sF1-RG-URI"/>
</constraints>
<textFieldCell key="cell" title="[i18n] Preview text here" id="ISE-9R-ncQ"> <textFieldCell key="cell" title="[i18n] Preview text here" id="ISE-9R-ncQ">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
@ -1223,7 +1226,7 @@ Gw
</connections> </connections>
</button> </button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5x7-ll-2f7"> <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5x7-ll-2f7">
<rect key="frame" x="18" y="60" width="444" height="28"/> <rect key="frame" x="18" y="60" width="504" height="28"/>
<textFieldCell key="cell" title="[i18n] Securing a domain requires administrative privileges. You may be prompted for your password or Touch ID." id="IMB-O5-ZOy"> <textFieldCell key="cell" title="[i18n] Securing a domain requires administrative privileges. You may be prompted for your password or Touch ID." id="IMB-O5-ZOy">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
@ -1239,7 +1242,7 @@ Gw
</textFieldCell> </textFieldCell>
</textField> </textField>
<textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="w0k-CK-0u4"> <textField hidden="YES" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="w0k-CK-0u4">
<rect key="frame" x="131" y="23" width="180" height="14"/> <rect key="frame" x="191" y="23" width="180" height="14"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="That domain name already exists." id="4sH-94-UJl"> <textFieldCell key="cell" lineBreakMode="clipping" title="That domain name already exists." id="4sH-94-UJl">
<font key="font" metaFont="smallSystem"/> <font key="font" metaFont="smallSystem"/>
<color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/> <color key="textColor" name="systemRedColor" catalog="System" colorSpace="catalog"/>
@ -1293,7 +1296,7 @@ Gw
</viewController> </viewController>
<customObject id="VaP-ZM-OcY" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/> <customObject id="VaP-ZM-OcY" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="210" y="1524"/> <point key="canvasLocation" x="220" y="1522"/>
</scene> </scene>
<!--Window Controller--> <!--Window Controller-->
<scene sceneID="5Gf-7O-tdA"> <scene sceneID="5Gf-7O-tdA">

View File

@ -18,9 +18,9 @@ class ServicesManager: ObservableObject {
public static func loadHomebrewServices(completed: (() -> Void)? = nil) { public static func loadHomebrewServices(completed: (() -> Void)? = nil) {
let rootServiceNames = [ let rootServiceNames = [
PhpEnv.phpInstall.formula, Homebrew.Formulae.php,
"nginx", Homebrew.Formulae.nginx,
"dnsmasq" Homebrew.Formulae.dnsmasq
] ]
DispatchQueue.global(qos: .background).async { DispatchQueue.global(qos: .background).async {
@ -39,9 +39,7 @@ class ServicesManager: ObservableObject {
} }
} }
guard let userServiceNames = Preferences.custom.services else { let userServiceNames = Preferences.custom.services ?? []
return
}
DispatchQueue.global(qos: .background).async { DispatchQueue.global(qos: .background).async {
let data = Shell let data = Shell

View File

@ -160,7 +160,7 @@ class Startup {
// Verify if the Homebrew services are running (as root). // Verify if the Homebrew services are running (as root).
// ================================================================================= // =================================================================================
EnvironmentCheck( EnvironmentCheck(
command: { return HomebrewDiagnostics.cannotLoadService() }, command: { return HomebrewDiagnostics.cannotLoadService("dnsmasq") },
name: "`sudo \(Paths.brew) services info` JSON loaded", name: "`sudo \(Paths.brew) services info` JSON loaded",
titleText: "startup.errors.services_json_error.title".localized, titleText: "startup.errors.services_json_error.title".localized,
subtitleText: "startup.errors.services_json_error.subtitle".localized, subtitleText: "startup.errors.services_json_error.subtitle".localized,

View File

@ -157,8 +157,14 @@ class AddProxyVC: NSViewController, NSTextFieldDelegate {
return return
} }
previewText.stringValue = "domain_list.add.proxy_available" var translationKey = "domain_list.add.proxy_available"
.localized(
if inputProxySubject.stringValue.starts(with: "https://") {
translationKey = "domain_list.add.proxy_https_warning"
}
previewText.stringValue =
translationKey.localized(
inputProxySubject.stringValue, inputProxySubject.stringValue,
buttonSecure.state == .on ? "https" : "http", buttonSecure.state == .on ? "https" : "http",
inputDomainName.stringValue, inputDomainName.stringValue,

View File

@ -113,9 +113,7 @@ class ComposerWindow {
private func removeBusyStatus() { private func removeBusyStatus() {
PhpEnv.shared.isBusy = false PhpEnv.shared.isBusy = false
DispatchQueue.main.async { [self] in menu?.updatePhpVersionInStatusBar()
menu?.updatePhpVersionInStatusBar()
}
} }
// MARK: Alert // MARK: Alert

View File

@ -29,6 +29,21 @@ class HomebrewDiagnostics {
return installedTaps.contains("nicoverbruggen/cask") return installedTaps.contains("nicoverbruggen/cask")
}() }()
/**
Determines whether to use the regular `nginx` or `nginx-full` formula.
*/
public static var usesNginxFullFormula: Bool = {
guard let destination = try? FileManager.default
.destinationOfSymbolicLink(atPath: "\(Paths.binPath)/nginx") else { return false }
return
// Verify that the `nginx` binary is symlinked to a directory that includes `nginx-full`.
destination.contains("/nginx-full/")
// Verify that the formula exists.
&& !Shell.pipe("\(Paths.brew) info nginx-full --json")
.contains("Error: No available formula")
}()
/** /**
It is possible to have the `shivammathur/php` tap installed, and for the core homebrew information to be outdated. It is possible to have the `shivammathur/php` tap installed, and for the core homebrew information to be outdated.
This will then result in two different aliases claiming to point to the same formula (`php`). This will then result in two different aliases claiming to point to the same formula (`php`).
@ -128,10 +143,10 @@ class HomebrewDiagnostics {
} }
/** /**
In order to see if we support the --json syntax, we'll query nginx. In order to see if we support the --json syntax, we'll query dnsmasq.
If the JSON response cannot be parsed, Homebrew is probably out of date. If the JSON response cannot be parsed, Homebrew is probably out of date.
*/ */
public static func cannotLoadService(_ name: String = "nginx") -> Bool { public static func cannotLoadService(_ name: String) -> Bool {
let serviceInfo = try? JSONDecoder().decode( let serviceInfo = try? JSONDecoder().decode(
[HomebrewService].self, [HomebrewService].self,
from: Shell.pipe( from: Shell.pipe(

View File

@ -29,12 +29,16 @@ extension MainMenu {
When the environment is all clear and the app can run, let's go. When the environment is all clear and the app can run, let's go.
*/ */
private func onEnvironmentPass() { private func onEnvironmentPass() {
// Determine install method
Log.info(HomebrewDiagnostics.customCaskInstalled Log.info(HomebrewDiagnostics.customCaskInstalled
? "The app has probably been installed via Homebrew Cask." ? "The app has probably been installed via Homebrew Cask."
: "The app has probably been installed directly." : "The app has probably been installed directly."
) )
Log.info(HomebrewDiagnostics.usesNginxFullFormula
? "The app will be using the `nginx-full` formula."
: "The app will be using the `nginx` formula."
)
// Attempt to find out more info about Valet // Attempt to find out more info about Valet
if Valet.shared.version != nil { if Valet.shared.version != nil {
Log.info("PHP Monitor has extracted the version number of Valet: \(Valet.shared.version!)") Log.info("PHP Monitor has extracted the version number of Valet: \(Valet.shared.version!)")

View File

@ -17,9 +17,9 @@ struct ServicesView: View {
static func asMenuItem(perRow: Int = 3) -> NSMenuItem { static func asMenuItem(perRow: Int = 3) -> NSMenuItem {
let item = NSMenuItem() let item = NSMenuItem()
var services = [ var services = [
PhpEnv.phpInstall.formula, Homebrew.Formulae.php,
"nginx", Homebrew.Formulae.nginx,
"dnsmasq" Homebrew.Formulae.dnsmasq
] ]
if Preferences.custom.hasServices() { if Preferences.custom.hasServices() {

View File

@ -139,6 +139,9 @@
"domain_list.add.domain_name" = "Domain name"; "domain_list.add.domain_name" = "Domain name";
"domain_list.add.create_proxy" = "Create Proxy"; "domain_list.add.create_proxy" = "Create Proxy";
"domain_list.add.proxy_available" = "%@ will be proxied and will be available via: %@://%@.%@"; "domain_list.add.proxy_available" = "%@ will be proxied and will be available via: %@://%@.%@";
"domain_list.add.proxy_https_warning" = "%@ will be proxied and will be available via: %@://%@.%@.
(!) IMPORTANT: This proxy may not work until you manually add `proxy_ssl_verify off;` to the nginx configuration file for this domain. It is recommended that you use an unsecured domain as the proxy subject.";
// ADD SITE TO DOMAINS LIST // ADD SITE TO DOMAINS LIST