Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/download-monitor/download-monitor.php
+++ b/download-monitor/download-monitor.php
@@ -3,7 +3,7 @@
Plugin Name: Download Monitor
Plugin URI: https://www.download-monitor.com
Description: A full solution for managing and selling downloadable files, monitoring downloads and outputting download links and file information on your WordPress powered site.
- Version: 5.1.10
+ Version: 5.1.11
Author: WPChill
Author URI: https://wpchill.com
Requires at least: 6.4
@@ -34,7 +34,7 @@
} // Exit if accessed directly
// Define DLM Version
-define('DLM_VERSION', '5.1.10');
+define('DLM_VERSION', '5.1.11');
define('DLM_UPGRADER_VERSION', '4.6.0');
// Define DLM FILE
--- a/download-monitor/includes/admin/class-dlm-upsells.php
+++ b/download-monitor/includes/admin/class-dlm-upsells.php
@@ -25,8 +25,6 @@
private $upsell_tabs = array();
- private $offer = array();
-
/**
* Holds the active license status.
*
@@ -82,8 +80,6 @@
}
public function upsells_init() {
- $this->set_offer();
-
$this->set_hooks();
$this->set_tabs();
@@ -91,38 +87,6 @@
$this->set_upsell_actions();
}
- private function set_offer() {
- $this->offer = array(
- 'class' => '',
- 'column' => '',
- 'label' => __( 'Get Premium', 'download-monitor' ),
- );
-
- $timezone_string = get_option( 'timezone_string' );
- $timezone = $timezone_string ? new DateTimeZone( $timezone_string ) : new DateTimeZone( 'UTC' );
-
- $now = new DateTime( 'now', $timezone );
-
- $bf_start = new DateTime( '2025-11-03 00:00:00', $timezone );
- $bf_end = new DateTime( '2025-12-03 10:00:00', $timezone );
-
- if ( $now >= $bf_start && $now <= $bf_end ) {
- $this->offer = array(
- 'class' => 'wpchill-bf-upsell',
- 'column' => 'bf-upsell-columns',
- 'label' => __( '65% OFF for Black Friday', 'download-monitor' ),
- 'description' => __( '65% OFF on new purchases, early renewals or upgrades.', 'download-monitor' ),
- );
- }
- // if ( 12 == $month ) {
- // $this->offer = array(
- // 'class' => 'wpchill-xmas-upsell',
- // 'column' => 'xmas-upsell-columns',
- // 'label' => __( '25% OFF for Christmas', 'download-monitor' ),
- // );
- // }
- }
-
/**
* Set our hooks
*
@@ -172,7 +136,7 @@
*/
public function generate_upsell_box( $title, $description, $tab, $extension, $features = array(), $utm_source = null, $icon = false ) {
- echo '<div class="wpchill-upsell ' . esc_attr( $this->offer['class'] ) . '">';
+ echo '<div class="wpchill-upsell">';
if ( $icon ) {
echo '<img src="' . esc_url( DLM_URL . 'assets/images/upsells/' . $icon ) . '">';
}
@@ -204,9 +168,13 @@
}
echo '<a target="_blank" href="https://www.download-monitor.com/pricing/?utm_source=' . ( ! empty( $extension ) ? esc_html( $extension ) . '_metabox' : '' ) . '&utm_medium=lite-vs-pro&utm_campaign=' . ( ! empty( $extension ) ? esc_html( str_replace( ' ', '_', $extension ) ) : '' ) . '"><div class="dlm-available-with-pro"><span class="dashicons dashicons-lock"></span><span>' . esc_html__( 'AVAILABLE WITH PREMIUM', 'download-monitor' ) . '</span></div></a>';
+ $buttons = '<a target="_blank" href="https://download-monitor.com/free-vs-pro/?utm_source=dlm-lite&utm_medium=link&utm_campaign=upsell&utm_term=lite-vs-pro" class="button">' . esc_html__( 'Free vs Premium', 'download-monitor' ) . '</a>';
+ $buttons .= '<a target="_blank" href="https://www.download-monitor.com/pricing/?utm_source=' . ( ! empty( $extension ) ? esc_html( $extension ) . '_metabox' : '' ) . '&utm_medium=lite-vs-pro&utm_campaign=' . ( ! empty( $extension ) ? esc_html( str_replace( ' ', '_', $extension ) ) : '' ) . '" class="button-primary button">' . esc_html__( 'Get Premium', 'download-monitor' ) . '</a>';
+
+ $buttons = apply_filters( 'dlm_upsell_buttons', $buttons, $extension );
+
echo '<div class="wpchill-upsell-buttons-wrap">';
- echo '<a target="_blank" href="https://download-monitor.com/free-vs-pro/?utm_source=dlm-lite&utm_medium=link&utm_campaign=upsell&utm_term=lite-vs-pro" class="button">' . esc_html__( 'Free vs Premium', 'download-monitor' ) . '</a> ';
- echo '<a target="_blank" href="https://www.download-monitor.com/pricing/?utm_source=' . ( ! empty( $extension ) ? esc_html( $extension ) . '_metabox' : '' ) . '&utm_medium=lite-vs-pro&utm_campaign=' . ( ! empty( $extension ) ? esc_html( str_replace( ' ', '_', $extension ) ) : '' ) . '" class="button-primary button">' . esc_html( $this->offer['label'] ) . '</a>';
+ echo $buttons; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Filtered HTML, escaped in the default output above.
echo '</div>';
echo '</div>';
}
@@ -788,7 +756,7 @@
* @since 4.4.5
*/
public function output_external_hosting_upsell() {
- echo '<div class="upsells-columns ' . esc_attr( $this->offer['column'] ) . '">';
+ echo '<div class="upsells-columns">';
if ( ! $this->check_extension( 'dlm-amazon-s3' ) ) {
echo '<div class="upsells-column"><span class="dashicons dashicons-amazon"></span>';
--- a/download-monitor/includes/admin/wpchill/class-wpchill-upsells.php
+++ b/download-monitor/includes/admin/wpchill/class-wpchill-upsells.php
@@ -0,0 +1,473 @@
+<?php
+
+if ( ! defined( 'ABSPATH' ) ) {
+ exit;
+}
+
+if ( ! class_exists( 'WPChill_Remote_Upsells' ) ) {
+ /**
+ * Class WPChill_Remote_Upsells
+ *
+ * Handles remote upsell promotions fetched from external REST API.
+ * Checks daily via WP Cron if promotions are still valid.
+ *
+ */
+ class WPChill_Remote_Upsells {
+
+ /**
+ * Singleton instance
+ *
+ * @var WPChill_Remote_Upsells
+ */
+ private static $instance;
+
+ /**
+ * Hook name for the cron event
+ *
+ * @var string
+ */
+ private $cron_hook = 'wpchill_upsells_check';
+
+ /**
+ * Option name for storing upsell data
+ *
+ * @var string
+ */
+ private $option_name = 'wpchill_upsells_data';
+
+ /**
+ * Transient name for caching API requests
+ *
+ * @var string
+ */
+ private $cache_transient = 'wpchill_upsells_cache';
+
+ /**
+ * Remote API URL
+ *
+ * @var string
+ */
+ private $api_url = '';
+
+ /**
+ * Current active promotions data (array of promotions)
+ *
+ * @var array
+ */
+ private $active_promotions = array();
+
+ /**
+ * Constructor
+ *
+ * @param array $args Optional arguments (api_url).
+ */
+ public function __construct( $args = array() ) {
+ // Set API URL from arguments
+ if ( ! empty( $args['api_url'] ) ) {
+ $this->api_url = $args['api_url'];
+ }
+
+ // Schedule daily cron if not already scheduled
+ if ( ! wp_next_scheduled( $this->cron_hook ) ) {
+ wp_schedule_event( time(), 'daily', $this->cron_hook );
+ }
+
+ // Hook the cron action
+ add_action( $this->cron_hook, array( $this, 'fetch_remote_upsells' ) );
+
+ // Load and apply active promotions
+ $this->load_active_promotions();
+
+ // Register activation and deactivation hooks
+ $plugin_slug = explode( '/', plugin_basename( __FILE__ ) )[0];
+ $active_plugins = (array) get_option( 'active_plugins', array() );
+ foreach ( $active_plugins as $active_plugin ) {
+ if ( 0 === strpos( $active_plugin, $plugin_slug . '/' ) ) {
+ $plugin_file = WP_PLUGIN_DIR . '/' . $active_plugin;
+ register_activation_hook( $plugin_file, array( $this, 'activate' ) );
+ register_deactivation_hook( $plugin_file, array( $this, 'deactivate' ) );
+ break;
+ }
+ }
+ }
+
+ /**
+ * Get singleton instance
+ *
+ * @param array $args Optional arguments (api_url).
+ * @return WPChill_Remote_Upsells
+ */
+ public static function get_instance( $args = array() ) {
+ if ( ! isset( self::$instance ) || ! ( self::$instance instanceof WPChill_Remote_Upsells ) ) {
+ self::$instance = new WPChill_Remote_Upsells( $args );
+ }
+
+ return self::$instance;
+ }
+
+ /**
+ * Load active promotions from options and apply filters for each valid one
+ */
+ private function load_active_promotions() {
+ $data = get_option( $this->option_name, array() );
+
+ if ( empty( $data ) || ! is_array( $data ) ) {
+ return;
+ }
+
+ $has_css = false;
+
+ foreach ( $data as $key => $promotion ) {
+ // Skip invalid promotions
+ if ( ! $this->validate_single_promotion( $promotion ) ) {
+ continue;
+ }
+
+ // Skip expired promotions
+ if ( ! $this->is_promotion_valid( $promotion ) ) {
+ continue;
+ }
+
+ // Store active promotion
+ $filter_hook = sanitize_text_field( $promotion['filter'] );
+ $this->active_promotions[ $filter_hook ] = $promotion;
+
+ // Apply the upsell button filter for this promotion
+ add_filter( $filter_hook, array( $this, 'override_upsell_buttons' ), 15, 2 );
+
+ // Check if any promotion has CSS
+ if ( ! empty( $promotion['css'] ) ) {
+ $has_css = true;
+ }
+ }
+
+ // Add CSS output only once if any promotion has CSS
+ if ( $has_css ) {
+ add_action( 'admin_print_styles', array( $this, 'output_promotion_styles' ), 999 );
+ }
+ }
+
+ /**
+ * Check if promotion is still valid based on start/end dates
+ *
+ * @param array $data Promotion data.
+ * @return bool
+ */
+ private function is_promotion_valid( $data ) {
+ if ( empty( $data ) || ! is_array( $data ) ) {
+ return false;
+ }
+
+ $now = time();
+
+ // Check start date if provided
+ if ( ! empty( $data['start_date'] ) ) {
+ $start = strtotime( $data['start_date'] );
+ if ( $now < $start ) {
+ return false;
+ }
+ }
+
+ // Check end date if provided
+ if ( ! empty( $data['end_date'] ) ) {
+ $end = strtotime( $data['end_date'] );
+ if ( $now > $end ) {
+ return false;
+ }
+ }
+
+ // Check active flag if provided
+ if ( isset( $data['active'] ) && ! $data['active'] ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Fetch upsell data from remote API
+ */
+ public function fetch_remote_upsells() {
+ // Return cached data if available
+ $cached = get_transient( $this->cache_transient );
+ if ( false !== $cached ) {
+ return $cached;
+ }
+
+ $api_url = apply_filters( 'wpchill_upsells_api_url', $this->api_url );
+
+ if ( empty( $api_url ) ) {
+ return array();
+ }
+
+ $response = wp_remote_get(
+ $api_url,
+ array(
+ 'timeout' => 15,
+ )
+ );
+
+ if ( is_wp_error( $response ) ) {
+ return array();
+ }
+
+ $status_code = wp_remote_retrieve_response_code( $response );
+ if ( 200 !== $status_code ) {
+ return array();
+ }
+
+ $body = wp_remote_retrieve_body( $response );
+ $data = json_decode( $body, true );
+
+ if ( json_last_error() !== JSON_ERROR_NONE ) {
+ return array();
+ }
+
+ // Validate - must be an array of promotions
+ if ( ! $this->validate_promotions_data( $data ) ) {
+ $this->clear_promotions();
+ return array();
+ }
+
+ // Store the promotions data
+ update_option( $this->option_name, $data );
+ set_transient( $this->cache_transient, $data, DAY_IN_SECONDS );
+
+ return $data;
+ }
+
+ /**
+ * Validate promotions data structure (array of promotions)
+ *
+ * Expected structure:
+ * [
+ * {
+ * "active": true,
+ * "start_date": "2024-11-25",
+ * "end_date": "2024-12-02",
+ * "filter": "modula_upsell_buttons",
+ * "buttons": [...],
+ * "css": "..."
+ * },
+ * {
+ * "active": true,
+ * "start_date": "2024-11-25",
+ * "end_date": "2024-12-02",
+ * "filter": "dlm_upsell_buttons",
+ * "buttons": [...],
+ * "css": "..."
+ * }
+ * ]
+ *
+ * @param array $data Promotions data.
+ * @return bool
+ */
+ private function validate_promotions_data( $data ) {
+ if ( empty( $data ) || ! is_array( $data ) ) {
+ return false;
+ }
+
+ // Check if it's an array of promotions (not a single promotion)
+ // If first key is numeric, it's an array of promotions
+ if ( ! isset( $data[0] ) ) {
+ return false;
+ }
+
+ // Validate at least one promotion
+ foreach ( $data as $promotion ) {
+ if ( $this->validate_single_promotion( $promotion ) ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Validate a single promotion data structure
+ *
+ * @param array $promotion Single promotion data.
+ * @return bool
+ */
+ private function validate_single_promotion( $promotion ) {
+ if ( empty( $promotion ) || ! is_array( $promotion ) ) {
+ return false;
+ }
+
+ // We need filter and buttons data
+ if ( empty( $promotion['filter'] ) ) {
+ return false;
+ }
+
+ if ( empty( $promotion['buttons'] ) || ! is_array( $promotion['buttons'] ) ) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Override upsell buttons with promotion data
+ *
+ * @param string $buttons Original buttons HTML.
+ * @param string $context The upsell context/location.
+ * @return string Modified buttons HTML.
+ */
+ public function override_upsell_buttons( $buttons, $context = '' ) {
+ // Get current filter being executed
+ $current_filter = current_filter();
+
+ // Find the promotion for this filter
+ if ( ! isset( $this->active_promotions[ $current_filter ] ) ) {
+ return $buttons;
+ }
+
+ $promotion = $this->active_promotions[ $current_filter ];
+
+ if ( empty( $promotion['buttons'] ) ) {
+ return $buttons;
+ }
+
+ // Extract original URLs from the buttons
+ preg_match_all( '~<a(.*?)href="([^"]+)"(.*?)>~', $buttons, $matches );
+ $original_urls = isset( $matches[2] ) ? $matches[2] : array();
+
+ $new_buttons = '';
+ $button_index = 0;
+
+ foreach ( $promotion['buttons'] as $button ) {
+ if ( empty( $button['text'] ) ) {
+ continue;
+ }
+
+ // Determine the URL
+ $url = '';
+ if ( isset( $button['url'] ) ) {
+ if ( 'use_original' === $button['url'] && isset( $original_urls[ $button_index ] ) ) {
+ $url = $original_urls[ $button_index ];
+ } else {
+ $url = $button['url'];
+ }
+ } elseif ( isset( $original_urls[ $button_index ] ) ) {
+ $url = $original_urls[ $button_index ];
+ }
+
+ // Build button attributes
+ $target = isset( $button['target'] ) ? $button['target'] : '_blank';
+ $class = isset( $button['class'] ) ? $button['class'] : 'button';
+ $style = isset( $button['style'] ) ? ' style="' . esc_attr( $button['style'] ) . '"' : '';
+
+ $new_buttons .= sprintf(
+ '<a target="%s" href="%s" class="%s"%s>%s</a>',
+ esc_attr( $target ),
+ esc_url( $url ),
+ esc_attr( $class ),
+ $style,
+ esc_html( $button['text'] )
+ );
+
+ ++$button_index;
+ }
+
+ return $new_buttons;
+ }
+
+ /**
+ * Output promotion CSS styles from all active promotions
+ */
+ public function output_promotion_styles() {
+ if ( empty( $this->active_promotions ) ) {
+ return;
+ }
+
+ $css = '';
+
+ foreach ( $this->active_promotions as $promotion ) {
+ if ( ! empty( $promotion['css'] ) ) {
+ $css .= $promotion['css'] . "n";
+ }
+ }
+
+ if ( ! empty( $css ) ) {
+ echo '<style>' . wp_strip_all_tags( $css ) . '</style>';
+ }
+ }
+
+ /**
+ * Clear stored promotions data
+ */
+ public function clear_promotions() {
+ delete_option( $this->option_name );
+ delete_transient( $this->cache_transient );
+ $this->active_promotions = array();
+ }
+
+ /**
+ * Get current active promotions data
+ *
+ * @return array
+ */
+ public function get_active_promotions() {
+ return $this->active_promotions;
+ }
+
+ /**
+ * Get promotion for a specific filter
+ *
+ * @param string $filter Filter hook name.
+ * @return array|false
+ */
+ public function get_promotion_for_filter( $filter ) {
+ return isset( $this->active_promotions[ $filter ] ) ? $this->active_promotions[ $filter ] : false;
+ }
+
+ /**
+ * Check if there are any active promotions
+ *
+ * @return bool
+ */
+ public function has_active_promotions() {
+ return ! empty( $this->active_promotions );
+ }
+
+ /**
+ * Manually set API URL
+ *
+ * @param string $url API URL.
+ */
+ public function set_api_url( $url ) {
+ $this->api_url = $url;
+ }
+
+ /**
+ * Run initial promotions check on plugin activation
+ */
+ public function activate() {
+ $this->fetch_remote_upsells();
+ }
+
+ /**
+ * Clean up on plugin deactivation
+ */
+ public function deactivate() {
+ wp_clear_scheduled_hook( $this->cron_hook );
+ }
+
+ /**
+ * Get transients to be cleared on uninstall
+ *
+ * @param array $transients Existing transients array.
+ * @return array
+ */
+ public function get_transients_to_clear( $transients ) {
+ $transients[] = $this->cache_transient;
+ return $transients;
+ }
+ }
+ // Initiate WPChill Upsells (remote promotions)
+ WPChill_Remote_Upsells::get_instance(
+ array(
+ 'api_url' => 'https://wp-modula.com/wp-json/upsells/v1/get',
+ )
+ );
+}
--- a/download-monitor/includes/bootstrap.php
+++ b/download-monitor/includes/bootstrap.php
@@ -33,6 +33,9 @@
// load the wpchill notifications.
require_once dirname( DLM_PLUGIN_FILE ) . '/includes/admin/wpchill/class-wpchill-notifications.php';
+// load the wpchill upsells system.
+require_once dirname( DLM_PLUGIN_FILE ) . '/includes/admin/wpchill/class-wpchill-upsells.php';
+
// include installer functions.
require_once 'installer-functions.php';
--- a/download-monitor/src/Admin/DownloadPaths/class-dlm-downloads-path.php
+++ b/download-monitor/src/Admin/DownloadPaths/class-dlm-downloads-path.php
@@ -417,73 +417,69 @@
return;
}
- // Check if the user has permission to update the path.
- if ( ! $this->check_access() ) {
+ $change = false;
+ if ( ! isset( $_GET['page'] ) || 'download-monitor-settings' !== $_GET['page'] ) {
return;
}
- $change = false;
- $check = false;
- // phpcs:disable WordPress.Security.NonceVerification.Recommended
- // The check is different for multisite, as the page is different.
- $check = isset( $_GET['page'] ) && 'download-monitor-settings' === $_GET['page'];
- if ( $check ) {
- $paths = DLM_Downloads_Path_Helper::get_all_paths();
- if ( ! empty( $_GET['action'] ) ) {
- $action = sanitize_text_field( wp_unslash( $_GET['action'] ) );
- switch ( $action ) {
- case 'enable':
- foreach ( $paths as $key => $path ) {
- if ( absint( $path['id'] ) === absint( $_GET['url'] ) ) {
- $paths[ $key ]['enabled'] = true;
- $change = true;
- break;
- }
- }
- break;
- case 'disable':
- foreach ( $paths as $key => $path ) {
- if ( absint( $path['id'] ) === absint( $_GET['url'] ) ) {
- $paths[ $key ]['enabled'] = false;
- $change = true;
- break;
- }
- }
- break;
- case 'delete':
- foreach ( $paths as $key => $path ) {
- if ( absint( $path['id'] ) === absint( $_GET['url'] ) ) {
- unset( $paths[ $key ] );
- $change = true;
- break;
- }
- }
- break;
- case 'enable-all':
- foreach ( $paths as $key => $path ) {
+ if ( ! $this->check_access( 'path_get_action' ) ) {
+ return;
+ }
+
+ $paths = DLM_Downloads_Path_Helper::get_all_paths();
+ if ( ! empty( $_GET['action'] ) ) {
+ $action = sanitize_text_field( wp_unslash( $_GET['action'] ) );
+ switch ( $action ) {
+ case 'enable':
+ foreach ( $paths as $key => $path ) {
+ if ( absint( $path['id'] ) === absint( $_GET['url'] ) ) {
$paths[ $key ]['enabled'] = true;
$change = true;
+ break;
}
- break;
- case 'disable-all':
- foreach ( $paths as $key => $path ) {
+ }
+ break;
+ case 'disable':
+ foreach ( $paths as $key => $path ) {
+ if ( absint( $path['id'] ) === absint( $_GET['url'] ) ) {
$paths[ $key ]['enabled'] = false;
$change = true;
+ break;
}
- break;
- default:
- $paths = apply_filters( 'dlm_download_paths_action_' . $action, $paths );
- $change = apply_filters( 'dlm_download_paths_change_' . $action, false, $paths );
- break;
- }
+ }
+ break;
+ case 'delete':
+ foreach ( $paths as $key => $path ) {
+ if ( absint( $path['id'] ) === absint( $_GET['url'] ) ) {
+ unset( $paths[ $key ] );
+ $change = true;
+ break;
+ }
+ }
+ break;
+ case 'enable-all':
+ foreach ( $paths as $key => $path ) {
+ $paths[ $key ]['enabled'] = true;
+ $change = true;
+ }
+ break;
+ case 'disable-all':
+ foreach ( $paths as $key => $path ) {
+ $paths[ $key ]['enabled'] = false;
+ $change = true;
+ }
+ break;
+ default:
+ $paths = apply_filters( 'dlm_download_paths_action_' . $action, $paths );
+ $change = apply_filters( 'dlm_download_paths_change_' . $action, false, $paths );
+ break;
}
- // phpcs:enable
+ }
- if ( $change ) {
- DLM_Downloads_Path_Helper::save_paths( $paths );
- wp_safe_redirect( DLM_Downloads_Path_Helper::get_base_url() );
- exit;
- }
+ if ( $change ) {
+ DLM_Downloads_Path_Helper::save_paths( $paths );
+ wp_safe_redirect( DLM_Downloads_Path_Helper::get_base_url() );
+ exit;
}
}
@@ -493,12 +489,11 @@
* @since 5.0.0
*/
public function bulk_actions_handler() {
- // Check if the user has permission to update the path.
- if ( ! $this->check_access() ) {
- return;
- }
- // Check for the bulk action.
- if ( ( ! empty( $_POST['bulk-action'] ) || ! empty( $_POST['bulk-action2'] ) ) && isset( $_POST['approveddownloadpaths'] ) ) {// phpcs:disable WordPress.Security.NonceVerification.Recommended
+ // Check for the bulk action; capability + nonce (from settings_fields( 'dlm_advanced_download_path' )) via check_access.
+ if ( ( ! empty( $_POST['bulk-action'] ) || ! empty( $_POST['bulk-action2'] ) ) && isset( $_POST['approveddownloadpaths'] ) ) {
+ if ( ! $this->check_access( 'path_bulk' ) ) {
+ return;
+ }
$changes = false;
$paths = DLM_Downloads_Path_Helper::get_all_paths();
// Get the action. It's one or the other, so we can just check one.
@@ -544,7 +539,6 @@
break;
}
}
- // phpcs:enable
if ( $changes ) {
DLM_Downloads_Path_Helper::save_paths( $paths );
}
@@ -618,19 +612,37 @@
/**
* Check if current user has access to the download paths.
- *
* @return bool
* @since 5.0.10
*/
- private function check_access() {
+ private function check_access( $verify_request = null ) {
// Load the load.php file to get the is_multisite() function.
require_once ABSPATH . 'wp-includes/load.php';
// Check if it's a multisite installation.
if ( ! is_multisite() ) {
- // Check if the user has the manage_options capability.
- return current_user_can( 'manage_options' );
+ $can = current_user_can( 'manage_options' );
+ } else {
+ $can = current_user_can( 'manage_network' );
+ }
+
+ if ( ! $can ) {
+ return false;
}
- // Check if the user has the manage_network capability.
- return current_user_can( 'manage_network' );
+
+ if ( null === $verify_request ) {
+ return true;
+ }
+
+ if ( 'path_get_action' === $verify_request ) {
+ return isset( $_GET['check'] )
+ && wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['check'] ) ), 'modify_approved_directories' );
+ }
+
+ if ( 'path_bulk' === $verify_request ) {
+ return isset( $_POST['_wpnonce'] )
+ && wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ), 'dlm_advanced_download_path-options' );
+ }
+
+ return false;
}
}
--- a/download-monitor/src/Admin/WritePanels.php
+++ b/download-monitor/src/Admin/WritePanels.php
@@ -633,7 +633,7 @@
// sanatize post data
$file_id = absint( $downloadable_file_id[ $i ] );
$file_menu_order = absint( $downloadable_file_menu_order[ $i ] );
- $file_version = strtolower( sanitize_text_field( $downloadable_file_version[ $i ] ) );
+ $file_version = ( sanitize_text_field( $downloadable_file_version[ $i ] ) );
$file_date_hour = ( ! empty( $downloadable_file_date_hour[ $i ] ) ) ? absint( $downloadable_file_date_hour[ $i ] ) : 0;
$file_date_minute = ! empty( $downloadable_file_date_minute[ $i ] ) ? absint( $downloadable_file_date_minute[ $i ] ) : 0;
$file_date = ! empty( $downloadable_file_date[ $i ] ) ? sanitize_text_field( $downloadable_file_date[ $i ] ) : new DateTime();
--- a/download-monitor/src/Download/Download.php
+++ b/download-monitor/src/Download/Download.php
@@ -504,7 +504,10 @@
}
if ( $current_lang && $default_lang && $current_lang !== $default_lang ) {
- return untrailingslashit( $url ) . '/' . $current_lang . '/';
+ $lang_segment = '/' . $current_lang . '/';
+ if ( strpos( $url, $lang_segment ) === false ) {
+ return untrailingslashit( $url ) . $lang_segment;
+ }
}
return $url;
--- a/download-monitor/src/Logs/LogItem.php
+++ b/download-monitor/src/Logs/LogItem.php
@@ -126,10 +126,12 @@
public function set_current_url( $current_url ) {
if ( get_option( 'permalink_structure' ) ) {
- $query_url = wp_parse_url( $current_url );
- $current_url = wp_parse_url( $current_url )['path'] . ( isset( $query_url['query'] ) ? '?' . $query_url['query'] : '' );
+ $query_url = wp_parse_url( $current_url );
+ $path = isset( $query_url['path'] ) ? $query_url['path'] : '/';
+ $current_url = $path . ( isset( $query_url['query'] ) ? '?' . $query_url['query'] : '' );
} else {
- $current_url = '/' . wp_parse_url( $current_url )['query'];
+ $query_url = wp_parse_url( $current_url );
+ $current_url = '/' . ( isset( $query_url['query'] ) ? $query_url['query'] : '' );
}
$this->current_url = $current_url;
--- a/download-monitor/src/Logs/Logging.php
+++ b/download-monitor/src/Logs/Logging.php
@@ -159,8 +159,18 @@
$cookie = 'true' === $_POST['cookie'];
$current_url = ( isset( $_POST['currentURL'] ) ) ? esc_url_raw( $_POST['currentURL'] ) : '-';
// Set our objects
- $download = download_monitor()->service( 'download_repository' )->retrieve_single( $download_id );
- $version = download_monitor()->service( 'version_repository' )->retrieve_single( $version_id );
+ try {
+ $download = download_monitor()->service( 'download_repository' )->retrieve_single( $download_id );
+ } catch ( Exception $e ) {
+ die();
+ }
+
+ try {
+ $version = download_monitor()->service( 'version_repository' )->retrieve_single( $version_id );
+ } catch ( Exception $e ) {
+ die();
+ }
+
$download->set_version( $version );
// Truly log the corresponding status
$this->log( $download, $version, $status, $cookie, $current_url );
--- a/download-monitor/vendor/composer/autoload_classmap.php
+++ b/download-monitor/vendor/composer/autoload_classmap.php
@@ -290,6 +290,7 @@
'WPChill\DownloadMonitor\Util\PageCreator' => $baseDir . '/src/Util/PageCreator.php',
'WPChill_About_Us' => $baseDir . '/includes/admin/wpchill/class-wpchill-about-us.php',
'WPChill_Notifications' => $baseDir . '/includes/admin/wpchill/class-wpchill-notifications.php',
+ 'WPChill_Remote_Upsells' => $baseDir . '/includes/admin/wpchill/class-wpchill-upsells.php',
'WPChill_Rest_Api' => $baseDir . '/includes/admin/wpchill/class-wpchill-rest-api.php',
'WPChill_Welcome' => $baseDir . '/includes/submodules/banner/class-wpchill-welcome.php',
'WP_DLM' => $baseDir . '/src/DLM.php',
--- a/download-monitor/vendor/composer/autoload_static.php
+++ b/download-monitor/vendor/composer/autoload_static.php
@@ -305,6 +305,7 @@
'WPChill\DownloadMonitor\Util\PageCreator' => __DIR__ . '/../..' . '/src/Util/PageCreator.php',
'WPChill_About_Us' => __DIR__ . '/../..' . '/includes/admin/wpchill/class-wpchill-about-us.php',
'WPChill_Notifications' => __DIR__ . '/../..' . '/includes/admin/wpchill/class-wpchill-notifications.php',
+ 'WPChill_Remote_Upsells' => __DIR__ . '/../..' . '/includes/admin/wpchill/class-wpchill-upsells.php',
'WPChill_Rest_Api' => __DIR__ . '/../..' . '/includes/admin/wpchill/class-wpchill-rest-api.php',
'WPChill_Welcome' => __DIR__ . '/../..' . '/includes/submodules/banner/class-wpchill-welcome.php',
'WP_DLM' => __DIR__ . '/../..' . '/src/DLM.php',
--- a/download-monitor/vendor/composer/installed.php
+++ b/download-monitor/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'wpchill/download-monitor',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => '999ec88570436d41fbdaeb5712d43ee23004ccd0',
+ 'reference' => 'a479ba9ba004a78e527ec6448d10314bbe535b48',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -13,7 +13,7 @@
'wpchill/download-monitor' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
- 'reference' => '999ec88570436d41fbdaeb5712d43ee23004ccd0',
+ 'reference' => 'a479ba9ba004a78e527ec6448d10314bbe535b48',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),