Files

238 lines
6.8 KiB
PHP

<?php
/**
* Plugin & Themes Sensor helper.
*
* @since 5.5.0
*
* @package wsal
* @subpackage sensors
*/
declare(strict_types=1);
namespace WSAL\WP_Sensors\Helpers;
use WSAL\Helpers\WP_Helper;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( '\WSAL\WP_Sensors\Helpers\WP_Plugins_Themes_Helper' ) ) {
/**
* Helper Sensor class for Tablepress.
*
* @package wsal
* @subpackage sensors-helpers
*
* @since 5.5.0
*/
class WP_Plugins_Themes_Helper {
/**
* Trim the name of a plugin or theme folder, in case it's not already a clean folder name.
*
* @param string $folder_name The folder name to trim.
*
* @return string|false The trimmed folder name or false if invalid.
*
* @since 5.5.0
*/
public static function trim_folder_name( $folder_name ) {
$folder_name = trim( (string) $folder_name, "/\\ \t\n\r\0\x0B" );
if ( '' === $folder_name ) {
return false;
}
return $folder_name;
}
/**
* Checks if a plugin/theme directory or if a plugin file exists with a given name.
*
* @param string $name - The name of the folder or file to check.
* @param string $type The type of the item to check, either 'plugin' or 'theme'. Default is 'plugin'.
*
* @return bool - Returns true if the plugin directory or file exists, false otherwise.
*
* @since 5.5.0
*/
public static function does_dir_or_file_exist( $name, $type = 'plugin' ) {
if ( 'plugin' === $type ) {
$plugin_root = defined( 'WP_PLUGIN_DIR' )
? \untrailingslashit( WP_PLUGIN_DIR )
: \untrailingslashit( WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'plugins' );
$is_plugin_dir = is_dir( $plugin_root . DIRECTORY_SEPARATOR . $name );
$is_plugin_file = file_exists( $plugin_root . DIRECTORY_SEPARATOR . $name . '.php' );
return $is_plugin_dir || $is_plugin_file;
}
if ( 'theme' === $type ) {
// Get the theme using wp_get_theme.
$theme = \wp_get_theme( $name );
if ( $theme->exists() ) {
return true;
}
}
return false;
}
/**
* Get the plugin information for an event from a folder name.
*
* @param mixed $folder - the folder name to get the plugin information from.
*
* @return array|bool - array with theme information or false if not found.
*
* @since 5.5.0
*/
public static function get_plugin_event_info_from_folder( $folder ) {
$folder = self::trim_folder_name( $folder );
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$plugins = \get_plugins( DIRECTORY_SEPARATOR . $folder );
if ( ! empty( $plugins ) ) {
$first_slug = array_key_first( $plugins );
$first = $plugins[ $first_slug ];
$plugin_event_data = array(
'Name' => $first['Name'] ?? false,
'Version' => $first['Version'] ?? false,
'PluginURI' => $first['Plugin URI'] ?? false,
'Author' => $first['Author'] ?? false,
'Network' => $first['Network'] ?? false,
'Slug' => $first_slug,
'Title' => $first['Title'] ?? ( $first['Name'] ?? false ),
'plugin_dir_path' => WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $first_slug,
);
$required_keys = array( 'Name', 'Version', 'plugin_dir_path' );
$values = array_intersect_key( $plugin_event_data, array_flip( $required_keys ) );
$has_keys_values = count( $values ) === count( $required_keys ) && ! in_array( '', $values, true );
if ( ! $has_keys_values ) {
return false;
}
return $plugin_event_data;
}
$single = \untrailingslashit( WP_PLUGIN_DIR ) . DIRECTORY_SEPARATOR . $folder . '.php';
if ( file_exists( $single ) ) {
$data = \get_file_data(
$single,
array(
'Name' => 'Plugin Name',
'Version' => 'Version',
'PluginURI' => 'Plugin URI',
'Author' => 'Author',
'Network' => 'Network',
'Title' => 'Title',
'Description' => 'Description',
'TextDomain' => 'Text Domain',
)
);
return array(
'Name' => $data['Name'] ?? false,
'Version' => $data['Version'] ?? false,
'PluginURI' => $data['PluginURI'] ?? false,
'Author' => $data['Author'] ?? false,
'Network' => $data['Network'] ?? false,
'Slug' => $folder,
'Title' => $data['Title'] ?? ( $data['Name'] ?? false ),
'plugin_dir_path' => WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $slug,
);
}
return false;
}
/**
* Get the theme information for an event from a folder name.
*
* @param mixed $folder - the folder name to get the theme information from.
*
* @return array|bool - array with theme information or false if not found.
*
* @since 5.5.0
*/
public static function get_theme_event_info_from_folder( $folder ) {
$folder = self::trim_folder_name( $folder );
if ( ! function_exists( 'wp_get_theme' ) ) {
require_once ABSPATH . 'wp-includes/theme.php';
}
$theme = \wp_get_theme( $folder );
if ( ! $theme->exists() ) {
return false;
}
$theme_event_data = array(
'Name' => $theme->get( 'Name' ) ?? false,
'ThemeURI' => $theme->get( 'ThemeURI' ) ?? false,
'Description' => $theme->get( 'Description' ) ?? false,
'Author' => $theme->get( 'Author' ) ?? false,
'Version' => $theme->get( 'Version' ) ?? false,
'get_template_directory' => $theme->get_template_directory(),
);
$required_keys = array( 'Name', 'Version', 'get_template_directory' );
$values = array_intersect_key( $theme_event_data, array_flip( $required_keys ) );
$has_keys_values = count( $values ) === count( $required_keys ) && ! in_array( '', $values, true );
if ( ! $has_keys_values ) {
return false;
}
return $theme_event_data;
}
/**
* Get the active/inactive status label for a plugin.
*
* @param string $plugin_file - Relative path to the plugin file (e.g. "akismet/akismet.php").
*
* @return string - Translated "Active" or "Inactive" label.
*
* @since 5.6.2
*/
public static function get_plugin_status_label( string $plugin_file ): string {
return WP_Helper::is_plugin_active( $plugin_file )
? \esc_html__( 'Active', 'wp-security-audit-log' )
: \esc_html__( 'Inactive', 'wp-security-audit-log' );
}
/**
* Get the active/inactive status label for a theme.
*
* @param string $theme_slug - Theme directory slug (e.g. "twentytwentyfive").
*
* @return string - Translated "Active" or "Inactive" label.
*
* @since 5.6.2
*/
public static function get_theme_status_label( string $theme_slug ): string {
return ( \get_stylesheet() === $theme_slug )
? \esc_html__( 'Active', 'wp-security-audit-log' )
: \esc_html__( 'Inactive', 'wp-security-audit-log' );
}
}
}