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

🎨 Cleanup code

This commit is contained in:
2021-01-26 18:42:26 +01:00
parent 0f6e47a594
commit 77f4de8ca9
10 changed files with 258 additions and 205 deletions

View File

@ -15,7 +15,7 @@
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3C22B0098000E7CF16 /* Main.storyboard */; }; C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = C41C1B3C22B0098000E7CF16 /* Main.storyboard */; };
C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4622B009A400E7CF16 /* Shell.swift */; }; C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4622B009A400E7CF16 /* Shell.swift */; };
C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */; }; C41C1B4922B00A9800E7CF16 /* MenuBarImageGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */; };
C41C1B4B22B019FF00E7CF16 /* PhpVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4A22B019FF00E7CF16 /* PhpVersion.swift */; }; C41C1B4B22B019FF00E7CF16 /* PhpInstall.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4A22B019FF00E7CF16 /* PhpInstall.swift */; };
C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4C22B0215A00E7CF16 /* Actions.swift */; }; C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4C22B0215A00E7CF16 /* Actions.swift */; };
C42295DD2358D02000E263B2 /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42295DC2358D02000E263B2 /* Command.swift */; }; C42295DD2358D02000E263B2 /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42295DC2358D02000E263B2 /* Command.swift */; };
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA23E246C358E00944F05 /* StringExtension.swift */; }; C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA23E246C358E00944F05 /* StringExtension.swift */; };
@ -44,7 +44,7 @@
C41C1B4022B0098000E7CF16 /* phpmon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = phpmon.entitlements; sourceTree = "<group>"; }; C41C1B4022B0098000E7CF16 /* phpmon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = phpmon.entitlements; sourceTree = "<group>"; };
C41C1B4622B009A400E7CF16 /* Shell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shell.swift; sourceTree = "<group>"; }; C41C1B4622B009A400E7CF16 /* Shell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shell.swift; sourceTree = "<group>"; };
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBarImageGenerator.swift; sourceTree = "<group>"; }; C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBarImageGenerator.swift; sourceTree = "<group>"; };
C41C1B4A22B019FF00E7CF16 /* PhpVersion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpVersion.swift; sourceTree = "<group>"; }; C41C1B4A22B019FF00E7CF16 /* PhpInstall.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpInstall.swift; sourceTree = "<group>"; };
C41C1B4C22B0215A00E7CF16 /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; }; C41C1B4C22B0215A00E7CF16 /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
C42295DC2358D02000E263B2 /* Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = "<group>"; }; C42295DC2358D02000E263B2 /* Command.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Command.swift; sourceTree = "<group>"; };
C46FA23E246C358E00944F05 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; }; C46FA23E246C358E00944F05 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
@ -124,6 +124,7 @@
C41E181722CB61EB0072CF09 /* Classes */ = { C41E181722CB61EB0072CF09 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C4B13B1D25C4915000548C3A /* Core */,
C47331A0247093AC009A0597 /* Menu */, C47331A0247093AC009A0597 /* Menu */,
C4811D2722D70D8E00B5F6B3 /* Commands */, C4811D2722D70D8E00B5F6B3 /* Commands */,
C4811D2822D70D9C00B5F6B3 /* Helpers */, C4811D2822D70D9C00B5F6B3 /* Helpers */,
@ -173,14 +174,21 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
C476FF9722B0DD830098105B /* Alert.swift */, C476FF9722B0DD830098105B /* Alert.swift */,
C41C1B4A22B019FF00E7CF16 /* PhpVersion.swift */,
C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */, C41C1B4822B00A9800E7CF16 /* MenuBarImageGenerator.swift */,
C474B00524C0E98C00066A22 /* LocalNotification.swift */, C474B00524C0E98C00066A22 /* LocalNotification.swift */,
C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */,
); );
path = Helpers; path = Helpers;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
C4B13B1D25C4915000548C3A /* Core */ = {
isa = PBXGroup;
children = (
C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */,
C41C1B4A22B019FF00E7CF16 /* PhpInstall.swift */,
);
path = Core;
sourceTree = "<group>";
};
C4F8C0A222D4F100002EFE61 /* Extensions */ = { C4F8C0A222D4F100002EFE61 /* Extensions */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -273,7 +281,7 @@
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */, C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */,
C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */, C412E5FC25700D5300A1FB67 /* HomebrewPackage.swift in Sources */,
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */, C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */,
C41C1B4B22B019FF00E7CF16 /* PhpVersion.swift in Sources */, C41C1B4B22B019FF00E7CF16 /* PhpInstall.swift in Sources */,
C486EFFC2586931100A02B2C /* PhpMenuItem.swift in Sources */, C486EFFC2586931100A02B2C /* PhpMenuItem.swift in Sources */,
C49EAB46259FC305007F6C3B /* Paths.swift in Sources */, C49EAB46259FC305007F6C3B /* Paths.swift in Sources */,
C476FF9822B0DD830098105B /* Alert.swift in Sources */, C476FF9822B0DD830098105B /* Alert.swift in Sources */,

View File

@ -11,7 +11,10 @@ import AppKit
class Actions { class Actions {
public static func detectPhpVersions() -> [String] { // MARK: - Detect PHP Versions
public static func detectPhpVersions() -> [String]
{
let files = Shell.user.pipe("ls \(Paths.optPath()) | grep php@") let files = Shell.user.pipe("ls \(Paths.optPath()) | grep php@")
var versions = files.components(separatedBy: "\n") var versions = files.components(separatedBy: "\n")
@ -30,6 +33,7 @@ class Actions {
// The user may have `php` installed, but not e.g. `php@8.0` // The user may have `php` installed, but not e.g. `php@8.0`
// We should also detect that as a version that is installed // We should also detect that as a version that is installed
let phpAlias = App.shared.brewPhpVersion let phpAlias = App.shared.brewPhpVersion
if (!versionsOnly.contains(phpAlias)) { if (!versionsOnly.contains(phpAlias)) {
versionsOnly.append(phpAlias); versionsOnly.append(phpAlias);
} }
@ -37,23 +41,21 @@ class Actions {
return versionsOnly return versionsOnly
} }
public static func restartPhpFpm() { // MARK: - Services
let version = App.shared.currentVersion!.short
if (version == App.shared.brewPhpVersion) { public static func restartPhpFpm()
Shell.user.run("sudo \(Paths.brew()) services restart php") {
} else { brew("services restart \(App.phpInstall!.formula)", sudo: true)
Shell.user.run("sudo \(Paths.brew()) services restart php@\(version)")
}
} }
public static func restartNginx() public static func restartNginx()
{ {
Shell.user.run("sudo \(Paths.brew()) services restart nginx") brew("services restart nginx", sudo: true)
} }
public static func restartDnsMasq() public static func restartDnsMasq()
{ {
Shell.user.run("sudo \(Paths.brew()) services restart dnsmasq") brew("services restart dnsmasq", sudo: true)
} }
/** /**
@ -65,7 +67,8 @@ class Actions {
Please note that depending on which version is installed, Please note that depending on which version is installed,
the version that is switched to may or may not be identical to `php` (without @version). the version that is switched to may or may not be identical to `php` (without @version).
*/ */
public static func switchToPhpVersion(version: String, availableVersions: [String]) { public static func switchToPhpVersion(version: String, availableVersions: [String])
{
availableVersions.forEach { (available) in availableVersions.forEach { (available) in
let formula = (available == App.shared.brewPhpVersion) ? "php" : "php@\(available)" let formula = (available == App.shared.brewPhpVersion) ? "php" : "php@\(available)"
Shell.user.run("\(Paths.brew()) unlink \(formula)") Shell.user.run("\(Paths.brew()) unlink \(formula)")
@ -77,22 +80,30 @@ class Actions {
Shell.user.run("sudo \(Paths.brew()) services start \(formula)") Shell.user.run("sudo \(Paths.brew()) services start \(formula)")
} }
public static func openGenericPhpConfigFolder() { // MARK: - Finding Config Files
public static func openGenericPhpConfigFolder()
{
let files = [NSURL(fileURLWithPath: "\(Paths.etcPath())/php")]; let files = [NSURL(fileURLWithPath: "\(Paths.etcPath())/php")];
NSWorkspace.shared.activateFileViewerSelecting(files as [URL]) NSWorkspace.shared.activateFileViewerSelecting(files as [URL])
} }
public static func openPhpConfigFolder(version: String) { public static func openPhpConfigFolder(version: String)
{
let files = [NSURL(fileURLWithPath: "\(Paths.etcPath())/php/\(version)/php.ini")]; let files = [NSURL(fileURLWithPath: "\(Paths.etcPath())/php/\(version)/php.ini")];
NSWorkspace.shared.activateFileViewerSelecting(files as [URL]) NSWorkspace.shared.activateFileViewerSelecting(files as [URL])
} }
public static func openValetConfigFolder() { public static func openValetConfigFolder()
{
let files = [NSURL(fileURLWithPath: NSString(string: "~/.config/valet").expandingTildeInPath)]; let files = [NSURL(fileURLWithPath: NSString(string: "~/.config/valet").expandingTildeInPath)];
NSWorkspace.shared.activateFileViewerSelecting(files as [URL]) NSWorkspace.shared.activateFileViewerSelecting(files as [URL])
} }
public static func didFindXdebug(_ version: String) -> Bool { // MARK: - Xdebug Actions
public static func didFindXdebug(_ version: String) -> Bool
{
let command = """ let command = """
grep -q 'zend_extension="xdebug.so"' \(Paths.etcPath())/php/\(version)/php.ini; [ $? -eq 0 ] && echo "YES" || echo "NO" grep -q 'zend_extension="xdebug.so"' \(Paths.etcPath())/php/\(version)/php.ini; [ $? -eq 0 ] && echo "YES" || echo "NO"
""" """
@ -100,7 +111,8 @@ class Actions {
return (output == "YES") return (output == "YES")
} }
public static func didEnableXdebug(_ version: String) -> Bool { public static func didEnableXdebug(_ version: String) -> Bool
{
let command = """ let command = """
grep -q '; zend_extension="xdebug.so"' \(Paths.etcPath())/php/\(version)/php.ini; [ $? -eq 0 ] && echo "YES" || echo "NO" grep -q '; zend_extension="xdebug.so"' \(Paths.etcPath())/php/\(version)/php.ini; [ $? -eq 0 ] && echo "YES" || echo "NO"
""" """
@ -108,43 +120,48 @@ class Actions {
return (output == "NO") return (output == "NO")
} }
public static func toggleXdebug() { public static func toggleXdebug()
let version = App.shared.currentVersion?.short {
let version = App.phpInstall!.version.short
var command = """ var command = """
sed -i '' 's/; zend_extension="xdebug.so"/zend_extension="xdebug.so"/g' \(Paths.etcPath())/php/\(version!)/php.ini sed -i '' 's/; zend_extension="xdebug.so"/zend_extension="xdebug.so"/g' \(Paths.etcPath())/php/\(version)/php.ini
""" """
if (self.didEnableXdebug(version!)) { if (self.didEnableXdebug(version)) {
command = """ command = """
sed -i '' 's/zend_extension="xdebug.so"/; zend_extension="xdebug.so"/g' \(Paths.etcPath())/php/\(version!)/php.ini sed -i '' 's/zend_extension="xdebug.so"/; zend_extension="xdebug.so"/g' \(Paths.etcPath())/php/\(version)/php.ini
""" """
} }
Shell.user.run(command) Shell.user.run(command)
} }
// MARK: - Quick Fix
/** /**
Detects all currently available PHP versions, and unlinks each and every one of them. Detects all currently available PHP versions, and unlinks each and every one of them.
After this, the brew services are also stopped, the latest PHP version is linked, and php + nginx are restarted. After this, the brew services are also stopped, the latest PHP version is linked, and php + nginx are restarted.
If this does not solve the issue, the user may need to install additional extensions and/or run `composer global update`. If this does not solve the issue, the user may need to install additional extensions and/or run `composer global update`.
*/ */
public static func fixMyPhp() { public static func fixMyPhp()
Shell.user.run("sudo \(Paths.brew()) services stop dnsmasq") {
Shell.user.run("sudo \(Paths.brew()) services start dnsmasq") brew("services restart dnsmasq", sudo: true)
let versions = self.detectPhpVersions()
versions.forEach { (version) in self.detectPhpVersions().forEach { (version) in
Shell.user.run("\(Paths.brew()) unlink php@\(version)") let formula = (version == App.shared.brewPhpVersion) ? "php" : "php@\(version)"
if (version == App.shared.brewPhpVersion) { brew("unlink php@\(version)")
Shell.user.run("\(Paths.brew()) services stop php") brew("services stop \(formula)")
Shell.user.run("sudo \(Paths.brew()) services stop php") brew("services stop \(formula)", sudo: true)
} else {
Shell.user.run("\(Paths.brew()) services stop php@\(version)")
Shell.user.run("sudo \(Paths.brew()) services stop php@\(version)")
}
} }
Shell.user.run("\(Paths.brew()) services stop php")
Shell.user.run("\(Paths.brew()) services stop nginx") brew("services stop php")
Shell.user.run("\(Paths.brew()) link php") brew("services stop nginx")
Shell.user.run("sudo \(Paths.brew()) services restart dnsmasq") brew("link php")
Shell.user.run("sudo \(Paths.brew()) services restart php") brew("services restart dnsmasq", sudo: true)
Shell.user.run("sudo \(Paths.brew()) services restart nginx") brew("services stop php", sudo: true)
brew("services stop nginx", sudo: true)
}
private static func brew(_ command: String, sudo: Bool = false)
{
Shell.user.run("\(sudo ? "sudo " : "")" + "\(Paths.brew()) \(command)")
} }
} }

View File

@ -105,23 +105,17 @@ class Startup {
messageText: String, messageText: String,
informativeText: String, informativeText: String,
breaking: Bool breaking: Bool
) ) {
{ if (!condition) { return }
if (condition) {
// Only breaking issues will cause the notification self.failed = breaking
DispatchQueue.main.async {
// Present the information to the user
Alert.notify(message: messageText, info: informativeText)
// Only breaking issues will throw the extra retry modal
if (breaking) { if (breaking) {
self.failed = true self.failureCallback()
}
DispatchQueue.main.async {
// Present the information to the user
_ = Alert.present(
messageText: messageText,
informativeText: informativeText
)
// Only breaking issues will throw the extra retry modal
if (breaking) {
self.failureCallback()
}
} }
} }
} }

View File

@ -0,0 +1,64 @@
//
// PhpVersionExtractor.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 11/06/2019.
// Copyright © 2019 Nico Verbruggen. All rights reserved.
//
import Foundation
class PhpInstall {
var version: Version = Version()
var xdebug: Xdebug = Xdebug()
// MARK: - Computed
var formula: String {
return (self.version.short == App.shared.brewPhpVersion) ? "php" : "php@\(self.version.short)"
}
// MARK: - Initializer
init() {
let version = Command.execute(path: Paths.php(), arguments: ["-r", "print phpversion();"])
if (version == "" || version.contains("Warning")) {
self.version.short = "💩 BROKEN"
self.version.long = "";
self.version.error = true
return;
}
// That's the long version
self.version.long = version
// Next up, let's strip away the minor version number
let segments = self.version.long.components(separatedBy: ".")
// Get the first two elements
self.version.short = segments[0...1].joined(separator: ".")
// Determine the Xdebug status
self.xdebug = Xdebug(
found: Actions.didFindXdebug(self.version.short),
enabled: Actions.didEnableXdebug(self.version.short)
)
self.version.error = false
}
// MARK: - Structs
struct Version {
var short = "???"
var long = "???"
var error = false
}
struct Xdebug {
var found: Bool = false
var enabled: Bool = false
}
}

View File

@ -24,4 +24,8 @@ class Alert {
} }
return alert.runModal() == .alertFirstButtonReturn return alert.runModal() == .alertFirstButtonReturn
} }
public static func notify(message: String, info: String) {
_ = self.present(messageText: message, informativeText: info, buttonTitle: "OK", secondButtonTitle: "")
}
} }

View File

@ -1,51 +0,0 @@
//
// PhpVersionExtractor.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 11/06/2019.
// Copyright © 2019 Nico Verbruggen. All rights reserved.
//
import Foundation
class PhpVersion {
var short : String = "???"
var long : String = "???"
var xdebugFound: Bool = false
var xdebugEnabled : Bool = false
var error : Bool = false
init() {
let version = Command.execute(
path: Paths.php(),
arguments: ["-r", "print phpversion();"]
)
if (version == "" || version.contains("Warning")) {
self.short = "💩 BROKEN"
self.long = "";
self.error = true
return;
}
// That's the long version
self.long = version
// Next up, let's strip away the minor version number
let segments = long.components(separatedBy: ".")
// Get the first two elements
self.short = segments[0...1].joined(separator: ".")
// Load xdebug support
self.xdebugFound = Actions.didFindXdebug(self.short)
if (self.xdebugFound) {
self.xdebugEnabled = Actions.didEnableXdebug(self.short)
}
self.error = false;
}
}

View File

@ -12,86 +12,92 @@ class StatusMenu : NSMenu {
public func addPhpVersionMenuItems() public func addPhpVersionMenuItems()
{ {
var string = "mi_unsure".localized if (App.shared.currentInstall == nil) {
if (App.shared.currentVersion != nil) { return
if (!App.shared.currentVersion!.error) { }
// in case the php version loaded without issue
string = "\("mi_php_version".localized) \(App.shared.currentVersion!.long)" if (!App.phpInstall!.version.error) {
self.addItem(NSMenuItem(title: string, action: nil, keyEquivalent: "")) // in case the php version loaded without issue
} else { let string = "\("mi_php_version".localized) \(App.phpInstall!.version.long)"
// in case of an error show the error message self.addItem(NSMenuItem(title: string, action: nil, keyEquivalent: ""))
["mi_php_broken_1", "mi_php_broken_2", } else {
"mi_php_broken_3", "mi_php_broken_4"].forEach { (message) in // in case of an error show the error message
self.addItem(NSMenuItem(title: message.localized, action: nil, keyEquivalent: "")) ["mi_php_broken_1", "mi_php_broken_2",
} "mi_php_broken_3", "mi_php_broken_4"].forEach { (message) in
self.addItem(NSMenuItem(title: message.localized, action: nil, keyEquivalent: ""))
} }
} }
} }
public func addPhpActionMenuItems() public func addPhpActionMenuItems()
{ {
if (App.shared.availablePhpVersions.count > 0 && !App.shared.busy) { if App.busy {
var shortcutKey = 1
for index in (0..<App.shared.availablePhpVersions.count).reversed() {
let version = App.shared.availablePhpVersions[index]
let action = #selector(MainMenu.switchToPhpVersion(sender:))
let brew = (version == App.shared.brewPhpVersion) ? "php" : "php@\(version)"
let menuItem = PhpMenuItem(title: "\("mi_php_switch".localized) \(version) (\(brew))", action: (version == App.shared.currentVersion?.short) ? nil : action, keyEquivalent: "\(shortcutKey)")
menuItem.version = version
shortcutKey = shortcutKey + 1
self.addItem(menuItem)
}
self.addItem(NSMenuItem.separator())
self.addItem(NSMenuItem(title: "mi_active_services".localized, action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "mi_restart_dnsmasq".localized, action: #selector(MainMenu.restartDnsMasq), keyEquivalent: "d"))
self.addItem(NSMenuItem(title: "mi_restart_php_fpm".localized, action: #selector(MainMenu.restartPhpFpm), keyEquivalent: "p"))
self.addItem(NSMenuItem(title: "mi_restart_nginx".localized, action: #selector(MainMenu.restartNginx), keyEquivalent: "n"))
self.addItem(NSMenuItem(title: "mi_restart_all_services".localized, action: #selector(MainMenu.restartAllServices), keyEquivalent: "s"))
self.addItem(NSMenuItem.separator())
self.addItem(NSMenuItem(title: "mi_diagnostics".localized, action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "mi_force_load_latest".localized, action: #selector(MainMenu.forceRestartLatestPhp), keyEquivalent: "f"))
}
if (App.shared.busy) {
self.addItem(NSMenuItem(title: "mi_busy".localized, action: nil, keyEquivalent: "")) self.addItem(NSMenuItem(title: "mi_busy".localized, action: nil, keyEquivalent: ""))
return
} }
if App.shared.availablePhpVersions.count == 0 {
return
}
var shortcutKey = 1
for index in (0..<App.shared.availablePhpVersions.count).reversed() {
let version = App.shared.availablePhpVersions[index]
let action = #selector(MainMenu.switchToPhpVersion(sender:))
let brew = (version == App.shared.brewPhpVersion) ? "php" : "php@\(version)"
let menuItem = PhpMenuItem(
title: "\("mi_php_switch".localized) \(version) (\(brew))",
action: (version == App.phpInstall?.version.short) ? nil : action, keyEquivalent: "\(shortcutKey)"
)
menuItem.version = version
shortcutKey = shortcutKey + 1
self.addItem(menuItem)
}
self.addItem(NSMenuItem.separator())
self.addItem(NSMenuItem(title: "mi_active_services".localized, action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "mi_restart_dnsmasq".localized, action: #selector(MainMenu.restartDnsMasq), keyEquivalent: "d"))
self.addItem(NSMenuItem(title: "mi_restart_php_fpm".localized, action: #selector(MainMenu.restartPhpFpm), keyEquivalent: "p"))
self.addItem(NSMenuItem(title: "mi_restart_nginx".localized, action: #selector(MainMenu.restartNginx), keyEquivalent: "n"))
self.addItem(NSMenuItem(title: "mi_restart_all_services".localized, action: #selector(MainMenu.restartAllServices), keyEquivalent: "s"))
self.addItem(NSMenuItem.separator())
self.addItem(NSMenuItem(title: "mi_diagnostics".localized, action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "mi_force_load_latest".localized, action: #selector(MainMenu.forceRestartLatestPhp), keyEquivalent: "f"))
} }
public func addPhpConfigurationMenuItems() public func addPhpConfigurationMenuItems()
{ {
if (App.shared.currentVersion != nil) { if App.shared.currentInstall == nil {
self.addItem(NSMenuItem(title: "mi_configuration".localized, action: nil, keyEquivalent: "")) return
self.addItem(NSMenuItem(title: "mi_valet_config".localized, action: #selector(MainMenu.openValetConfigFolder), keyEquivalent: "v"))
self.addItem(NSMenuItem(title: "mi_php_config".localized, action: #selector(MainMenu.openActiveConfigFolder), keyEquivalent: "c"))
self.addItem(NSMenuItem(title: "mi_phpinfo".localized, action: #selector(MainMenu.openPhpInfo), keyEquivalent: "i"))
self.addItem(NSMenuItem.separator())
self.addItem(NSMenuItem(title: "mi_enabled_extensions".localized, action: nil, keyEquivalent: ""))
self.addXdebugMenuItem()
} }
self.addItem(NSMenuItem(title: "mi_configuration".localized, action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "mi_valet_config".localized, action: #selector(MainMenu.openValetConfigFolder), keyEquivalent: "v"))
self.addItem(NSMenuItem(title: "mi_php_config".localized, action: #selector(MainMenu.openActiveConfigFolder), keyEquivalent: "c"))
self.addItem(NSMenuItem(title: "mi_phpinfo".localized, action: #selector(MainMenu.openPhpInfo), keyEquivalent: "i"))
self.addItem(NSMenuItem.separator())
self.addItem(NSMenuItem(title: "mi_enabled_extensions".localized, action: nil, keyEquivalent: ""))
self.addXdebugMenuItem()
} }
private func addXdebugMenuItem() private func addXdebugMenuItem()
{ {
let xdebugFound = App.shared.currentVersion!.xdebugFound let xdebugFound = App.phpInstall!.xdebug.found
if (xdebugFound) { let xdebugOn = App.phpInstall!.xdebug.enabled
let xdebugOn = App.shared.currentVersion!.xdebugEnabled
let xdebugToggleMenuItem = NSMenuItem( let menuItem = NSMenuItem(
title: "mi_xdebug".localized, title: xdebugFound ? "mi_xdebug".localized : "mi_xdebug_missing".localized,
action: #selector(MainMenu.toggleXdebug), keyEquivalent: "x" action: #selector(MainMenu.toggleXdebug), keyEquivalent: "x"
) )
if (xdebugOn) {
xdebugToggleMenuItem.state = .on if (!xdebugFound) {
} menuItem.isEnabled = false
self.addItem(xdebugToggleMenuItem)
} else { } else {
let disabledItem = NSMenuItem( menuItem.state = xdebugOn ? .on : .off
title: "mi_xdebug_missing".localized,
action: nil, keyEquivalent: "x"
)
disabledItem.isEnabled = false
self.addItem(disabledItem)
} }
self.addItem(menuItem)
} }
} }

View File

@ -12,15 +12,23 @@ class App {
static let shared = App() static let shared = App()
static var phpInstall: PhpInstall? {
return App.shared.currentInstall
}
static var busy: Bool {
return App.shared.busy
}
/** /**
Whether the application is busy switching versions. Whether the application is busy switching versions.
*/ */
var busy: Bool = false var busy: Bool = false
/** /**
The currently active version of PHP. The currently active installation of PHP.
*/ */
var currentVersion: PhpVersion? = nil var currentInstall: PhpInstall? = nil
/** /**
All available versions of PHP. All available versions of PHP.

View File

@ -29,11 +29,9 @@ class MainMenu: NSObject, NSWindowDelegate {
self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!) self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
// Perform environment boot checks // Perform environment boot checks
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
Startup().checkEnvironment(success: { Startup().checkEnvironment(success: { self.onEnvironmentPass() },
self.onEnvironmentPass() failure: { self.onEnvironmentFail() }
}, failure: { )
self.onEnvironmentFail()
})
} }
} }
@ -66,11 +64,12 @@ class MainMenu: NSObject, NSWindowDelegate {
buttonTitle: "alert.cannot_start.close".localized, buttonTitle: "alert.cannot_start.close".localized,
secondButtonTitle: "alert.cannot_start.retry".localized secondButtonTitle: "alert.cannot_start.retry".localized
) )
if (!close) {
self.startup() if (close) {
} else {
exit(1) exit(1)
} }
self.startup()
} }
} }
@ -137,7 +136,7 @@ class MainMenu: NSObject, NSWindowDelegate {
while updating the UI as required. As long as the completion callback while updating the UI as required. As long as the completion callback
does not fire, the app is presumed to be busy and the UI reflects this. does not fire, the app is presumed to be busy and the UI reflects this.
- Parameter execute: Escaping callback of the work that needs to happen. - Parameter execute: Callback of the work that needs to happen.
- Parameter completion: Callback that is fired when the work is done. - Parameter completion: Callback that is fired when the work is done.
*/ */
private func waitAndExecute(_ execute: @escaping () -> Void, _ completion: @escaping () -> Void = {}) private func waitAndExecute(_ execute: @escaping () -> Void, _ completion: @escaping () -> Void = {})
@ -159,16 +158,16 @@ class MainMenu: NSObject, NSWindowDelegate {
// MARK: - User Interface // MARK: - User Interface
@objc func updatePhpVersionInStatusBar() { @objc func updatePhpVersionInStatusBar() {
App.shared.currentVersion = PhpVersion() App.shared.currentInstall = PhpInstall()
if (App.shared.busy) {
DispatchQueue.main.async { DispatchQueue.main.async {
if (App.shared.busy) {
self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!) self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
} } else {
} else { self.setStatusBarImage(version: App.phpInstall!.version.short)
DispatchQueue.main.async {
self.setStatusBarImage(version: App.shared.currentVersion!.short)
} }
} }
self.update() self.update()
} }
@ -223,28 +222,26 @@ class MainMenu: NSObject, NSWindowDelegate {
@objc public func forceRestartLatestPhp() { @objc public func forceRestartLatestPhp() {
// Tell the user the switch is about to occur // Tell the user the switch is about to occur
_ = Alert.present( Alert.notify(message: "alert.force_reload.title".localized, info: "alert.force_reload.info".localized)
messageText: "alert.force_reload.title".localized,
informativeText: "alert.force_reload.info".localized
)
// Start switching // Start switching
self.waitAndExecute({ Actions.fixMyPhp() }, { self.waitAndExecute(
_ = Alert.present( { Actions.fixMyPhp() },
messageText: "alert.force_reload_done.title".localized, { Alert.notify(
informativeText: "alert.force_reload_done.info".localized message: "alert.force_reload_done.title".localized,
) info: "alert.force_reload_done.info".localized
}) ) }
)
} }
@objc public func openActiveConfigFolder() { @objc public func openActiveConfigFolder() {
if (App.shared.currentVersion!.error) { if (App.phpInstall!.version.error) {
// php version was not identified // php version was not identified
Actions.openGenericPhpConfigFolder() Actions.openGenericPhpConfigFolder()
} else { return
// php version was identified
Actions.openPhpConfigFolder(version: App.shared.currentVersion!.short)
} }
// php version was identified
Actions.openPhpConfigFolder(version: App.phpInstall!.version.short)
} }
@objc public func openValetConfigFolder() { @objc public func openValetConfigFolder() {
@ -253,20 +250,26 @@ class MainMenu: NSObject, NSWindowDelegate {
@objc public func switchToPhpVersion(sender: PhpMenuItem) { @objc public func switchToPhpVersion(sender: PhpMenuItem) {
print("Switching to: PHP \(sender.version)") print("Switching to: PHP \(sender.version)")
self.setBusyImage() self.setBusyImage()
App.shared.busy = true App.shared.busy = true
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
// Update the PHP version in the status bar // Update the PHP version in the status bar
self.updatePhpVersionInStatusBar() self.updatePhpVersionInStatusBar()
// Update the menu // Update the menu
self.update() self.update()
// Switch the PHP version // Switch the PHP version
Actions.switchToPhpVersion( Actions.switchToPhpVersion(
version: sender.version, version: sender.version,
availableVersions: App.shared.availablePhpVersions availableVersions: App.shared.availablePhpVersions
) )
// Mark as no longer busy // Mark as no longer busy
App.shared.busy = false App.shared.busy = false
// Perform UI updates on main thread // Perform UI updates on main thread
DispatchQueue.main.async { DispatchQueue.main.async {
self.updatePhpVersionInStatusBar() self.updatePhpVersionInStatusBar()