diff --git a/README.md b/README.md index 4ac3e04..25713ba 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,8 @@ This repository contains the PostFinance Checkout plugin that enables WooCommerc ## Documentation -* [Documentation](https://plugin-documentation.postfinance-checkout.ch/pfpayments/woocommerce/3.1.0/docs/en/documentation.html) +* [Documentation](https://plugin-documentation.postfinance-checkout.ch/pfpayments/woocommerce/3.1.1 +/docs/en/documentation.html) ## Support @@ -33,7 +34,8 @@ ____________________________________________________________________________ ## License -Please see the [license file](https://github.com/pfpayments/woocommerce/blob/3.1.0/LICENSE) for more information. +Please see the [license file](https://github.com/pfpayments/woocommerce/blob/3.1.1 +/LICENSE) for more information. ## Privacy Policy diff --git a/build/index.asset.php b/build/index.asset.php deleted file mode 100644 index 2c194d5..0000000 --- a/build/index.asset.php +++ /dev/null @@ -1,9 +0,0 @@ - array( - '@woocommerce/blocks-registry', - 'react', - 'wp-element', - 'wp-polyfill', - ), - 'version' => 'b53687c38b284a0c8c13', -); diff --git a/build/index.css b/build/index.css deleted file mode 100644 index 8b13789..0000000 --- a/build/index.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/build/index.js b/build/index.js deleted file mode 100644 index 8552c0d..0000000 --- a/build/index.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var e=window.wp.element,n=window.React,o=function({paymentMethodConfigurationId:o,eventRegistration:t}){const{onCheckoutSuccess:i,onCheckoutFail:a,onCheckoutValidation:c,onPaymentProcessing:r,onPaymentSetup:s}=t,[l,u]=(0,n.useState)(!0),d=`payment-method-${o}`;let m=window.IframeCheckoutHandler(o);const g=(0,n.useCallback)((()=>{m.create(d),u(!1)}),[o,d]);return(0,n.useEffect)((()=>{document.getElementById(d)&&g();const e=i((()=>(console.log("onCheckoutSuccess"),new Promise((e=>{console.log("Running submit"),m.submit(),setTimeout((function(){e(!1)}),3e4)}))))),n=c((()=>{console.log("onCheckoutValidation");let e=new Promise((e=>{m.setValidationCallback((n=>{console.log("Validation was ",n),void 0!==n.success?e(n.success):(console.error("Validation result did not return a success status."),e(!1))}))}));return m.validate(),e})),o=a((()=>{console.log("onCheckoutFail")})),t=r((()=>{console.log("onPaymentProcessing")})),l=s((()=>{console.log("onPaymentSetup")}));return()=>{e(),o(),n(),t(),l()}}),[g,d,i,a,c,r,s]),(0,e.createElement)("div",null,l&&(0,e.createElement)("div",null,"Loading payment method..."),(0,e.createElement)("div",{id:d}))},t=function({paymentMethodConfigurationId:e,eventRegistration:o}){console.log("LightboxComponent");const{onCheckoutSuccess:t,onCheckoutValidationBeforeProcessing:i,onCheckoutError:a}=o,[c,r]=(0,n.useState)(!0);(0,n.useEffect)((()=>{const n=t((()=>new Promise(((n,o)=>{console.log("onCheckoutSuccess"),window.LightboxCheckoutHandler.startPayment(e,(function(e,t){!e||e.error?o(e):n(e)}))})).then((e=>{console.log("Payment process finished",e)})).catch((e=>{alert("An error occurred during the initialization of the payment lightbox."),console.error(e)}))));return()=>{n()}}),[t,e])},i=window.wc.wcBlocksRegistry;jQuery((function(n){const a=wp.apiFetch.nonceEndpoint;n.post(a,{action:"get_payment_methods"},(function(c){c.map((function(c){let r;r="iframe"===c.integration_mode?(0,e.createElement)(o,{paymentMethodConfigurationId:c.configuration_id}):(0,e.createElement)(t,{paymentMethodConfigurationId:c.configuration_id});let s={name:c.name,label:c.label,content:r,edit:(0,e.createElement)("div",null,c.description),ariaLabel:c.ariaLabel,canMakePayment:async e=>await async function(){try{return new Promise(((e,o)=>{n.post(a,{action:"is_payment_method_available",payment_method:c.name,configuration_id:c.configuration_id},(function(n){e(n)})).fail((function(e){console.error("Error:",e),o(!1)}))}))}catch(e){return console.error("Error:",e),!1}}()};(0,i.registerPaymentMethod)(s)}))})).fail((function(e){console.error("Error getting payment methods. ",e)}))}))}(); \ No newline at end of file diff --git a/changelog.txt b/changelog.txt index fc01d31..61e312d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -822,3 +822,10 @@ Tested against: - [Tested Against] Woocommerce 9.1.4 & Woocommerce 9.2.1 - [Tested Against] PHP SDK 4.5.0 += 3.1.1 - Sept 13 2024 = +- [Bugfix] Added migrations for 3.1.0 changes. +- [Tested Against] PHP 8.2 +- [Tested Against] Wordpress 6.6 +- [Tested Against] Woocommerce 9.3.1 +- [Tested Against] PHP SDK 4.5.0 + diff --git a/docs/en/documentation.html b/docs/en/documentation.html index ba6eb2b..e160845 100644 --- a/docs/en/documentation.html +++ b/docs/en/documentation.html @@ -23,7 +23,8 @@

Documentation

  • - + Source
  • diff --git a/includes/admin/class-wc-postfinancecheckout-admin-settings-page.php b/includes/admin/class-wc-postfinancecheckout-admin-settings-page.php index f5a83c8..1a46e18 100644 --- a/includes/admin/class-wc-postfinancecheckout-admin-settings-page.php +++ b/includes/admin/class-wc-postfinancecheckout-admin-settings-page.php @@ -184,7 +184,8 @@ public function get_settings() { $settings = array( array( 'links' => array( - 'https://plugin-documentation.postfinance-checkout.ch/pfpayments/woocommerce/3.1.0/docs/en/documentation.html' => esc_html__( 'Documentation', 'woo-postfinancecheckout' ), + 'https://plugin-documentation.postfinance-checkout.ch/pfpayments/woocommerce/3.1.1 +/docs/en/documentation.html' => esc_html__( 'Documentation', 'woo-postfinancecheckout' ), 'https://checkout.postfinance.ch/en-ch/user/signup' => esc_html__( 'Sign Up', 'woo-postfinancecheckout' ), ), 'type' => 'postfinancecheckout_links', diff --git a/includes/class-wc-postfinancecheckout-blocks-support.php b/includes/class-wc-postfinancecheckout-blocks-support.php index 1ecb79d..ce18521 100644 --- a/includes/class-wc-postfinancecheckout-blocks-support.php +++ b/includes/class-wc-postfinancecheckout-blocks-support.php @@ -190,7 +190,7 @@ public static function enqueue_portal_scripts() { true ); } catch ( Exception $e ) { - PostFinanceCheckout_WooCommerce::instance()->log( $e->getMessage(), WC_Log_Levels::DEBUG ); + WooCommerce_PostFinanceCheckout::instance()->log( $e->getMessage(), WC_Log_Levels::DEBUG ); } } diff --git a/includes/class-wc-postfinancecheckout-migration.php b/includes/class-wc-postfinancecheckout-migration.php index ad16f1d..65bf04a 100644 --- a/includes/class-wc-postfinancecheckout-migration.php +++ b/includes/class-wc-postfinancecheckout-migration.php @@ -26,6 +26,20 @@ class WC_PostFinanceCheckout_Migration { const POSTFINANCECHECKOUT_CK_DB_VERSION = 'wc_postfinancecheckout_db_version'; + /** + * Deprecated table prefix. + * + * This constant holds the deprecated table prefix. It is necessary to avoid using this prefix + * to stay aligned with the WordPress coding standards. The WordPress coding standards recommend + * using table names without custom prefixes to ensure compatibility and standardization. + * + * @deprecated Avoid using this prefix to comply with WordPress coding standards. + */ + const POSTFINANCECHECKOUT_DEPRECATED_TABLE_PREFIX = 'wc_'; + const POSTFINANCECHECKOUT_DEPRECATED_PLUGIN_PREFIX = 'woo-'; + + // const POSTFINANCECHECKOUT_CK_DB_VERSION = 'wc_postfinancecheckout_db_version'; + /** * Database migrations. * @@ -39,6 +53,7 @@ class WC_PostFinanceCheckout_Migration { '1.0.4' => 'update_1_0_4_failure_msg_and_attribute', '1.0.5' => 'update_1_0_5_clear_provider_transients', '1.0.6' => 'update_1_0_6_shorten_table_names', + '1.0.7' => 'update_1_0_7_migrate_plugin_name_and_tables', ); /** @@ -254,7 +269,8 @@ public static function check_version() { public static function plugin_row_meta( $links, $file ) { if ( WC_POSTFINANCECHECKOUT_PLUGIN_BASENAME === $file ) { $row_meta = array( - 'docs' => '' . esc_html__( 'Documentation', 'woo-postfinancecheckout' ) . '', + 'docs' => '' . esc_html__( 'Documentation', 'woo-postfinancecheckout' ) . '', ); return array_merge( $links, $row_meta ); @@ -375,7 +391,7 @@ public static function update_1_0_0_initialize() { `updated_at` datetime NOT NULL, `restock` varchar(1) COLLATE utf8_unicode_ci, `items` longtext COLLATE utf8_unicode_ci, - `failure_reason` longtext COLLATE utf8_unicode_ci, + `failure_reason` longtext COLLATE utf8_unicode_ci, PRIMARY KEY (`id`), KEY `idx_transaction_id_space_id` (`transaction_id`,`space_id`), KEY `idx_completion_id_space_id` (`completion_id`,`space_id`) @@ -543,7 +559,7 @@ public static function update_1_0_3_image_domain() { if ( 0 === $result ) { // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. $result = $wpdb->query( "ALTER TABLE $table_transaction_info ADD COLUMN `image_base` VARCHAR(2047) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL AFTER image" ); - // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. + // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. if ( false === $result ) { throw new Exception( esc_html( $wpdb->last_error ) ); @@ -562,21 +578,21 @@ public static function update_1_0_4_failure_msg_and_attribute() { $table_transaction_info = $wpdb->prefix . 'postfinancecheckout_transaction_info'; //phpcs:ignore $table_attribute_options = $wpdb->prefix . 'postfinancecheckout_attribute_options'; //phpcs:ignore - // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. $result = $wpdb->query( $wpdb->prepare( "SHOW COLUMNS FROM $table_transaction_info LIKE %s", 'user_failure_message' ) ); // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. if ( 0 === $result ) { - // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. $result = $wpdb->query( "ALTER TABLE $table_transaction_info ADD COLUMN `user_failure_message` VARCHAR(2047) CHARACTER SET utf8 COLLATE utf8_unicode_ci NULL DEFAULT NULL AFTER failure_reason" ); - // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. + // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. if ( false === $result ) { throw new Exception( esc_html( $wpdb->last_error ) ); } } // Do not use foreign keys to reference attribute to cascade deletion, as some shop still run with MyISAM enginge as default. - // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. $result = $wpdb->query( "CREATE TABLE IF NOT EXISTS $table_attribute_options( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, @@ -586,7 +602,7 @@ public static function update_1_0_4_failure_msg_and_attribute() { UNIQUE `unq_attribute_id` (`attribute_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci" ); - // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. + // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. if ( false == $result ) { throw new Exception( esc_html( $wpdb->last_error ) ); @@ -608,54 +624,44 @@ public static function update_1_0_5_clear_provider_transients() { public static function update_1_0_6_shorten_table_names() { global $wpdb; // old table names format => new table names format. + $table_prefix = self::POSTFINANCECHECKOUT_DEPRECATED_TABLE_PREFIX; $table_rename_map = array( - "{$wpdb->prefix}woocommerce_postfinancecheckout_attribute_options" => "{$wpdb->prefix}postfinancecheckout_attribute_options", - "{$wpdb->prefix}woocommerce_postfinancecheckout_completion_job" => "{$wpdb->prefix}postfinancecheckout_completion_job", - "{$wpdb->prefix}woocommerce_postfinancecheckout_method_configuration" => "{$wpdb->prefix}postfinancecheckout_method_config", - "{$wpdb->prefix}woocommerce_postfinancecheckout_refund_job" => "{$wpdb->prefix}postfinancecheckout_refund_job", - "{$wpdb->prefix}woocommerce_postfinancecheckout_token_info" => "{$wpdb->prefix}postfinancecheckout_token_info", - "{$wpdb->prefix}woocommerce_postfinancecheckout_transaction_info" => "{$wpdb->prefix}postfinancecheckout_transaction_info", - "{$wpdb->prefix}woocommerce_postfinancecheckout_void_job" => "{$wpdb->prefix}postfinancecheckout_void_job", + "{$wpdb->prefix}{$table_prefix}woocommerce_postfinancecheckout_attribute_options" => "{$wpdb->prefix}{$table_prefix}postfinancecheckout_attribute_options", + "{$wpdb->prefix}{$table_prefix}woocommerce_postfinancecheckout_completion_job" => "{$wpdb->prefix}{$table_prefix}postfinancecheckout_completion_job", + "{$wpdb->prefix}{$table_prefix}woocommerce_postfinancecheckout_method_configuration" => "{$wpdb->prefix}{$table_prefix}postfinancecheckout_method_config", + "{$wpdb->prefix}{$table_prefix}woocommerce_postfinancecheckout_refund_job" => "{$wpdb->prefix}{$table_prefix}postfinancecheckout_refund_job", + "{$wpdb->prefix}{$table_prefix}woocommerce_postfinancecheckout_token_info" => "{$wpdb->prefix}{$table_prefix}postfinancecheckout_token_info", + "{$wpdb->prefix}{$table_prefix}woocommerce_postfinancecheckout_transaction_info" => "{$wpdb->prefix}{$table_prefix}postfinancecheckout_transaction_info", + "{$wpdb->prefix}{$table_prefix}woocommerce_postfinancecheckout_void_job" => "{$wpdb->prefix}{$table_prefix}postfinancecheckout_void_job", ); - // rollback table rename if there are issues. - // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. - $wpdb->query( 'START TRANSACTION' ); //phpcs:ignore - // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. - - $table_statement = 'Tables_in_' . $wpdb->dbname; - - foreach ( $table_rename_map as $key => $value ) { - // check old table exists. - // phpcs:ignore - // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. - $old_table_result = $wpdb->get_row( - $wpdb->prepare( "SHOW TABLES WHERE $table_statement = %s", $key ) - ); - // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. - - if ( $old_table_result ) { - // check new table doesn't exist, if it does there's a problem! - // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. - $new_table_result = $wpdb->get_row( - $wpdb->prepare( "SHOW TABLES WHERE $table_statement = %s", $value ) - ); - // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. + self::rename_tables( $table_rename_map ); + } - if ( ! $new_table_result ) { - // phpcs:ignore - // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. - $result = $wpdb->query( "RENAME TABLE $key TO $value" ); - // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. - if ( false === $result ) { - throw new Exception( esc_html( $wpdb->last_error ) ); - } - } - } - } - $wpdb->query( 'COMMIT' ); //phpcs:ignore + /** + * Rename plugin tables and update plugin name. + * + * This function renames the tables and updates the plugin name + * to ensure a smooth upgrade without duplicating the plugin installation, version 4.0.0. + * + * @throws Exception Exception. + */ + public static function update_1_0_7_migrate_plugin_name_and_tables() { + global $wpdb; + // old table names format => new table names format. + $table_prefix = self::POSTFINANCECHECKOUT_DEPRECATED_TABLE_PREFIX; + $table_rename_map = array( + "{$wpdb->prefix}{$table_prefix}postfinancecheckout_attribute_options" => "{$wpdb->prefix}postfinancecheckout_attribute_options", + "{$wpdb->prefix}{$table_prefix}postfinancecheckout_completion_job" => "{$wpdb->prefix}postfinancecheckout_completion_job", + "{$wpdb->prefix}{$table_prefix}postfinancecheckout_method_config" => "{$wpdb->prefix}postfinancecheckout_method_config", + "{$wpdb->prefix}{$table_prefix}postfinancecheckout_refund_job" => "{$wpdb->prefix}postfinancecheckout_refund_job", + "{$wpdb->prefix}{$table_prefix}postfinancecheckout_token_info" => "{$wpdb->prefix}postfinancecheckout_token_info", + "{$wpdb->prefix}{$table_prefix}postfinancecheckout_transaction_info" => "{$wpdb->prefix}postfinancecheckout_transaction_info", + "{$wpdb->prefix}{$table_prefix}postfinancecheckout_void_job" => "{$wpdb->prefix}postfinancecheckout_void_job", + ); + self::rename_tables( $table_rename_map ); } /** @@ -698,6 +704,51 @@ function () { } } } + + /** + * Rename tables based on the mapping. + * + * @param array $table_rename_map Array of old table names => new table names. + * @throws Exception Exception. + */ + private static function rename_tables( $table_rename_map ) { + global $wpdb; + // rollback table rename if there are issues. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. + $wpdb->query( 'START TRANSACTION' ); //phpcs:ignore + // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. + $table_stament = 'Tables_in_' . $wpdb->dbname; + + foreach ( $table_rename_map as $old_table_name => $new_table_name ) { + // check old table exists. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. + $old_table_result = $wpdb->get_row( + $wpdb->prepare( "SHOW TABLES WHERE $table_stament = %s", $old_table_name ) + ); + // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. + + if ( $old_table_result ) { + // check new table doesn't exist, if it does there's a problem!. + // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. + $new_table_result = $wpdb->get_row( + $wpdb->prepare( "SHOW TABLES WHERE $table_stament = %s", $new_table_name ) + ); + // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. + + if ( ! $new_table_result ) { + // phpcs:disable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare -- Values are escaped in $wpdb->prepare. + $result = $wpdb->query( "RENAME TABLE $old_table_name TO $new_table_name" ); + // phpcs:enable WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare. + if ( false === $result ) { + throw new Exception( esc_html( $wpdb->last_error ) ); + } + } + } + } + + $wpdb->query( 'COMMIT' ); //phpcs:ignore + } + } WC_PostFinanceCheckout_Migration::init(); diff --git a/includes/packages/coupon/class-wc-postfinancecheckout-packages-coupon-discount.php b/includes/packages/coupon/class-wc-postfinancecheckout-packages-coupon-discount.php index 0792062..2674360 100644 --- a/includes/packages/coupon/class-wc-postfinancecheckout-packages-coupon-discount.php +++ b/includes/packages/coupon/class-wc-postfinancecheckout-packages-coupon-discount.php @@ -110,15 +110,16 @@ public static function copy_total_coupon_discount_meta_data_to_order_item( WC_Or public static function get_coupons_discount_totals_including_tax( $currency ) { $coupons_discount_total = 0; - //guard clause if the order doesn't exists, nothing to do here. + // guard clause if the order doesn't exists, nothing to do here. $session = WC()->session; - if ( ! class_exists('WC_Session' ) || ! ( $session instanceof WC_Session ) ) { + if ( ! class_exists( 'WC_Session' ) || ! ( $session instanceof WC_Session ) ) { return $coupons_discount_total; } $order_id = $session->get( 'postfinancecheckout_order_id' ); - if ( WC()->cart->get_cart_contents_count() == 0 && !is_null( $order_id ) ) { - if ( $order = wc_get_order( $order_id ) ) { + if ( WC()->cart->get_cart_contents_count() == 0 && ! is_null( $order_id ) ) { + $order = wc_get_order( $order_id ); + if ( $order ) { $coupons_discount_total += $order->get_total_discount(); } } diff --git a/includes/service/class-wc-postfinancecheckout-service-webhook.php b/includes/service/class-wc-postfinancecheckout-service-webhook.php index 0440188..234500c 100644 --- a/includes/service/class-wc-postfinancecheckout-service-webhook.php +++ b/includes/service/class-wc-postfinancecheckout-service-webhook.php @@ -304,7 +304,7 @@ protected function get_webhook_url( $space_id ) { return null; } } catch ( \Exception $e ) { - PostFinanceCheckout_WooCommerce::instance()->log( $e->getMessage(), WC_Log_Levels::ERROR ); + WooCommerce_PostFinanceCheckout::instance()->log( $e->getMessage(), WC_Log_Levels::ERROR ); } } diff --git a/includes/webhook/strategies/class-wc-postfinancecheckout-webhook-refund-strategy.php b/includes/webhook/strategies/class-wc-postfinancecheckout-webhook-refund-strategy.php index 47aebdf..9d277f5 100644 --- a/includes/webhook/strategies/class-wc-postfinancecheckout-webhook-refund-strategy.php +++ b/includes/webhook/strategies/class-wc-postfinancecheckout-webhook-refund-strategy.php @@ -113,7 +113,7 @@ protected function process_order_related_inner( WC_Order $order, \PostFinanceChe protected function failed( \PostFinanceCheckout\Sdk\Model\Refund $refund, WC_Order $order ) { $refund_job = WC_PostFinanceCheckout_Entity_Refund_Job::load_by_external_id( $refund->getLinkedSpaceId(), $refund->getExternalId() ); if ( $refund_job->get_id() ) { - $refund_job->set_state( WC_PostFinanceCheckout_Entity_Refund_Job::STATE_FAILURE ); + $refund_job->set_state( WC_PostFinanceCheckout_Entity_Refund_Job::POSTFINANCECHECKOUT_STATE_FAILURE ); if ( $refund->getFailureReason() != null ) { $refund_job->set_failure_reason( $refund->getFailureReason()->getDescription() ); } @@ -141,7 +141,7 @@ protected function refunded( \PostFinanceCheckout\Sdk\Model\Refund $refund, WC_O $refund_job = WC_PostFinanceCheckout_Entity_Refund_Job::load_by_external_id( $refund->getLinkedSpaceId(), $refund->getExternalId() ); if ( $refund_job->get_id() ) { - $refund_job->set_state( WC_PostFinanceCheckout_Entity_Refund_Job::STATE_SUCCESS ); + $refund_job->set_state( WC_PostFinanceCheckout_Entity_Refund_Job::POSTFINANCECHECKOUT_STATE_SUCCESS ); $refund_job->save(); $refunds = $order->get_refunds(); foreach ( $refunds as $wc_refund ) { diff --git a/includes/webhook/strategies/class-wc-postfinancecheckout-webhook-transaction-void-strategy.php b/includes/webhook/strategies/class-wc-postfinancecheckout-webhook-transaction-void-strategy.php index b29cdfb..53d92cb 100644 --- a/includes/webhook/strategies/class-wc-postfinancecheckout-webhook-transaction-void-strategy.php +++ b/includes/webhook/strategies/class-wc-postfinancecheckout-webhook-transaction-void-strategy.php @@ -124,7 +124,7 @@ protected function success( WC_Order $order, \PostFinanceCheckout\Sdk\Model\Tran } $void_job->set_void_id( $void->getId() ); } - $void_job->set_state( WC_PostFinanceCheckout_Entity_Void_Job::STATE_DONE ); + $void_job->set_state( WC_PostFinanceCheckout_Entity_Void_Job::POSTFINANCECHECKOUT_STATE_DONE ); if ( $void_job->get_restock() ) { WC_PostFinanceCheckout_Helper::instance()->maybe_restock_items_for_order( $order ); @@ -155,7 +155,7 @@ protected function failed( WC_Order $order, \PostFinanceCheckout\Sdk\Model\Trans if ( $void_job->getFailureReason() != null ) { $void_job->set_failure_reason( $void->getFailureReason()->getDescription() ); } - $void_job->set_state( WC_PostFinanceCheckout_Entity_Void_Job::STATE_DONE ); + $void_job->set_state( WC_PostFinanceCheckout_Entity_Void_Job::POSTFINANCECHECKOUT_STATE_DONE ); $void_job->save(); } } diff --git a/readme.txt b/readme.txt index 26b6323..41fec2f 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Contributors: postfinancecheckout AG Tags: woocommerce PostFinance Checkout, woocommerce, PostFinance Checkout, payment, e-commerce, webshop, psp, invoice, packing slips, pdf, customer invoice, processing Requires at least: 4.7 Tested up to: 6.6 -Stable tag: 3.1.0 +Stable tag: 3.1.1 License: Apache 2 License URI: http://www.apache.org/licenses/LICENSE-2.0 @@ -23,7 +23,8 @@ To use this extension, a PostFinance Checkout account is required. Sign up on [P == Documentation == -Additional documentation for this plugin is available [here](https://plugin-documentation.postfinance-checkout.ch/pfpayments/woocommerce/3.1.0/docs/en/documentation.html). +Additional documentation for this plugin is available [here](https://plugin-documentation.postfinance-checkout.ch/pfpayments/woocommerce/3.1.1 +/docs/en/documentation.html). == Support == @@ -64,13 +65,9 @@ Enquiries about our terms of use can be made on the [PostFinance Checkout terms == Changelog == -= 3.1.0 - Sept 12 2024 = -- [Feature] Add privacy policy URL -- [Feature] Adhere to WP code standards -- [Feature] Add Support for WC 9.2.x -- [Bugfix] Fix for error when renewing subscriptions -- [Bugfix] Fix for deferred payments status being incorrect -- [Tested Against] PHP 8.2 and PHP 7.4 -- [Tested Against] Wordpress 6.6 -- [Tested Against] Woocommerce 9.1.4 & Woocommerce 9.2.1 += 3.1.1 - Sept 13 2024 = +- [Bugfix] Added migrations for 3.1.0 changes. +- [Tested Against] PHP 8.2 +- [Tested Against] Wordpress 6.6 +- [Tested Against] Woocommerce 9.3.1 - [Tested Against] PHP SDK 4.5.0 diff --git a/woocommerce-postfinancecheckout.php b/woocommerce-postfinancecheckout.php index 47c02bf..86279c6 100644 --- a/woocommerce-postfinancecheckout.php +++ b/woocommerce-postfinancecheckout.php @@ -3,7 +3,7 @@ * Plugin Name: PostFinance Checkout * Plugin URI: https://wordpress.org/plugins/woo-postfinance-checkout * Description: Process WooCommerce payments with PostFinance Checkout. - * Version: 3.1.0 + * Version: 3.1.1 * Author: postfinancecheckout AG * Author URI: https://postfinance.ch/en/business/products/e-commerce/postfinance-checkout-all-in-one.html * Text Domain: postfinancecheckout @@ -38,6 +38,7 @@ final class WooCommerce_PostFinanceCheckout { const POSTFINANCECHECKOUT_CK_INTEGRATION = 'wc_postfinancecheckout_integration'; const POSTFINANCECHECKOUT_CK_ORDER_REFERENCE = 'wc_postfinancecheckout_order_reference'; const POSTFINANCECHECKOUT_CK_ENFORCE_CONSISTENCY = 'wc_postfinancecheckout_enforce_consistency'; + const POSTFINANCECHECKOUT_UPGRADE_VERSION = '3.1.1'; const WC_MAXIMUM_VERSION = '9.2.3'; /** @@ -45,7 +46,7 @@ final class WooCommerce_PostFinanceCheckout { * * @var string */ - private $version = '3.1.0'; + private $version = '3.1.1'; /** * The single instance of the class. @@ -135,6 +136,14 @@ protected function includes() { * @return void */ protected function init_hooks() { + register_activation_hook( + __FILE__, + array( + 'WooCommerce_PostFinanceCheckout', + 'migrate_plugin_data_on_activation' + ) + ); + register_activation_hook( __FILE__, array( @@ -178,6 +187,17 @@ protected function init_hooks() { ) ); + // Hook to run migration after plugin update. + add_action( + 'upgrader_process_complete', + array( + $this, + 'migrate_plugin_data_after_update', + ), + 10, + 2 + ); + add_action( 'plugins_loaded', array( @@ -277,7 +297,7 @@ protected function init_hooks() { * Activation hook. * Fired when the plugin is activated. */ - public function plugin_activate() { + public static function plugin_activate() { // Clear the permalinks after the post type has been registered. flush_rewrite_rules(); } @@ -286,7 +306,28 @@ public function plugin_activate() { * Deactivation hook. * Fired when the plugin is deactivated. */ - public function plugin_deactivate() { + public static function plugin_deactivate() { + // Get the plugin version. + $old_plugin_prefix = WC_PostFinanceCheckout_Migration::POSTFINANCECHECKOUT_DEPRECATED_PLUGIN_PREFIX; + $plugin_current_version = self::get_installed_plugin_version( $old_plugin_prefix . 'postfinancecheckout' ); // The slug of the old plugin. + + // Check if the plugin version is lower than 3.1.0. + if ( version_compare( $plugin_current_version, self::POSTFINANCECHECKOUT_UPGRADE_VERSION, '<' ) ) { + // Start output buffering to prevent "headers already sent" errors. + ob_start(); + } + + // Hook to run migration after plugin update. + add_action( + 'upgrader_process_complete', + array( + 'WooCommerce_PostFinanceCheckout', + 'migrate_plugin_data_after_update', + ), + 10, + 2 + ); + // Clear the permalinks to remove our post type's rules from the database. flush_rewrite_rules(); } @@ -300,6 +341,27 @@ public static function plugin_uninstall() { // delete the registered options. } + /** + * Function to get the installed version of a plugin. + * + * @param string $plugin_slug The slug of the plugin. + * @return string|null The version of the plugin or null if not found. + */ + public static function get_installed_plugin_version( $plugin_slug ) { + if (!function_exists( 'get_plugins' ) ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + } + + $all_plugins = get_plugins(); + foreach ( $all_plugins as $plugin_path => $plugin_info ) { + if ( strpos( $plugin_path, $plugin_slug ) !== false ) { + return $plugin_info[ 'Version' ]; + } + } + + return null; + } + /** * Security check in the thank you page. * @@ -322,6 +384,90 @@ public function secure_redirect_order_confirmed( $order_id ) { } } + /** + * Migrates settings from the old plugin version to the new version 4.0.0. + * + * This function checks if the settings from the old plugin version exist. + * If they do, it transfers these settings to the new plugin's options + * and deletes the old settings from the database. + * + * This ensures that users retain their configurations when updating + * from the old plugin version to the new version. + * + * @return void + */ + public static function migrate_plugin_data_on_activation() { + $old_option_prefix = WC_PostFinanceCheckout_Migration::POSTFINANCECHECKOUT_DEPRECATED_TABLE_PREFIX; + $old_plugin_prefix = WC_PostFinanceCheckout_Migration::POSTFINANCECHECKOUT_DEPRECATED_PLUGIN_PREFIX; + + $plugin_slug = $old_plugin_prefix . 'postfinancecheckout'; // The slug of the old plugin. + $installed_version = self::get_installed_plugin_version( $plugin_slug ); + + /** + * Check if the installed version is 3.1.1 or higher. + * If the version is 3.1.1 or higher, do not run the migration. + */ + if ( version_compare( $installed_version, self::POSTFINANCECHECKOUT_UPGRADE_VERSION, '>=' ) ) { + return; + } + + global $wpdb; + $options_to_migrate = [ + $old_option_prefix . WC_PostFinanceCheckout_Migration::POSTFINANCECHECKOUT_CK_DB_VERSION, + $old_option_prefix . WC_PostFinanceCheckout_Service_Manual_Task::POSTFINANCECHECKOUT_CONFIG_KEY, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_SPACE_ID, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_SPACE_VIEW_ID, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_APP_USER_ID, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_APP_USER_KEY, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_CUSTOMER_INVOICE, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_CUSTOMER_PACKING, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_SHOP_EMAIL, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_INTEGRATION, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_ORDER_REFERENCE, + $old_option_prefix . self::POSTFINANCECHECKOUT_CK_ENFORCE_CONSISTENCY, + $old_option_prefix . self::POSTFINANCECHECKOUT_WC_MAXIMUM_VERSION, + ]; + + // If the old plugin options exist, perform the migration + foreach ( $options_to_migrate as $option_name ) { + $option_value = get_option( $option_name ); + if ( $option_value !== false ) { + // Rename the options to the new prefix 'postfinancecheckout_'. + $new_option_name = str_replace( $old_option_prefix . 'postfinancecheckout_', 'postfinancecheckout_', $option_name ); + if ( get_option( $new_option_name ) !== false ) { + // Update the option if it already exists. + update_option( $new_option_name, $option_value ); + } else { + // Add the option if it doesn't exist. + add_option( $new_option_name, $option_value ); + } + // Delete the old option. + //delete_option( $option_name );. + } + } + } + + /** + * Function to migrate plugin data after update + * This function is triggered after the plugin is updated + * + * @param object $upgrader_object The upgrader object. + * @param array $options The options array. + */ + public static function migrate_plugin_data_after_update( $upgrader_object, $options ) { + // Check if the plugin was just updated. + if ( $options['action'] == 'update' && $options['type'] == 'plugin' ) { + $plugin_basename = plugin_basename( __FILE__ ); + foreach ( $options['plugins'] as $plugin ) { + if ( $plugin == $plugin_basename ) { + self::migrate_plugin_data_on_activation(); + break; + } + } + } + } + + /** * Load Localization files. *