Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SP-940 Adding BitPay Support Package download button #91

Merged
merged 1 commit into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ codeception.yml
logs/*.*
/.idea/
/vendor
/build
/build
.phpunit.result.cache
tests/.env
tests/Unit/wp-config.php
8 changes: 6 additions & 2 deletions BitPayLib/class-bitpaylogger.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ class BitPayLogger {

public function execute( $msg, string $type, bool $is_array = false, $error = false ): void {
$bitpay_checkout_options = get_option( 'woocommerce_bitpay_checkout_gateway_settings' );
$log_directory = plugin_dir_path( __FILE__ ) . '..' . DIRECTORY_SEPARATOR . '..'
. DIRECTORY_SEPARATOR . 'logs/';
$log_directory = $this->get_log_directory();
if ( ! file_exists( $log_directory ) && ! mkdir( $log_directory ) && ! is_dir( $log_directory ) ) {
throw new \RuntimeException( sprintf( 'Directory "%s" was not created', esc_html( $log_directory ) ) );
}
Expand Down Expand Up @@ -47,4 +46,9 @@ public function execute( $msg, string $type, bool $is_array = false, $error = fa
}
// @codingStandardsIgnoreEnd
}

public function get_log_directory(): string {
return plugin_dir_path( __FILE__ ) . '..' . DIRECTORY_SEPARATOR . '..'
. DIRECTORY_SEPARATOR . 'logs/';
}
}
16 changes: 16 additions & 0 deletions BitPayLib/class-bitpaypluginsetup.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class BitPayPluginSetup {
private BitPayPaymentSettings $bitpay_payment_settings;
private BitPayInvoiceCreate $bitpay_invoice_create;
private BitPayCheckoutTransactions $bitpay_checkout_transactions;
private BitPaySupportPackage $bitpay_support_package;

public function __construct() {
$this->bitpay_payment_settings = new BitPayPaymentSettings();
Expand All @@ -42,6 +43,10 @@ public function __construct() {
$wordpress_helper,
$logger
);
$this->bitpay_support_package = new BitPaySupportPackage(
$wordpress_helper,
$logger
);
}

public function execute(): void {
Expand Down Expand Up @@ -82,6 +87,17 @@ function () {
'permission_callback' => '__return_true',
)
);
register_rest_route(
'bitpay/site',
'/health-status',
array(
'methods' => 'GET',
'callback' => array( $this->bitpay_support_package, 'get_zip' ),
'permission_callback' => function () {
return current_user_can( 'manage_woocommerce' );
},
)
);
}
);
}
Expand Down
198 changes: 198 additions & 0 deletions BitPayLib/class-bitpaysupportpackage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<?php

declare(strict_types=1);

namespace BitPayLib;

use WP_HTTP_Response;
use WP_REST_Response;

class BitPaySupportPackage {

private BitPayWordpressHelper $bitpay_wordpress;
private BitPayLogger $bitpay_logger;

public function __construct(
BitPayWordpressHelper $bitpay_wordpress,
BitPayLogger $bitpay_logger
) {
$this->bitpay_wordpress = $bitpay_wordpress;
$this->bitpay_logger = $bitpay_logger;
}

public function get_zip(): WP_REST_Response {
$zipfile_string = $this->create_site_info_zip();

return $this->get_zip_rest_response( $zipfile_string );
}

private function create_site_info_zip(): string {
$json_data = $this->get_site_data_as_json();
$tmp_file = tmpfile();
$tmp_location = stream_get_meta_data( $tmp_file )['uri'];

$zip = new \ZipArchive();

if ( true !== $zip->open( $tmp_location, \ZipArchive::CREATE ) ) {
throw new \RuntimeException( 'Could not create zip file' );
}

$zip->addFromString( 'site-info.json', $json_data );
$log_directory = $this->bitpay_logger->get_log_directory();

if ( is_readable( $log_directory ) ) {
$zip->addGlob(
$log_directory . '*.log',
0,
array(
'remove_all_path' => true,
)
);
}

$zip->close();
$file_contents = file_get_contents( $tmp_location );

// This removes the file.
fclose( $tmp_file );

return $file_contents;
}

private function get_site_data_as_json(): bool|string {
$active_plugins = get_plugins();
$active_plugin_data = array();

foreach ( $active_plugins as $plugin_path => $plugin_data ) {
if ( is_plugin_active( $plugin_path ) ) {
$active_plugin_data[] = array(
'name' => $plugin_data['Name'],
'version' => $plugin_data['Version'],
);
}
}

$wpdb = $this->bitpay_wordpress->get_wpdb();
$extension = null;

// Populate the database debug fields.
if ( is_object( $wpdb->dbh ) ) {
// mysqli or PDO.
$extension = get_class( $wpdb->dbh );
}

$json_data = array(
'bitpay_plugin_version' => BitPayPluginSetup::VERSION,
'plugins' => $active_plugin_data,
'database' => array(
array(
'dbms' => $extension,
'dbms_version' => $wpdb->get_var( 'SELECT VERSION()' ), // phpcs:ignore
'char_set' => $wpdb->charset,
'collation' => $wpdb->collate,
'tables' => array(
array(
'table' => '_bitpay_checkout_transactions',
'exists' => $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}_bitpay_checkout_transactions'" ) ? 'yes' : 'no',
),
),
),
),
'wordpress' => array(
array(
'url' => home_url(),
'version' => get_bloginfo( 'version' ),
),
),
'server' => array(
array(
'software' => $_SERVER['SERVER_SOFTWARE'], // phpcs:ignore
'document_root' => $_SERVER['DOCUMENT_ROOT'], // phpcs:ignore
),
),
'php' => array(
'version' => phpversion(),
'memory_limit' => ini_get( 'memory_limit' ),
'max_execution_time' => ini_get( 'max_execution_time' ),
'max_file_upload_size' => ini_get( 'upload_max_filesize' ),
'max_post_size' => ini_get( 'post_max_size' ),
'max_input_variables' => ini_get( 'max_input_vars' ),
'curl_enabled' => function_exists( 'curl_version' ) ? 'yes' : 'no',
'curl_version' => function_exists( 'curl_version' ) ? curl_version()['version'] : '',
'openssl_version' => defined( 'OPENSSL_VERSION_TEXT' ) ? OPENSSL_VERSION_TEXT : '',
'mcrypt_enabled' => function_exists( 'mcrypt_encrypt' ) ? 'yes' : 'no',
'mbstring_enabled' => function_exists( 'mb_detect_encoding' ) ? 'yes' : 'no',
'extensions' => get_loaded_extensions(),
),
);

return json_encode( $json_data, JSON_PRETTY_PRINT );
}

/**
* Serves a zip via the REST endpoint.
*
* By default, every REST response is passed through json_encode(), as the
* typical REST response contains JSON data.
*
* This method hooks into the REST server to return a binary zip.
*
* @param string $data Data of the ZIP to serve.
*
* @return WP_REST_Response The REST response object to serve the zip.
*/
private function get_zip_rest_response( string $data ): WP_REST_Response {
$response = new WP_REST_Response();

$response->set_data( $data );
$response->set_headers(
array(
'Content-Type' => 'application/zip',
'Content-Length' => strlen( $data ),
)
);

// This filter will return our binary zip.
add_filter( 'rest_pre_serve_request', array( $this, 'serve_zip_action_handler' ), 0, 2 );

return $response;
}

/**
* Action handler that is used by `get_zip_rest_response()` to serve a binary image
* instead of a JSON string.
*
* @param bool $served Whether the request has already been served. Default false.
* @param WP_HTTP_Response $result Result to send to the client. Usually a WP_REST_Response.
*
* @return bool Returns true, if the image was served; this will skip the
* default REST response logic.
*
* @see https://developer.wordpress.org/reference/hooks/rest_pre_serve_request/
* */
public function serve_zip_action_handler( bool $served, WP_HTTP_Response $result ): bool {
$is_zip = false;
$zip_data = null;

// Check the "Content-Type" header to confirm that we really want to return
// binary zip data.
foreach ( $result->get_headers() as $header => $value ) {
if ( 'content-type' === strtolower( $header ) ) {
$is_zip = 0 === strpos( $value, 'application/zip' );
$zip_data = $result->get_data();
break;
}
}

// Output the binary data and tell the REST server to not send any other
// details (via "return true").
if ( $is_zip && is_string( $zip_data ) ) {
// phpcs:ignore
echo $zip_data;

return true;
}

return $served;
}
}
20 changes: 20 additions & 0 deletions BitPayLib/class-wcgatewaybitpay.php
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,24 @@ private function get_bitpay_version_info(): string {

return $plugin_name . ' ' . $plugin_data['Version'];
}

public function admin_options(): void {
parent::admin_options();
$this->add_support_package_download_button();
}

private function add_support_package_download_button() {
?>
<div style="display: flex; align-items: center">
<div style="padding-right: 24px;">
<p style="color: #1d2327; font-weight: 600; font-size: 14px; padding: 20px 10px 20px 0; width: 200px">Support Package </p>
</div>
<div style="padding: 15px 0; margin-top: 9px;">
<button type="button" style="height: 36px;" class="button button-secondary" id="download_support_package">Download</button>
<p style="margin-top: 2px; margin-bottom: 0;">Select to download a package of files that can be used for technical support. No personal
information will be captured.</p>
</div>
</div>
<?php
}
}
25 changes: 25 additions & 0 deletions js/wc_gateway_bitpay.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,30 @@ jQuery( document ).ready(
dark.html( '<img src="' + url + '" style="background-color: black"/>' );
}
)

function downloadZipFile(blob, name) {
const a = document.createElement( 'a' );
a.href = URL.createObjectURL( blob );
a.download = name;
a.click();
}

document.getElementById( 'download_support_package' ).addEventListener(
'click',
async function () {
const nonce = document.getElementById( '_wpnonce' );
wp.apiFetch.use( wp.apiFetch.createNonceMiddleware( nonce ) );

const response = await wp.apiFetch(
{
path: '/bitpay/site/health-status',
parse: false
}
);
const blob = await response.blob();

downloadZipFile( blob, 'bitpay-support-package.zip' );
}
);
}
);
9 changes: 8 additions & 1 deletion phpcs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@
<exclude name="WordPress.WP.AlternativeFunctions"/>
<exclude name="WordPress.DateTime.RestrictedFunctions"/>
</rule>
</ruleset>
<rule ref="WordPress.WP.Capabilities">
<properties>
<property name="custom_capabilities" type="array">
<element value="manage_woocommerce" />
</property>
</properties>
</rule>
</ruleset>
2 changes: 2 additions & 0 deletions scoper.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ static function (string $filePath, string $prefix, string $contents): string {
'WP_User',
'WC_Order',
'WP_REST_Request',
'WP_Rest_Response',
'WP_Http_Response',
'WC_Admin_Settings',
'Automattic\WooCommerce\Blocks\Package',
'Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry',
Expand Down
Loading