Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,816 @@
<?php
/**
* Allows plugins to use their own update API.
*
* @author Pippin Williamson and Dan Lester
* @version 13
*
* @package WP PDF Secure
*/
/**
* EDD Updater Class
*/
class EDD_SL_Plugin_Updater13 {
/**
* API URL.
*
* @var string
*/
private $api_url = '';
/**
* API Data.
*
* @var array
*/
private $api_data = array();
/**
* Name.
*
* @var string
*/
private $name = '';
/**
* Slug
*
* @var string
*/
private $slug = '';
/**
* Optname.
*
* @var string
*/
private $license_status_optname = '';
/**
* Settings URL.
*
* @var string
*/
private $license_settings_url = '';
/**
* Warning Delay.
*
* @var int
*/
private $license_warning_delay = 3600;
/**
* Display Warnings
*
* @var bool
*/
private $display_warnings = true;
/**
* Cache Key.
*
* @var string
*/
private $cache_key = '';
/**
* Version Info
*
* @var mixed
*/
protected $version_info = null;
/**
* Auto Check
*
* @var bool
*/
protected $auto_license_checked = false;
/**
* Class constructor.
*
* @uses plugin_basename()
* @uses hook()
*
* @param string $_api_url The URL pointing to the custom API endpoint.
* @param string $_plugin_file Path to the plugin file.
* @param array $_api_data Optional data to send with API calls.
* @param string $license_status_optname Opt name.
* @param string $license_settings_url settigns url.
* @param bool $display_warnings Display Warning.
* @return void
*/
public function __construct( $_api_url, $_plugin_file, $_api_data = null,
$license_status_optname = null, $license_settings_url = null, $display_warnings = true ) {
$this->api_url = trailingslashit( $_api_url );
$this->api_data = $_api_data;
$this->name = plugin_basename( $_plugin_file );
$this->slug = basename( $_plugin_file, '.php' );
$this->version = $_api_data['version'];
$this->beta = $_api_data['beta'];
$this->display_warnings = $display_warnings;
$this->cache_key = md5( serialize( $this->slug . $this->api_data['license'] ) );
if ( is_null( $license_status_optname ) ) {
$license_status_optname = 'eddsl_' . $this->slug;
}
$this->license_status_optname = $license_status_optname;
if ( ! is_null( $license_settings_url ) ) {
$this->license_settings_url = $license_settings_url;
}
}
/**
* Set up WordPress filters to hook into WP's update process.
*
* @uses add_filter()
*
* @return void
*/
public function setup_hooks() {
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
add_filter( 'http_request_args', array( $this, 'http_request_args' ), 10, 2 );
add_action( 'admin_init', array( $this, 'admin_init' ) );
add_action( 'admin_init', array( $this, 'show_changelog' ) );
}
/**
* Undocumented function
*
* @return void
*/
public function admin_init() {
if ( ! current_user_can( is_multisite() ? 'manage_network_options' : 'manage_options' ) ) {
return;
}
// Setup hooks to display message if license is not valid.
$license_status = $this->get_license_status_option();
if ( isset( $license_status['status'] ) && isset( $license_status['result_cleared'] )
&& ! $license_status['result_cleared'] ) {
// Do they want it cleared?.
// $nothanks_url = add_query_arg( $this->license_status_optname.'_eddsl_action', 'no_thanks' );.
$queryname = $this->license_status_optname . '_eddsl_action';
if ( isset( $_REQUEST[ $queryname ] ) && 'no_thanks' === $_REQUEST[ $queryname ] ) {
$license_status = $this->get_license_status_option();
$license_status['result_cleared'] = true;
update_site_option( $this->license_status_optname, $license_status );
$this->license_status_option = $license_status;
} elseif ( $this->display_warnings ) {
if ( is_multisite() ) {
add_action( 'network_admin_notices', array( $this, 'eddsl_license_notice' ) );
}
add_action( 'admin_notices', array( $this, 'eddsl_license_notice' ) );
}
}
}
/**
* Check for Updates at the defined API endpoint and modify the update array.
*
* This function dives into the update api just when WordPress creates its update array,
* then adds a custom API call and injects the custom plugin data retrieved from the API.
* It is reassembled from parts of the native WordPress plugin update code.
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
*
* @uses api_request()
*
* @param array $_transient_data Update array build by WordPress.
* @return array Modified update array with custom plugin data.
*/
public function pre_set_site_transient_update_plugins_filter( $_transient_data ) {
global $pagenow;
if ( ! is_object( $_transient_data ) ) {
$_transient_data = new stdClass();
}
if ( empty( $_transient_data->response ) || empty( $_transient_data->response[ $this->name ] ) ) {
if ( is_null( $this->version_info ) ) {
$this->version_info = $this->api_request( 'get_version', array( 'slug' => $this->slug ) );
}
if ( false !== $this->version_info && is_object( $this->version_info ) && isset( $this->version_info->new_version ) ) {
if ( version_compare( $this->version, $this->version_info->new_version, '<' ) ) {
$this->version_info->plugin = $this->name;
$_transient_data->response[ $this->name ] = $this->version_info;
}
$_transient_data->last_checked = time();
$_transient_data->checked[ $this->name ] = $this->version;
}
}
// Do actual license check now.
if ( ! $this->auto_license_checked ) {
$api_check = $this->api_request( 'check_license', array( 'slug' => $this->slug ) );
// Returns only valid or invalid, but also contains expires and renewal_link.
// Record latest status from license server.
$license_status = $this->update_license_status_option( $api_check );
$this->auto_license_checked = true;
// If we got invalid, then trying activating now.
if ( isset( $license_status['status'] ) && ( 'invalid' === $license_status['status'] || 'site_inactive' === $license_status['status'] ) ) {
$license_status = $this->edd_license_activate(); // calls update_license_status_option.
}
}
return $_transient_data;
}
/**
* Show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
*
* @param string $file Update file.
* @param array $plugin Plugin.
*/
public function show_update_notification( $file, $plugin ) {
if ( ! current_user_can( 'update_plugins' ) ) {
return;
}
if ( ! is_multisite() ) {
return;
}
if ( $this->name !== $file ) {
return;
}
// Remove our filter on the site transient.
remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
$update_cache = get_site_transient( 'update_plugins' );
if ( ! is_object( $update_cache ) || empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
$cache_key = md5( 'edd_plugin_' . sanitize_key( $this->name ) . '_version_info' . ( $this->api_data['beta'] ? '-beta' : '-reg' ) );
$version_info = $this->get_cached_version_info( $cache_key );
if ( false === $version_info ) {
$version_info = $this->api_request( 'get_version', array( 'slug' => $this->slug ) ); // 'plugin_latest_version'
$this->set_version_info_cache( $version_info, $cache_key );
}
if ( ! is_object( $version_info ) ) {
return;
}
if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
$update_cache->response[ $this->name ] = $version_info;
}
$update_cache->last_checked = time();
$update_cache->checked[ $this->name ] = $this->version;
set_site_transient( 'update_plugins', $update_cache );
} else {
$version_info = $update_cache->response[ $this->name ];
}
// Restore our filter.
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'pre_set_site_transient_update_plugins_filter' ) );
if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version, $version_info->new_version, '<' ) ) {
// build a plugin list row, with update notification.
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
echo '<tr class="plugin-update-tr"><td colspan="' . esc_attr( $wp_list_table->get_column_count() ) . '" class="plugin-update colspanchange"><div class="update-message">';
$changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
if ( empty( $version_info->download_link ) ) {
printf(
__( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a>.', 'edd' ),
esc_html( $version_info->name ),
esc_url( $changelog_link ),
esc_html( $version_info->new_version )
);
} else {
printf(
__( 'There is a new version of %1$s available. <a target="_blank" class="thickbox" href="%2$s">View version %3$s details</a> or <a href="%4$s">update now</a>.', 'edd' ),
esc_html( $version_info->name ),
esc_url( $changelog_link ),
esc_html( $version_info->new_version ),
esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name, 'upgrade-plugin_' . $this->name ) )
);
}
echo '</div></td></tr>';
}
}
/**
* Undocumented function
*
* @param [type] $api_response
* @return void
*/
protected function update_license_status_option( $api_response ) {
if ( false === $api_response || ( is_null( $api_response ) && ! empty( $this->api_data['license'] ) ) ) {
return;
// Probably unable to reach server this time.
}
$license_status = array( 'license_id' => $this->api_data['license'] );
// Problem such as missing license key?
if ( empty( $this->api_data['license'] ) && is_null( $api_response ) ) {
$license_status['status'] = 'empty';
} elseif ( isset( $api_response->license_check ) ) { // Probably called get_version.
$license_status['status'] = $api_response->license_check;
} elseif ( isset( $api_response->error ) ) { // activate_license.
$license_status['status'] = $api_response->error;
} elseif ( isset( $api_response->license ) ) {
$license_status['status'] = $api_response->license; // check_license.
} else { // Call was activate_license or check_license.
$license_status['status'] = isset( $api_response->error ) ? $api_response->error :
( isset( $api_response->success ) && $api_response->success ? 'valid' : 'invalid' );
}
if ( ! in_array( $license_status['status'], array( 'valid', 'invalid', 'missing', 'item_name_mismatch', 'invalid_item_id', 'expired', 'site_inactive', 'inactive', 'disabled', 'empty' ), true ) ) {
$license_status['status'] = 'invalid';
}
$license_status['expires'] = null;
$license_status['expires_time'] = null;
$license_status['expires_day'] = null;
$license_status['renewal_link'] = null;
$license_status['download_link'] = null;
if ( isset( $api_response->expires ) ) {
$expires_time = strtotime( $api_response->expires );
if ( $expires_time ) {
$license_status['expires'] = $api_response->expires;
$license_status['expires_time'] = $expires_time;
$license_status['expires_day'] = date( 'j M Y', $expires_time );
}
}
if ( isset( $api_response->renewal_link ) ) {
$license_status['renewal_link'] = $api_response->renewal_link;
}
if ( isset( $api_response->download_link ) ) {
$license_status['download_link'] = $api_response->download_link;
}
// Compare to existing option if any.
$license_status['last_check_time'] = $license_status['first_check_time'] = time();
$license_status['result_cleared'] = false;
$old_license_status = get_site_option( $this->license_status_optname, true );
if ( is_array( $old_license_status ) && isset( $old_license_status['license_id'] )
&& isset( $old_license_status['status'] ) ) {
if ( $old_license_status['license_id'] === $license_status['license_id']
&& $old_license_status['status'] === $license_status['status']
&& ( isset( $old_license_status['expires'] ) ? $old_license_status['expires'] : 0 ) === $license_status['expires'] ) {
if ( isset( $old_license_status['first_check_time'] ) ) {
$license_status['first_check_time'] = $old_license_status['first_check_time'];
}
if ( isset( $old_license_status['result_cleared'] ) ) {
$license_status['result_cleared'] = $old_license_status['result_cleared'];
}
}
}
update_site_option( $this->license_status_optname, $license_status );
$this->license_status_option = $license_status;
return $license_status;
}
/**
* Undocumented variable
*
* @var [type]
*/
protected $license_status_option = null;
/**
* Undocumented function
*
* @return string
*/
protected function get_license_status_option() {
if ( ! is_null( $this->license_status_option ) ) {
return $this->license_status_option;
}
$this->license_status_option = get_site_option( $this->license_status_optname, array() );
return $this->license_status_option;
}
/**
* Updates information on the "View version x.x details" page with custom data.
*
* @uses api_request()
*
* @param mixed $_data
* @param string $_action
* @param object $_args
* @return object $_data
*/
public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
if ( 'plugin_information' !== $_action ) {
return $_data;
}
if ( ! isset( $_args->slug ) || ( $_args->slug !== $this->slug ) ) {
return $_data;
}
$to_send = array(
'slug' => $this->slug,
'is_ssl' => is_ssl(),
'fields' => array(
'banners' => false, // These will be supported soon hopefully.
'reviews' => false,
),
);
$cache_key = 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . ( $this->api_data['beta'] ? '-beta' : '-reg' ) ) );
$edd_api_request_transient = $this->get_cached_version_info( $cache_key );
// If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
if ( empty( $edd_api_request_transient ) ) {
$api_response = $this->api_request( 'get_version', $to_send ); // 'plugin_information'.
// Expires in 3 hours.
$this->set_version_info_cache( $api_response, $cache_key );
if ( false !== $api_response ) {
$_data = $api_response;
}
} else {
// Convert sections into an assoc array.
if ( isset( $edd_api_request_transient->sections ) ) {
$new_sections = array();
foreach ( $edd_api_request_transient->sections as $k => $v ) {
$new_sections[ $k ] = $v;
}
$edd_api_request_transient->sections = $new_sections;
}
$_data = $edd_api_request_transient;
}
return $_data;
}
/**
* Disable SSL verification in order to prevent download update failures
*
* @param array $args
* @param string $url
* @return object $array
*/
public function http_request_args( $args, $url ) {
// If it is an https request and we are performing a package download, disable ssl verification.
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd-sl/package_download' ) ) {
$args['sslverify'] = false;
}
return $args;
}
/**
* Calls the API and, if successfull, returns the object delivered by the API.
*
* @uses get_bloginfo()
* @uses wp_remote_post()
* @uses is_wp_error()
*
* @param string $_action The requested action.
* @param array $_data Parameters for the API action.
* @return false||object
*/
private function api_request( $_action, $_data ) {
global $wp_version;
$data = array_merge( $this->api_data, $_data );
if ( $data['slug'] !== $this->slug ) {
return;
}
if ( empty( $data['license'] ) ) {
return;
}
if ( home_url() === $this->api_url ) {
return false; // Don't allow a plugin to ping itself.
}
$api_params = array(
'edd_action' => $_action,
'license' => $data['license'],
'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
'slug' => $data['slug'],
'author' => $data['author'],
'url' => home_url(),
'beta' => $data['beta'],
);
// '?XDEBUG_SESSION_START=7777'
$request = wp_remote_post(
$this->api_url,
array(
'timeout' => $this->get_timeout(),
'sslverify' => false,
'body' => $api_params,
)
);
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ) );
}
if ( is_object( $request ) ) {
if ( isset( $request->sections ) ) {
$request->sections = maybe_unserialize( $request->sections );
} else {
$request->sections = array();
}
$request->last_updated = null; // For changelog page only to avoid error.
}
return $request;
}
/**
* Undocumented function
*
* @return int
*/
private function get_timeout() {
$timeout = intval( get_site_option( 'eddsl_dsl_license_timeout', '10' ) );
return empty( $timeout ) ? 10 : $timeout;
}
/**
* Undocumented function
*
* @return void
*/
public function show_changelog() {
if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' !== $_REQUEST['edd_sl_action'] ) {
return;
}
if ( empty( $_REQUEST['plugin'] ) ) {
return;
}
if ( empty( $_REQUEST['slug'] ) ) {
return;
}
if ( ! current_user_can( 'update_plugins' ) ) {
wp_die( esc_html__( 'You do not have permission to install plugin updates', 'edd' ), esc_html__( 'Error', 'edd' ), array( 'response' => 403 ) );
}
$cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_version_info' . ( $this->api_data['beta'] ? '-beta' : '-reg' ) );
$version_info = $this->get_cached_version_info( $cache_key );
if ( false === $version_info ) {
$api_params = array(
'edd_action' => 'get_version',
'item_name' => isset( $this->api_data['item_name'] ) ? $this->api_data['item_name'] : false,
'item_id' => isset( $this->api_data['item_id'] ) ? $this->api_data['item_id'] : false,
'slug' => sanitize_text_field( wp_unslash( $_REQUEST['slug'] ) ),
'author' => isset( $this->api_data['author'] ) ? $this->api_data['author'] : '',
'url' => home_url(),
'beta' => $this->api_data['beta'],
);
$request = wp_remote_post(
$this->api_url,
array(
'timeout' => 15,
'sslverify' => false,
'body' => $api_params,
)
);
if ( ! is_wp_error( $request ) ) {
$version_info = json_decode( wp_remote_retrieve_body( $request ) );
}
if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
$version_info->sections = maybe_unserialize( $version_info->sections );
} else {
$version_info = false;
}
if ( ! empty( $version_info ) ) {
foreach ( $version_info->sections as $key => $section ) {
$version_info->$key = (array) $section;
}
}
$this->set_version_info_cache( $version_info, $cache_key );
}
if ( ! empty( $version_info ) && isset( $version_info->sections['changelog'] ) ) {
echo '<div style="background:#fff;padding:10px;">' . esc_html( $version_info->sections['changelog'] ) . '</div>';
}
exit;
}
/**
* Undocumented function
*
* @return string
*/
public function edd_license_activate() {
// data to send in our API request.
$api_params = array(
'edd_action' => 'activate_license',
'license' => $this->api_data['license'],
'item_id' => $this->api_data['item_id'],
'beta' => $this->api_data['beta'],
);
// Call the custom API.
$response = wp_remote_get(
add_query_arg( $api_params, $this->api_url ),
array(
'timeout' => $this->get_timeout(),
'sslverify' => false,
)
);
// make sure the response came back okay.
if ( is_wp_error( $response ) ) {
return false;
}
// decode the license data.
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
return $this->update_license_status_option( $license_data );
}
/**
* Undocumented function
*
* @return void
*/
public function eddsl_license_notice() {
$license_status = $this->get_license_status_option();
$msg = '';
$yes_link = $this->license_settings_url ? $this->license_settings_url : '';
$yes_text = 'Enter License';
$yes_target = '';
if ( isset( $license_status['status'] ) && 'valid' !== $license_status['status']
&& ( ! isset( $license_status['result_cleared'] ) || ! $license_status['result_cleared'] ) ) {
// Wait a couple of days before warning about the issue - give them time to finish setup first.
if ( ! isset( $license_status['first_check_time'] ) || $license_status['first_check_time'] < time() - $this->license_warning_delay ) {
if ( '' === $license_status['license_id'] ) {
$license_status['status'] = 'empty';
}
switch ( $license_status['status'] ) {
case 'missing':
$msg = 'Your license key is not found in our system at all.';
break;
case 'item_name_mismatch':
case 'invalid_item_id':
$msg = 'The license key you entered is for a different product.';
break;
case 'expired':
$msg = 'Your license key has expired.';
if ( isset( $license_status['renewal_link'] ) && $license_status['renewal_link'] ) {
$yes_link = $license_status['renewal_link'];
$yes_text = 'Renew License';
$yes_target = ' target="_blank" ';
}
break;
case 'site_inactive':
$msg = 'Your license key is not active for this website.';
break;
case 'inactive':
$msg = 'Your license key is not active.';
break;
case 'disabled':
$msg = 'Your license key has been disabled.';
break;
case 'empty':
$msg = 'You have not entered your license key.';
break;
case 'invalid':
default:
$msg = 'Your license key is invalid.';
break;
}
}
} elseif ( isset( $license_status['status'] ) && 'valid' === $license_status['status']
&& ( ! isset( $license_status['result_cleared'] ) || ! $license_status['result_cleared'] ) ) {
// License valid, but will it expire soon?
if ( isset( $license_status['expires_time'] ) && $license_status['expires_time'] < time() + 24 * 60 * 60 * 30 ) {
$msg = 'License will expire ' . ( isset( $license_status['expires_day'] ) ? 'on ' . $license_status['expires_day'] : 'soon' );
if ( isset( $license_status['renewal_link'] ) && $license_status['renewal_link'] ) {
$yes_link = $license_status['renewal_link'];
$yes_text = 'Renew License';
$yes_target = ' target="_blank" ';
}
}
}
if ( '' !== $msg ) {
$nothanks_url = add_query_arg( $this->license_status_optname . '_eddsl_action', 'no_thanks' );
echo '<div class="error"><p>';
if ( isset( $this->api_data['item_name'] ) ) {
echo wp_kses_post( htmlentities( 'Alert for ' . urldecode( $this->api_data['item_name'] ) . ': ' ) );
}
echo wp_kses_post( htmlentities( $msg ) );
if ( $yes_link ) {
echo ' &nbsp; <a href="' . esc_url( $yes_link ) . '" class="button-secondary" ' . esc_attr( $yes_target )
. '>' . wp_kses_post( htmlentities( $yes_text ) ) . '</a>';
}
echo '&nbsp;<a href="' . esc_url( $nothanks_url ) . '" class="button-secondary">Ignore</a>';
echo '</p></div>';
}
}
/**
* Undocumented function
*
* @param string $cache_key
* @return string
*/
private function get_cached_version_info( $cache_key = '' ) {
if ( empty( $cache_key ) ) {
$cache_key = $this->cache_key;
}
$cache = get_option( $cache_key );
if ( empty( $cache['timeout'] ) || current_time( 'timestamp' ) > $cache['timeout'] ) { // @codingStandardsIgnoreLine
return false; // Cache is expired.
}
return json_decode( $cache['value'] );
}
/**
* Adds the plugin version information to the database.
*
* @param string $value
* @param string $cache_key
*/
private function set_version_info_cache( $value = '', $cache_key = '' ) {
if ( empty( $cache_key ) ) {
$cache_key = $this->cache_key;
}
$data = array(
'timeout' => strtotime( '+3 hours', current_time( 'timestamp' ) ), // @codingStandardsIgnoreLine
'value' => wp_json_encode( $value ),
);
update_option( $cache_key, $data );
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,200 @@
<?php
/**
* WPPDF Review Class
*
* @since 5.1.0
*
* @package WP-PDF-Secure
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Review Class
*
* @since 5.1.0
*/
class WPPDF_Review {
/**
* Holds the class object.
*
* @since 1.1.4.5
*
* @var object
*/
public static $instance;
/**
* Path to the file.
*
* @since 1.1.4.5
*
* @var string
*/
public $file = __FILE__;
/**
* Holds the review slug.
*
* @since 1.1.4.5
*
* @var string
*/
public $hook;
/**
* Holds the base class object.
*
* @since 1.1.4.5
*
* @var object
*/
public $base;
/**
* API Username.
*
* @since 1.1.4.5
*
* @var bool|string
*/
public $user = false;
/**
* Primary class constructor.
*
* @since 1.1.4.5
*/
public function __construct() {
add_action( 'admin_notices', array( $this, 'review' ) );
add_action( 'wp_ajax_wppdf_dismiss_review', array( $this, 'dismiss_review' ) );
}
/**
* Add admin notices as needed for reviews.
*
* @since 1.1.6.1
*/
public function review() {
// Verify that we can do a check for reviews.
$review = get_option( 'wppdf_review' );
$activation_time = get_option( 'wppdf_emb_activation', false );
$time = time();
$load = false;
if ( ! $review ) {
$review = array(
'time' => $time,
'dismissed' => false,
);
$load = true;
} else {
// Check if it has been dismissed or not.
if ( ( isset( $review['dismissed'] ) && ! $review['dismissed'] ) && ( isset( $review['time'] ) ) ) {
$load = true;
}
}
// If we cannot load, return early.
if ( ! $load ) {
return;
}
// Bail if activation time isnt set.
if ( ! $activation_time ) {
return;
}
$valid = false;
if ( intval( time() ) >= intval( strtotime( '+7 day', $activation_time ) ) ) {
$valid = true;
} else {
$valid = false;
}
// if there hasnt been enough time, dont show.
if ( ! $valid ) {
return;
}
// Update the review option now.
update_option( 'wppdf_review', $review );
// We have a candidate! Output a review message.
?>
<div class="notice notice-info is-dismissible wppdf-review-notice">
<p><?php esc_html_e( "Hey, I noticed you're using PDF Embedder - thats awesome! Could you please do me a BIG favor and give it a 5-star rating on WordPress to help us spread the word and boost our motivation?", 'pdf-embedder' ); ?>
</p>
<p><strong><?php esc_html_e( '~ Nathan Singh - CEO of PDF Embedder', 'wppdf' ); ?></strong></p>
<p>
<a href="https://wordpress.org/support/plugin/pdf-embedder/reviews/?filter=5#new-post"
class="wppdf-dismiss-review-notice wppdf-review-out" target="_blank"
rel="noopener"><?php esc_html_e( 'Ok, you deserve it', 'pdf-embedder' ); ?></a><br>
<a href="#" class="wppdf-dismiss-review-notice" target="_blank"
rel="noopener"><?php esc_html_e( 'Nope, maybe later', 'pdf-embedder' ); ?></a><br>
<a href="#" class="wppdf-dismiss-review-notice" target="_blank"
rel="noopener"><?php esc_html_e( 'I already did', 'pdf-embedder' ); ?></a><br>
</p>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
$(document).on('click', '.wppdf-dismiss-review-notice, .wppdf-review-notice button', function(event) {
if (!$(this).hasClass('wppdf-review-out')) {
event.preventDefault();
}
$.post(ajaxurl, {
action: 'wppdf_dismiss_review'
});
$('.wppdf-review-notice').remove();
});
});
</script>
<?php
}
/**
* Dismiss the review nag
*
* @since 1.1.6.1
*/
public function dismiss_review() {
$review = get_option( 'wppdf_review' );
if ( ! $review ) {
$review = array();
}
$review['time'] = time();
$review['dismissed'] = true;
update_option( 'wppdf_review', $review );
wp_send_json_success( $review );
die;
}
/**
* Singleton Instance
*
* @return object
*/
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof WPPDF_Review ) ) {
self::$instance = new WPPDF_Review();
}
return self::$instance;
}
}
$wppdf_review = WPPDF_Review::get_instance();

View File

@@ -0,0 +1,125 @@
<?php
/**
* PDF RC4 Class
*
* @package WP PDF Secure
*/
/**
* RC4 symmetric cipher using blocks
*/
class WP_PDF_SimpleRC4 {
/**
* Key
*
* @var string
*/
protected $key;
/**
* Constructor
*
* @param string $key RC4 key.
*/
public function __construct( $key ) {
$this->key = $key;
}
/**
* Undocumented variable
*
* @var [type]
*/
protected $s = null;
/**
* Undocumented variable
*
* @var [type]
*/
protected $i;
/**
* Undocumented variable
*
* @var [type]
*/
protected $j;
/**
* Undocumented function
*
* @return void
*/
protected function init_rc4() {
$this->s = array();
for ( $i = 0; $i < 256; $i++ ) {
$this->s[ $i ] = $i;
}
$j = 0;
for ( $i = 0; $i < 256; $i++ ) {
$j = ( $j + $this->s[ $i ] + ord( $this->key[ $i % strlen( $this->key ) ] ) ) % 256;
$x = $this->s[ $i ];
$this->s[ $i ] = $this->s[ $j ];
$this->s[ $j ] = $x;
}
$this->i = 0;
$this->j = 0;
}
/**
* Undocumented function
*
* @param string $str rc4_encrypt_block.
* @return string
*/
public function rc4_encrypt_block( $str ) {
if ( is_null( $this->s ) ) {
$this->init_rc4();
}
$res = '';
for ( $y = 0; $y < strlen( $str ); $y++ ) {
$this->i = ( $this->i + 1 ) % 256;
$this->j = ( $this->j + $this->s[ $this->i ] ) % 256;
$x = $this->s[ $this->i ];
$this->s[ $this->i ] = $this->s[ $this->j ];
$this->s[ $this->j ] = $x;
$res .= $str[ $y ] ^ chr( $this->s[ ( $this->s[ $this->i ] + $this->s[ $this->j ] ) % 256 ] );
}
return $res;
}
}
/**
* Undocumented class
*/
class WP_PDF_DirectRC4 {
/**
* Undocumented variable
*
* @var string
*/
protected $key;
/**
* Undocumented function
*
* @param string $key RC4 key.
*/
public function __construct( $key ) {
$this->key = $key;
}
/**
* Undocumented function
*
* @param string $str rc4_encrypt_block.
* @return string
*/
public function rc4_encrypt_block( $str ) {
return $str;
}
}

View File

@@ -0,0 +1,454 @@
<?php
/**
* Secure Uploader
*
* @since 1.0.0
*
* @package WP-PDF-Secure
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Uploader class
*/
class WP_PDF_Secure_Uploader {
/**
* Undocumented variable
*
* @var bool
*/
protected $pdfemb_secure = true;
/**
* Undocumented variable
*
* @var bool
*/
protected $pdfemb_cacheencrypted = true;
/**
* Undocumented function
*
* @param object $pdfemb_secure PDF secure object.
* @param bool $pdfemb_cacheencrypted Encrypted cache.
*/
public function __construct( $pdfemb_secure = true, $pdfemb_cacheencrypted = true ) {
$this->pdfemb_secure = $pdfemb_secure;
$this->pdfemb_cacheencrypted = $pdfemb_cacheencrypted;
}
/**
* Undocumented function
*
* @return void
*/
public function intercept_uploads() {
// Called in admin_init.
add_filter( 'wp_handle_upload_prefilter', array( $this, 'custom_upload_filter' ) );
}
/**
* Undocumented function
*
* @return void
*/
public function handle_downloads() {
// Called in init.
if ( ! isset( $_GET['pdfemb-serveurl'] ) && ! isset( $_GET['pdfemb-nonce'] ) ) {
return;
}
if ( 'POST' !== $_SERVER['REQUEST_METHOD'] && ! isset( $_GET['pdfemb-nonce'] ) ) {
return;
}
$direct_download = false;
if ( isset( $_GET['pdfemb-nonce'] ) ) {
if ( ! wp_verify_nonce( $_GET['pdfemb-nonce'], 'pdfemb-secure-download-' . $_GET['pdfemb-serveurl'] ) ) {
return;
} else {
$direct_download = true;
}
}
$pdfurl = $_GET['pdfemb-serveurl'];
$filepath = $this->get_secure_path( $pdfurl );
if ( '' !== $filepath && file_exists( $filepath ) ) {
$filename = basename( $filepath );
if ( ! $this->is_func_disabled( 'set_time_limit' ) && ! ini_get( 'safe_mode' ) ) { // @codingStandardsIgnoreLine
@set_time_limit( 0 ); // @codingStandardsIgnoreLine
}
if ( function_exists( 'get_magic_quotes_runtime' ) && get_magic_quotes_runtime() && version_compare( phpversion(), '5.4', '<' ) ) { // @codingStandardsIgnoreLine
set_magic_quotes_runtime( 0 ); // @codingStandardsIgnoreLine
}
@session_write_close(); // @codingStandardsIgnoreLine
if ( function_exists( 'apache_setenv' ) ) {
@apache_setenv( 'no-gzip', 1 ); // @codingStandardsIgnoreLine
}
@ini_set( 'zlib.output_compression', 'Off' ); // @codingStandardsIgnoreLine
if ( ob_get_length() ) {
ob_clean(); // Clear output buffer in case Unicode BOM was added by a PHP file saved in wrong encoding.
}
nocache_headers();
header( 'Robots: none' );
header( 'Content-Type: application/octet-stream' );
header( 'Content-Description: File Transfer' );
header( 'Content-Disposition: attachment; filename="' . $filename . ( $direct_download ? '' : '.binary' ) . '"' );
header( 'Content-Transfer-Encoding: binary' );
if ( ! class_exists( 'WP_PDF_SimpleRC4' ) ) {
include_once dirname( __FILE__ ) . '/rc4_simple.php';
}
$sk = $this->get_secret_key();
$filetime = filemtime( $filepath );
$cache_to_file = ( false !== $filetime && ! $direct_download && $this->pdfemb_cacheencrypted
? $filepath . '.encrypted-cache.' . md5( $filetime . '-' . $sk ) . '.pdf'
: '' );
$myrc4 = $direct_download
? new WP_PDF_DirectRC4( '' )
: new WP_PDF_SimpleRC4( $sk );
$this->readfile_chunked( $filepath, true, $myrc4, $cache_to_file );
} else {
header( 'Location: ' . $pdfurl );
}
exit();
}
/**
* Helper Method to get secure
*
* @param string $pdfurl PDF Url.
* @return string
*/
public function get_secure_path( $pdfurl ) {
$upload_dir = wp_upload_dir();
$basedir = trailingslashit( $upload_dir['basedir'] ) . 'securepdfs/';
$baseurl = trailingslashit( set_url_scheme( $upload_dir['baseurl'] ) ) . 'securepdfs/';
$regex = '|^' . $baseurl . '(([^/]+/)*([^/]+\.pdf))$|';
$matches = array();
if ( preg_match( $regex, set_url_scheme( $pdfurl ), $matches ) ) {
// Check for .. tricks.
if ( ! preg_match( '|[\\\/]\.\.[\\\/]|', $pdfurl ) && strpos( $pdfurl, '\\' ) === false ) {
return $basedir . $matches[1];
}
}
return ''; // Wasn't a secure PDF.
}
/**
* Hash
*
* @var string
*/
protected $myrc4;
/**
* Read Chunk file
*
* @param string $file File.
* @param bool $retbytes Retbytes.
* @param bool $myrc4 RC4.
* @param string $cache_to_file file to cache.
* @return mixed
*/
protected function readfile_chunked( $file, $retbytes = true, $myrc4 = false, $cache_to_file = '' ) {
$chunksize = 1024 * 1024;
$buffer = '';
$cnt = 0;
$reading_from_cache = false;
$handle = false;
$cache_handle = false;
if ( '' !== $cache_to_file ) {
$cache_handle = @fopen( $cache_to_file, 'r' ); // @codingStandardsIgnoreLine
if ( false === $cache_handle ) {
$cache_handle = @fopen( $cache_to_file, 'w' ); // @codingStandardsIgnoreLine
} else {
// Read from cache.
$reading_from_cache = true;
$handle = $cache_handle;
$cache_handle = false;
}
}
$size = @filesize( $file ); // @codingStandardsIgnoreLine
if ( $reading_from_cache && @filesize( $cache_to_file ) != $size ) { // @codingStandardsIgnoreLine
// Revert back to non-cached version since can't be trusted.
error_log( 'Cached encrypted PDF was not of correct filesize: ' . $cache_to_file );
$handle = false;
$reading_from_cache = false;
$cache_handle = false;
}
if ( false === $handle ) {
$handle = @fopen( $file, 'r' ); // @codingStandardsIgnoreLine
}
if ( false === $handle ) {
return false;
}
if ( $size = @filesize( $file ) ) { // @codingStandardsIgnoreLine
header( 'Content-Length: ' . $size );
}
while ( ! @feof( $handle ) ) { // @codingStandardsIgnoreLine
$buffer = @fread( $handle, $chunksize ); // @codingStandardsIgnoreLine
if ( ! $reading_from_cache ) {
$buffer = $myrc4->rc4_encrypt_block( $buffer );
}
echo $buffer; // @codingStandardsIgnoreLine
if ( ! $reading_from_cache && false !== $cache_handle ) {
// Write to cache.
@fwrite( $cache_handle, $buffer ); // @codingStandardsIgnoreLine
}
if ( $retbytes ) {
$cnt += strlen( $buffer );
}
}
$status = @fclose( $handle ); // @codingStandardsIgnoreLine
if ( false !== $cache_handle ) {
@fclose( $cache_handle ); // @codingStandardsIgnoreLine
}
if ( $retbytes && $status ) {
return $cnt;
}
return $status;
}
/**
* Helper method for Secret Key
*
* @return string
*/
public function get_secret_key() {
$sk = get_site_option( 'pdfemb-sk' );
if ( false === $sk ) {
$sk = md5( sprintf( 'pdfemb-%d-%d', wp_rand(), time() ) );
update_site_option( 'pdfemb-sk', $sk, 60 * 60 * 12 );
}
return $sk;
}
/**
* Helper Method for Custom Upload Filter.
*
* @param string $file Upload File.
* @return string
*/
public function custom_upload_filter( $file ) {
if ( 'application/pdf' === $file['type'] && $this->pdfemb_secure ) {
add_filter( 'upload_dir', array( $this, 'custom_upload_dir' ) );
}
return $file;
}
/**
* Undocumented function
*
* @param string $function Function.
* @return bool
*/
protected function is_func_disabled( $function ) {
$disabled = explode( ',', ini_get( 'disable_functions' ) );
return in_array( $function, $disabled, true );
}
/**
* Undocumented function
*
* @param array $upload Upload.
* @return array
*/
public function custom_upload_dir( $upload ) {
// Override the year / month being based on the post publication date, if year/month organization is enabled.
if ( get_option( 'uploads_use_yearmonth_folders' ) ) {
// Generate the yearly and monthly dirs.
$time = current_time( 'mysql' );
$y = substr( $time, 0, 4 );
$m = substr( $time, 5, 2 );
$upload['subdir'] = "/$y/$m";
}
$upload['subdir'] = '/securepdfs' . $upload['subdir'];
$upload['path'] = $upload['basedir'] . $upload['subdir'];
$upload['url'] = $upload['baseurl'] . $upload['subdir'];
return $upload;
}
/**
* Helper Method to create protected files
*
* @param bool $force Force Upload.
* @param string $method Protected method.
* @return void
*/
public function create_protection_files( $force = false, $method = false ) {
if ( false === get_transient( 'pdfemb_check_protection_files' ) || $force ) {
$wp_upload_dir = wp_upload_dir();
$upload_path = $wp_upload_dir['basedir'] . '/securepdfs';
wp_mkdir_p( $upload_path );
// Make sure the /edd folder is created.
wp_mkdir_p( $upload_path );
// Top level .htaccess file.
$rules = $this->get_htaccess_rules( $method );
if ( file_exists( $upload_path . '/.htaccess' ) ) {
$contents = @file_get_contents( $upload_path . '/.htaccess' ); // @codingStandardsIgnoreLine
if ( $contents !== $rules ) {
// Update the .htaccess rules if they don't match.
@file_put_contents( $upload_path . '/.htaccess', $rules ); // @codingStandardsIgnoreLine
}
} elseif ( wp_is_writable( $upload_path ) ) {
// Create the file if it doesn't exist.
@file_put_contents( $upload_path . '/.htaccess', $rules ); // @codingStandardsIgnoreLine
}
// Top level blank index.php.
if ( ! file_exists( $upload_path . '/index.php' ) && wp_is_writable( $upload_path ) ) {
@file_put_contents( $upload_path . '/index.php', '<?php' . PHP_EOL . '// This file is intentionally blank.' ); // @codingStandardsIgnoreLine
}
// Now place index.php files in all sub folders.
$folders = array();
$this->scan_folders( $upload_path, $folders );
foreach ( $folders as $folder ) {
// Create index.php, if it doesn't exist.
if ( ! file_exists( $folder . 'index.php' ) && wp_is_writable( $folder ) ) {
@file_put_contents( $folder . 'index.php', '<?php' . PHP_EOL . '// This file is intentionally blank.' ); // @codingStandardsIgnoreLine
}
}
// Check for the files every eight days.
set_transient( 'pdfemb_check_protection_files', true, 3600 * 24 * 8 );
}
}
/**
* Helper method to get htacess rules.
*
* @param string $method Protected Method.
* @return string
*/
protected function get_htaccess_rules( $method = false ) {
if ( empty( $method ) ) {
$method = 'direct';
}
switch ( $method ) {
case 'redirect':
// Prevent directory browsing.
$rules = 'Options -Indexes';
break;
case 'direct':
default:
$rules = "Options -Indexes\n";
$rules .= "<IfModule mod_version.c>\n";
$rules .= " <IfVersion < 2.4>\n";
$rules .= " Order Deny,Allow\n";
$rules .= " Deny from all\n";
$rules .= " <FilesMatch '\.(jpg|png|gif|mp3|ogg)$'>\n";
$rules .= " Order Allow,Deny\n";
$rules .= " Allow from all\n";
$rules .= " </FilesMatch>\n";
$rules .= " </IfVersion>\n";
$rules .= " <IfVersion >= 2.4>\n";
$rules .= " Require all denied\n";
$rules .= " <FilesMatch '\.(jpg|png|gif|mp3|ogg)$'>\n";
$rules .= " Require all granted\n";
$rules .= " </FilesMatch>\n";
$rules .= " </IfVersion>\n";
$rules .= "</IfModule>\n";
$rules .= "<IfModule !mod_version.c>\n";
$rules .= " <IfModule !mod_authz_core.c>\n";
$rules .= " Order Deny,Allow\n";
$rules .= " Deny from all\n";
$rules .= " <FilesMatch '\.(jpg|png|gif|mp3|ogg)$'>\n";
$rules .= " Order Allow,Deny\n";
$rules .= " Allow from all\n";
$rules .= " </FilesMatch>\n";
$rules .= " </IfModule>\n";
$rules .= " <IfModule mod_authz_core.c>\n";
$rules .= " Require all denied\n";
$rules .= " <FilesMatch '\.(jpg|png|gif|mp3|ogg)$'>\n";
$rules .= " Require all granted\n";
$rules .= " </FilesMatch>\n";
$rules .= " </IfModule>\n";
$rules .= "</IfModule>\n";
break;
}
return $rules;
}
/**
* Helper Method to scan folders
*
* @param string $path Path.
* @param string $return Return Path.
* @return void
*/
protected function scan_folders( $path, &$return ) {
$lists = @scandir( $path ); // @codingStandardsIgnoreLine
if ( ! empty( $lists ) ) {
foreach ( $lists as $f ) {
if ( is_dir( $path . DIRECTORY_SEPARATOR . $f ) && '.' !== $f && '..' !== $f ) {
$finaldirpath = trailingslashit( $path . DIRECTORY_SEPARATOR . $f );
if ( ! in_array( $finaldirpath, $return, true ) ) {
$return[] = $finaldirpath;
}
$this->scan_folders( $path . DIRECTORY_SEPARATOR . $f, $return );
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* PDF VIew
*
* @package WP PDF Secure
*/
// get instance of embedder.
$pdf_embedder = WP_PDF_Secure::get_instance();
// process any override options/arguments passed in the url.
$args = isset( $_GET ) ? $_GET : array(); // @codingStandardsIgnoreLine
// should we enable some caching (javascript, etc.).
$should_cache = apply_filters( 'pdfemb_view_should_cache', time(), $args );
?> <!DOCTYPE html>
<html lang="en-us" id="wp-pdf-embbed" style="height: 100%;">
<head>
<link rel="profile" href="https://gmpg.org/xfn/11">
<meta name='robots' content='noindex, nofollow' />
<link rel="resource" type="application/l10n" href="<?php echo esc_url( trailingslashit( WP_PDF_SECURE_URL ) . '/assets/js/pdfjs/locale/locale.properties' ); ?>">
<?php
do_action( 'wp_pdf_viewer_head' );
?>
</head>
<body id="wppdf-iframe-body">
<?php
echo $pdf_embedder->pdfemb_shortcode_display_pdf_noncanvas_process( apply_filters( 'pdfemb_shortcode_display_args', $args ) ); //@codingStandardsIgnoreLine
do_action( 'wp_pdf_viewer_footer' );
?>
</body>
</html>