mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 20:10:08 +02:00
✨ Allow toggling of PHP extensions in php.ini
This commit is contained in:
@ -26,6 +26,7 @@
|
|||||||
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2322D70A4700B5F6B3 /* App.swift */; };
|
C4811D2422D70A4700B5F6B3 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2322D70A4700B5F6B3 /* App.swift */; };
|
||||||
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; };
|
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */; };
|
||||||
C49EAB46259FC305007F6C3B /* Paths.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAB45259FC305007F6C3B /* Paths.swift */; };
|
C49EAB46259FC305007F6C3B /* Paths.swift in Sources */ = {isa = PBXBuildFile; fileRef = C49EAB45259FC305007F6C3B /* Paths.swift */; };
|
||||||
|
C4ACA38F25C754C100060C66 /* PhpExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4ACA38E25C754C100060C66 /* PhpExtension.swift */; };
|
||||||
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4D8016522B1584700C6DA1B /* Startup.swift */; };
|
||||||
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE188322D3386B00E126E5 /* Constants.swift */; };
|
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE188322D3386B00E126E5 /* Constants.swift */; };
|
||||||
C4F8C0A422D4F12C002EFE61 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F8C0A322D4F12C002EFE61 /* DateExtension.swift */; };
|
C4F8C0A422D4F12C002EFE61 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F8C0A322D4F12C002EFE61 /* DateExtension.swift */; };
|
||||||
@ -54,6 +55,7 @@
|
|||||||
C4811D2322D70A4700B5F6B3 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.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>"; };
|
C4811D2922D70F9A00B5F6B3 /* MainMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainMenu.swift; sourceTree = "<group>"; };
|
||||||
C49EAB45259FC305007F6C3B /* Paths.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Paths.swift; sourceTree = "<group>"; };
|
C49EAB45259FC305007F6C3B /* Paths.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Paths.swift; sourceTree = "<group>"; };
|
||||||
|
C4ACA38E25C754C100060C66 /* PhpExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhpExtension.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>"; };
|
||||||
C4E713562570150F00007428 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; };
|
C4E713562570150F00007428 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; };
|
||||||
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
||||||
@ -182,6 +184,7 @@
|
|||||||
children = (
|
children = (
|
||||||
C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */,
|
C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */,
|
||||||
C41C1B4A22B019FF00E7CF16 /* PhpInstall.swift */,
|
C41C1B4A22B019FF00E7CF16 /* PhpInstall.swift */,
|
||||||
|
C4ACA38E25C754C100060C66 /* PhpExtension.swift */,
|
||||||
);
|
);
|
||||||
path = Core;
|
path = Core;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -268,6 +271,7 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
C4ACA38F25C754C100060C66 /* PhpExtension.swift in Sources */,
|
||||||
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */,
|
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */,
|
||||||
C4F8C0A422D4F12C002EFE61 /* DateExtension.swift in Sources */,
|
C4F8C0A422D4F12C002EFE61 /* DateExtension.swift in Sources */,
|
||||||
C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */,
|
C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */,
|
||||||
|
@ -165,7 +165,7 @@ class Actions {
|
|||||||
/**
|
/**
|
||||||
Runs a `brew` command. Can run as superuser.
|
Runs a `brew` command. Can run as superuser.
|
||||||
*/
|
*/
|
||||||
private static func brew(_ command: String, sudo: Bool = false)
|
public static func brew(_ command: String, sudo: Bool = false)
|
||||||
{
|
{
|
||||||
Shell.run("\(sudo ? "sudo " : "")" + "\(Paths.brew) \(command)")
|
Shell.run("\(sudo ? "sudo " : "")" + "\(Paths.brew) \(command)")
|
||||||
}
|
}
|
||||||
@ -173,17 +173,15 @@ class Actions {
|
|||||||
/**
|
/**
|
||||||
Runs `sed` in order to replace all occurrences of a string in a specific file with another.
|
Runs `sed` in order to replace all occurrences of a string in a specific file with another.
|
||||||
*/
|
*/
|
||||||
private static func sed(file: String, original: String, replacement: String)
|
public static func sed(file: String, original: String, replacement: String)
|
||||||
{
|
{
|
||||||
Shell.run("""
|
Shell.run("sed -i '' 's/\(original)/\(replacement)/g' \(file)")
|
||||||
sed -i '' 's/\(original)/\(replacement)/g' \(file)
|
|
||||||
""")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Uses `grep` to determine whether a particular query string can be found in a particular file.
|
Uses `grep` to determine whether a particular query string can be found in a particular file.
|
||||||
*/
|
*/
|
||||||
private static func grepContains(file: String, query: String) -> Bool
|
public static func grepContains(file: String, query: String) -> Bool
|
||||||
{
|
{
|
||||||
return Shell.pipe("""
|
return Shell.pipe("""
|
||||||
grep -q '\(query)' \(file); [ $? -eq 0 ] && echo "YES" || echo "NO"
|
grep -q '\(query)' \(file); [ $? -eq 0 ] && echo "YES" || echo "NO"
|
||||||
|
@ -113,9 +113,7 @@ class Startup {
|
|||||||
// Present the information to the user
|
// Present the information to the user
|
||||||
Alert.notify(message: messageText, info: informativeText)
|
Alert.notify(message: messageText, info: informativeText)
|
||||||
// Only breaking issues will throw the extra retry modal
|
// Only breaking issues will throw the extra retry modal
|
||||||
if (breaking) {
|
breaking ? self.failureCallback() : ()
|
||||||
self.failureCallback()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
58
phpmon/Classes/Core/PhpExtension.swift
Normal file
58
phpmon/Classes/Core/PhpExtension.swift
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// PhpExtension.swift
|
||||||
|
// PHP Monitor
|
||||||
|
//
|
||||||
|
// Created by Nico Verbruggen on 31/01/2021.
|
||||||
|
// Copyright © 2021 Nico Verbruggen. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/**
|
||||||
|
A PHP extension that was detected in the php.ini file.
|
||||||
|
Please note that the extension may be disabled.
|
||||||
|
|
||||||
|
- Note: You need to know more about regular expressions to be able to deal with these NSRegularExpression
|
||||||
|
instances. You can find more information here: https://nshipster.com/swift-regular-expressions/
|
||||||
|
*/
|
||||||
|
class PhpExtension {
|
||||||
|
var file: String
|
||||||
|
var line: String
|
||||||
|
var name: String
|
||||||
|
var enabled: Bool
|
||||||
|
|
||||||
|
init(_ line: String, file: String) {
|
||||||
|
let regex = try! NSRegularExpression(pattern: #"^(extension=|zend_extension=|; extension=|; zend_extension=)"(?<name>[a-zA-Z]*).so"$"#, options: [])
|
||||||
|
let match = regex.matches(in: line, options: [], range: NSMakeRange(0, line.count)).first
|
||||||
|
let range = Range(match!.range(withName: "name"), in: line)!
|
||||||
|
|
||||||
|
self.line = line
|
||||||
|
self.name = line[range]
|
||||||
|
self.enabled = !line.contains(";")
|
||||||
|
self.file = file
|
||||||
|
}
|
||||||
|
|
||||||
|
public func toggle() {
|
||||||
|
Actions.sed(
|
||||||
|
file: self.file,
|
||||||
|
original: self.line,
|
||||||
|
replacement: self.enabled ? "; \(self.line)" : self.line.replacingOccurrences(of: "; ", with: "")
|
||||||
|
)
|
||||||
|
self.enabled = !self.enabled
|
||||||
|
}
|
||||||
|
|
||||||
|
static func load(from path: URL) -> [PhpExtension] {
|
||||||
|
let file = try! String(contentsOf: path, encoding: .utf8)
|
||||||
|
|
||||||
|
return file.components(separatedBy: "\n")
|
||||||
|
.filter({ (line) -> Bool in
|
||||||
|
return line.range(
|
||||||
|
of: #"^(extension=|zend_extension=|; extension=|; zend_extension=)"[a-zA-Z]*.so"$"#,
|
||||||
|
options: .regularExpression
|
||||||
|
) != nil
|
||||||
|
})
|
||||||
|
.map { (line) -> PhpExtension in
|
||||||
|
return PhpExtension(line, file: path.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,8 +9,8 @@ import Foundation
|
|||||||
|
|
||||||
class PhpInstall {
|
class PhpInstall {
|
||||||
|
|
||||||
var version: Version = Version()
|
var version: Version!
|
||||||
var xdebug: Xdebug = Xdebug()
|
var extensions: [PhpExtension]!
|
||||||
|
|
||||||
// MARK: - Computed
|
// MARK: - Computed
|
||||||
|
|
||||||
@ -23,6 +23,8 @@ class PhpInstall {
|
|||||||
init() {
|
init() {
|
||||||
let version = Command.execute(path: Paths.php, arguments: ["-r", "print phpversion();"])
|
let version = Command.execute(path: Paths.php, arguments: ["-r", "print phpversion();"])
|
||||||
|
|
||||||
|
self.version = Version()
|
||||||
|
|
||||||
if (version == "" || version.contains("Warning")) {
|
if (version == "" || version.contains("Warning")) {
|
||||||
self.version.short = "💩 BROKEN"
|
self.version.short = "💩 BROKEN"
|
||||||
self.version.long = "";
|
self.version.long = "";
|
||||||
@ -39,13 +41,9 @@ class PhpInstall {
|
|||||||
// Get the first two elements
|
// Get the first two elements
|
||||||
self.version.short = segments[0...1].joined(separator: ".")
|
self.version.short = segments[0...1].joined(separator: ".")
|
||||||
|
|
||||||
// Determine the Xdebug status
|
// Load extension information
|
||||||
self.xdebug = Xdebug(
|
let path = URL(fileURLWithPath: "\(Paths.etcPath)/php/\(self.version.short)/php.ini")
|
||||||
found: Actions.didFindXdebug(self.version.short),
|
self.extensions = PhpExtension.load(from: path)
|
||||||
enabled: Actions.didEnableXdebug(self.version.short)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.version.error = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Structs
|
// MARK: - Structs
|
||||||
@ -55,9 +53,4 @@ class PhpInstall {
|
|||||||
var long = "???"
|
var long = "???"
|
||||||
var error = false
|
var error = false
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Xdebug {
|
|
||||||
var found: Bool = false
|
|
||||||
var enabled: Bool = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,10 +7,6 @@
|
|||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
|
||||||
class PhpMenuItem: NSMenuItem {
|
|
||||||
var version: String = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
class StatusMenu : NSMenu {
|
class StatusMenu : NSMenu {
|
||||||
public func addPhpVersionMenuItems()
|
public func addPhpVersionMenuItems()
|
||||||
{
|
{
|
||||||
@ -79,26 +75,34 @@ class StatusMenu : NSMenu {
|
|||||||
self.addItem(NSMenuItem(title: "mi_phpinfo".localized, action: #selector(MainMenu.openPhpInfo), keyEquivalent: "i"))
|
self.addItem(NSMenuItem(title: "mi_phpinfo".localized, action: #selector(MainMenu.openPhpInfo), keyEquivalent: "i"))
|
||||||
|
|
||||||
self.addItem(NSMenuItem.separator())
|
self.addItem(NSMenuItem.separator())
|
||||||
self.addItem(NSMenuItem(title: "mi_enabled_extensions".localized, action: nil, keyEquivalent: ""))
|
self.addItem(NSMenuItem(title: "mi_detected_extensions".localized, action: nil, keyEquivalent: ""))
|
||||||
self.addXdebugMenuItem()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func addXdebugMenuItem()
|
|
||||||
{
|
|
||||||
let xdebugFound = App.phpInstall!.xdebug.found
|
|
||||||
let xdebugOn = App.phpInstall!.xdebug.enabled
|
|
||||||
|
|
||||||
let menuItem = NSMenuItem(
|
for phpExtension in App.phpInstall!.extensions {
|
||||||
title: xdebugFound ? "mi_xdebug".localized : "mi_xdebug_missing".localized,
|
self.addExtensionItem(phpExtension)
|
||||||
action: #selector(MainMenu.toggleXdebug), keyEquivalent: "x"
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!xdebugFound) {
|
|
||||||
menuItem.isEnabled = false
|
|
||||||
} else {
|
|
||||||
menuItem.state = xdebugOn ? .on : .off
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (App.phpInstall!.extensions.count == 0) {
|
||||||
|
self.addItem(NSMenuItem(title: "mi_no_extensions_detected".localized, action: nil, keyEquivalent: ""))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func addExtensionItem(_ phpExtension: PhpExtension) {
|
||||||
|
let menuItem = ExtensionMenuItem(
|
||||||
|
title: "\(phpExtension.name.capitalized) (php.ini)",
|
||||||
|
action: #selector(MainMenu.toggleExtension), keyEquivalent: ""
|
||||||
|
)
|
||||||
|
menuItem.state = phpExtension.enabled ? .on : .off
|
||||||
|
menuItem.phpExtension = phpExtension
|
||||||
self.addItem(menuItem)
|
self.addItem(menuItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - In order to store extra data in each item, NSMenuItem is subclassed
|
||||||
|
|
||||||
|
class PhpMenuItem: NSMenuItem {
|
||||||
|
var version: String = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
class ExtensionMenuItem: NSMenuItem {
|
||||||
|
var phpExtension: PhpExtension? = nil
|
||||||
|
}
|
||||||
|
@ -27,4 +27,10 @@ extension String {
|
|||||||
|
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subscript (r: Range<String.Index>) -> String {
|
||||||
|
let start = r.lowerBound
|
||||||
|
let end = r.upperBound
|
||||||
|
return String(self[start ..< end])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,8 @@
|
|||||||
"mi_valet_config" = "Locate Valet folder (.config/valet)";
|
"mi_valet_config" = "Locate Valet folder (.config/valet)";
|
||||||
"mi_php_config" = "Locate PHP configuration file (php.ini)";
|
"mi_php_config" = "Locate PHP configuration file (php.ini)";
|
||||||
"mi_phpinfo" = "Show current configuration (phpinfo)";
|
"mi_phpinfo" = "Show current configuration (phpinfo)";
|
||||||
"mi_enabled_extensions" = "Enabled Extensions";
|
"mi_detected_extensions" = "Detected Extensions";
|
||||||
|
"mi_no_extensions_detected" = "No additional extensions detected.";
|
||||||
"mi_xdebug" = "Xdebug";
|
|
||||||
"mi_xdebug_missing" = "xdebug.so missing";
|
|
||||||
|
|
||||||
"mi_quit" = "Quit PHP Monitor";
|
"mi_quit" = "Quit PHP Monitor";
|
||||||
"mi_about" = "About PHP Monitor";
|
"mi_about" = "About PHP Monitor";
|
||||||
|
@ -210,6 +210,14 @@ class MainMenu: NSObject, NSWindowDelegate {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc public func toggleExtension(sender: ExtensionMenuItem) {
|
||||||
|
self.waitAndExecute({
|
||||||
|
// Toggle that extension
|
||||||
|
print("Toggling extension '\(sender.phpExtension!.name)'")
|
||||||
|
sender.phpExtension?.toggle()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
@objc public func openPhpInfo() {
|
@objc public func openPhpInfo() {
|
||||||
self.waitAndExecute({
|
self.waitAndExecute({
|
||||||
try! "<?php phpinfo();".write(toFile: "/tmp/phpmon_phpinfo.php", atomically: true, encoding: .utf8)
|
try! "<?php phpinfo();".write(toFile: "/tmp/phpmon_phpinfo.php", atomically: true, encoding: .utf8)
|
||||||
|
Reference in New Issue
Block a user