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

🔀 Merge branch 'develop'

* develop:
  📝 Changes to the README, bump version number
  ♻️ Menu refactor
  ♻️ Use Localizable.strings
  ♻️ Change default shell for commands, cleanup files
This commit is contained in:
2020-05-17 00:22:09 +02:00
12 changed files with 253 additions and 172 deletions

View File

@ -16,6 +16,8 @@
C41C1B4D22B0215A00E7CF16 /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C41C1B4C22B0215A00E7CF16 /* Actions.swift */; };
C42295DD2358D02000E263B2 /* Command.swift in Sources */ = {isa = PBXBuildFile; fileRef = C42295DC2358D02000E263B2 /* Command.swift */; };
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46FA23E246C358E00944F05 /* StringExtension.swift */; };
C473319F2470923A009A0597 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C473319E2470923A009A0597 /* Localizable.strings */; };
C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C47331A1247093B7009A0597 /* StatusMenu.swift */; };
C476FF9822B0DD830098105B /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = C476FF9722B0DD830098105B /* Alert.swift */; };
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2322D70A4700B5F6B3 /* App.swift */; };
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; };
@ -37,6 +39,8 @@
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>"; };
C46FA23E246C358E00944F05 /* StringExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringExtension.swift; sourceTree = "<group>"; };
C473319E2470923A009A0597 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = "<group>"; };
C47331A1247093B7009A0597 /* StatusMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusMenu.swift; sourceTree = "<group>"; };
C476FF9722B0DD830098105B /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = "<group>"; };
C4811D2322D70A4700B5F6B3 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenu.swift; sourceTree = "<group>"; };
@ -86,6 +90,7 @@
C41C1B3F22B0098000E7CF16 /* Info.plist */,
C41C1B4022B0098000E7CF16 /* phpmon.entitlements */,
C41C1B3A22B0098000E7CF16 /* Assets.xcassets */,
C473319E2470923A009A0597 /* Localizable.strings */,
);
path = phpmon;
sourceTree = "<group>";
@ -93,6 +98,7 @@
C41E181722CB61EB0072CF09 /* Classes */ = {
isa = PBXGroup;
children = (
C47331A0247093AC009A0597 /* Menu */,
C4811D2722D70D8E00B5F6B3 /* Commands */,
C4811D2822D70D9C00B5F6B3 /* Helpers */,
);
@ -107,13 +113,21 @@
path = "View Controllers";
sourceTree = "<group>";
};
C47331A0247093AC009A0597 /* Menu */ = {
isa = PBXGroup;
children = (
C47331A1247093B7009A0597 /* StatusMenu.swift */,
);
path = Menu;
sourceTree = "<group>";
};
C4811D2622D70CEF00B5F6B3 /* Singletons */ = {
isa = PBXGroup;
children = (
C41C1B4622B009A400E7CF16 /* Shell.swift */,
C42295DC2358D02000E263B2 /* Command.swift */,
C4811D2322D70A4700B5F6B3 /* App.swift */,
C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */,
C42295DC2358D02000E263B2 /* Command.swift */,
);
path = Singletons;
sourceTree = "<group>";
@ -206,6 +220,7 @@
files = (
C41C1B3B22B0098000E7CF16 /* Assets.xcassets in Resources */,
C41C1B3E22B0098000E7CF16 /* Main.storyboard in Resources */,
C473319F2470923A009A0597 /* Localizable.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -227,6 +242,7 @@
C41C1B3722B0097F00E7CF16 /* AppDelegate.swift in Sources */,
C41C1B4B22B019FF00E7CF16 /* PhpVersion.swift in Sources */,
C476FF9822B0DD830098105B /* Alert.swift in Sources */,
C47331A2247093B7009A0597 /* StatusMenu.swift in Sources */,
C46FA23F246C358E00944F05 /* StringExtension.swift in Sources */,
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */,
);
@ -369,14 +385,14 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 22;
DEVELOPMENT_TEAM = 8M54J5J787;
INFOPLIST_FILE = phpmon/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.9;
MARKETING_VERSION = 2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
@ -391,14 +407,14 @@
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 20;
CURRENT_PROJECT_VERSION = 22;
DEVELOPMENT_TEAM = 8M54J5J787;
INFOPLIST_FILE = phpmon/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MARKETING_VERSION = 1.9;
MARKETING_VERSION = 2.0;
PRODUCT_BUNDLE_IDENTIFIER = com.nicoverbruggen.phpmon;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;

View File

@ -1,20 +1,22 @@
# PHP Monitor
PHP Monitor (or phpmon) is a macOS utility that runs on your Mac and displays the active PHP version in your status bar. It also gives you quick access to various useful functionality (like switching PHP versions, restarting services, accessing configuration files, and more).
PHP Monitor (or phpmon) is a lightweight macOS utility app that runs on your Mac and displays the active PHP version in your status bar.
It also gives you quick access to various useful functionality (like switching PHP versions, restarting services, accessing configuration files, and more).
<img src="./docs/screenshot.png" width="278px" alt="phpmon screenshot"/>
For me, it comes in handy when running multiple versions of PHP with Homebrew and you wish to be able to see at a glance which version is currently linked & active with Laravel Valet, and switch between versions.
For me, it comes in handy when running multiple versions of PHP with Homebrew. If you wish to be able to see at a glance which version is currently linked & active with Laravel Valet, PHP Monitor is your new best friend.
It's also super convenient to and switch between versions.
## System requirements
* macOS 10.15 Catalina
* PHP 7.4 installed with Homebrew 2.x
- other versions of PHP are optional
- includes support for PHP 5.6 and PHP 7.0 [as well](https://github.com/eXolnet/homebrew-deprecated)
* Laravel Valet 2.8
* Laravel Valet 2.x
If you're looking to run PHP Monitor in combination with an older version of macOS or Laravel Valet, please check out the older releases of the software.
_Please note that future versions of PHP will not work automatically, minor changes are required to add support for newer versions of PHP._
## Why I built this
@ -26,7 +28,7 @@ Initially, I had an Alfred workflow for this. But this does the job as well, whi
### Version detection
This utility runs `php -r 'print phpversion();'` in the background periodically (every 60 seconds) and extracts the version number.
This utility runs `php -r 'print phpversion()'` in the background periodically (every 60 seconds).
### Switching PHP versions
@ -54,7 +56,7 @@ This app isn't very complicated after all. In the end, this just (conveniently)
## Troubleshooting
---
**If you are having issues, the first thing you should be doing is installing the latest version of PHP Monitor. This can resolve a variety of issues.**
### Reasons for alerts at startup
@ -69,11 +71,25 @@ PHP Monitor performs some integrity checks to ensure a good experience when usin
Follow instructions as specified in the alert in order to resolve any issues.
---
### Additional troubleshooting
### Laravel Valet is using a different version of PHP than what is active in PHP Monitor and in my terminal!
#### Q: I want PHP Monitor to start up when I boot my Mac!
If you're still seeing another version of PHP in your scripts — e.g. when running `phpinfo()` — I recommend you shut down all PHP services that are currently active. You can find out what services are active by running:
You can do this by dragging *PHP Monitor.app* into the **Login Items** section in **System Preferences > Users & Groups** for your account.
Super convenient!
#### Q: PHP Monitor says that the latest version of PHP is not installed, but it is!
Try installing again using `brew install php@7.4`.
This should resolve the issue.
#### Q: PHP Monitor reports another version compared to phpinfo on my local website, what is going on?
_Beginning with version 2.0 you'll get alerts about this at startup._
If you're still seeing another version of PHP in your scripts running on your local webserver (nginx) — e.g. when running `phpinfo()` — I recommend you shut down all PHP services that are currently active. You can find out what services are active by running:
sudo brew services list | grep php
@ -110,7 +126,9 @@ The easiest way to make sure that PHP Monitor works again is to run the followin
sudo brew services stop php@5.6
sudo brew services stop nginx
Then, in PHP Monitor, select "Restart php-fpm service", which should start the service. Alternatively, you can run `sudo brew services start php@{x}` where `{x}` is your preferred version of PHP (for the latest version of PHP, you can omit `@{x}`).
Then, in PHP Monitor, select "Restart php-fpm service", which should start the service.
Alternatively, you can run `sudo brew services start php@7.4` where `7.4` is your preferred version of PHP (for the latest version of PHP, you may omit `@7.4` like in the example above).
---

View File

@ -65,6 +65,11 @@ class Actions {
}
}
public static func openGenericPhpConfigFolder() {
let files = [NSURL(fileURLWithPath: "/usr/local/etc/php")];
NSWorkspace.shared.activateFileViewerSelecting(files as [URL])
}
public static func openPhpConfigFolder(version: String) {
let files = [NSURL(fileURLWithPath: "/usr/local/etc/php/\(version)/php.ini")];
NSWorkspace.shared.activateFileViewerSelecting(files as [URL])
@ -75,7 +80,7 @@ class Actions {
NSWorkspace.shared.activateFileViewerSelecting(files as [URL])
}
public static func XdebugFound(_ version: String) -> Bool {
public static func didFindXdebug(_ version: String) -> Bool {
let command = """
grep -q 'zend_extension="xdebug.so"' /usr/local/etc/php/\(version)/php.ini; [ $? -eq 0 ] && echo "YES" || echo "NO"
"""
@ -83,7 +88,7 @@ class Actions {
return (output == "YES")
}
public static func XdebugEnabled(_ version: String) -> Bool {
public static func didEnableXdebug(_ version: String) -> Bool {
let command = """
grep -q '; zend_extension="xdebug.so"' /usr/local/etc/php/\(version)/php.ini; [ $? -eq 0 ] && echo "YES" || echo "NO"
"""
@ -96,7 +101,7 @@ class Actions {
var command = """
sed -i '' 's/; zend_extension="xdebug.so"/zend_extension="xdebug.so"/g' /usr/local/etc/php/\(version!)/php.ini
"""
if (self.XdebugEnabled(version!)) {
if (self.didEnableXdebug(version!)) {
command = """
sed -i '' 's/zend_extension="xdebug.so"/; zend_extension="xdebug.so"/g' /usr/local/etc/php/\(version!)/php.ini
"""

View File

@ -21,7 +21,7 @@ class Startup {
self.presentAlertOnMainThreadIf(
!Shell.user.pipe("ls /usr/local/opt | grep php@7.4").contains("php@7.4"),
messageText: "PHP 7.4 is not correctly installed",
informativeText: "PHP 7.4 alias was not found in `/usr/local/opt`. The app will not work correctly until you resolve this issue."
informativeText: "PHP 7.4 alias was not found in `/usr/local/opt`. The app will not work correctly until you resolve this issue. If you already have the `php` formula installed, you may need to run `brew install php@7.4` in order for PHP Monitor to detect this installation."
)
self.presentAlertOnMainThreadIf(

View File

@ -38,9 +38,9 @@ class PhpVersion {
self.short = segments[0...1].joined(separator: ".")
// Load xdebug support
self.xdebugFound = Actions.XdebugFound(self.short)
self.xdebugFound = Actions.didFindXdebug(self.short)
if (self.xdebugFound) {
self.xdebugEnabled = Actions.XdebugEnabled(self.short)
self.xdebugEnabled = Actions.didEnableXdebug(self.short)
}
self.error = false;

View File

@ -0,0 +1,88 @@
//
// MainMenuBuilder.swift
// PHP Monitor
//
// Created by Nico Verbruggen on 16/05/2020.
// Copyright © 2020 Nico Verbruggen. All rights reserved.
//
import Cocoa
class StatusMenu : NSMenu {
public func addPhpVersionMenuItems()
{
var string = "We are not sure what version of PHP you are running."
if (App.shared.currentVersion != nil) {
if (!App.shared.currentVersion!.error) {
string = "You are running PHP \(App.shared.currentVersion!.long)"
self.addItem(NSMenuItem(title: string, action: nil, keyEquivalent: ""))
} else {
// in case of an error show the error message
self.addItem(NSMenuItem(title: "Oof! It appears your PHP installation is broken...", action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "Try running `php -v` in your terminal.", action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "You could also try switching to another version.", action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "Running `brew reinstall php` (or for the equivalent version) might help.", action: nil, keyEquivalent: ""))
}
}
}
public func addPhpActionMenuItems()
{
if (App.shared.availablePhpVersions.count > 0 && !App.shared.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 menuItem = NSMenuItem(title: "Switch to PHP \(version)", action: (version == App.shared.currentVersion?.short) ? nil : action, keyEquivalent: "\(shortcutKey)")
menuItem.tag = index
shortcutKey = shortcutKey + 1
self.addItem(menuItem)
}
self.addItem(NSMenuItem.separator())
self.addItem(NSMenuItem(title: "Active Services", action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "Restart php-fpm service", action: #selector(MainMenu.restartPhpFpm), keyEquivalent: "f"))
self.addItem(NSMenuItem(title: "Restart nginx service", action: #selector(MainMenu.restartNginx), keyEquivalent: "n"))
self.addItem(NSMenuItem(title: "Force load latest PHP version", action: #selector(MainMenu.forceRestartLatestPhp), keyEquivalent: ""))
}
if (App.shared.busy) {
self.addItem(NSMenuItem(title: "PHP Monitor is busy...", action: nil, keyEquivalent: ""))
}
}
public func addPhpConfigurationMenuItems()
{
if (App.shared.currentVersion != nil) {
self.addItem(NSMenuItem(title: "Configuration", action: nil, keyEquivalent: ""))
self.addItem(NSMenuItem(title: "Valet configuration (.config/valet)", action: #selector(MainMenu.openValetConfigFolder), keyEquivalent: "v"))
self.addItem(NSMenuItem(title: "PHP configuration file (php.ini)", action: #selector(MainMenu.openActiveConfigFolder), keyEquivalent: "c"))
self.addItem(NSMenuItem.separator())
self.addItem(NSMenuItem(title: "Enabled Extensions", action: nil, keyEquivalent: ""))
self.addXdebugMenuItem()
}
}
private func addXdebugMenuItem()
{
let xdebugFound = App.shared.currentVersion!.xdebugFound
if (xdebugFound) {
let xdebugOn = App.shared.currentVersion!.xdebugEnabled
let xdebugToggleMenuItem = NSMenuItem(
title: "Xdebug",
action: #selector(MainMenu.toggleXdebug), keyEquivalent: "x"
)
if (xdebugOn) {
xdebugToggleMenuItem.state = .on
}
self.addItem(xdebugToggleMenuItem)
} else {
let disabledItem = NSMenuItem(
title: "xdebug.so missing",
action: nil, keyEquivalent: "x"
)
disabledItem.isEnabled = false
self.addItem(disabledItem)
}
}
}

View File

@ -10,8 +10,7 @@ import Cocoa
extension Date
{
func toString() -> String
{
func toString() -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
return dateFormatter.string(from: self)

View File

@ -9,14 +9,24 @@
import Foundation
extension String {
var localized: String {
return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "")
}
func countInstances(of stringToFind: String) -> Int {
assert(!stringToFind.isEmpty)
if (stringToFind.isEmpty) {
return 0
}
var count = 0
var searchRange: Range<String.Index>?
while let foundRange = range(of: stringToFind, options: [], range: searchRange) {
count += 1
searchRange = Range(uncheckedBounds: (lower: foundRange.upperBound, upper: endIndex))
}
return count
}
}

View File

@ -0,0 +1,17 @@
/*
Strings.strings
PHP Monitor
Created by Nico Verbruggen on 16/05/2020.
Copyright © 2020 Nico Verbruggen. All rights reserved.
*/
// ALERTS
// Force Reload Started
"alert.force_reload.title" = "PHP Monitor will force reload the latest version of PHP";
"alert.force_reload.info" = "This can take a while. You'll get another alert when the force reload has completed.";
// Force Reload Done
"alert.force_reload_done.title" = "PHP has been force reloaded";
"alert.force_reload_done.info" = "All appropriate services have been restarted, and the latest version of PHP is now active. You can now try switching to another version of PHP.";

View File

@ -10,6 +10,7 @@ import Cocoa
class Command {
/// Immediately executes a command.
public static func execute(path: String, arguments: [String]) -> String {
let task = Process()
task.launchPath = path
@ -24,27 +25,4 @@ class Command {
return output;
}
public static func experiment() {
/*
print("Running '/usr/local/bin/php -v' directly...")
print("========================================")
var start = DispatchTime.now()
print(Command.execute(path: "/usr/local/bin/php", arguments: ["-v"]))
var end = DispatchTime.now()
var nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
var timeInterval = Double(nanoTime) / 1_000_000_000
print("Time to run command directly: \(timeInterval) seconds")
print("")
print("Running 'bash -> php -v'...")
print("========================================")
start = DispatchTime.now()
print(Shell.user.pipe("php -v"))
end = DispatchTime.now()
nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds
timeInterval = Double(nanoTime) / 1_000_000_000
print("Time to run command via bash: \(timeInterval) seconds")
*/
}
}

View File

@ -39,75 +39,31 @@ class MainMenu: NSObject, NSWindowDelegate {
public func update() {
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
let menu = NSMenu()
var string = "We are not sure what version of PHP you are running."
if (App.shared.currentVersion != nil) {
if (!App.shared.currentVersion!.error) {
string = "You are running PHP \(App.shared.currentVersion!.long)"
menu.addItem(NSMenuItem(title: string, action: nil, keyEquivalent: ""))
} else {
// in case of an error show the error message
menu.addItem(NSMenuItem(title: "Oof! It appears your PHP installation is broken...", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "Try running `php -v` in your terminal.", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "You could also try switching to another version.", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "Running `brew reinstall php` (or for the equivalent version) might help.", action: nil, keyEquivalent: ""))
}
}
// Create a new menu
let menu = StatusMenu()
// Add the PHP versions (or error messages)
menu.addPhpVersionMenuItems()
menu.addItem(NSMenuItem.separator())
if (App.shared.availablePhpVersions.count > 0 && !App.shared.busy) {
var shortcutKey = 1
for index in (0..<App.shared.availablePhpVersions.count).reversed() {
let version = App.shared.availablePhpVersions[index]
let action = #selector(self.switchToPhpVersion(sender:))
let menuItem = NSMenuItem(title: "Switch to PHP \(version)", action: (version == App.shared.currentVersion?.short) ? nil : action, keyEquivalent: "\(shortcutKey)")
menuItem.tag = index
shortcutKey = shortcutKey + 1
menu.addItem(menuItem)
}
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: "Active Services", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "Restart php-fpm service", action: #selector(self.restartPhpFpm), keyEquivalent: "f"))
menu.addItem(NSMenuItem(title: "Restart nginx service", action: #selector(self.restartNginx), keyEquivalent: "n"))
menu.addItem(NSMenuItem(title: "Force load latest PHP version", action: #selector(self.fixMyPhp), keyEquivalent: ""))
menu.addItem(NSMenuItem.separator())
}
if (App.shared.busy) {
menu.addItem(NSMenuItem(title: "PHP Monitor is busy...", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem.separator())
}
if (App.shared.currentVersion != nil) {
menu.addItem(NSMenuItem(title: "Configuration", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "Valet configuration (.config/valet)", action: #selector(self.openValetConfigFolder), keyEquivalent: "v"))
menu.addItem(NSMenuItem(title: "PHP configuration file (php.ini)", action: #selector(self.openActiveConfigFolder), keyEquivalent: "c"))
menu.addItem(NSMenuItem.separator())
menu.addItem(NSMenuItem(title: "Enabled Extensions", action: nil, keyEquivalent: ""))
let xdebugFound = App.shared.currentVersion!.xdebugFound
if (xdebugFound) {
let xdebugOn = App.shared.currentVersion!.xdebugEnabled
let xdebugToggleMenuItem = NSMenuItem(
title: "Xdebug",
action: #selector(self.toggleXdebug), keyEquivalent: "x"
)
if (xdebugOn) {
xdebugToggleMenuItem.state = .on
}
menu.addItem(xdebugToggleMenuItem)
} else {
let disabledItem = NSMenuItem(
title: "xdebug.so missing",
action: nil, keyEquivalent: "x"
)
disabledItem.isEnabled = false
menu.addItem(disabledItem)
}
}
// Add the possible actions
menu.addPhpActionMenuItems()
menu.addItem(NSMenuItem.separator())
// Add information about services & actions
menu.addPhpConfigurationMenuItems()
menu.addItem(NSMenuItem.separator())
// Add about & quit menu items
menu.addItem(NSMenuItem(title: "About PHP Monitor", action: #selector(self.openAbout), keyEquivalent: ""))
menu.addItem(NSMenuItem(title: "Quit PHP Monitor", action: #selector(self.terminateApp), keyEquivalent: "q"))
// Make sure every item can be interacted with
menu.items.forEach({ (item) in
item.target = self
})
menu.addItem(NSMenuItem(title: "Quit PHP Monitor", action: #selector(NSApplication.terminate(_:)), keyEquivalent: "q"))
// Update the menu item on the main thread
DispatchQueue.main.async {
self.statusItem.menu = menu
}
@ -115,11 +71,7 @@ class MainMenu: NSObject, NSWindowDelegate {
}
func setStatusBarImage(version: String) {
self.setStatusBar(
image: MenuBarImageGenerator.textToImage(
text: version
)
)
self.setStatusBar(image: MenuBarImageGenerator.textToImage(text: version))
}
func setStatusBar(image: NSImage) {
@ -129,7 +81,25 @@ class MainMenu: NSObject, NSWindowDelegate {
}
}
// MARK: - Callable via Obj-C (#selector)
// MARK: - Nicer callbacks
private func waitAndExecute(_ execute: @escaping () -> Void, _ completion: @escaping () -> Void = {})
{
App.shared.busy = true
self.setBusyImage()
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
self.update()
execute()
App.shared.busy = false
DispatchQueue.main.async {
self.updatePhpVersionInStatusBar()
self.update()
completion()
}
}
}
// MARK: - Actions & Menu Manipulation
@objc func updatePhpVersionInStatusBar() {
App.shared.currentVersion = PhpVersion()
@ -151,21 +121,6 @@ class MainMenu: NSObject, NSWindowDelegate {
}
}
private func waitAndExecute(_ execute: @escaping () -> Void)
{
App.shared.busy = true
self.setBusyImage()
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
self.update()
execute()
App.shared.busy = false
DispatchQueue.main.async {
self.updatePhpVersionInStatusBar()
self.update()
}
}
}
@objc public func restartPhpFpm() {
self.waitAndExecute({
Actions.restartPhpFpm()
@ -178,13 +133,34 @@ class MainMenu: NSObject, NSWindowDelegate {
})
}
@objc public func openAbout() {
NSApplication.shared.activate(ignoringOtherApps: true)
NSApplication.shared.orderFrontStandardAboutPanel()
@objc public func toggleXdebug() {
self.waitAndExecute({
Actions.toggleXdebug()
})
}
@objc public func forceRestartLatestPhp() {
Alert.present(
messageText: "alert.force_reload.title".localized,
informativeText: "alert.force_reload.info".localized
)
self.waitAndExecute({ Actions.fixMyPhp() }, {
Alert.present(
messageText: "alert.force_reload_done.title".localized,
informativeText: "alert.force_reload_done.info".localized
)
})
}
@objc public func openActiveConfigFolder() {
Actions.openPhpConfigFolder(version: App.shared.currentVersion!.short)
if (App.shared.currentVersion!.error) {
// php version was not identified
Actions.openGenericPhpConfigFolder()
} else {
// php version was identified
Actions.openPhpConfigFolder(version: App.shared.currentVersion!.short)
}
}
@objc public func openValetConfigFolder() {
@ -216,37 +192,17 @@ class MainMenu: NSObject, NSWindowDelegate {
}
}
@objc public func toggleXdebug() {
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
DispatchQueue.main.async {
self.setStatusBar(image: NSImage(named: NSImage.Name("StatusBarIcon"))!)
}
Actions.toggleXdebug()
DispatchQueue.main.async {
self.updatePhpVersionInStatusBar()
self.update()
}
}
@objc public func openAbout() {
NSApplication.shared.activate(ignoringOtherApps: true)
NSApplication.shared.orderFrontStandardAboutPanel()
}
@objc public func fixMyPhp() {
DispatchQueue.global(qos: .userInitiated).async { [unowned self] in
DispatchQueue.main.async {
Alert.present(messageText: "PHP Monitor will force reload the latest version of PHP", informativeText: "This can take a while. You'll get another alert when the force reload has completed.")
App.shared.busy = true
self.updatePhpVersionInStatusBar()
self.update()
}
Actions.fixMyPhp()
DispatchQueue.main.async {
Alert.present(messageText: "PHP has been force reloaded", informativeText: "All appropriate services have been restarted, and the latest version of PHP is now active. You can now try switching to another version of PHP.")
App.shared.busy = false
self.updatePhpVersionInStatusBar()
self.update()
}
}
@objc public func terminateApp() {
NSApplication.shared.terminate(nil)
}
// MARK: - Cleanup when window closes
func windowWillClose(_ notification: Notification) {
App.shared.windowController = nil
Shell.user.delegate = nil

View File

@ -40,9 +40,9 @@ class Shell {
}
/// Runs a shell command and returns the output.
public func pipe(_ command: String) -> String {
public func pipe(_ command: String, shell: String = "/bin/sh") -> String {
let task = Process()
task.launchPath = "/bin/bash"
task.launchPath = shell
task.arguments = ["--login", "-c", command]
let pipe = Pipe()
@ -51,13 +51,7 @@ class Shell {
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output: String = NSString(
data: data,
encoding: String.Encoding.utf8.rawValue
)!.replacingOccurrences(
of: "\u{1B}(B\u{1B}[m",
with: ""
) as String
let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
let historyItem = ShellHistoryItem(command: command, output: output)