Files
2026-04-28 15:13:50 +02:00

478 lines
13 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Backwards Compatibility class
*
* @since 4.6.0
*/
class DLM_Backwards_Compatibility {
/**
* Holds the class object.
*
* @since 4.6.0
*
* @var object
*/
public static $instance;
/**
* The filters for the query.
*
* @since 4.6.0
*
* @var object
*/
private $filters;
/**
* The upgrade option.
*
* @since 4.6.0
*
* @var mixed
*/
private $upgrade_option;
/**
* Class constructor
*
* @return void
*/
public function __construct() {
// Add post meta count to total downloads.
add_filter( 'dlm_shortcode_total_downloads', array( $this, 'total_downloads_shortcode' ) );
// Add orderby postmeta compatibility.
add_action( 'dlm_query_args', array( $this, 'orderby_compatibility' ), 15, 1 );
// Reset postdata after the loop.
add_action( 'dlm_reset_postdata', array( $this, 'reset_postdata' ), 15, 1 );
// Add version postmeta downloads to the version download count.
add_filter( 'dlm_add_version_meta_download_count', array( $this, 'add_meta_download_count' ), 15, 2 );
// Add Download postmeta downloads to the Download's download count.
add_filter( 'dlm_add_meta_download_count', array( $this, 'add_meta_download_count' ), 30, 2 );
// If the DB upgrade functionality did not take place we won't have the option stored.
$this->upgrade_option = get_option( 'dlm_db_upgraded' );
// Hashes backwards compatibility.
$this->hashes_compatibility();
// Compatibility mode for X-Sendfile.
add_filter( 'dlm_x_sendfile', array( $this, 'x_sendfile_compatibility' ), 5 );
// Compatibility mode for X-Forwarded-For.
add_filter( 'dlm_allow_x_forwarded_for', array( $this, 'allow_x_forwarded_compatibility' ), 5 );
// Compatibility mode for hotlink protection.
add_filter( 'dlm_hotlink_protection', array( $this, 'hotlink_protection_compatibility' ), 5 );
}
/**
* Returns the singleton instance of the class.
*
* @return object The DLM_Backwards_Compatibility object.
*
* @since 4.6.0
*/
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof DLM_Backwards_Compatibility ) ) {
self::$instance = new DLM_Backwards_Compatibility();
}
return self::$instance;
}
/**
* Backwards compatibility function for the total_downloads shortcode.
*
* @param mixed $total Total downloads to be displayed.
*
* @return mixed
*
* @since 4.6.0
*/
public function total_downloads_shortcode( $total ) {
global $wpdb;
$meta_counts = 0;
// Apply the meta count to the total downloads.
if ( apply_filters( 'dlm_count_meta_downloads', true ) ) {
$meta_counts = $wpdb->get_var(
"
SELECT SUM( meta_value ) FROM
( SELECT post_id, meta_value, meta_key FROM $wpdb->postmeta WHERE meta_key = '_download_count' GROUP BY post_id ) PM
LEFT JOIN $wpdb->posts on PM.post_id = $wpdb->posts.ID
WHERE PM.meta_key = '_download_count'
AND post_type = 'dlm_download'
AND post_status = 'publish'
"
);
}
return absint( $total ) + absint( $meta_counts );
}
/**
* Order by post meta download_count compatibility
*
* @param mixed $filters Filters for the query.
*
* @return void
*
* @since 4.6.0
*/
public function orderby_compatibility( $filters ) {
global $wpdb;
if ( ! isset( $filters['post_type'] ) ) {
return;
}
if ( 'dlm_download' !== $filters['post_type'] ) {
return;
}
do_action( 'dlm_backwards_compatibility_orderby_meta_before', $filters );
if ( apply_filters( 'dlm_backwards_compatibility_orderby_meta', false ) ) {
add_filter( 'dlm_admin_sort_columns', array( $this, 'no_log_query_args_compatibility' ), 15, 1 );
add_filter( 'dlm_query_args_filter', array( $this, 'no_log_query_args_compatibility' ), 15, 1 );
return;
}
add_filter( 'posts_fields', array( $this, 'select_download_count_compatibility' ) );
add_filter( 'posts_join', array( $this, 'join_download_count_compatibility' ) );
if ( ! DLM_Utils::table_checker( $wpdb->download_log ) || ! DLM_Logging::is_logging_enabled() ) {
return;
}
$download_count_order = false;
// We should keep this if custom functionality using our retrieve function was made by users / other developers.
if ( isset( $filters['meta_query'] ) && isset( $filters['meta_query']['orderby_meta'] ) && '_download_count' === $filters['meta_query']['orderby_meta']['key'] ) {
$download_count_order = true;
}
if ( ! empty( $filters ) && isset( $filters['orderby'] ) && isset( $filters['meta_key'] ) && 'meta_value_num' === $filters['orderby'] && '_download_count' === $filters['meta_key'] ) {
$download_count_order = true;
}
if ( ! empty( $filters ) && isset( $filters['order_by_count'] ) && '1' === $filters['order_by_count'] ) {
$download_count_order = true;
}
if ( ! $download_count_order ) {
return;
}
$this->filters = $filters;
// @todo: Think the below filters are not useful anymore as we changed the SQL query.
// add_filter( 'dlm_admin_sort_columns', array( $this, 'query_args_download_count_compatibility' ), 60 );
// add_filter( 'dlm_query_args_filter', array( $this, 'query_args_download_count_compatibility' ), 60 );
// @todo: delete this filter and function after feedback, as version 4.7.0 doesn't need it.
// add_filter( 'posts_where', array( $this, 'where_download_count_compatibility' ) );
add_filter( 'posts_groupby', array( $this, 'groupby_download_count_compatibility' ) );
add_filter( 'posts_orderby', array( $this, 'orderby_download_count_compatibility' ) );
do_action( 'dlm_backwards_compatibility_orderby_meta_after', $filters );
}
/**
* Add custom table to query JOIN
*
* @param mixed $join The join query part.
*
* @return string
* @since 4.6.0
*
*/
public function join_download_count_compatibility( $join ) {
global $wpdb;
if ( ! DLM_Utils::table_checker( $wpdb->dlm_downloads ) ) {
return $join;
}
$join .= " LEFT JOIN {$wpdb->dlm_downloads} ON ({$wpdb->posts}.ID = {$wpdb->dlm_downloads}.download_id)";
$join .= " LEFT JOIN {$wpdb->postmeta} AS meta_downloads ON ({$wpdb->posts}.ID = meta_downloads.post_id AND meta_downloads.meta_key = '_download_count')";
return $join;
}
/**
* Add where clause on our query
*
* @param string $where The query where clause.
*
* @return string
*/
// @todo: delete this filter and function after feedback, as version 4.7.0 doesn't need it.
public function where_download_count_compatibility( $where ) {
global $wpdb;
$where .= " AND {$wpdb->download_log}.download_status IN ('completed', 'redirected') ";
return $where;
}
/**
* Add select from custom table to the query fields part
*
* @param mixed $fields The fields query part.
*
* @return string
* @since 4.6.0
*
*/
public function select_download_count_compatibility( $fields ) {
global $wpdb;
if ( ! DLM_Utils::table_checker( $wpdb->dlm_downloads ) ) {
return $fields;
}
if ( apply_filters( 'dlm_count_meta_downloads', true ) ) {
$fields .= ", {$wpdb->dlm_downloads}.download_count, ( IFNULL( {$wpdb->dlm_downloads}.download_count, 0 ) +
IFNULL( meta_downloads.meta_value, 0 ) ) total_downloads, {$wpdb->dlm_downloads}.download_versions as download_versions ";
} else {
$fields .= ", {$wpdb->dlm_downloads}.download_count, ( IFNULL( {$wpdb->dlm_downloads}.download_count, 0 ) )
total_downloads, {$wpdb->dlm_downloads}.download_versions as download_versions";
}
return $fields;
}
/**
* Group by download_id from download_log in order to properly return our downloads
*
* @param [type] $group_by
*
* @return void
*
* @since 4.6.0
*/
public function groupby_download_count_compatibility( $group_by ) {
global $wpdb;
return " {$wpdb->posts}.ID ";
}
/**
* Add orderby custom table count value
*
* @param mixed $orderby The orderby string which we overwrite.
*
* @return string
* @since 4.6.0
*
*/
public function orderby_download_count_compatibility( $orderby ) {
global $wpdb;
if ( ! DLM_Utils::table_checker( $wpdb->dlm_downloads ) ) {
return $orderby;
}
$order = 'DESC';
if ( isset( $this->filters['order'] ) ) {
$order = in_array( strtoupper( $this->filters['order'] ), array( 'ASC', 'DESC' ), true )
? strtoupper( $this->filters['order'] )
: 'DESC';
}
if ( apply_filters( 'dlm_count_meta_downloads', true ) ) {
return " ( IFNULL( {$wpdb->dlm_downloads}.download_count, 0 ) +
IFNULL( meta_downloads.meta_value, 0 ) ) {$order}";
} else {
return " ( IFNULL( {$wpdb->dlm_downloads}.download_count, 0 ) ) {$order}";
}
}
/**
* Let's reset the query if we have completed our display of downloads, removing our added filters.
*
* @return void
* @since 4.6.0
*
*/
public function reset_postdata() {
do_action( 'dlm_backwards_compatibility_reset_postdata' );
remove_filter( 'posts_join', array( $this, 'join_download_count_compatibility' ) );
remove_filter( 'posts_groupby', array( $this, 'groupby_download_count_compatibility' ) );
remove_filter( 'posts_fields', array( $this, 'select_download_count_compatibility' ) );
remove_filter( 'posts_orderby', array( $this, 'orderby_download_count_compatibility' ) );
// @todo: delete this filter and function after feedback, as version 4.7.0 doesn't need it.
//remove_filter( 'posts_where', array( $this, 'where_download_count_compatibility' ) );
}
/**
* Backwards compatiblity for query args if using custom functionality
*
* @param [type] $query_args
*
* @return void
*
* @since 4.6.0
*/
public function query_args_download_count_compatibility( $filters ) {
if ( isset( $filters['meta_query'] ) && isset( $filters['meta_query']['orderby_meta'] ) && '_download_count' === $filters['meta_query']['orderby_meta']['key'] ) {
unset( $filters['meta_query'] );
unset( $filters['orderby_meta'] );
}
if ( ! empty( $filters ) && isset( $filters['orderby'] ) && isset( $filters['meta_key'] ) && 'meta_value_num' === $filters['orderby'] && '_download_count' === $filters['meta_key'] ) {
unset( $filters['meta_key'] );
unset( $filters['orderby'] );
}
if ( isset( $filters['orderby'] ) && 'download_count' == $filters['orderby'] ) {
unset( $filters['orderby'] );
}
return $filters;
}
/**
* Backwards compatibility for query args if user wants to still order by post meta
*
* @param [type] $query_args
*
* @return void
*
* @since 4.6.0
*/
public function no_log_query_args_compatibility( $filters ) {
if ( isset( $filters['order_by_count'] ) ) {
$filters['meta_key'] = '_download_count';
$filters['orderby'] = 'meta_value_num';
}
return $filters;
}
/**
* Backwards compatibility to take meta count into consideration for Downloads & Versions
*
* @param [type] $count
* @param [type] $download_id
*
* @return void
*
* @since 4.6.0
*/
public function add_meta_download_count( $counts, $download_id ) {
// Filter to enable adding meta counts to download counts.
$count_meta = apply_filters( 'dlm_count_meta_downloads', true );
if ( ( isset( $this->upgrade_option['using_logs'] ) && '0' === $this->upgrade_option['using_logs'] ) || $count_meta ) {
if ( 'dlm_download' !== get_post_type( $download_id ) && 'dlm_download_version' !== get_post_type( $download_id ) ) {
return $counts;
}
$meta_counts = get_post_meta( $download_id, '_download_count', true );
if ( isset( $meta_counts ) && '' !== $meta_counts ) {
return ( (int) $counts + (int) $meta_counts );
}
}
return $counts;
}
/**
* Hashes backwards compatibility.
*
* @return void
*
* @since 4.9.6
*/
private function hashes_compatibility() {
if ( is_admin() && ! DLM_Admin_Helper::is_dlm_admin_page() ) {
return;
}
// Create the used hashes array.
$hashes = array( 'md5', 'sha1', 'crc32b', 'sha256' );
// Cycle through hash types and add filter if option exists.
foreach ( $hashes as $hash ) {
if ( '1' == get_option( 'dlm_generate_hash_' . $hash, 0 ) ) {
// Return true to enable hash generation.
add_filter( 'dlm_generate_hash_' . $hash, '__return_true', 5 );
}
}
}
/**
* Compatibility mode for X-Sendfile.
*
* @param bool $return The return value.
*
* @return bool
*
* @since 4.9.6
*/
public function x_sendfile_compatibility( $return ) {
// Check if the X-Sendfile option exists in the DB. IF exists, most likely the user had it enabled.
if ( '1' === get_option( 'dlm_xsendfile_enabled', '0' ) ) {
$return = true;
}
return $return;
}
/**
* Compatibility mode for X-Forwarded-For.
*
* @param bool $return The return value.
*
* @return bool
*
* @since 4.9.6
*/
public function allow_x_forwarded_compatibility( $return ) {
// Check if the X-Forwarded-For option exists in the DB. IF exists, most likely the user had it enabled.
if ( '1' === get_option( 'dlm_allow_x_forwarded_for', '0' ) ) {
$return = true;
}
return $return;
}
/**
* Compatibility mode for hotlink protection.
*
* @param bool $return The return value.
*
* @return bool
*
* @since 4.9.6
*/
public function hotlink_protection_compatibility( $return ) {
// Check if the hotlink protection option exists in the DB. IF exists, most likely the user had it enabled.
if ( '1' === get_option( 'dlm_hotlink_protection_enabled', '0' ) ) {
$return = true;
}
return $return;
}
}