Skip to content

Instantly share code, notes, and snippets.

@littlepackage
Created August 19, 2022 15:32
Show Gist options
  • Save littlepackage/d97541b1959e824910c58d2a2cda950c to your computer and use it in GitHub Desktop.
Save littlepackage/d97541b1959e824910c58d2a2cda950c to your computer and use it in GitHub Desktop.
/**
* Constructor
*/
public function __construct() {
parent::__construct( 'edd', null );
// For consistent time-stamping
$this->timestamp = time();
$this->_get();
}
/**
* Listen for specific $_GET requests
*
* @return void
*/
public function _get() {
// For EDD main plugin and "All Access" extension
if ( isset( $_GET['eddfile'] ) || isset( $_GET['edd-all-access-download'] ) ) {
add_filter( 'edd_requested_file', array( $this, 'edd_requested_file' ), 20, 4 );
}
// For EDD Free Downloads extension
// Free Downloads "Auto Download" bypasses usual EDD hooks for altering files pre-download
// Free Downloads other methods seem to use the 'edd_requested_file' hook above.
// Without hooks we are left listening for requests
if ( isset( $_POST['edd_free_download_id'] ) ) {
// The only hook we seem to be able to use is 'edd_download_files'
// which is quite awkward for the purposes of
// editing some files, esp those that are remote (e.g. not abspath or url)
// this all breaks when using with EDD S3, for example
add_filter( 'edd_download_files', array( $this, 'edd_download_files' ), 11, 3 );
}
}
/*
* For EDD *** Free Downloads *** extension
* Hooked into EDD 'edd_download_files' filter hook
* @todo Does not work with non-standard download URLs, e.g. Amazon S3, Dropbox - because all we get is the file stub string, not a full URL
*
* @param array $files $files['file'] is a URL
* @param int $download_id e.g. WP post ID
* @param int $variable_price_id
* @return array $files
*/
public function edd_download_files( $files, $download_id, $variable_price_id ) {
$settings = (array) get_option( 'wppdfw_admin', array() );
$edd_global = $settings['integrate']['edd']['global'] ?? 'off';
$edd_files = $settings['integrate']['edd']['files'] ?? array();
$edd_file_list = [];
if ( ! empty( $edd_files ) ) {
// Get EDD integration admin settings list of PDFs to watermark
$edd_file_list = array_filter( array_map( 'trim', explode( PHP_EOL, $edd_files ) ) );
}
// A good effort to find user's email address
$email = '';
if ( isset( $_POST['edd_free_download_email'] ) ) {
$email = sanitize_email( trim( $_POST['edd_free_download_email'] ) );
} else if ( is_user_logged_in() ) {
$user_id = get_current_user_id();
$user = get_userdata( $user_id );
$email = $user->data->user_email;
}
// Auto/direct download will either have payment ID or download ID
$payment_id = 0;
if ( isset( $_GET['payment-id'] ) ) {
$payment_id = $_GET['payment-id'];
$uid = $_GET['payment-id'];
} else if ( ! empty( $email ) ) { // if no payment ID maybe make a unique string with an email address
$uid = str_replace( '.', '-', $email );
$uid = str_replace( '@', '-', $uid );
} else {
$uid = uniqid();
}
$this->temp_folder = $this->get_temp_folder( $uid );
$success = false;
foreach ( $files as $key => $file ) {
$parsed_file_path = $this->parse_file_path( $file['file'] );
if ( ! $this->is_pdf( $file['file'] ) && ! $parsed_file_path['remote_file'] ) {
continue;
}
$filename = wp_basename( $file['file'] );
if ( false === $parsed_file_path['remote_file'] && ! file_exists( $parsed_file_path['file_path'] ) ) {
wppdfw_debug_log( 'Warning - EDD file ' . $filename . ' not found. PDF manipulation aborted.', 'notice' );
continue;
}
if ( $parsed_file_path['remote_file'] ) {
wppdfw_debug_log( 'Warning - EDD Free Downloads does not provide the developer with the means necessary to integrate with 3rd party file hosting such as Amazon S3 or Dropbox. Contact EDD to request they add more hooks for developers.', 'warning' );
continue;
}
$file_in_list = in_array( $filename, $edd_file_list );
$this->settings = PDFW()->settings->get_settings( 'frontend', $download_id, $key );
// Add email to the settings array
$this->settings['email'] = $email;
// Is watermarking turned on for the specific download?
$override = $this->settings['setup']['override'] ?? 'off';
$watermark_this = $this->settings['setup']['wm_this'] ?? 'off';
// Is PDF manipulation turned on for a specific file key?
$key_override = $this->settings['setup'][$key]['override'] ?? 'off';
$key_watermark_this = $this->settings['setup'][$key]['wm_this'] ?? 'off';
// In this order, specific to general:
if ( 'on' === $key_override && 'on' !== $key_watermark_this
|| 'on' === $override && 'on' !== $watermark_this
|| 'off' === $edd_global && empty( $edd_files )
|| 'on' === $edd_global && $file_in_list
) {
wppdfw_debug_log( 'Notice - PDF not watermarked. Watermarking turned off for this file: ' . $filename, 'notice' );
continue;
}
$this->temp_filename = $this->get_temp_filename( $filename, $uid );
// If we aren't keeping a copy then let's add it to the cleanup queue
if ( isset( $this->settings['housekeep']['copy'] ) && 'on' !== $this->settings['housekeep']['copy'] ) {
// Add a unique ID ($order_id in this case) to a queue for cleanup later
$cleanup_queue = (array) get_option( 'wppdfw_cleanup_queue', array() );
if ( ! in_array( [ $uid, $this->temp_filename ], $cleanup_queue ) ) {
$cleanup_queue[] = array(
'uid' => $uid,
'filename' => $this->temp_filename
);
update_option( 'wppdfw_cleanup_queue', $cleanup_queue );
// @todo if this option gets huge, best to prune it and warn user Cron is not taking place
}
}
// If recycling on and PDF exists, return that
if ( $this->can_recycle_PDF( $uid ) ) {
wppdfw_debug_log( 'Notice - PDF recycling attempt: ' . $filename, 'notice' );
return $this->temp_folder . $this->temp_filename;
}
try {
$this->set_content( $download_id, $email, $payment_id );
// Do manipulation, return $file to array
$manipulated_file = $this->send_to_library( $parsed_file_path['file_path'] );
$files[ $key ]["file"] = get_site_url( null, '/' . str_replace( ABSPATH, '', $manipulated_file ) );
$success = true;
} catch ( Exception $e ) {
if ( 'yes' === $this->settings['security']['fallback'] ) {
continue;
}
wppdfw_debug_log( 'Caught exception: ' . $e->getMessage(), 'error' );
// @todo what to do if exception thrown in this loop
wp_die();
}
wppdfw_debug_log( 'Notice - PDF watermarked and delivered back to EDD [Free Downloads]: ' . $filename, 'notice' );
}
if ( $success ) {
// Cleanup by PHP shutdown or Cron, depending
$this->maybe_cleanup( $uid );
}
return $files;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment