Skip to content
Open
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
52 changes: 39 additions & 13 deletions inc/checkout.php
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
<?php
/**
* Checkout policy terms: customize the terms checkbox and validate consent.
* Checkout policy terms: require the consent and link the policy.
*
* @package libresign
*/

defined( 'ABSPATH' ) || exit;

/**
* Customize the checkout terms checkbox text to point at the policy page.
* Require the policy consent on the checkout.
*/
function libresign_theme_checkout_policy_checkbox_text( $text ) {
$policy_url = libresign_theme_get_policy_url();
function libresign_theme_register_policy_consent_field() {
if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
return;
}

return sprintf(
/* translators: %s: policy page link */
__( 'I agree to the %s before placing the order.', 'libresign' ),
sprintf(
'<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
esc_url( $policy_url ),
esc_html__( 'terms and privacy policy', 'libresign' )
woocommerce_register_additional_checkout_field(
array(
'id' => 'libresign/policy-consent',
'label' => __( 'I agree to the terms and privacy policy before placing the order.', 'libresign' ),
'location' => 'order',
'type' => 'checkbox',
'required' => true,
'error_message' => __( 'You must agree to the policies before completing the purchase.', 'libresign' ),
)
);
}
add_filter( 'woocommerce_get_terms_and_conditions_checkbox_text', 'libresign_theme_checkout_policy_checkbox_text' );
add_action( 'woocommerce_init', 'libresign_theme_register_policy_consent_field' );

/**
* Prevent checkout submission without policy terms acceptance.
* Refuse an order placed through the classic checkout without the policy consent.
*/
function libresign_theme_validate_checkout_policy_consent( $data, $errors ) {
if ( empty( $data['terms'] ) ) {
Expand All @@ -37,3 +40,26 @@ function libresign_theme_validate_checkout_policy_consent( $data, $errors ) {
}
}
add_action( 'woocommerce_after_checkout_validation', 'libresign_theme_validate_checkout_policy_consent', 10, 2 );

/**
* Link the checkout terms text to the policy.
*/
function libresign_theme_link_checkout_terms_to_policy( $block_content ) {
$text = sprintf(
/* translators: %s: policy page link */
__( 'Read the %s.', 'libresign' ),
sprintf(
'<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
esc_url( libresign_theme_get_policy_url() ),
esc_html__( 'terms and privacy policy', 'libresign' )
)
);

return (string) preg_replace(
'/<div(?=[^>]*\bwp-block-woocommerce-checkout-terms-block\b)/',
'<div data-text="' . esc_attr( $text ) . '"',
(string) $block_content,
1
);
}
add_filter( 'render_block_woocommerce/checkout-terms-block', 'libresign_theme_link_checkout_terms_to_policy' );
53 changes: 39 additions & 14 deletions tests/Integration/Inc/CheckoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,59 @@

namespace LibreSign\WordPressTheme\Tests\Integration\Inc;

use Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields;
use Automattic\WooCommerce\Blocks\Package;
use WP_Error;
use WP_UnitTestCase;

final class CheckoutTest extends WP_UnitTestCase {

private function checkout_errors( $data ) {
$errors = new WP_Error();
do_action( 'woocommerce_after_checkout_validation', $data, $errors );
public function test_requires_the_policy_consent_to_place_an_order() {
__internal_woocommerce_blocks_deregister_checkout_field( 'libresign/policy-consent' );

return $errors;
}
libresign_theme_register_policy_consent_field();

public function test_the_terms_checkbox_links_to_the_policy_in_a_new_tab() {
$this->assertSame(
'I agree to the <a href="https://libresign.coop/privacy-policy" target="_blank" rel="noopener noreferrer">terms and privacy policy</a> before placing the order.',
apply_filters( 'woocommerce_get_terms_and_conditions_checkbox_text', '' )
);
$field = Package::container()->get( CheckoutFields::class )->get_additional_fields()['libresign/policy-consent'];

$this->assertSame( 'checkbox', $field['type'] );
$this->assertSame( 'order', $field['location'] );
$this->assertTrue( $field['required'] );
$this->assertSame( 'I agree to the terms and privacy policy before placing the order.', $field['label'] );
$this->assertSame( 'You must agree to the policies before completing the purchase.', $field['errorMessage'] );
}

public function test_refuses_an_order_without_the_policy_consent() {
$errors = $this->checkout_errors( array( 'terms' => 0 ) );
public function test_the_classic_checkout_refuses_an_order_without_the_consent() {
$errors = new WP_Error();

do_action( 'woocommerce_after_checkout_validation', array( 'terms' => 0 ), $errors );

$this->assertContains( 'libresign_policy_consent', $errors->get_error_codes() );
}

public function test_accepts_an_order_with_the_policy_consent() {
$errors = $this->checkout_errors( array( 'terms' => 1 ) );
public function test_the_classic_checkout_accepts_an_order_with_the_consent() {
$errors = new WP_Error();

do_action( 'woocommerce_after_checkout_validation', array( 'terms' => 1 ), $errors );

$this->assertNotContains( 'libresign_policy_consent', $errors->get_error_codes() );
}

/**
* @dataProvider provide_terms_blocks
*/
public function test_links_the_checkout_terms_to_the_policy( $block_content ) {
$this->assertSame(
'<div data-text="Read the &lt;a href=&quot;https://libresign.coop/privacy-policy&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;terms and privacy policy&lt;/a&gt;."' . substr( $block_content, 4 ),
apply_filters( 'render_block_woocommerce/checkout-terms-block', $block_content )
);
}

public static function provide_terms_blocks() {
yield 'as saved' => array( '<div class="wp-block-woocommerce-checkout-terms-block"></div>' );
yield 'as woocommerce renders it' => array( '<div data-block-name="woocommerce/checkout-terms-block" class="wp-block-woocommerce-checkout-terms-block"></div>' );
}

public function test_leaves_other_markup_alone() {
$this->assertSame( '<div class="wp-block-group"></div>', libresign_theme_link_checkout_terms_to_policy( '<div class="wp-block-group"></div>' ) );
}
}
Loading