File: /home/assotraipi/www/wp-content/plugins/download-monitor/src/Admin/class-dlm-plugin-status.php
<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
} // Exit if accessed directly
/**
* DLM_Plugin_Status class.
*
* @since 4.9.6
*/
class DLM_Plugin_Status {
/**
* Holds the class object.
*
* @since 4.9.6
*
* @var object
*/
public static $instance;
private function __construct() {
$this->set_hooks();
}
/**
* Returns the singleton instance of the class.
*
* @return object The DLM_Plugin_Status object.
* @since 4.9.6
*/
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof DLM_Plugin_Status ) ) {
self::$instance = new DLM_Plugin_Status();
}
return self::$instance;
}
/**
* Set required hooks
*
* @since 4.9.6
*/
private function set_hooks() {
// Add Templates tab in the Download Monitor's settings page.
add_filter( 'dlm_settings', array( $this, 'status_tab' ), 15, 1 );
// Show the templates tab content.
add_action( 'dlm_tab_section_content_templates', array( $this, 'templates_content' ) );
// Add tests to the Site Health Info page.
add_filter( 'site_status_tests', array( $this, 'add_wp_tests' ), 30, 1 );
// Add required modules to the Site Health Info page.
add_filter( 'site_status_test_php_modules', array( $this, 'check_modules' ), 30, 1 );
// Hide the save button in the Templates tab.
add_filter( 'dlm_show_save_settings_button', array( $this, 'hide_save_button' ), 15, 3 );
}
/**
* Add Status tab in the Download Monitor's settings page.
*
* @param array $settings Array of settings.
*
* @return array
* @since 4.9.6
*/
public function status_tab( $settings ) {
$settings['general']['sections']['templates'] = array(
'title' => __( 'Templates', 'download-monitor' ),
'fields' => array(
// Add empty title field to show the templates tab, otherwise it won't show because of the
// "Hide empty sections" setting when having a license.
array(
'name' => '',
'type' => 'title',
'title' => __( '', 'download-monitor' ),
'priority' => 10,
),
),
);
return $settings;
}
/**
* Show the templates tab content.
*
* @since 4.9.6
*/
public function templates_content() {
echo '<div class="wp-clearfix">';
$theme_info = $this->get_theme_info();
if ( empty( $theme_info['overrides'] ) ) {
echo '<h3>' . esc_html__( 'None of Download Monitor\'s output templates are being overridden by your theme.', 'download-monitor' ) . '</h3>';
echo '</div>';
return;
}
echo '<h3>' . sprintf( esc_html__( 'There are %s overriden templates!', 'download-monitor' ), count( $theme_info['overrides'] ) ) . '</h3>';
?>
<table
class='dlm-template-override'>
<thead>
<tr>
<td>
<?php
esc_html_e( 'Overridden file', 'download-monitor' );
?>
<div
class='wpchill-tooltip'>
<i>[?]</i>
<div
class='wpchill-tooltip-content'><?php
esc_html_e( 'The template that has been overridden.', 'download-monitor' ); ?></div>
</div>
</td>
<td>
<?php
esc_html_e( 'Overridden file version', 'download-monitor' );
?>
<div
class='wpchill-tooltip'>
<i>[?]</i>
<div
class='wpchill-tooltip-content'><?php
esc_html_e( 'The version of the overridden file.', 'download-monitor' ); ?></div>
</div>
</td>
<td>
<?php
esc_html_e( 'Core version', 'download-monitor' );
?>
<div
class='wpchill-tooltip'>
<i>[?]</i>
<div
class='wpchill-tooltip-content'><?php
esc_html_e( 'The version of the core file.', 'download-monitor' ); ?></div>
</div>
</td>
<td>
<?php
esc_html_e( 'Status', 'download-monitor' );
?>
<div
class='wpchill-tooltip'>
<i>[?]</i>
<div
class='wpchill-tooltip-content'><?php
esc_html_e( 'Action status. If core version is bigger than the overridden file version it is recommended to update the overridden file.', 'download-monitor' ); ?></div>
</div>
</td>
<td>
<?php
esc_html_e( 'Edit', 'download-monitor' );
?>
<div
class='wpchill-tooltip'>
<i>[?]</i>
<div
class='wpchill-tooltip-content'><?php
esc_html_e( 'Edit the file using the theme editor.', 'download-monitor' ); ?></div>
</div>
</td>
</tr>
</thead>
<tbody>
<?php
// Cycle through the overrides and show them in a table.
foreach ( $theme_info['overrides'] as $override ) {
$core_version = ! empty( $override['core_version'] ) ? $override['core_version'] : '-';
$theme_version = ! empty( $override['version'] ) ? $override['version'] : '-';
$theme_version_class = '';
$needs_update = false;
if ( ! empty( $theme_version ) && version_compare( $theme_version, $core_version, '<' ) ) {
$theme_version_class = ' class="dlm-template-outdated"';
$needs_update = true;
}
?>
<tr>
<td class="dlm-template-file">
<?php
echo '<strong>' . esc_html( $override['file'] ) . '</strong>'; ?>
</td>
<td class="dlm-template-version">
<?php
echo esc_html( $theme_version ); ?>
</td>
<td class="dlm-template-core-version">
<?php
echo esc_html( $core_version ); ?>
</td>
<td class="dlm-template-update <?php
echo esc_attr( $theme_version_class ) ?>">
<?php
if ( $needs_update ) {
echo '<span class="dashicons dashicons-warning" style="color:red;" title="needs update"></span>';
} else {
echo '<span class="dashicons dashicons-yes" style="color:green;"></span>';
}
?>
</td>
<td class='dlm-template-core-version'>
<?php
$edit_url = http_build_query(
array(
'file' => str_replace( $theme_info['template'] . '/', '', $override['file'] ),
'theme' => $theme_info['template'],
)
);
echo '<a href="' . esc_url( admin_url( 'theme-editor.php?' ) . $edit_url ) . '" class="button button-secondary" target="_blank">' . esc_html__( 'Edit', 'download-monitor' ) . '</a>';
?>
</td>
</tr>
<?php
}
?>
</tbody>
</table>
<?php
echo '</div>';
}
/**
* Get info on the current active theme, info on parent theme
* and a list of template overrides.
*
* @return array
*
* @since 4.9.6
*/
public function get_theme_info() {
$theme_info = get_transient( 'dlm_templates_info' );
//if ( false === $theme_info ) {
$active_theme = wp_get_theme();
// Get parent theme info if this theme is a child theme, otherwise
// pass empty info in the response.
if ( is_child_theme() ) {
$parent_theme = wp_get_theme( $active_theme->template );
$parent_theme_info = array(
'parent_name' => $parent_theme->name,
'parent_version' => $parent_theme->version,
'parent_version_latest' => self::get_latest_theme_version( $parent_theme ),
'parent_author_url' => $parent_theme->{'Author URI'},
);
} else {
$parent_theme_info = array(
'parent_name' => '',
'parent_version' => '',
'parent_version_latest' => '',
'parent_author_url' => '',
);
}
/**
* Scan the theme directory for all DLM templates to see if our theme
* overrides any of them.
*/
$override_files = array();
$outdated_templates = false;
/**
* Filter the list of template files to scan. Defaults to all files in the templates directory.
*
* @hook dlm_template_files
*
* @param array $scan_files Array of template files to scan.
*
* @since 4.9.6
*/
$scan_files = apply_filters( 'dlm_template_files', self::scan_template_files( plugin_dir_path( DLM_PLUGIN_FILE ) . '/templates' ) );
foreach ( $scan_files as $file ) {
$located = apply_filters( 'dlm_get_template', $file, $file, array(), 'download-monitor', $this->templates_path() );
if ( file_exists( $located ) ) {
$theme_file = $located;
} elseif ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
$theme_file = get_stylesheet_directory() . '/' . $file;
} elseif ( file_exists( get_stylesheet_directory() . '/' . $this->templates_path() . $file ) ) {
$theme_file = get_stylesheet_directory() . '/' . $this->templates_path() . $file;
} elseif ( file_exists( get_template_directory() . '/' . $file ) ) {
$theme_file = get_template_directory() . '/' . $file;
} elseif ( file_exists( get_template_directory() . '/' . $this->templates_path() . $file ) ) {
$theme_file = get_template_directory() . '/' . $this->templates_path() . $file;
} else {
$theme_file = false;
}
if ( ! empty( $theme_file ) ) {
$core_file = $file;
$core_version = self::get_file_version( plugin_dir_path( DLM_PLUGIN_FILE ) . '/templates/' . $core_file );
$theme_version = self::get_file_version( $theme_file );
if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) {
if ( ! $outdated_templates ) {
$outdated_templates = true;
}
}
$override_files[] = array(
'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ),
'version' => $theme_version,
'core_version' => $core_version,
);
}
}
$active_theme_info = array(
'name' => $active_theme->name,
'version' => $active_theme->version,
'template' => $active_theme->template,
'version_latest' => self::get_latest_theme_version( $active_theme ),
'author_url' => esc_url_raw( $active_theme->{'Author URI'} ),
'is_child_theme' => is_child_theme(),
'has_outdated_templates' => $outdated_templates,
'overrides' => $override_files,
);
$theme_info = array_merge( $active_theme_info, $parent_theme_info );
set_transient( 'dlm_templates_info', $theme_info, HOUR_IN_SECONDS );
// }
return $theme_info;
}
/**
* Retrieve metadata from a file. Based on WP Core's get_file_data function.
*
* @param string $file Path to the file.
*
* @return string
* @since 4.9.6
*/
public static function get_file_version( $file ) {
// Avoid notices if file does not exist.
if ( ! file_exists( $file ) ) {
return '';
}
// We don't need to write to the file, so just open for reading.
$fp = fopen( $file, 'r' ); // @codingStandardsIgnoreLine.
// Pull only the first 8kiB of the file in.
$file_data = fread( $fp, 8192 ); // @codingStandardsIgnoreLine.
// PHP will close file handle, but we are good citizens.
fclose( $fp ); // @codingStandardsIgnoreLine.
// Make sure we catch CR-only line endings.
$file_data = str_replace( "\r", "\n", $file_data );
$version = '';
if ( preg_match( '/^[ \t\/*#@]*' . preg_quote( '@version', '/' ) . '(.*)$/mi', $file_data, $match ) && $match[1] ) {
$version = _cleanup_header_comment( $match[1] );
}
return $version;
}
/**
* Scan the template files.
*
* @param string $template_path Path to the template directory.
*
* @return array
* @since 4.9.6
*/
public static function scan_template_files( $template_path ) {
$files = @scandir( $template_path ); // @codingStandardsIgnoreLine.
$result = array();
if ( ! empty( $files ) ) {
foreach ( $files as $key => $value ) {
if ( ! in_array( $value, array( '.', '..' ), true ) ) {
if ( is_dir( $template_path . DIRECTORY_SEPARATOR . $value ) ) {
$sub_files = self::scan_template_files( $template_path . DIRECTORY_SEPARATOR . $value );
foreach ( $sub_files as $sub_file ) {
$result[] = $value . DIRECTORY_SEPARATOR . $sub_file;
}
} else {
$result[] = $value;
}
}
}
}
return $result;
}
/**
* Get latest version of a theme by slug.
*
* @param object $theme WP_Theme object.
*
* @return string Version number if found.
* @since 4.9.6
*/
public static function get_latest_theme_version( $theme ) {
include_once ABSPATH . 'wp-admin/includes/theme.php';
$api = themes_api(
'theme_information',
array(
'slug' => $theme->get_stylesheet(),
'fields' => array(
'sections' => false,
'tags' => false,
),
)
);
$update_theme_version = 0;
// Check .org for updates.
if ( is_object( $api ) && ! is_wp_error( $api ) && isset( $api->version ) ) {
$update_theme_version = $api->version;
}
return $update_theme_version;
}
/**
* Get the path to the templates directory.
*
* @return string
* @since 4.9.6
*/
public function templates_path() {
return apply_filters( 'dlm_template_path', 'download-monitor/' ); // phpcs:ignore WooCommerce.Commenting.CommentHooks.MissingSinceComment
}
/**
* Add tests to the Site Health Info page.
*
* @param array $tests Array of tests.
*
* @return array
* @since 4.9.6
*/
public function add_wp_tests( $tests ) {
$tests['direct']['dlm_required_modules'] = array(
'label' => __( 'Download Monitor required modules / functions', 'download-monitor' ),
'test' => array( $this, 'dlm_required_modules' ),
);
return $tests;
}
/**
* Check if the download meets the requirements to be downloaded.
*
* @return array
* @since 4.9.6
*
*/
public function dlm_required_functions() {
$errors = $this->check_requirements();
// Default good result.
$result = array(
'label' => __( 'DLM - All required modules/functions are active!', 'download-monitor' ),
'status' => 'good',
'badge' => array(
'label' => __( 'Plugin functionality', 'download-monitor' ),
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'Modules and functions help Download Monitor achieve the functionality you desire, and to do that we require that functions and modules, that Download Monitor depends on, be enabled.', 'download-monitor' )
),
'actions' => '',
'test' => 'dlm_required_functions',
);
// Check if there are any errors.
if ( ! empty( $errors ) ) {
$result = array(
'label' => __( 'DLM - One or more functions are missing!', 'download-monitor' ),
'status' => 'critical',
'badge' => array(
'label' => __( 'Plugin functionality', 'download-monitor' ),
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'Modules and functions help Download Monitor achieve the functionality you desire, and to do that we require that functions and modules, that Download Monitor depends on, be enabled.', 'download-monitor' )
),
'actions' => sprintf(
'<p>%s</p>',
__( 'Ask your hosting service to enable the following required modules/functions!', 'download-monitor' )
),
'test' => 'dlm_required_functions',
);
// Show functions errors.
$result['actions'] .= '<strong>' . __( 'Functions:', 'download-monitor' ) . '</strong><ul>';
foreach ( $errors as $function ) {
$result['actions'] .= '<li>' . $function . '</li>';
}
$result['actions'] .= '</ul>';
}
return $result;
}
/**
* Check if the download meets the requirements to be downloaded.
*
*
* @return array
* @since 4.9.6
*
*/
private function check_requirements() {
$errors = array();
/**
* Filter the requirements to be checked. Will be completed with more requirements in the future if needed.
*
* @hook dlm_health_check_requirements_functions
*
* @param array $checks Array of requirements to be checked.
*
* @since 4.9.6
*/
$checks = apply_filters(
'dlm_health_check_requirements_functions',
array( 'set_time_limit', 'session_write_close', 'ini_set', 'error_reporting' )
);
// Let's do the checks for functions.
if ( ! empty( $checks ) ) {
foreach ( $checks as $function ) {
if ( ! function_exists( $function ) ) {
$errors[] = $function;
}
}
}
return $errors;
}
/**
* Check if all the required modules are active.
*
* @return array
* @since 4.9.6
*
*/
public function check_modules( $modules ) {
// For the moment we only return the modules from WordPress. Placed here for future use.
return $modules;
}
/**
* Add the templates tab to the settings page.
*
* @param array $settings Array of settings.
*
* @return bool
* @since 5.0.0
*/
public function hide_save_button( $return, $settings, $active_section ) {
if ( 'templates' === $active_section ) {
return false;
}
return $return;
}
}