Skip to content

Commit

Permalink
🚀 Version 6.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoverbruggen committed Sep 10, 2023
2 parents 94f3c1c + e40b9fe commit d5888c1
Show file tree
Hide file tree
Showing 67 changed files with 4,068 additions and 257 deletions.
408 changes: 272 additions & 136 deletions PHP Monitor.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 and Ventura are supported)
* macOS 12.4 or later (Monterey, Ventura and Sonoma are supported)
* Homebrew is installed in the default location (`/usr/local/homebrew` or `/opt/homebrew`)
* Homebrew `php` formula is installed
* Optional but recommended: Laravel Valet
Expand Down
5 changes: 3 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ Generally speaking, only the latest version of **PHP Monitor** is supported, exc

| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Recommended Valet Version |
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
| 6.0 | ✅ Universal binary | ✅ Yes | 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 |
| 6.1 | ✅ Universal binary | ✅ Yes | Monterey (12.4+)<br/>Ventura (13.0+)<br/>Sonoma (14.0) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.4 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.4 (w/ Valet 4.x)| 3.0 or higher recommended<br/> 2.16.2 minimum |

## Legacy versions

These versions of PHP Monitor are no longer supported, but if you’re using an older computer with an older version of Homebrew, Valet or macOS, you might want to use one of these versions.

| Version | Apple Silicon | Supported | Supported macOS | Deployment Target | Detected PHP Versions | Minimum Required Valet Version |
| ------- | ------------- | ------------------ | ----- | ----- | ----- | ----
| 5.8 | ✅ Universal binary | ✅ Yes | 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 |
| 6.0 | ✅ Universal binary || Monterey (12.4+)<br/>Ventura (13.0+) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.2 (w/ Valet 4.x) | 3.0 or higher recommended<br/> 2.16.2 minimum |
| 5.8 | ✅ Universal binary || Monterey (12.4+)<br/>Ventura (13.0+) | macOS 12.4 | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.2 (w/ Valet 4.x) | 3.0 or higher recommended<br/> 2.16.2 minimum |
| 5.7 | ✅ Universal binary || Big Sur (11.0)<br/>Monterey (12.0)<br/>Ventura (13.0) | macOS 11+ | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x)<br/>PHP 7.1-PHP 8.2 (w/ Valet 4.x) | 3.0 or higher recommended<br/> 2.16.2 minimum |
| 5.6 | ✅ Universal binary || Big Sur (11.0)<br/>Monterey (12.0)<br/>Ventura (13.0) | macOS 11+ | PHP 5.6—PHP 8.2 (w/ Valet 2.x)<br/>PHP 7.0—PHP 8.2 (w/ Valet 3.x) | 3.0 recommended<br/> 2.16.2 minimum |
| 4.1 | ✅ Universal binary || Big Sur (11.0)<br/>Monterey (12.0) | macOS 11+ | PHP 5.6—PHP 8.2 | 2.16.2 |
Expand Down
15 changes: 12 additions & 3 deletions phpmon/Common/Core/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,23 @@ struct Constants {
*/
static let MinimumRecommendedValetVersion = "2.16.2"

/**
* The PHP versions that are considered pre-release versions.
*/
static let ExperimentalPhpVersions: Set = [
"8.3", "8.4"
]

/**
* The PHP versions supported by this application.
* Any other PHP versions are considered invalid.
*/
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.0", "8.1", "8.2",
"8.3",
"8.4"
]

/**
Expand All @@ -42,13 +51,13 @@ struct Constants {
[
"7.0", "7.1", "7.2", "7.3", "7.4",
"8.0", "8.1", "8.2",
"8.3" // dev
"8.3", "8.4" // dev
],
4: // Valet v4 dropped support for v7.0
[
"7.1", "7.2", "7.3", "7.4",
"8.0", "8.1", "8.2",
"8.3" // dev
"8.3", "8.4" // dev
]
]

Expand Down
5 changes: 4 additions & 1 deletion phpmon/Common/Core/Paths.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ public class Paths {
}

userName = identity()
Log.info("The current username is `\(userName)`.")

if !isRunningSwiftUIPreview {
Log.info("The current username is `\(userName)`.")
}
}

public func detectBinaryPaths() {
Expand Down
23 changes: 19 additions & 4 deletions phpmon/Common/Extensions/StringExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,22 @@ struct Localization {

extension String {
var localized: String {
let string = NSLocalizedString(self, tableName: nil, bundle: Localization.bundle, value: "", comment: "")

// Fallback to English translation if the localized value is equal to the key (should not happen)
if string == self {
guard let path = Localization.bundle.path(forResource: "en", ofType: "lproj"),
let bundle = Bundle(path: path)
else { return self }
return NSLocalizedString(self, bundle: bundle, comment: "")
}

// Ensure that on more recent versions of macOS, "Preferences" is replaced with "Settings"
if #available(macOS 13, *) {
return NSLocalizedString(
self, tableName: nil, bundle: Localization.bundle, value: "", comment: ""
).replacingOccurrences(of: "Preferences", with: "Settings")
return string.replacingOccurrences(of: "Preferences", with: "Settings")
}

return NSLocalizedString(self, tableName: nil, bundle: Localization.bundle, value: "", comment: "")
return string
}

var localizedForSwiftUI: LocalizedStringKey {
Expand Down Expand Up @@ -131,4 +140,10 @@ extension String {
return ""
}
}

var isNumber: Bool {
return self.range(
of: "^[0-9]*$", // 1
options: .regularExpression) != nil
}
}
18 changes: 12 additions & 6 deletions phpmon/Common/Testables/TestableConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public struct TestableConfiguration: Codable {
self.filesystem = self.filesystem.merging([
"/opt/homebrew/opt/php@\(version.short)/bin/php"
: .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)/bin/php"),
"/opt/homebrew/opt/php@\(version.short)/bin/php-config"
: .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)/bin/php-config"),
"/opt/homebrew/Cellar/php/\(version.long)/bin/php"
: .fake(.binary),
"/opt/homebrew/Cellar/php/\(version.long)/bin/php-config"
Expand All @@ -70,6 +72,9 @@ public struct TestableConfiguration: Codable {
: .fake(.text)
]) { (_, new) in new }

self.commandOutput["/opt/homebrew/opt/php@\(version.short)/bin/php-config --version"]
= version.long

if primary {
self.shellOutput["ls /opt/homebrew/opt | grep php"]
= .instant("php")
Expand All @@ -80,20 +85,21 @@ public struct TestableConfiguration: Codable {
self.filesystem["/opt/homebrew/bin/php"]
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)/bin/php")
self.filesystem["/opt/homebrew/bin/php-config"]
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.long)/bin/php-config")
= .fake(.symlink, "/opt/homebrew/Cellar/php/\(version.short)/bin/php-config")
self.commandOutput["/opt/homebrew/bin/php-config --version"]
= version.long
self.commandOutput["/opt/homebrew/bin/php -r echo php_ini_scanned_files();"] =
"""
/opt/homebrew/etc/php/\(version.short)/conf.d/php-memory-limits.ini,
"""
} else {

self.shellOutput["ls /opt/homebrew/opt | grep php@"] =
BatchFakeShellOutput.instant(
self.secondaryPhpVersions
.map { "php@\($0.short)" }
.joined(separator: "\n")
)
BatchFakeShellOutput.instant(
self.secondaryPhpVersions
.map { "php@\($0.short)" }
.joined(separator: "\n")
)
}
}

Expand Down
4 changes: 2 additions & 2 deletions phpmon/Domain/App/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ class App {
var onboardingWindowController: OnboardingWindowController?

/** The window controller of the warnings window. */
var warningsWindowController: WarningsWindowController?
var phpDoctorWindowController: PhpDoctorWindowController?

/** The window controller of the warnings window. */
var versionManagerWindowController: PhpVersionManagerWindowController?
var phpVersionManagerWindowController: PhpVersionManagerWindowController?

/** List of detected (installed) applications that PHP Monitor can work with. */
var detectedApplications: [Application] = []
Expand Down
15 changes: 11 additions & 4 deletions phpmon/Domain/App/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
Log.info("Extra CLI mode is on (`~/.config/phpmon/verbose` exists).")
}

Log.separator(as: .info)
Log.info("PHP MONITOR by Nico Verbruggen")
Log.info("Version \(App.version)")
Log.separator(as: .info)
if !isRunningSwiftUIPreview {
Log.separator(as: .info)
Log.info("PHP MONITOR by Nico Verbruggen")
Log.info("Version \(App.version)")
Log.separator(as: .info)
}

self.state = App.shared
self.menu = MainMenu.shared
Expand All @@ -118,6 +120,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
startup procedure.
*/
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Prevent previews from kicking off a costly boot
if isRunningSwiftUIPreview {
return
}

// Make sure notifications will work
setupNotifications()

Expand Down
8 changes: 4 additions & 4 deletions phpmon/Domain/App/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,7 @@ Gw
</tableCellView>
</prototypeCellViews>
</tableColumn>
<tableColumn identifier="KIND" width="36" minWidth="36" maxWidth="36" id="7EV-ZL-92u">
<tableColumn identifier="KIND" width="50" minWidth="50" maxWidth="120" id="7EV-ZL-92u">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Kind">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
Expand All @@ -987,11 +987,11 @@ Gw
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="domainListKindCell" wantsLayer="YES" id="AhT-xR-16a" customClass="DomainListKindCell" customModule="PHP_Monitor" customModuleProvider="target">
<rect key="frame" x="403" y="0.0" width="36" height="54"/>
<rect key="frame" x="403" y="0.0" width="48" height="54"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="sYR-vb-OW1">
<rect key="frame" x="9" y="18" width="18" height="18"/>
<rect key="frame" x="15" y="18" width="18" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="18" id="XcB-uw-szU"/>
<constraint firstAttribute="height" constant="18" id="bGN-Vh-Sh0"/>
Expand Down Expand Up @@ -1024,7 +1024,7 @@ Gw
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="domainListTypeCell" wantsLayer="YES" id="ntU-Rl-ciP" customClass="DomainListTypeCell" customModule="PHP_Monitor" customModuleProvider="target">
<rect key="frame" x="456" y="0.0" width="97" height="54"/>
<rect key="frame" x="468" y="0.0" width="97" height="54"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="Ljl-8B-key">
Expand Down
10 changes: 5 additions & 5 deletions phpmon/Domain/App/Services/ServicesManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,22 @@ class ServicesManager: ObservableObject {

public var statusMessage: String {
if self.services.isEmpty || !self.firstRunComplete {
return "Loading..."
return "phpman.services.loading".localized
}

let statuses = self.services[0...2].map { $0.status }

if statuses.contains(.missing) {
return "A key service is not installed."
return "phpman.services.not_installed".localized
}
if statuses.contains(.error) {
return "A key service is reporting an error state."
return "phpman.services.error".localized
}
if statuses.contains(.inactive) {
return "A key service is not running."
return "phpman.services.inactive".localized
}

return "All Valet services are OK."
return "phpman.services.all_ok".localized
}

public var statusColor: Color {
Expand Down
1 change: 1 addition & 0 deletions phpmon/Domain/Integrations/Homebrew/Brew.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Brew {

/// Each formula for each PHP version that can be installed.
public static let phpVersionFormulae = [
"8.3": "shivammathur/php/[email protected]",
"8.2": "[email protected]",
"8.1": "[email protected]",
"8.0": "[email protected]",
Expand Down
17 changes: 17 additions & 0 deletions phpmon/Domain/Integrations/Homebrew/BrewFormula.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,28 @@ struct BrewFormula {
/// The upgrade that is currently available, if it exists.
let upgradeVersion: String?

/// Whether this formula is a stable version of PHP.
let prerelease: Bool

/// Whether the formula is currently installed.
var isInstalled: Bool {
return installedVersion != nil
}

init(
name: String,
displayName: String,
installedVersion: String?,
upgradeVersion: String?,
prerelease: Bool = false
) {
self.name = name
self.displayName = displayName
self.installedVersion = installedVersion
self.upgradeVersion = upgradeVersion
self.prerelease = prerelease
}

/// Whether the formula can be upgraded.
var hasUpgrade: Bool {
return upgradeVersion != nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class BrewFormulaeHandler: HandlesBrewFormulae {

return Brew.phpVersionFormulae.map { (version, formula) in
let fullVersion = PhpEnvironments.shared.cachedPhpInstallations[version]?.versionNumber.text

var upgradeVersion: String?

if let version = fullVersion {
Expand All @@ -56,7 +57,8 @@ class BrewFormulaeHandler: HandlesBrewFormulae {
name: formula,
displayName: "PHP \(version)",
installedVersion: fullVersion,
upgradeVersion: upgradeVersion
upgradeVersion: upgradeVersion,
prerelease: Constants.ExperimentalPhpVersions.contains(version)
)
}.sorted { $0.displayName > $1.displayName }
}
Expand Down
10 changes: 8 additions & 2 deletions phpmon/Domain/Integrations/Valet/Valet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,14 @@ class Valet {
)

if let defaultPath = Valet.shared.config.defaultSite,
let site = ValetScanner.active.resolveSite(path: defaultPath) {
sites.insert(site, at: 0)
let defaultSite = ValetScanner.active.resolveSite(path: defaultPath) {
// Only insert the default site if it isn't already included in the list
if !sites.contains(where: { site in
site.absolutePath == defaultSite.absolutePath
&& site.name == defaultSite.name
}) {
sites.insert(defaultSite, at: 0)
}
}

Log.info("\(sites.count) sites & \(proxies.count) proxies have been scanned.")
Expand Down
2 changes: 1 addition & 1 deletion phpmon/Domain/Menu/MainMenu.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ class MainMenu: NSObject, NSWindowDelegate, NSMenuDelegate, PhpSwitcherDelegate
}

@objc func openWarnings() {
WarningsWindowController.show()
PhpDoctorWindowController.show()
}

@objc func openDomainList() {
Expand Down
8 changes: 4 additions & 4 deletions phpmon/Domain/Preferences/PreferencesWindowController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,22 @@ class PreferencesWindowController: PMWindowController {
return [
PrefTabView(
viewController: GeneralPreferencesVC.fromStoryboard(),
label: "General",
label: "prefs.tabs.general".localized,
icon: "gearshape"
),
PrefTabView(
viewController: AppearancePreferencesVC.fromStoryboard(),
label: "Appearance",
label: "prefs.tabs.appearance".localized,
icon: "paintbrush"
),
PrefTabView(
viewController: MenuStructurePreferencesVC.fromStoryboard(),
label: "Visibility",
label: "prefs.tabs.visibility".localized,
icon: "eye"
),
PrefTabView(
viewController: NotificationPreferencesVC.fromStoryboard(),
label: "Notifications",
label: "prefs.tabs.notifications".localized,
icon: "bell.badge"
)
]
Expand Down
Loading

0 comments on commit d5888c1

Please sign in to comment.