mirror of
https://github.com/nicoverbruggen/phpmon.git
synced 2025-08-07 03:50: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 */; };
|
||||
C4811D2A22D70F9A00B5F6B3 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4811D2922D70F9A00B5F6B3 /* MainMenu.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 */; };
|
||||
C4EE188422D3386B00E126E5 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4EE188322D3386B00E126E5 /* Constants.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
C4E713562570150F00007428 /* SECURITY.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = SECURITY.md; sourceTree = "<group>"; };
|
||||
C4E713572570151400007428 /* docs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = docs; sourceTree = "<group>"; };
|
||||
@ -182,6 +184,7 @@
|
||||
children = (
|
||||
C412E5FB25700D5300A1FB67 /* HomebrewPackage.swift */,
|
||||
C41C1B4A22B019FF00E7CF16 /* PhpInstall.swift */,
|
||||
C4ACA38E25C754C100060C66 /* PhpExtension.swift */,
|
||||
);
|
||||
path = Core;
|
||||
sourceTree = "<group>";
|
||||
@ -268,6 +271,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
C4ACA38F25C754C100060C66 /* PhpExtension.swift in Sources */,
|
||||
C4D8016622B1584700C6DA1B /* Startup.swift in Sources */,
|
||||
C4F8C0A422D4F12C002EFE61 /* DateExtension.swift in Sources */,
|
||||
C41C1B4722B009A400E7CF16 /* Shell.swift in Sources */,
|
||||
|
@ -165,7 +165,7 @@ class Actions {
|
||||
/**
|
||||
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)")
|
||||
}
|
||||
@ -173,17 +173,15 @@ class Actions {
|
||||
/**
|
||||
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("""
|
||||
sed -i '' 's/\(original)/\(replacement)/g' \(file)
|
||||
""")
|
||||
Shell.run("sed -i '' 's/\(original)/\(replacement)/g' \(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("""
|
||||
grep -q '\(query)' \(file); [ $? -eq 0 ] && echo "YES" || echo "NO"
|
||||
|
@ -113,9 +113,7 @@ class Startup {
|
||||
// Present the information to the user
|
||||
Alert.notify(message: messageText, info: informativeText)
|
||||
// Only breaking issues will throw the extra retry modal
|
||||
if (breaking) {
|
||||
self.failureCallback()
|
||||
}
|
||||
breaking ? 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 {
|
||||
|
||||
var version: Version = Version()
|
||||
var xdebug: Xdebug = Xdebug()
|
||||
var version: Version!
|
||||
var extensions: [PhpExtension]!
|
||||
|
||||
// MARK: - Computed
|
||||
|
||||
@ -23,6 +23,8 @@ class PhpInstall {
|
||||
init() {
|
||||
let version = Command.execute(path: Paths.php, arguments: ["-r", "print phpversion();"])
|
||||
|
||||
self.version = Version()
|
||||
|
||||
if (version == "" || version.contains("Warning")) {
|
||||
self.version.short = "💩 BROKEN"
|
||||
self.version.long = "";
|
||||
@ -39,13 +41,9 @@ class PhpInstall {
|
||||
// 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
|
||||
// Load extension information
|
||||
let path = URL(fileURLWithPath: "\(Paths.etcPath)/php/\(self.version.short)/php.ini")
|
||||
self.extensions = PhpExtension.load(from: path)
|
||||
}
|
||||
|
||||
// MARK: - Structs
|
||||
@ -55,9 +53,4 @@ class PhpInstall {
|
||||
var long = "???"
|
||||
var error = false
|
||||
}
|
||||
|
||||
struct Xdebug {
|
||||
var found: Bool = false
|
||||
var enabled: Bool = false
|
||||
}
|
||||
}
|
||||
|
@ -7,10 +7,6 @@
|
||||
|
||||
import Cocoa
|
||||
|
||||
class PhpMenuItem: NSMenuItem {
|
||||
var version: String = ""
|
||||
}
|
||||
|
||||
class StatusMenu : NSMenu {
|
||||
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.separator())
|
||||
self.addItem(NSMenuItem(title: "mi_enabled_extensions".localized, action: nil, keyEquivalent: ""))
|
||||
self.addXdebugMenuItem()
|
||||
}
|
||||
|
||||
private func addXdebugMenuItem()
|
||||
{
|
||||
let xdebugFound = App.phpInstall!.xdebug.found
|
||||
let xdebugOn = App.phpInstall!.xdebug.enabled
|
||||
self.addItem(NSMenuItem(title: "mi_detected_extensions".localized, action: nil, keyEquivalent: ""))
|
||||
|
||||
let menuItem = NSMenuItem(
|
||||
title: xdebugFound ? "mi_xdebug".localized : "mi_xdebug_missing".localized,
|
||||
action: #selector(MainMenu.toggleXdebug), keyEquivalent: "x"
|
||||
)
|
||||
|
||||
if (!xdebugFound) {
|
||||
menuItem.isEnabled = false
|
||||
} else {
|
||||
menuItem.state = xdebugOn ? .on : .off
|
||||
for phpExtension in App.phpInstall!.extensions {
|
||||
self.addExtensionItem(phpExtension)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
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_php_config" = "Locate PHP configuration file (php.ini)";
|
||||
"mi_phpinfo" = "Show current configuration (phpinfo)";
|
||||
"mi_enabled_extensions" = "Enabled Extensions";
|
||||
|
||||
"mi_xdebug" = "Xdebug";
|
||||
"mi_xdebug_missing" = "xdebug.so missing";
|
||||
"mi_detected_extensions" = "Detected Extensions";
|
||||
"mi_no_extensions_detected" = "No additional extensions detected.";
|
||||
|
||||
"mi_quit" = "Quit 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() {
|
||||
self.waitAndExecute({
|
||||
try! "<?php phpinfo();".write(toFile: "/tmp/phpmon_phpinfo.php", atomically: true, encoding: .utf8)
|
||||
|
Reference in New Issue
Block a user